Filled update_tx_approvals in sidechain_net_manager
This commit is contained in:
parent
810051e7c9
commit
ff57653584
7 changed files with 111 additions and 74 deletions
|
|
@ -234,6 +234,7 @@
|
||||||
#define SIDECHAIN_MAX_SHARE_SUPPLY int64_t(21000000ll * 100000000ll)
|
#define SIDECHAIN_MAX_SHARE_SUPPLY int64_t(21000000ll * 100000000ll)
|
||||||
#define SIDECHAIN_DEFAULT_NUMBER_UNCONFIRMED_VINS 25
|
#define SIDECHAIN_DEFAULT_NUMBER_UNCONFIRMED_VINS 25
|
||||||
#define SIDECHAIN_DEFAULT_NUMBER_SIG_MULTISIG 5
|
#define SIDECHAIN_DEFAULT_NUMBER_SIG_MULTISIG 5
|
||||||
|
#define SIDECHAIN_DEFAULT_NUMBER_OF_CONFIRMATIONS 6
|
||||||
#define SIDECHAIN_DEFAULT_CONDENSING_TX_VINS_NUMBER 5
|
#define SIDECHAIN_DEFAULT_CONDENSING_TX_VINS_NUMBER 5
|
||||||
#define SIDECHAIN_DEFAULT_CONDENSING_TX_VOUTS_NUMBER 5
|
#define SIDECHAIN_DEFAULT_CONDENSING_TX_VOUTS_NUMBER 5
|
||||||
#define SIDECHAIN_DEFAULT_PERCENTAGE_PAYMENT_TO_WIT 0.001
|
#define SIDECHAIN_DEFAULT_PERCENTAGE_PAYMENT_TO_WIT 0.001
|
||||||
|
|
|
||||||
|
|
@ -16,23 +16,24 @@ namespace graphene { namespace chain { class database; } }
|
||||||
|
|
||||||
namespace sidechain {
|
namespace sidechain {
|
||||||
|
|
||||||
struct btc_tx_confirmations
|
struct bitcoin_transaction_confirmations
|
||||||
{
|
{
|
||||||
btc_tx_confirmations() = default;
|
bitcoin_transaction_confirmations() = default;
|
||||||
|
|
||||||
btc_tx_confirmations( fc::sha256 trx_id ) : transaction_id( trx_id ) {}
|
bitcoin_transaction_confirmations( fc::sha256 trx_id ) : transaction_id( trx_id ) {}
|
||||||
|
|
||||||
fc::sha256 transaction_id;
|
fc::sha256 transaction_id;
|
||||||
|
|
||||||
uint64_t count_blocks = 0;
|
uint64_t count_block = 0;
|
||||||
bool confirmed = false;
|
bool confirmed = false;
|
||||||
|
bool missing = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct by_hash;
|
struct by_hash;
|
||||||
|
|
||||||
using btc_tx_confirmations_index = boost::multi_index_container<btc_tx_confirmations,
|
using btc_tx_confirmations_index = boost::multi_index_container<bitcoin_transaction_confirmations,
|
||||||
indexed_by<
|
indexed_by<
|
||||||
ordered_unique<tag<by_hash>, member<btc_tx_confirmations, fc::sha256, &btc_tx_confirmations::transaction_id>>
|
ordered_unique<tag<by_hash>, member<bitcoin_transaction_confirmations, fc::sha256, &bitcoin_transaction_confirmations::transaction_id>>
|
||||||
>
|
>
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ namespace sidechain {
|
||||||
uint8_t multisig_sigs_num = SIDECHAIN_DEFAULT_NUMBER_SIG_MULTISIG;
|
uint8_t multisig_sigs_num = SIDECHAIN_DEFAULT_NUMBER_SIG_MULTISIG;
|
||||||
uint8_t condensing_tx_vins_num = SIDECHAIN_DEFAULT_CONDENSING_TX_VINS_NUMBER;
|
uint8_t condensing_tx_vins_num = SIDECHAIN_DEFAULT_CONDENSING_TX_VINS_NUMBER;
|
||||||
uint8_t condensing_tx_vouts_num = SIDECHAIN_DEFAULT_CONDENSING_TX_VOUTS_NUMBER;
|
uint8_t condensing_tx_vouts_num = SIDECHAIN_DEFAULT_CONDENSING_TX_VOUTS_NUMBER;
|
||||||
|
uint8_t confirmations_num = SIDECHAIN_DEFAULT_NUMBER_OF_CONFIRMATIONS;
|
||||||
|
|
||||||
graphene::chain::account_id_type managing_account;
|
graphene::chain::account_id_type managing_account;
|
||||||
graphene::chain::asset_id_type asset_id;
|
graphene::chain::asset_id_type asset_id;
|
||||||
|
|
@ -19,6 +20,7 @@ FC_REFLECT( sidechain::sidechain_parameters_extension,
|
||||||
(multisig_sigs_num)
|
(multisig_sigs_num)
|
||||||
(condensing_tx_vins_num)
|
(condensing_tx_vins_num)
|
||||||
(condensing_tx_vins_num)
|
(condensing_tx_vins_num)
|
||||||
|
(confirmations_num)
|
||||||
(managing_account)
|
(managing_account)
|
||||||
(asset_id)
|
(asset_id)
|
||||||
)
|
)
|
||||||
|
|
@ -39,13 +39,14 @@ int32_t bitcoin_rpc_client::receive_confirmations_tx( const std::string& tx_hash
|
||||||
const auto reply = send_post_request( body );
|
const auto reply = send_post_request( body );
|
||||||
|
|
||||||
if ( reply.status != 200 )
|
if ( reply.status != 200 )
|
||||||
return -1;
|
return 0;
|
||||||
|
|
||||||
const auto result = std::string( reply.body.begin(), reply.body.end() );
|
const auto result = std::string( reply.body.begin(), reply.body.end() );
|
||||||
|
|
||||||
std::stringstream ss( result );
|
std::stringstream ss( result );
|
||||||
boost::property_tree::ptree tx;
|
boost::property_tree::ptree tx;
|
||||||
boost::property_tree::read_json( ss, tx );
|
boost::property_tree::read_json( ss, tx );
|
||||||
|
|
||||||
if( tx.count( "result" ) ) {
|
if( tx.count( "result" ) ) {
|
||||||
if( tx.get_child( "result" ).count( "confirmations" ) ) {
|
if( tx.get_child( "result" ).count( "confirmations" ) ) {
|
||||||
return tx.get_child( "result" ).get_child( "confirmations" ).get_value<int64_t>();
|
return tx.get_child( "result" ).get_child( "confirmations" ).get_value<int64_t>();
|
||||||
|
|
@ -93,19 +94,32 @@ uint64_t bitcoin_rpc_client::receive_estimated_fee()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string bitcoin_rpc_client::send_btc_tx( const std::string& tx_hex )
|
void bitcoin_rpc_client::send_btc_tx( const std::string& tx_hex )
|
||||||
{
|
{
|
||||||
const auto body = std::string("{\"jsonrpc\": \"1.0\", \"id\":\"send_tx\", \"method\": \"sendrawtransaction\", \"params\": [") +
|
const auto body = std::string("{\"jsonrpc\": \"1.0\", \"id\":\"send_tx\", \"method\": \"sendrawtransaction\", \"params\": [") +
|
||||||
std::string("\"") + tx_hex + std::string("\"") + std::string("] }");
|
std::string("\"") + tx_hex + std::string("\"") + std::string("] }");
|
||||||
|
|
||||||
const auto reply = send_post_request( body );
|
const auto reply = send_post_request( body );
|
||||||
|
|
||||||
if( reply.body.empty() || reply.status != 200 )
|
if( reply.body.empty() )
|
||||||
return "";
|
return;
|
||||||
|
|
||||||
std::string reply_str( reply.body.begin(), reply.body.end() );
|
std::string reply_str( reply.body.begin(), reply.body.end() );
|
||||||
|
|
||||||
return reply_str;
|
std::stringstream ss(reply_str);
|
||||||
|
boost::property_tree::ptree json;
|
||||||
|
boost::property_tree::read_json( ss, json );
|
||||||
|
|
||||||
|
if( reply.status == 200 ) {
|
||||||
|
idump(( tx_hex ));
|
||||||
|
return;
|
||||||
|
} else if( json.count( "error" ) && !json.get_child( "error" ).empty() ) {
|
||||||
|
const auto error_code = json.get_child( "error" ).get_child( "code" ).get_value<int>();
|
||||||
|
if( error_code == -27 ) // transaction already in block chain
|
||||||
|
return;
|
||||||
|
|
||||||
|
wlog( "BTC tx is not sent! Reply: ${msg}", ("msg", reply_str) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bitcoin_rpc_client::connection_is_not_defined() const
|
bool bitcoin_rpc_client::connection_is_not_defined() const
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ public:
|
||||||
|
|
||||||
uint64_t receive_estimated_fee();
|
uint64_t receive_estimated_fee();
|
||||||
|
|
||||||
std::string send_btc_tx( const std::string& tx_hex );
|
void send_btc_tx( const std::string& tx_hex );
|
||||||
|
|
||||||
bool connection_is_not_defined() const;
|
bool connection_is_not_defined() const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,8 @@ private:
|
||||||
|
|
||||||
std::vector<info_for_vin> extract_info_from_block( const std::string& _block );
|
std::vector<info_for_vin> extract_info_from_block( const std::string& _block );
|
||||||
|
|
||||||
|
void update_transaction_status( std::vector<fc::sha256> trx_for_check );
|
||||||
|
|
||||||
inline uint64_t parse_amount(std::string raw);
|
inline uint64_t parse_amount(std::string raw);
|
||||||
|
|
||||||
std::unique_ptr<zmq_listener> listener;
|
std::unique_ptr<zmq_listener> listener;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#include <sidechain/network/sidechain_net_manager.hpp>
|
#include <sidechain/network/sidechain_net_manager.hpp>
|
||||||
#include <sidechain/serialize.hpp>
|
#include <sidechain/serialize.hpp>
|
||||||
|
#include <sidechain/sidechain_parameters.hpp>
|
||||||
|
|
||||||
#include <fc/network/http/connection.hpp>
|
#include <fc/network/http/connection.hpp>
|
||||||
#include <fc/network/ip.hpp>
|
#include <fc/network/ip.hpp>
|
||||||
|
|
@ -43,15 +44,67 @@ void sidechain_net_manager::initialize_manager( graphene::chain::database* _db,
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sidechain_net_manager::update_tx_infos( const std::string& block_hash )
|
||||||
|
{
|
||||||
|
std::string block = bitcoin_client->receive_full_block( block_hash );
|
||||||
|
if( block != "" ) {
|
||||||
|
const auto& vins = extract_info_from_block( block );
|
||||||
|
for( const auto& v : vins ) {
|
||||||
|
db->i_w_info.insert_info_for_vin( prev_out{ v.out.hash_tx, v.out.n_vout, v.out.amount }, v.address );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sidechain_net_manager::update_tx_approvals()
|
||||||
|
{
|
||||||
|
std::vector<fc::sha256> trx_for_check;
|
||||||
|
const auto& confirmations_num = db->get_sidechain_params().confirmations_num;
|
||||||
|
|
||||||
|
db->bitcoin_confirmations.safe_for<by_hash>([&]( btc_tx_confirmations_index::iterator itr_b, btc_tx_confirmations_index::iterator itr_e ){
|
||||||
|
for(auto iter = itr_b; iter != itr_e; iter++) {
|
||||||
|
db->bitcoin_confirmations.modify<by_hash>( iter->transaction_id, [&]( bitcoin_transaction_confirmations& obj ) {
|
||||||
|
obj.count_block++;
|
||||||
|
});
|
||||||
|
|
||||||
|
if( iter->count_block == confirmations_num ) {
|
||||||
|
trx_for_check.push_back( iter->transaction_id );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
update_transaction_status( trx_for_check );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void sidechain_net_manager::update_estimated_fee()
|
||||||
|
{
|
||||||
|
db->estimated_feerate = bitcoin_client->receive_estimated_fee();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sidechain_net_manager::send_btc_tx( const sidechain::bitcoin_transaction& trx )
|
||||||
|
{
|
||||||
|
db->bitcoin_confirmations.insert( bitcoin_transaction_confirmations( trx.get_txid() ) );
|
||||||
|
|
||||||
|
FC_ASSERT( !bitcoin_client->connection_is_not_defined() );
|
||||||
|
const auto tx_hex = fc::to_hex( pack( trx ) );
|
||||||
|
|
||||||
|
bitcoin_client->send_btc_tx( tx_hex );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sidechain_net_manager::connection_is_not_defined() const
|
||||||
|
{
|
||||||
|
return listener->connection_is_not_defined() && bitcoin_client->connection_is_not_defined();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sidechain_net_manager::handle_block( const std::string& block_hash )
|
||||||
|
{
|
||||||
|
update_tx_approvals();
|
||||||
|
update_estimated_fee();
|
||||||
|
update_tx_infos( block_hash );
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<info_for_vin> sidechain_net_manager::extract_info_from_block( const std::string& _block )
|
std::vector<info_for_vin> sidechain_net_manager::extract_info_from_block( const std::string& _block )
|
||||||
{
|
{
|
||||||
|
|
||||||
// std::map<std::string, bool> test = { {"2MsmG481n4W4AC1QcPgBUJQrVRTrLNM2GpB", false},
|
|
||||||
// {"2N2LkZG2Zp9eXGjSJzP9taR1gYdZBPzH7S7", false},
|
|
||||||
// {"2N4MCW3XggAxs9C8Dh2vNcx7uH8zUqoLMjA", false},
|
|
||||||
// {"2NEkNoDyQ9tyREFDAPehi9Jr2m6EFiTDxAS", false},
|
|
||||||
// {"2N1rQcKr4F14L8dfnNiUVpc4LzcZTWN9Kpd", false} };
|
|
||||||
|
|
||||||
std::stringstream ss( _block );
|
std::stringstream ss( _block );
|
||||||
boost::property_tree::ptree block;
|
boost::property_tree::ptree block;
|
||||||
boost::property_tree::read_json( ss, block );
|
boost::property_tree::read_json( ss, block );
|
||||||
|
|
@ -86,66 +139,30 @@ std::vector<info_for_vin> sidechain_net_manager::extract_info_from_block( const
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sidechain_net_manager::update_tx_infos( const std::string& block_hash )
|
void sidechain_net_manager::update_transaction_status( std::vector<fc::sha256> trx_for_check )
|
||||||
{
|
{
|
||||||
std::string block = bitcoin_client->receive_full_block( block_hash );
|
const auto& confirmations_num = db->get_sidechain_params().confirmations_num;
|
||||||
if( block != "" ) {
|
|
||||||
const auto& vins = extract_info_from_block( block );
|
for( const auto& trx : trx_for_check ) {
|
||||||
for( const auto& v : vins ) {
|
auto confirmations = bitcoin_client->receive_confirmations_tx( trx.str() );
|
||||||
db->i_w_info.insert_info_for_vin( prev_out{ v.out.hash_tx, v.out.n_vout, v.out.amount }, v.address );
|
db->bitcoin_confirmations.modify<by_hash>( trx, [&]( bitcoin_transaction_confirmations& obj ) {
|
||||||
|
obj.count_block = confirmations;
|
||||||
|
});
|
||||||
|
|
||||||
|
if( confirmations >= confirmations_num ) {
|
||||||
|
db->bitcoin_confirmations.modify<by_hash>( trx, [&]( bitcoin_transaction_confirmations& obj ) {
|
||||||
|
obj.confirmed = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
} else if( confirmations == 0 ) {
|
||||||
|
auto is_in_mempool = bitcoin_client->receive_mempool_entry_tx( trx.str() );
|
||||||
|
db->bitcoin_confirmations.modify<by_hash>( trx, [&]( bitcoin_transaction_confirmations& obj ) {
|
||||||
|
obj.missing = !is_in_mempool;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sidechain_net_manager::update_tx_approvals()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void sidechain_net_manager::update_estimated_fee()
|
|
||||||
{
|
|
||||||
auto estimated_fee = bitcoin_client->receive_estimated_fee();
|
|
||||||
}
|
|
||||||
|
|
||||||
void sidechain_net_manager::send_btc_tx( const sidechain::bitcoin_transaction& trx )
|
|
||||||
{
|
|
||||||
db->bitcoin_confirmations.insert( btc_tx_confirmations( trx.get_txid() ) );
|
|
||||||
|
|
||||||
FC_ASSERT( !bitcoin_client->connection_is_not_defined() );
|
|
||||||
const auto tx_hex = fc::to_hex( pack( trx ) );
|
|
||||||
|
|
||||||
auto reply = bitcoin_client->send_btc_tx( tx_hex );
|
|
||||||
|
|
||||||
std::stringstream ss(reply);
|
|
||||||
boost::property_tree::ptree json;
|
|
||||||
boost::property_tree::read_json(ss, json);
|
|
||||||
|
|
||||||
if( !json.get_child( "error" ).empty() ) {
|
|
||||||
wlog( "BTC tx is not sent! Reply: ${msg}", ("msg", reply) );
|
|
||||||
const auto error_code = json.get_child( "error" ).get_child( "code" ).get_value<int>();
|
|
||||||
|
|
||||||
if( error_code != -27 ) // transaction already in block chain
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( reply == "" ){
|
|
||||||
wlog( "Don't receive successful reply status" );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool sidechain_net_manager::connection_is_not_defined() const
|
|
||||||
{
|
|
||||||
return listener->connection_is_not_defined() && bitcoin_client->connection_is_not_defined();
|
|
||||||
}
|
|
||||||
|
|
||||||
void sidechain_net_manager::handle_block( const std::string& block_hash )
|
|
||||||
{
|
|
||||||
update_tx_approvals();
|
|
||||||
update_estimated_fee();
|
|
||||||
update_tx_infos( block_hash );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Removes dot from amount output: "50.00000000"
|
// Removes dot from amount output: "50.00000000"
|
||||||
inline uint64_t sidechain_net_manager::parse_amount(std::string raw) {
|
inline uint64_t sidechain_net_manager::parse_amount(std::string raw) {
|
||||||
raw.erase(std::remove(raw.begin(), raw.end(), '.'), raw.end());
|
raw.erase(std::remove(raw.begin(), raw.end(), '.'), raw.end());
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue