Added creation and approving propose with issue

This commit is contained in:
Alexander Suslikov 2019-02-06 10:07:07 +03:00 committed by Anzhy Cherrnyavski
parent f4afdbe145
commit 40e13800f2
11 changed files with 126 additions and 42 deletions

View file

@ -102,6 +102,7 @@ void bitcoin_transaction_send_evaluator::send_bitcoin_transaction( const bitcoin
database& d = db();
uint32_t skip = d.get_node_properties().skip_flags;
if( !(skip & graphene::chain::database::skip_btc_tx_sending) && d.send_btc_tx_flag ){
idump((btc_tx));
d.send_btc_tx( btc_tx.transaction );
}
}

View file

@ -398,7 +398,7 @@ signed_block database::_generate_block(
size_t total_block_size = max_block_header_size;
if( !is_sidechain_fork_needed() ) {
processing_sidechain_proposals( witness_obj, block_signing_private_key );
processing_sidechain_proposals( witness_obj, block_signing_private_key );
}
signed_block pending_block;
@ -418,10 +418,15 @@ signed_block database::_generate_block(
_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 ) );
}
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 ) );
}
auto iss_op = create_bitcoin_issue_proposals( witness_obj );
if( iss_op.valid() ) {
_pending_tx.insert( _pending_tx.begin(), create_signed_transaction( block_signing_private_key, *iss_op ) );
}
}
send_btc_tx_flag = false;

View file

