Issue tokens to the user who deposited Bitcoin, WIP...

This commit is contained in:
Srdjan Obucina 2020-02-05 20:19:47 +01:00
parent bb8d334e6c
commit 9056ba6d07
7 changed files with 102 additions and 65 deletions

View file

@ -10,13 +10,15 @@ namespace graphene { namespace chain {
asset fee;
account_id_type payer;
std::string uid;
fc::time_point_sec timestamp;
peerplays_sidechain::sidechain_type sidechain;
std::string transaction_id;
std::string from;
std::string to;
int64_t amount;
std::string sidechain_uid;
std::string sidechain_transaction_id;
std::string sidechain_from;
std::string sidechain_to;
int64_t sidechain_amount;
chain::account_id_type peerplays_from;
chain::account_id_type peerplays_to;
account_id_type fee_payer()const { return payer; }
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
@ -39,7 +41,7 @@ namespace graphene { namespace chain {
FC_REFLECT(graphene::chain::son_wallet_transfer_create_operation::fee_parameters_type, (fee) )
FC_REFLECT(graphene::chain::son_wallet_transfer_create_operation, (fee)(payer)
(uid) (timestamp) (sidechain) (transaction_id) (from) (to) (amount))
(timestamp) (sidechain) (sidechain_uid) (sidechain_transaction_id) (sidechain_from) (sidechain_to) (sidechain_amount) (peerplays_from) (peerplays_to))
FC_REFLECT(graphene::chain::son_wallet_transfer_process_operation::fee_parameters_type, (fee) )
FC_REFLECT(graphene::chain::son_wallet_transfer_process_operation, (fee)(payer)
(son_wallet_transfer_id))

View file

@ -16,19 +16,21 @@ namespace graphene { namespace chain {
static const uint8_t space_id = protocol_ids;
static const uint8_t type_id = son_wallet_transfer_object_type;
std::string uid;
time_point_sec timestamp;
peerplays_sidechain::sidechain_type sidechain;
std::string transaction_id;
std::string from;
std::string to;
int64_t amount;
std::string sidechain_uid;
std::string sidechain_transaction_id;
std::string sidechain_from;
std::string sidechain_to;
int64_t sidechain_amount;
chain::account_id_type peerplays_from;
chain::account_id_type peerplays_to;
bool processed;
};
struct by_uid;
struct by_sidechain;
struct by_sidechain_uid;
struct by_processed;
struct by_sidechain_and_processed;
using son_wallet_transfer_multi_index_type = multi_index_container<
@ -37,12 +39,12 @@ namespace graphene { namespace chain {
ordered_unique< tag<by_id>,
member<object, object_id_type, &object::id>
>,
ordered_unique< tag<by_uid>,
member<son_wallet_transfer_object, std::string, &son_wallet_transfer_object::uid>
>,
ordered_non_unique< tag<by_sidechain>,
member<son_wallet_transfer_object, peerplays_sidechain::sidechain_type, &son_wallet_transfer_object::sidechain>
>,
ordered_unique< tag<by_sidechain_uid>,
member<son_wallet_transfer_object, std::string, &son_wallet_transfer_object::sidechain_uid>
>,
ordered_non_unique< tag<by_processed>,
member<son_wallet_transfer_object, bool, &son_wallet_transfer_object::processed>
>,
@ -58,5 +60,7 @@ namespace graphene { namespace chain {
} } // graphene::chain
FC_REFLECT_DERIVED( graphene::chain::son_wallet_transfer_object, (graphene::db::object),
(uid) (timestamp) (sidechain) (transaction_id) (from) (to) (amount)
(timestamp) (sidechain)
(sidechain_uid) (sidechain_transaction_id) (sidechain_from) (sidechain_to) (sidechain_amount)
(peerplays_from) (peerplays_to)
(processed) )

View file

@ -11,22 +11,24 @@ void_result create_son_wallet_transfer_evaluator::do_evaluate(const son_wallet_t
//FC_ASSERT(db().get_global_properties().parameters.get_son_btc_account_id() != GRAPHENE_NULL_ACCOUNT, "SON paying account not set.");
FC_ASSERT( op.payer == db().get_global_properties().parameters.get_son_btc_account_id() );
const auto& idx = db().get_index_type<son_wallet_transfer_index>().indices().get<by_uid>();
FC_ASSERT(idx.find(op.uid) == idx.end(), "Already registered " + op.uid);
const auto& idx = db().get_index_type<son_wallet_transfer_index>().indices().get<by_sidechain_uid>();
FC_ASSERT(idx.find(op.sidechain_uid) == idx.end(), "Already registered " + op.sidechain_uid);
return void_result();
} FC_CAPTURE_AND_RETHROW( (op) ) }
object_id_type create_son_wallet_transfer_evaluator::do_apply(const son_wallet_transfer_create_operation& op)
{ try {
const auto& new_son_wallet_transfer_object = db().create<son_wallet_transfer_object>( [&]( son_wallet_transfer_object& obj ){
obj.uid = op.uid;
obj.timestamp = op.timestamp;
obj.sidechain = op.sidechain;
obj.transaction_id = op.transaction_id;
obj.from = op.from;
obj.to = op.to;
obj.amount = op.amount;
obj.processed = false;
const auto& new_son_wallet_transfer_object = db().create<son_wallet_transfer_object>( [&]( son_wallet_transfer_object& swto ){
swto.timestamp = op.timestamp;
swto.sidechain = op.sidechain;
swto.sidechain_uid = op.sidechain_uid;
swto.sidechain_transaction_id = op.sidechain_transaction_id;
swto.sidechain_from = op.sidechain_from;
swto.sidechain_to = op.sidechain_to;
swto.sidechain_amount = op.sidechain_amount;
swto.peerplays_from = op.peerplays_from;
swto.peerplays_to = op.peerplays_to;
swto.processed = false;
});
return new_son_wallet_transfer_object.id;
} FC_CAPTURE_AND_RETHROW( (op) ) }

View file

@ -64,15 +64,15 @@ struct info_for_vin
};
struct sidechain_event_data {
std::string uid;
fc::time_point_sec timestamp;
sidechain_type sidechain;
std::string transaction_id;
std::string from;
std::string sidechain_uid;
std::string sidechain_transaction_id;
std::string sidechain_from;
std::string sidechain_to;
int64_t sidechain_amount;
chain::account_id_type peerplays_from;
std::string to;
chain::account_id_type peerplays_to;
int64_t amount;
};
} } // graphene::peerplays_sidechain

View file

@ -10,6 +10,7 @@
#include <graphene/chain/sidechain_address_object.hpp>
#include <graphene/chain/son_wallet_object.hpp>
#include <graphene/chain/son_wallet_transfer_object.hpp>
#include <graphene/chain/protocol/transfer.hpp>
#include <graphene/peerplays_sidechain/sidechain_net_manager.hpp>
#include <graphene/utilities/key_conversion.hpp>
@ -48,7 +49,6 @@ class peerplays_sidechain_plugin_impl
private:
peerplays_sidechain_plugin& plugin;
graphene::chain::database& database;
bool config_ready_son;
bool config_ready_bitcoin;
@ -62,7 +62,6 @@ class peerplays_sidechain_plugin_impl
peerplays_sidechain_plugin_impl::peerplays_sidechain_plugin_impl(peerplays_sidechain_plugin& _plugin) :
plugin(_plugin),
database(_plugin.database()),
config_ready_son(false),
config_ready_bitcoin(false),
net_manager(nullptr)
@ -140,8 +139,8 @@ void peerplays_sidechain_plugin_impl::plugin_initialize(const boost::program_opt
throw;
}
database.applied_block.connect( [&] (const signed_block& b) { on_block_applied(b); } );
database.new_objects.connect( [&] (const vector<object_id_type>& ids, const flat_set<account_id_type>& impacted_accounts) { on_objects_new(ids); } );
plugin.database().applied_block.connect( [&] (const signed_block& b) { on_block_applied(b); } );
plugin.database().new_objects.connect( [&] (const vector<object_id_type>& ids, const flat_set<account_id_type>& impacted_accounts) { on_objects_new(ids); } );
net_manager = std::unique_ptr<sidechain_net_manager>(new sidechain_net_manager(plugin));
@ -198,7 +197,7 @@ son_id_type peerplays_sidechain_plugin_impl::get_son_id()
son_object peerplays_sidechain_plugin_impl::get_son_object()
{
const auto& idx = database.get_index_type<chain::son_index>().indices().get<by_id>();
const auto& idx = plugin.database().get_index_type<chain::son_index>().indices().get<by_id>();
auto son_obj = idx.find( get_son_id() );
if (son_obj == idx.end())
return {};
@ -207,12 +206,12 @@ son_object peerplays_sidechain_plugin_impl::get_son_object()
bool peerplays_sidechain_plugin_impl::is_active_son()
{
const auto& idx = database.get_index_type<chain::son_index>().indices().get<by_id>();
const auto& idx = plugin.database().get_index_type<chain::son_index>().indices().get<by_id>();
auto son_obj = idx.find( get_son_id() );
if (son_obj == idx.end())
return false;
const chain::global_property_object& gpo = database.get_global_properties();
const chain::global_property_object& gpo = plugin.database().get_global_properties();
vector<son_id_type> active_son_ids;
active_son_ids.reserve(gpo.active_sons.size());
std::transform(gpo.active_sons.begin(), gpo.active_sons.end(),
@ -347,13 +346,38 @@ void peerplays_sidechain_plugin_impl::recreate_primary_wallet()
void peerplays_sidechain_plugin_impl::process_deposits() {
const auto& idx = database.get_index_type<son_wallet_transfer_index>().indices().get<by_processed>();
// Account who issues tokens to the user who made deposit
account_id_type pay_from = GRAPHENE_NULL_ACCOUNT;
const auto& account_idx = plugin.database().get_index_type<account_index>().indices().get<by_name>();
const auto& account_itr = account_idx.find("nathan");
if (account_itr != account_idx.end())
pay_from = (*account_itr).id;
const auto& idx = plugin.database().get_index_type<son_wallet_transfer_index>().indices().get<by_processed>();
const auto& idx_range = idx.equal_range(false);
std::for_each(idx_range.first, idx_range.second,
[&] (const son_wallet_transfer_object& swto) {
const chain::global_property_object& gpo = plugin.database().get_global_properties();
transfer_operation op;
op.from = pay_from;
op.to = swto.peerplays_from;
op.amount = asset(swto.sidechain_amount); // For Bitcoin, the exchange rate is 1:1, for others, get the exchange rate from market
proposal_create_operation proposal_op;
proposal_op.fee_paying_account = plugin.get_son_object().son_account;
proposal_op.proposed_ops.push_back( op_wrapper( op ) );
uint32_t lifetime = ( gpo.parameters.block_interval * gpo.active_witnesses.size() ) * 3;
proposal_op.expiration_time = time_point_sec( plugin.database().head_block_time().sec_since_epoch() + lifetime );
signed_transaction trx = plugin.database().create_signed_transaction(plugin.get_private_keys().begin()->second, proposal_op);
try {
plugin.database().push_transaction(trx);
} catch(fc::exception e){
ilog("sidechain_net_handler: sending proposal for transfer operation failed with exception ${e}",("e", e.what()));
}
});
}
@ -444,6 +468,11 @@ void peerplays_sidechain_plugin_impl::on_objects_new(const vector<object_id_type
&& proposal->proposed_transaction.operations[0].which() == chain::operation::tag<chain::son_wallet_update_operation>::value) {
approve_proposal( proposal->id );
}
if(proposal->proposed_transaction.operations.size() == 1
&& proposal->proposed_transaction.operations[0].which() == chain::operation::tag<chain::transfer_operation>::value) {
approve_proposal( proposal->id );
}
}
}
}

View file

@ -44,25 +44,29 @@ std::vector<std::string> sidechain_net_handler::get_sidechain_addresses() {
void sidechain_net_handler::sidechain_event_data_received(const sidechain_event_data& sed) {
ilog( __FUNCTION__ );
ilog( "sidechain_event_data:" );
ilog( " uid: ${uid}", ( "uid", sed.uid ) );
ilog( " timestamp: ${timestamp}", ( "timestamp", sed.timestamp ) );
ilog( " sidechain: ${sidechain}", ( "sidechain", sed.sidechain ) );
ilog( " transaction_id: ${transaction_id}", ( "transaction_id", sed.transaction_id ) );
ilog( " from: ${from}", ( "from", sed.from ) );
ilog( " to: ${to}", ( "to", sed.to ) );
ilog( " amount: ${amount}", ( "amount", sed.amount ) );
ilog( " timestamp: ${timestamp}", ( "timestamp", sed.timestamp ) );
ilog( " sidechain: ${sidechain}", ( "sidechain", sed.sidechain ) );
ilog( " sidechain_uid: ${uid}", ( "uid", sed.sidechain_uid ) );
ilog( " sidechain_transaction_id: ${transaction_id}", ( "transaction_id", sed.sidechain_transaction_id ) );
ilog( " sidechain_from: ${from}", ( "from", sed.sidechain_from ) );
ilog( " sidechain_to: ${to}", ( "to", sed.sidechain_to ) );
ilog( " sidechain_amount: ${amount}", ( "amount", sed.sidechain_amount ) );
ilog( " peerplays_from: ${peerplays_from}", ( "peerplays_from", sed.peerplays_from ) );
ilog( " peerplays_to: ${peerplays_to}", ( "peerplays_to", sed.peerplays_to ) );
const chain::global_property_object& gpo = database.get_global_properties();
son_wallet_transfer_create_operation op;
op.payer = gpo.parameters.get_son_btc_account_id();
op.uid = sed.uid;
op.timestamp = sed.timestamp;
op.sidechain = sed.sidechain;
op.transaction_id = sed.transaction_id;
op.from = sed.from;
op.to = sed.to;
op.amount = sed.amount;
op.sidechain_uid = sed.sidechain_uid;
op.sidechain_transaction_id = sed.sidechain_transaction_id;
op.sidechain_from = sed.sidechain_from;
op.sidechain_to = sed.sidechain_to;
op.sidechain_amount = sed.sidechain_amount;
op.peerplays_from = sed.peerplays_from;
op.peerplays_to = sed.peerplays_to;
proposal_create_operation proposal_op;
proposal_op.fee_paying_account = plugin.get_son_object().son_account;

View file

@ -338,12 +338,6 @@ void sidechain_net_handler_bitcoin::handle_event( const std::string& event_data
if( block != "" ) {
const auto& vins = extract_info_from_block( block );
account_id_type peerplays_to = GRAPHENE_NULL_ACCOUNT;
const auto& account_idx = database.get_index_type<account_index>().indices().get<by_name>();
const auto& account_itr = account_idx.find("nathan");
if (account_itr != account_idx.end())
peerplays_to = (*account_itr).id;
const auto& sidechain_addresses_idx = database.get_index_type<sidechain_address_index>().indices().get<by_sidechain_and_address>();
for( const auto& v : vins ) {
@ -351,18 +345,20 @@ void sidechain_net_handler_bitcoin::handle_event( const std::string& event_data
if ( addr_itr == sidechain_addresses_idx.end() )
continue;
sidechain_event_data sed;
std::stringstream ss;
ss << "bitcoin" << "-" << v.out.hash_tx << "-" << v.out.n_vout;
sed.uid = ss.str();
std::string sidechain_uid = ss.str();
sidechain_event_data sed;
sed.timestamp = plugin.database().head_block_time();
sed.sidechain = addr_itr->sidechain;
sed.transaction_id = v.out.hash_tx;
sed.from = "";
sed.sidechain_uid = sidechain_uid;
sed.sidechain_transaction_id = v.out.hash_tx;
sed.sidechain_from = "";
sed.sidechain_to = v.address;
sed.sidechain_amount = v.out.amount;
sed.peerplays_from = addr_itr->sidechain_address_account;
sed.to = v.address;
sed.peerplays_to = peerplays_to;
sed.amount = v.out.amount;
sed.peerplays_to = GRAPHENE_SON_ACCOUNT_ID;
sidechain_event_data_received(sed);
}
}