Added checking bitcoin inputs

This commit is contained in:
Anzhy Cherrnyavski 2019-02-08 12:00:49 +03:00
parent 9a5c9092e1
commit 320cba9f42
5 changed files with 43 additions and 11 deletions

View file

@ -20,7 +20,8 @@ struct bitcoin_transaction_confirmations
{
bitcoin_transaction_confirmations() = default;
bitcoin_transaction_confirmations( fc::sha256 trx_id ) : id( count_id_tx_conf++ ), transaction_id( trx_id ) {}
bitcoin_transaction_confirmations( const fc::sha256& trx_id, const std::set<fc::sha256>& vins ) :
id( count_id_tx_conf++ ), transaction_id( trx_id ), valid_vins( vins ) {}
struct comparer {
bool operator()( const bitcoin_transaction_confirmations& lhs, const bitcoin_transaction_confirmations& rhs ) const {
@ -36,6 +37,7 @@ struct bitcoin_transaction_confirmations
bool is_confirmed_and_not_used() const { return !used && confirmed; }
fc::sha256 transaction_id;
std::set<fc::sha256> valid_vins;
uint64_t count_block = 0;
bool confirmed = false;

View file

@ -12,6 +12,7 @@ class sidechain_proposal_checker
{
public:
sidechain_proposal_checker( graphene::chain::database& _db ) : db(_db) {}
bool check_bitcoin_transaction_send_operation( const bitcoin_transaction_send_operation& op );

View file

@ -37,6 +37,8 @@ private:
void update_transaction_status( std::vector<fc::sha256> trx_for_check );
std::set<fc::sha256> get_valid_vins( const std::string tx_hash );
inline uint64_t parse_amount(std::string raw);
std::unique_ptr<zmq_listener> listener;

View file

@ -86,7 +86,11 @@ void sidechain_net_manager::update_estimated_fee()
void sidechain_net_manager::send_btc_tx( const sidechain::bitcoin_transaction& trx )
{
db->bitcoin_confirmations.insert( bitcoin_transaction_confirmations( trx.get_txid() ) );
std::set<fc::sha256> valid_vins;
for( const auto& v : trx.vin ) {
valid_vins.insert( v.prevout.hash );
}
db->bitcoin_confirmations.insert( bitcoin_transaction_confirmations( trx.get_txid(), valid_vins ) );
FC_ASSERT( !bitcoin_client->connection_is_not_defined() );
const auto tx_hex = fc::to_hex( pack( trx ) );
@ -142,6 +146,22 @@ std::vector<info_for_vin> sidechain_net_manager::extract_info_from_block( const
return result;
}
std::set<fc::sha256> sidechain_net_manager::get_valid_vins( const std::string tx_hash )
{
const auto& confirmations_obj = db->bitcoin_confirmations.find<sidechain::by_hash>( fc::sha256( tx_hash ) );
FC_ASSERT( confirmations_obj.valid() );
std::set<fc::sha256> valid_vins;
for( const auto& v : confirmations_obj->valid_vins ) {
auto confirmations = bitcoin_client->receive_confirmations_tx( v.str() );
if( confirmations == 0 ) {
continue;
}
valid_vins.insert( v );
}
return valid_vins;
}
void sidechain_net_manager::update_transaction_status( std::vector<fc::sha256> trx_for_check )
{
const auto& confirmations_num = db->get_sidechain_params().confirmations_num;
@ -159,8 +179,15 @@ void sidechain_net_manager::update_transaction_status( std::vector<fc::sha256> t
} else if( confirmations == 0 ) {
auto is_in_mempool = bitcoin_client->receive_mempool_entry_tx( trx.str() );
std::set<fc::sha256> valid_vins;
if( !is_in_mempool ) {
valid_vins = get_valid_vins( trx.str() );
}
db->bitcoin_confirmations.modify<by_hash>( trx, [&]( bitcoin_transaction_confirmations& obj ) {
obj.missing = !is_in_mempool;
obj.valid_vins = valid_vins;
});
}
}

View file

@ -58,7 +58,7 @@ BOOST_AUTO_TEST_CASE( check_deleting_all_btc_transaction_information )
const auto& vouts_info_idx = db.get_index_type<info_for_vout_index>().indices().get<by_id>();
create_bitcoin_issue_operation_environment( db );
db.bitcoin_confirmations.insert( sidechain::bitcoin_transaction_confirmations( fc::sha256( "1111111111111111111111111111111111111111111111111111111111111111" ) ) );
db.bitcoin_confirmations.insert( sidechain::bitcoin_transaction_confirmations( fc::sha256( std::string( 64,'1' ) ), std::set<fc::sha256>() ) );
FC_ASSERT( btc_trx_idx.size() == 1 );
FC_ASSERT( vins_info_idx.size() == 3 );
@ -67,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_ids = { fc::sha256( "1111111111111111111111111111111111111111111111111111111111111111" ) };
op.transaction_ids = { fc::sha256( std::string( 64,'1' ) ) };
db.apply_operation( context, op );
FC_ASSERT( btc_trx_idx.size() == 0 );
@ -85,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_ids = { fc::sha256( "1111111111111111111111111111111111111111111111111111111111111111" ) };
op.transaction_ids = { fc::sha256( std::string( 64,'1' ) ) };
db.apply_operation( context, op );
@ -107,7 +107,7 @@ BOOST_AUTO_TEST_CASE( check_bitcoin_issue_operation_throw )
const auto& vouts_info_idx = db.get_index_type<info_for_vout_index>().indices().get<by_id>();
create_bitcoin_issue_operation_environment( db );
db.bitcoin_confirmations.insert( sidechain::bitcoin_transaction_confirmations( fc::sha256( "1111111111111111111111111111111111111111111111111111111111111111" ) ) );
db.bitcoin_confirmations.insert( sidechain::bitcoin_transaction_confirmations( fc::sha256( std::string( 64,'1' ) ), std::set<fc::sha256>() ) );
{
auto session = db._undo_db.start_undo_session();
@ -116,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_ids = { fc::sha256( "1111111111111111111111111111111111111111111111111111111111111111" ) };
op.transaction_ids = { fc::sha256( std::string( 64,'1' ) ) };
GRAPHENE_REQUIRE_THROW( db.apply_operation( context, op ) , fc::exception );
session.undo();
@ -129,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_ids = { fc::sha256( "1111111111111111111111111111111111111111111111111111111111111111" ) };
op.transaction_ids = { fc::sha256( std::string( 64,'1' ) ) };
GRAPHENE_REQUIRE_THROW( db.apply_operation( context, op ) , fc::exception );
session.undo();
@ -142,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_ids = { fc::sha256( "1111111111111111111111111111111111111111111111111111111111111111" ) };
op.transaction_ids = { fc::sha256( std::string( 64,'1' ) ) };
GRAPHENE_REQUIRE_THROW( db.apply_operation( context, op ) , fc::exception );
session.undo();
@ -155,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_ids = { fc::sha256( "1111111111111111111111111111111111111111111111111111111111111111" ) };
op.transaction_ids = { fc::sha256( std::string( 64,'1' ) ) };
GRAPHENE_REQUIRE_THROW( db.apply_operation( context, op ) , fc::exception );
session.undo();
@ -166,7 +166,7 @@ BOOST_AUTO_TEST_CASE( check_bitcoin_issue_operation_throw )
bitcoin_issue_operation op;
op.payer = account_id_type(1);
op.transaction_ids = { fc::sha256( "1111111111111111111111111111111111111111111111111111111111111111" ) };
op.transaction_ids = { fc::sha256( std::string( 64,'1' ) ) };
GRAPHENE_REQUIRE_THROW( db.apply_operation( context, op ) , fc::exception );
session.undo();