@ -2,8 +2,10 @@
#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>
#include <graphene/chain/bitcoin_transaction_object.hpp>
#include <sidechain/sidechain_condensing_tx.hpp>
#include <sidechain/sign_bitcoin_transaction.hpp>
using namespace sidechain;
@ -133,7 +135,14 @@ void database::processing_sidechain_proposals( const witness_object& current_wit
FC_ASSERT( proposal != proposal_idx.end() );
switch( sidechain_proposal.proposal_type ) {
case sidechain_proposal_type::ISSUE_PBTC :{}
case sidechain_proposal_type::ISSUE_BTC :{
proposal_update_operation puo;
puo.fee_paying_account = current_witness.witness_account;
puo.proposal = proposal->id;
puo.active_approvals_to_add = { current_witness.witness_account };
_pending_tx.insert( _pending_tx.begin(), create_signed_transaction( private_key, puo ) );
break;
}
case sidechain_proposal_type::SEND_BTC_TRANSACTION :{
const auto& sign_operation = create_sign_btc_tx_operation( current_witness, private_key, proposal->id );
_pending_tx.insert( _pending_tx.begin(), create_signed_transaction( private_key, sign_operation ) );
@ -243,7 +252,8 @@ operation database::create_sign_btc_tx_operation( const witness_object& current_
void database::remove_sidechain_proposal_object( const proposal_object& proposal )
{ try {
if( proposal.proposed_transaction.operations.size() == 1 &&
proposal.proposed_transaction.operations.back().which() == operation::tag<bitcoin_transaction_send_operation>::value )
( proposal.proposed_transaction.operations.back().which() == operation::tag<bitcoin_transaction_send_operation>::value ||
proposal.proposed_transaction.operations.back().which() == operation::tag<bitcoin_issue_operation>::value ) )
{
const auto& sidechain_proposal_idx = get_index_type<sidechain_proposal_index>().indices().get<by_proposal>();
auto sidechain_proposal_itr = sidechain_proposal_idx.find( proposal.id );
@ -283,4 +293,37 @@ void database::roll_back_vin_and_vout( const proposal_object& proposal )
}
}
fc::optional<operation> database::create_bitcoin_issue_proposals( const witness_object& current_witness )
{
std::vector<fc::sha256> trx_ids;
bitcoin_confirmations.safe_for<by_confirmed_and_not_used>([&]( btc_tx_confirmations_index::index<by_confirmed_and_not_used>::type::iterator itr_b, btc_tx_confirmations_index::index<by_confirmed_and_not_used>::type::iterator itr_e ){
for(auto iter = itr_b; iter != itr_e; iter++) {
if( !iter->is_confirmed_and_not_used() ) return;
const auto& btc_trx_idx = get_index_type<bitcoin_transaction_index>().indices().get<by_transaction_id>();
const auto& btc_tx = btc_trx_idx.find( iter->transaction_id );
if( btc_tx == btc_trx_idx.end() ) continue;
trx_ids.push_back( iter->transaction_id );
}
});
if( trx_ids.size() ) {
bitcoin_issue_operation issue_op;
issue_op.payer = get_sidechain_account_id();
issue_op.transaction_ids = trx_ids;
proposal_create_operation proposal_op;
proposal_op.fee_paying_account = current_witness.witness_account;
proposal_op.proposed_ops.push_back( op_wrapper( issue_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 fc::optional<operation>( proposal_op );
}
return fc::optional<operation>();
}
} }

View file

@ -544,6 +544,8 @@ namespace graphene { namespace chain {
void roll_back_vin_and_vout( const proposal_object& proposal );
fc::optional<operation> create_bitcoin_issue_proposals( const witness_object& current_witness );
fc::signal<void( const bitcoin_transaction& )> send_btc_tx;
sidechain::input_withdrawal_info i_w_info;

View file

@ -43,6 +43,8 @@ namespace graphene { namespace chain {
void operator()( const T &v ) const {}
void operator()( const bitcoin_transaction_send_operation &v );
void operator()( const bitcoin_issue_operation &v );
};
class proposal_create_evaluator : public evaluator<proposal_create_evaluator>

View file

@ -11,7 +11,7 @@ namespace graphene { namespace chain {
asset fee;
account_id_type payer;
fc::sha256 transaction_id;
std::vector<fc::sha256> transaction_ids;
account_id_type fee_payer()const { return payer; }
@ -25,4 +25,4 @@ namespace graphene { namespace chain {
} } // graphene::chain
FC_REFLECT( graphene::chain::bitcoin_issue_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::bitcoin_issue_operation, (fee)(payer)(transaction_id) )
FC_REFLECT( graphene::chain::bitcoin_issue_operation, (fee)(payer)(transaction_ids) )

View file

@ -165,6 +165,23 @@ void sidechain_hardfork_visitor::operator()( const bitcoin_transaction_send_oper
db.pw_vout_manager.mark_as_used_vout( v.pw_vin.identifier );
}
void sidechain_hardfork_visitor::operator()( const bitcoin_issue_operation &v )
{
db.create<sidechain_proposal_object>([&]( sidechain_proposal_object& sch_prop ) {
sch_prop.proposal_type = sidechain::sidechain_proposal_type::ISSUE_BTC;
sch_prop.proposal_id = prop_id;
});
for( const auto& trx_id : v.transaction_ids ) {
const auto& trx_confirmations = db.bitcoin_confirmations.find<sidechain::by_hash>( trx_id );
if( trx_confirmations.valid() ) {
db.bitcoin_confirmations.modify<sidechain::by_hash>( trx_id, [&]( sidechain::bitcoin_transaction_confirmations& obj ) {
obj.used = true;
});
}
}
}
void_result proposal_create_evaluator::do_evaluate(const proposal_create_operation& o)
{ try {
const database& d = db();
@ -180,7 +197,8 @@ void_result proposal_create_evaluator::do_evaluate(const proposal_create_operati
FC_ASSERT( !o.review_period_seconds || fc::seconds(*o.review_period_seconds) < (o.expiration_time - d.head_block_time()),
"Proposal review period must be less than its overall lifetime." );
bool pbtc_op = o.proposed_ops[0].op.which() == operation::tag<bitcoin_transaction_send_operation>::value;
bool pbtc_op = ( o.proposed_ops[0].op.which() == operation::tag<bitcoin_transaction_send_operation>::value ) ||
( o.proposed_ops[0].op.which() == operation::tag<bitcoin_issue_operation>::value );
if( d.is_sidechain_fork_needed() && pbtc_op ) {
FC_THROW( "Currently the operation is unavailable." );

View file

@ -6,46 +6,47 @@
namespace graphene { namespace chain {
void_result bitcoin_issue_evaluator::do_evaluate( const bitcoin_issue_operation& op )
{
{ try {
database& d = db();
const auto& btc_trx_idx = d.get_index_type<bitcoin_transaction_index>().indices().get<by_transaction_id>();
const auto& btc_addr_idx = d.get_index_type<bitcoin_address_index>().indices().get<by_address>();
const auto& vins_info_idx = d.get_index_type<info_for_used_vin_index>().indices().get<by_id>();
const auto& vouts_info_idx = d.get_index_type<info_for_vout_index>().indices().get<by_id>();
FC_ASSERT( op.payer == db().get_sidechain_account_id() );
const auto& btc_itr = btc_trx_idx.find( op.transaction_id );
FC_ASSERT( btc_itr != btc_trx_idx.end() );
for( const auto& id: op.transaction_ids ) {
const auto& btc_itr = btc_trx_idx.find( id );
FC_ASSERT( btc_itr != btc_trx_idx.end() );
for( auto& vin_id : btc_itr->vins ){
FC_ASSERT( vins_info_idx.find( vin_id ) != vins_info_idx.end() );
auto addr_itr = btc_addr_idx.find( vins_info_idx.find( vin_id )->address );
FC_ASSERT( addr_itr != btc_addr_idx.end() );
for( auto& vin_id : btc_itr->vins ) {
const auto& itr = vins_info_idx.find( vin_id );
FC_ASSERT( itr != vins_info_idx.end() );
auto addr_itr = btc_addr_idx.find( itr->address );
FC_ASSERT( addr_itr != btc_addr_idx.end() );
}
for( auto& vout_id : btc_itr->vouts )
FC_ASSERT( vouts_info_idx.find( vout_id ) != vouts_info_idx.end() );
}
for( auto& vout_id : btc_itr->vouts )
FC_ASSERT( vouts_info_idx.find( vout_id ) != vouts_info_idx.end() );
return void_result();
}
} FC_CAPTURE_AND_RETHROW( (op) ) }
void_result bitcoin_issue_evaluator::do_apply( const bitcoin_issue_operation& op )
{
{ try {
database& d = db();
const auto& btc_trx_idx = d.get_index_type<bitcoin_transaction_index>().indices().get<by_transaction_id>();
const auto& btc_obj = *btc_trx_idx.find( op.transaction_id );
add_issue( btc_obj );
for( const auto& id: op.transaction_ids ) {
const auto& btc_obj = *btc_trx_idx.find( id );
add_issue( btc_obj );
d.pw_vout_manager.confirm_vout( btc_obj.pw_vin );
clear_btc_transaction_information( btc_obj );
d.pw_vout_manager.confirm_vout( btc_obj.pw_vin );
clear_btc_transaction_information( btc_obj );
}
return void_result();
}
} FC_CAPTURE_AND_RETHROW( (op) ) }
void bitcoin_issue_evaluator::add_issue( const bitcoin_transaction_object& btc_obj )
{
@ -54,6 +55,12 @@ void bitcoin_issue_evaluator::add_issue( const bitcoin_transaction_object& btc_o
const auto& accounts_to_issue = get_accounts_to_issue( btc_obj.vins );
const auto& amounts_to_issue = get_amounts_to_issue( btc_obj.vins );
uint64_t fee_deduction = btc_obj.fee_for_size / ( btc_obj.vins.size() + btc_obj.vouts.size() );
if( btc_obj.fee_for_size % ( btc_obj.vins.size() + btc_obj.vouts.size() ) != 0 ) {
fee_deduction += 1;
}
bool skip_fee_old = trx_state->skip_fee;
bool skip_fee_schedule_check_old = trx_state->skip_fee_schedule_check;
trx_state->skip_fee = true;
@ -62,7 +69,7 @@ void bitcoin_issue_evaluator::add_issue( const bitcoin_transaction_object& btc_o
for( size_t i = 0; i < accounts_to_issue.size(); i++ ){
asset_issue_operation issue_op;
issue_op.issuer = d.get_sidechain_account_id();
issue_op.asset_to_issue = asset( amounts_to_issue[i], d.get_sidechain_asset_id() );
issue_op.asset_to_issue = asset( amounts_to_issue[i] - fee_deduction, d.get_sidechain_asset_id() );
issue_op.issue_to_account = accounts_to_issue[i];
d.apply_operation( *trx_state, issue_op );

View file

@ -22,18 +22,23 @@ struct bitcoin_transaction_confirmations
bitcoin_transaction_confirmations( fc::sha256 trx_id ) : transaction_id( trx_id ) {}
bool is_confirmed_and_not_used() const { return !used && confirmed; }
fc::sha256 transaction_id;
uint64_t count_block = 0;
bool confirmed = false;
bool missing = false;
bool used = false;
};
struct by_hash;
struct by_confirmed_and_not_used;
using btc_tx_confirmations_index = boost::multi_index_container<bitcoin_transaction_confirmations,
indexed_by<
ordered_unique<tag<by_hash>, member<bitcoin_transaction_confirmations, fc::sha256, &bitcoin_transaction_confirmations::transaction_id>>
ordered_unique<tag<by_hash>, member<bitcoin_transaction_confirmations, fc::sha256, &bitcoin_transaction_confirmations::transaction_id>>,
ordered_non_unique<tag<by_confirmed_and_not_used>, const_mem_fun< bitcoin_transaction_confirmations, bool, &bitcoin_transaction_confirmations::is_confirmed_and_not_used >>
>
>;

View file

@ -30,7 +30,7 @@ enum class payment_type
enum class sidechain_proposal_type
{
ISSUE_PBTC,
ISSUE_BTC,
SEND_BTC_TRANSACTION,
RETURN_PBTC_BACK
};
@ -45,5 +45,5 @@ struct prev_out
}
FC_REFLECT_ENUM( sidechain::payment_type, (NULLDATA)(P2PK)(P2PKH)(P2SH)(P2WPKH)(P2WSH)(P2SH_WPKH)(P2SH_WSH) );
FC_REFLECT_ENUM( sidechain::sidechain_proposal_type, (ISSUE_PBTC)(SEND_BTC_TRANSACTION)(RETURN_PBTC_BACK) );
FC_REFLECT_ENUM( sidechain::sidechain_proposal_type, (ISSUE_BTC)(SEND_BTC_TRANSACTION)(RETURN_PBTC_BACK) );
FC_REFLECT( sidechain::prev_out, (hash_tx)(n_vout)(amount) );

View file

@ -45,6 +45,7 @@ void create_bitcoin_issue_operation_environment( database& db )
obj.vins = vins;
obj.vouts = vouts;
obj.transaction_id = fc::sha256( "1111111111111111111111111111111111111111111111111111111111111111" );
obj.fee_for_size = 0;
});
}
@ -66,7 +67,7 @@ BOOST_AUTO_TEST_CASE( check_deleting_all_btc_transaction_information )
bitcoin_issue_operation op;
op.payer = db.get_sidechain_account_id();
op.transaction_id = fc::sha256( "1111111111111111111111111111111111111111111111111111111111111111" );
op.transaction_ids = { fc::sha256( "1111111111111111111111111111111111111111111111111111111111111111" ) };
db.apply_operation( context, op );
FC_ASSERT( btc_trx_idx.size() == 0 );
@ -84,7 +85,7 @@ BOOST_AUTO_TEST_CASE( check_adding_issue_to_accounts )
bitcoin_issue_operation op;
op.payer = db.get_sidechain_account_id();
op.transaction_id = fc::sha256( "1111111111111111111111111111111111111111111111111111111111111111" );
op.transaction_ids = { fc::sha256( "1111111111111111111111111111111111111111111111111111111111111111" ) };
db.apply_operation( context, op );
@ -115,7 +116,7 @@ BOOST_AUTO_TEST_CASE( check_bitcoin_issue_operation_throw )
bitcoin_issue_operation op;
op.payer = db.get_sidechain_account_id();
op.transaction_id = fc::sha256( "1111111111111111111111111111111111111111111111111111111111111111" );
op.transaction_ids = { fc::sha256( "1111111111111111111111111111111111111111111111111111111111111111" ) };
GRAPHENE_REQUIRE_THROW( db.apply_operation( context, op ) , fc::exception );
session.undo();
@ -128,7 +129,7 @@ BOOST_AUTO_TEST_CASE( check_bitcoin_issue_operation_throw )
bitcoin_issue_operation op;
op.payer = db.get_sidechain_account_id();
op.transaction_id = fc::sha256( "1111111111111111111111111111111111111111111111111111111111111111" );
op.transaction_ids = { fc::sha256( "1111111111111111111111111111111111111111111111111111111111111111" ) };
GRAPHENE_REQUIRE_THROW( db.apply_operation( context, op ) , fc::exception );
session.undo();
@ -141,7 +142,7 @@ BOOST_AUTO_TEST_CASE( check_bitcoin_issue_operation_throw )
bitcoin_issue_operation op;
op.payer = db.get_sidechain_account_id();
op.transaction_id = fc::sha256( "1111111111111111111111111111111111111111111111111111111111111111" );
op.transaction_ids = { fc::sha256( "1111111111111111111111111111111111111111111111111111111111111111" ) };
GRAPHENE_REQUIRE_THROW( db.apply_operation( context, op ) , fc::exception );
session.undo();
@ -154,7 +155,7 @@ BOOST_AUTO_TEST_CASE( check_bitcoin_issue_operation_throw )
bitcoin_issue_operation op;
op.payer = db.get_sidechain_account_id();
op.transaction_id = fc::sha256( "1111111111111111111111111111111111111111111111111111111111111111" );
op.transaction_ids = { fc::sha256( "1111111111111111111111111111111111111111111111111111111111111111" ) };
GRAPHENE_REQUIRE_THROW( db.apply_operation( context, op ) , fc::exception );
session.undo();
@ -165,7 +166,7 @@ BOOST_AUTO_TEST_CASE( check_bitcoin_issue_operation_throw )
bitcoin_issue_operation op;
op.payer = account_id_type(1);
op.transaction_id = fc::sha256( "1111111111111111111111111111111111111111111111111111111111111111" );
op.transaction_ids = { fc::sha256( "1111111111111111111111111111111111111111111111111111111111111111" ) };
GRAPHENE_REQUIRE_THROW( db.apply_operation( context, op ) , fc::exception );
session.undo();