Compare commits
8 commits
master
...
feature/SO
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dc26b5b2ac | ||
|
|
110676d8dd | ||
|
|
94fcedabb4 | ||
|
|
cef6a534a1 | ||
|
|
34cbd82d0c | ||
|
|
51da9e829d | ||
|
|
49e245f37d | ||
|
|
63e3b3a420 |
20 changed files with 479 additions and 112 deletions
|
|
@ -1906,15 +1906,24 @@ void perform_son_tasks(database& db)
|
||||||
const asset_object& btc_asset =
|
const asset_object& btc_asset =
|
||||||
db.create<asset_object>( [&gpo, &dyn_asset]( asset_object& a ) {
|
db.create<asset_object>( [&gpo, &dyn_asset]( asset_object& a ) {
|
||||||
a.symbol = "BTC";
|
a.symbol = "BTC";
|
||||||
a.options.max_supply = GRAPHENE_MAX_SHARE_SUPPLY;
|
|
||||||
a.precision = 8;
|
a.precision = 8;
|
||||||
a.options.flags = 0;
|
|
||||||
a.options.issuer_permissions = 0;
|
|
||||||
a.issuer = gpo.parameters.son_account();
|
a.issuer = gpo.parameters.son_account();
|
||||||
a.options.core_exchange_rate.base.amount = 1;
|
a.options.max_supply = GRAPHENE_MAX_SHARE_SUPPLY;
|
||||||
|
a.options.market_fee_percent = 500; // 5%
|
||||||
|
a.options.issuer_permissions = UIA_ASSET_ISSUER_PERMISSION_MASK;
|
||||||
|
a.options.flags = asset_issuer_permission_flags::charge_market_fee |
|
||||||
|
//asset_issuer_permission_flags::white_list |
|
||||||
|
asset_issuer_permission_flags::override_authority |
|
||||||
|
asset_issuer_permission_flags::transfer_restricted |
|
||||||
|
asset_issuer_permission_flags::disable_confidential;
|
||||||
|
a.options.core_exchange_rate.base.amount = 100000;
|
||||||
a.options.core_exchange_rate.base.asset_id = asset_id_type(0);
|
a.options.core_exchange_rate.base.asset_id = asset_id_type(0);
|
||||||
a.options.core_exchange_rate.quote.amount = 1;
|
a.options.core_exchange_rate.quote.amount = 2500; // CoinMarketCap approx value
|
||||||
a.options.core_exchange_rate.quote.asset_id = asset_id_type(0);
|
a.options.core_exchange_rate.quote.asset_id = asset_id_type(0);
|
||||||
|
a.options.whitelist_authorities.clear(); // accounts allowed to use asset, if not empty
|
||||||
|
a.options.blacklist_authorities.clear(); // accounts who can blacklist other accounts to use asset, if white_list flag is set
|
||||||
|
a.options.whitelist_markets.clear(); // might be traded with
|
||||||
|
a.options.blacklist_markets.clear(); // might not be traded with
|
||||||
a.dynamic_asset_data_id = dyn_asset.id;
|
a.dynamic_asset_data_id = dyn_asset.id;
|
||||||
});
|
});
|
||||||
db.modify( gpo, [&btc_asset]( global_property_object& gpo ) {
|
db.modify( gpo, [&btc_asset]( global_property_object& gpo ) {
|
||||||
|
|
@ -2137,6 +2146,8 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
|
||||||
p.pending_parameters->extensions.value.son_heartbeat_frequency = p.parameters.extensions.value.son_heartbeat_frequency;
|
p.pending_parameters->extensions.value.son_heartbeat_frequency = p.parameters.extensions.value.son_heartbeat_frequency;
|
||||||
if( !p.pending_parameters->extensions.value.son_down_time.valid() )
|
if( !p.pending_parameters->extensions.value.son_down_time.valid() )
|
||||||
p.pending_parameters->extensions.value.son_down_time = p.parameters.extensions.value.son_down_time;
|
p.pending_parameters->extensions.value.son_down_time = p.parameters.extensions.value.son_down_time;
|
||||||
|
if( !p.pending_parameters->extensions.value.son_bitcoin_min_tx_confirmations.valid() )
|
||||||
|
p.pending_parameters->extensions.value.son_bitcoin_min_tx_confirmations = p.parameters.extensions.value.son_bitcoin_min_tx_confirmations;
|
||||||
p.parameters = std::move(*p.pending_parameters);
|
p.parameters = std::move(*p.pending_parameters);
|
||||||
p.pending_parameters.reset();
|
p.pending_parameters.reset();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -234,6 +234,7 @@
|
||||||
#define SON_DEREGISTER_TIME (60*60*12) // 12 Hours in seconds
|
#define SON_DEREGISTER_TIME (60*60*12) // 12 Hours in seconds
|
||||||
#define SON_HEARTBEAT_FREQUENCY (60*3) // 3 minutes in seconds
|
#define SON_HEARTBEAT_FREQUENCY (60*3) // 3 minutes in seconds
|
||||||
#define SON_DOWN_TIME (60*3*2) // 2 Heartbeats in seconds
|
#define SON_DOWN_TIME (60*3*2) // 2 Heartbeats in seconds
|
||||||
|
#define SON_BITCOIN_MIN_TX_CONFIRMATIONS (1)
|
||||||
#define SON_PAY_TIME (60*60*24) // 1 day
|
#define SON_PAY_TIME (60*60*24) // 1 day
|
||||||
#define SON_PAY_MAX (GRAPHENE_BLOCKCHAIN_PRECISION * int64_t(200))
|
#define SON_PAY_MAX (GRAPHENE_BLOCKCHAIN_PRECISION * int64_t(200))
|
||||||
#define SWEEPS_DEFAULT_DISTRIBUTION_PERCENTAGE (2*GRAPHENE_1_PERCENT)
|
#define SWEEPS_DEFAULT_DISTRIBUTION_PERCENTAGE (2*GRAPHENE_1_PERCENT)
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ namespace graphene { namespace chain {
|
||||||
optional < uint32_t > son_deregister_time = SON_DEREGISTER_TIME;
|
optional < uint32_t > son_deregister_time = SON_DEREGISTER_TIME;
|
||||||
optional < uint32_t > son_heartbeat_frequency = SON_HEARTBEAT_FREQUENCY;
|
optional < uint32_t > son_heartbeat_frequency = SON_HEARTBEAT_FREQUENCY;
|
||||||
optional < uint32_t > son_down_time = SON_DOWN_TIME;
|
optional < uint32_t > son_down_time = SON_DOWN_TIME;
|
||||||
|
optional < uint16_t > son_bitcoin_min_tx_confirmations = SON_BITCOIN_MIN_TX_CONFIRMATIONS;
|
||||||
|
|
||||||
optional < account_id_type > son_account;
|
optional < account_id_type > son_account;
|
||||||
optional < asset_id_type > btc_asset;
|
optional < asset_id_type > btc_asset;
|
||||||
|
|
@ -161,6 +162,9 @@ namespace graphene { namespace chain {
|
||||||
inline uint16_t son_down_time()const {
|
inline uint16_t son_down_time()const {
|
||||||
return extensions.value.son_down_time.valid() ? *extensions.value.son_down_time : SON_DOWN_TIME;
|
return extensions.value.son_down_time.valid() ? *extensions.value.son_down_time : SON_DOWN_TIME;
|
||||||
}
|
}
|
||||||
|
inline uint16_t son_bitcoin_min_tx_confirmations()const {
|
||||||
|
return extensions.value.son_bitcoin_min_tx_confirmations.valid() ? *extensions.value.son_bitcoin_min_tx_confirmations : SON_BITCOIN_MIN_TX_CONFIRMATIONS;
|
||||||
|
}
|
||||||
inline uint32_t gpos_period()const {
|
inline uint32_t gpos_period()const {
|
||||||
return extensions.value.gpos_period.valid() ? *extensions.value.gpos_period : GPOS_PERIOD; /// total seconds of current gpos period
|
return extensions.value.gpos_period.valid() ? *extensions.value.gpos_period : GPOS_PERIOD; /// total seconds of current gpos period
|
||||||
}
|
}
|
||||||
|
|
@ -203,6 +207,7 @@ FC_REFLECT( graphene::chain::parameter_extension,
|
||||||
(son_deregister_time)
|
(son_deregister_time)
|
||||||
(son_heartbeat_frequency)
|
(son_heartbeat_frequency)
|
||||||
(son_down_time)
|
(son_down_time)
|
||||||
|
(son_bitcoin_min_tx_confirmations)
|
||||||
(son_account)
|
(son_account)
|
||||||
(btc_asset)
|
(btc_asset)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ namespace graphene { namespace chain {
|
||||||
|
|
||||||
son_id_type son_id;
|
son_id_type son_id;
|
||||||
fc::time_point_sec timestamp;
|
fc::time_point_sec timestamp;
|
||||||
|
uint32_t block_num;
|
||||||
sidechain_type sidechain;
|
sidechain_type sidechain;
|
||||||
std::string sidechain_uid;
|
std::string sidechain_uid;
|
||||||
std::string sidechain_transaction_id;
|
std::string sidechain_transaction_id;
|
||||||
|
|
@ -47,7 +48,7 @@ namespace graphene { namespace chain {
|
||||||
|
|
||||||
FC_REFLECT(graphene::chain::son_wallet_deposit_create_operation::fee_parameters_type, (fee) )
|
FC_REFLECT(graphene::chain::son_wallet_deposit_create_operation::fee_parameters_type, (fee) )
|
||||||
FC_REFLECT(graphene::chain::son_wallet_deposit_create_operation, (fee)(payer)
|
FC_REFLECT(graphene::chain::son_wallet_deposit_create_operation, (fee)(payer)
|
||||||
(son_id) (timestamp) (sidechain)
|
(son_id) (timestamp) (block_num) (sidechain)
|
||||||
(sidechain_uid) (sidechain_transaction_id) (sidechain_from) (sidechain_to) (sidechain_currency) (sidechain_amount)
|
(sidechain_uid) (sidechain_transaction_id) (sidechain_from) (sidechain_to) (sidechain_currency) (sidechain_amount)
|
||||||
(peerplays_from) (peerplays_to) (peerplays_asset) )
|
(peerplays_from) (peerplays_to) (peerplays_asset) )
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ namespace graphene { namespace chain {
|
||||||
|
|
||||||
son_id_type son_id;
|
son_id_type son_id;
|
||||||
fc::time_point_sec timestamp;
|
fc::time_point_sec timestamp;
|
||||||
|
uint32_t block_num;
|
||||||
sidechain_type sidechain;
|
sidechain_type sidechain;
|
||||||
std::string peerplays_uid;
|
std::string peerplays_uid;
|
||||||
std::string peerplays_transaction_id;
|
std::string peerplays_transaction_id;
|
||||||
|
|
@ -46,7 +47,7 @@ namespace graphene { namespace chain {
|
||||||
|
|
||||||
FC_REFLECT(graphene::chain::son_wallet_withdraw_create_operation::fee_parameters_type, (fee) )
|
FC_REFLECT(graphene::chain::son_wallet_withdraw_create_operation::fee_parameters_type, (fee) )
|
||||||
FC_REFLECT(graphene::chain::son_wallet_withdraw_create_operation, (fee)(payer)
|
FC_REFLECT(graphene::chain::son_wallet_withdraw_create_operation, (fee)(payer)
|
||||||
(son_id) (timestamp) (sidechain)
|
(son_id) (timestamp) (block_num) (sidechain)
|
||||||
(peerplays_uid) (peerplays_transaction_id) (peerplays_from) (peerplays_asset)
|
(peerplays_uid) (peerplays_transaction_id) (peerplays_from) (peerplays_asset)
|
||||||
(withdraw_sidechain) (withdraw_address) (withdraw_currency) (withdraw_amount) )
|
(withdraw_sidechain) (withdraw_address) (withdraw_currency) (withdraw_amount) )
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
#include <boost/multi_index/composite_key.hpp>
|
#include <boost/multi_index/composite_key.hpp>
|
||||||
#include <graphene/chain/protocol/types.hpp>
|
#include <graphene/chain/protocol/types.hpp>
|
||||||
#include <graphene/chain/sidechain_defs.hpp>
|
#include <graphene/chain/sidechain_defs.hpp>
|
||||||
|
#include <graphene/chain/son_info.hpp>
|
||||||
|
|
||||||
namespace graphene { namespace chain {
|
namespace graphene { namespace chain {
|
||||||
using namespace graphene::db;
|
using namespace graphene::db;
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ namespace graphene { namespace chain {
|
||||||
static const uint8_t type_id = son_wallet_deposit_object_type;
|
static const uint8_t type_id = son_wallet_deposit_object_type;
|
||||||
|
|
||||||
time_point_sec timestamp;
|
time_point_sec timestamp;
|
||||||
|
uint32_t block_num;
|
||||||
sidechain_type sidechain = sidechain_type::unknown;
|
sidechain_type sidechain = sidechain_type::unknown;
|
||||||
std::string sidechain_uid;
|
std::string sidechain_uid;
|
||||||
std::string sidechain_transaction_id;
|
std::string sidechain_transaction_id;
|
||||||
|
|
@ -61,7 +62,7 @@ namespace graphene { namespace chain {
|
||||||
} } // graphene::chain
|
} } // graphene::chain
|
||||||
|
|
||||||
FC_REFLECT_DERIVED( graphene::chain::son_wallet_deposit_object, (graphene::db::object),
|
FC_REFLECT_DERIVED( graphene::chain::son_wallet_deposit_object, (graphene::db::object),
|
||||||
(timestamp) (sidechain)
|
(timestamp) (block_num) (sidechain)
|
||||||
(sidechain_uid) (sidechain_transaction_id) (sidechain_from) (sidechain_to) (sidechain_currency) (sidechain_amount)
|
(sidechain_uid) (sidechain_transaction_id) (sidechain_from) (sidechain_to) (sidechain_currency) (sidechain_amount)
|
||||||
(peerplays_from) (peerplays_to) (peerplays_asset)
|
(peerplays_from) (peerplays_to) (peerplays_asset)
|
||||||
(expected_reports) (received_reports)
|
(expected_reports) (received_reports)
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ namespace graphene { namespace chain {
|
||||||
static const uint8_t type_id = son_wallet_withdraw_object_type;
|
static const uint8_t type_id = son_wallet_withdraw_object_type;
|
||||||
|
|
||||||
time_point_sec timestamp;
|
time_point_sec timestamp;
|
||||||
|
uint32_t block_num;
|
||||||
sidechain_type sidechain = sidechain_type::unknown;
|
sidechain_type sidechain = sidechain_type::unknown;
|
||||||
std::string peerplays_uid;
|
std::string peerplays_uid;
|
||||||
std::string peerplays_transaction_id;
|
std::string peerplays_transaction_id;
|
||||||
|
|
@ -60,7 +61,7 @@ namespace graphene { namespace chain {
|
||||||
} } // graphene::chain
|
} } // graphene::chain
|
||||||
|
|
||||||
FC_REFLECT_DERIVED( graphene::chain::son_wallet_withdraw_object, (graphene::db::object),
|
FC_REFLECT_DERIVED( graphene::chain::son_wallet_withdraw_object, (graphene::db::object),
|
||||||
(timestamp) (sidechain)
|
(timestamp) (block_num) (sidechain)
|
||||||
(peerplays_uid) (peerplays_transaction_id) (peerplays_from) (peerplays_asset)
|
(peerplays_uid) (peerplays_transaction_id) (peerplays_from) (peerplays_asset)
|
||||||
(withdraw_sidechain) (withdraw_address) (withdraw_currency) (withdraw_amount)
|
(withdraw_sidechain) (withdraw_address) (withdraw_currency) (withdraw_amount)
|
||||||
(expected_reports) (received_reports)
|
(expected_reports) (received_reports)
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ object_id_type create_son_wallet_deposit_evaluator::do_apply(const son_wallet_de
|
||||||
if (itr == idx.end()) {
|
if (itr == idx.end()) {
|
||||||
const auto& new_son_wallet_deposit_object = db().create<son_wallet_deposit_object>( [&]( son_wallet_deposit_object& swdo ){
|
const auto& new_son_wallet_deposit_object = db().create<son_wallet_deposit_object>( [&]( son_wallet_deposit_object& swdo ){
|
||||||
swdo.timestamp = op.timestamp;
|
swdo.timestamp = op.timestamp;
|
||||||
|
swdo.block_num = op.block_num;
|
||||||
swdo.sidechain = op.sidechain;
|
swdo.sidechain = op.sidechain;
|
||||||
swdo.sidechain_uid = op.sidechain_uid;
|
swdo.sidechain_uid = op.sidechain_uid;
|
||||||
swdo.sidechain_transaction_id = op.sidechain_transaction_id;
|
swdo.sidechain_transaction_id = op.sidechain_transaction_id;
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,7 @@ object_id_type create_son_wallet_withdraw_evaluator::do_apply(const son_wallet_w
|
||||||
if (itr == idx.end()) {
|
if (itr == idx.end()) {
|
||||||
const auto& new_son_wallet_withdraw_object = db().create<son_wallet_withdraw_object>( [&]( son_wallet_withdraw_object& swwo ){
|
const auto& new_son_wallet_withdraw_object = db().create<son_wallet_withdraw_object>( [&]( son_wallet_withdraw_object& swwo ){
|
||||||
swwo.timestamp = op.timestamp;
|
swwo.timestamp = op.timestamp;
|
||||||
|
swwo.block_num = op.block_num;
|
||||||
swwo.sidechain = op.sidechain;
|
swwo.sidechain = op.sidechain;
|
||||||
swwo.peerplays_uid = op.peerplays_uid;
|
swwo.peerplays_uid = op.peerplays_uid;
|
||||||
swwo.peerplays_transaction_id = op.peerplays_transaction_id;
|
swwo.peerplays_transaction_id = op.peerplays_transaction_id;
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@ struct info_for_vin {
|
||||||
|
|
||||||
struct sidechain_event_data {
|
struct sidechain_event_data {
|
||||||
fc::time_point_sec timestamp;
|
fc::time_point_sec timestamp;
|
||||||
|
uint32_t block_num;
|
||||||
sidechain_type sidechain;
|
sidechain_type sidechain;
|
||||||
std::string sidechain_uid;
|
std::string sidechain_uid;
|
||||||
std::string sidechain_transaction_id;
|
std::string sidechain_transaction_id;
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,7 @@
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
|
|
||||||
#include <fc/signals.hpp>
|
#include <fc/signals.hpp>
|
||||||
#include <graphene/chain/global_property_object.hpp>
|
#include <graphene/chain/proposal_object.hpp>
|
||||||
#include <graphene/chain/chain_property_object.hpp>
|
|
||||||
#include <graphene/chain/sidechain_address_object.hpp>
|
#include <graphene/chain/sidechain_address_object.hpp>
|
||||||
#include <graphene/chain/sidechain_transaction_object.hpp>
|
#include <graphene/chain/sidechain_transaction_object.hpp>
|
||||||
#include <graphene/chain/son_wallet_deposit_object.hpp>
|
#include <graphene/chain/son_wallet_deposit_object.hpp>
|
||||||
|
|
@ -26,13 +25,18 @@ public:
|
||||||
std::vector<std::string> get_sidechain_withdraw_addresses();
|
std::vector<std::string> get_sidechain_withdraw_addresses();
|
||||||
std::string get_private_key(std::string public_key);
|
std::string get_private_key(std::string public_key);
|
||||||
|
|
||||||
|
bool approve_proposal(const proposal_id_type &proposal_id, const son_id_type &son_id);
|
||||||
void sidechain_event_data_received(const sidechain_event_data &sed);
|
void sidechain_event_data_received(const sidechain_event_data &sed);
|
||||||
|
|
||||||
|
void process_proposals();
|
||||||
|
void process_active_sons_change();
|
||||||
void process_deposits();
|
void process_deposits();
|
||||||
void process_withdrawals();
|
void process_withdrawals();
|
||||||
void process_sidechain_transactions();
|
void process_sidechain_transactions();
|
||||||
void send_sidechain_transactions();
|
void send_sidechain_transactions();
|
||||||
|
|
||||||
virtual void recreate_primary_wallet() = 0;
|
virtual bool process_proposal(const proposal_object &po) = 0;
|
||||||
|
virtual void process_primary_wallet() = 0;
|
||||||
virtual bool process_deposit(const son_wallet_deposit_object &swdo) = 0;
|
virtual bool process_deposit(const son_wallet_deposit_object &swdo) = 0;
|
||||||
virtual bool process_withdrawal(const son_wallet_withdraw_object &swwo) = 0;
|
virtual bool process_withdrawal(const son_wallet_withdraw_object &swwo) = 0;
|
||||||
virtual std::string process_sidechain_transaction(const sidechain_transaction_object &sto, bool &complete) = 0;
|
virtual std::string process_sidechain_transaction(const sidechain_transaction_object &sto, bool &complete) = 0;
|
||||||
|
|
|
||||||
|
|
@ -29,13 +29,14 @@ public:
|
||||||
std::string decodepsbt(std::string const &tx_psbt);
|
std::string decodepsbt(std::string const &tx_psbt);
|
||||||
std::string decoderawtransaction(std::string const &tx_hex);
|
std::string decoderawtransaction(std::string const &tx_hex);
|
||||||
std::string encryptwallet(const std::string &passphrase);
|
std::string encryptwallet(const std::string &passphrase);
|
||||||
uint64_t estimatesmartfee();
|
uint64_t estimatesmartfee(uint16_t conf_target = 128);
|
||||||
std::string finalizepsbt(std::string const &tx_psbt);
|
std::string finalizepsbt(std::string const &tx_psbt);
|
||||||
std::string getaddressinfo(const std::string &address);
|
std::string getaddressinfo(const std::string &address);
|
||||||
std::string getblock(const std::string &block_hash, int32_t verbosity = 2);
|
std::string getblock(const std::string &block_hash, int32_t verbosity = 2);
|
||||||
|
std::string gettransaction(const std::string &txid, const bool include_watch_only = false);
|
||||||
void importaddress(const std::string &address_or_script);
|
void importaddress(const std::string &address_or_script);
|
||||||
std::vector<btc_txout> listunspent();
|
std::vector<btc_txout> listunspent(const uint32_t minconf = 1, const uint32_t maxconf = 9999999);
|
||||||
std::vector<btc_txout> listunspent_by_address_and_amount(const std::string &address, double transfer_amount);
|
std::vector<btc_txout> listunspent_by_address_and_amount(const std::string &address, double transfer_amount, const uint32_t minconf = 1, const uint32_t maxconf = 9999999);
|
||||||
std::string loadwallet(const std::string &filename);
|
std::string loadwallet(const std::string &filename);
|
||||||
bool sendrawtransaction(const std::string &tx_hex);
|
bool sendrawtransaction(const std::string &tx_hex);
|
||||||
std::string signrawtransactionwithwallet(const std::string &tx_hash);
|
std::string signrawtransactionwithwallet(const std::string &tx_hash);
|
||||||
|
|
@ -83,7 +84,8 @@ public:
|
||||||
sidechain_net_handler_bitcoin(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options);
|
sidechain_net_handler_bitcoin(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options);
|
||||||
virtual ~sidechain_net_handler_bitcoin();
|
virtual ~sidechain_net_handler_bitcoin();
|
||||||
|
|
||||||
void recreate_primary_wallet();
|
bool process_proposal(const proposal_object &po);
|
||||||
|
void process_primary_wallet();
|
||||||
bool process_deposit(const son_wallet_deposit_object &swdo);
|
bool process_deposit(const son_wallet_deposit_object &swdo);
|
||||||
bool process_withdrawal(const son_wallet_withdraw_object &swwo);
|
bool process_withdrawal(const son_wallet_withdraw_object &swwo);
|
||||||
std::string process_sidechain_transaction(const sidechain_transaction_object &sto, bool &complete);
|
std::string process_sidechain_transaction(const sidechain_transaction_object &sto, bool &complete);
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,8 @@ public:
|
||||||
sidechain_net_handler_peerplays(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options);
|
sidechain_net_handler_peerplays(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options);
|
||||||
virtual ~sidechain_net_handler_peerplays();
|
virtual ~sidechain_net_handler_peerplays();
|
||||||
|
|
||||||
void recreate_primary_wallet();
|
bool process_proposal(const proposal_object &po);
|
||||||
|
void process_primary_wallet();
|
||||||
bool process_deposit(const son_wallet_deposit_object &swdo);
|
bool process_deposit(const son_wallet_deposit_object &swdo);
|
||||||
bool process_withdrawal(const son_wallet_withdraw_object &swwo);
|
bool process_withdrawal(const son_wallet_withdraw_object &swwo);
|
||||||
std::string process_sidechain_transaction(const sidechain_transaction_object &sto, bool &complete);
|
std::string process_sidechain_transaction(const sidechain_transaction_object &sto, bool &complete);
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,8 @@ public:
|
||||||
virtual ~sidechain_net_manager();
|
virtual ~sidechain_net_manager();
|
||||||
|
|
||||||
bool create_handler(sidechain_type sidechain, const boost::program_options::variables_map &options);
|
bool create_handler(sidechain_type sidechain, const boost::program_options::variables_map &options);
|
||||||
void recreate_primary_wallet();
|
void process_proposals();
|
||||||
|
void process_active_sons_change();
|
||||||
void process_deposits();
|
void process_deposits();
|
||||||
void process_withdrawals();
|
void process_withdrawals();
|
||||||
void process_sidechain_transactions();
|
void process_sidechain_transactions();
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,9 @@ public:
|
||||||
void approve_proposals();
|
void approve_proposals();
|
||||||
void create_son_down_proposals();
|
void create_son_down_proposals();
|
||||||
void create_son_deregister_proposals();
|
void create_son_deregister_proposals();
|
||||||
void recreate_primary_wallet();
|
|
||||||
|
void process_proposals();
|
||||||
|
void process_active_sons_change();
|
||||||
void process_deposits();
|
void process_deposits();
|
||||||
void process_withdrawals();
|
void process_withdrawals();
|
||||||
void process_sidechain_transactions();
|
void process_sidechain_transactions();
|
||||||
|
|
@ -373,16 +375,16 @@ void peerplays_sidechain_plugin_impl::son_processing() {
|
||||||
("scheduled_son_id", scheduled_son_id)("now", now));
|
("scheduled_son_id", scheduled_son_id)("now", now));
|
||||||
|
|
||||||
for (son_id_type son_id : plugin.get_sons()) {
|
for (son_id_type son_id : plugin.get_sons()) {
|
||||||
|
current_son_id = son_id;
|
||||||
|
|
||||||
|
// These tasks are executed by
|
||||||
|
// - All active SONs, no matter if scheduled
|
||||||
|
// - All previously active SONs
|
||||||
|
approve_proposals();
|
||||||
|
process_proposals();
|
||||||
|
process_sidechain_transactions();
|
||||||
|
|
||||||
if (plugin.is_active_son(son_id)) {
|
if (plugin.is_active_son(son_id)) {
|
||||||
|
|
||||||
current_son_id = son_id;
|
|
||||||
|
|
||||||
// Tasks that are executed by all active SONs, no matter if scheduled
|
|
||||||
// E.g. sending approvals and signing (only signing that can be done in parallel)
|
|
||||||
approve_proposals();
|
|
||||||
process_sidechain_transactions();
|
|
||||||
|
|
||||||
// Tasks that are executed by scheduled and active SON only
|
// Tasks that are executed by scheduled and active SON only
|
||||||
if (current_son_id == scheduled_son_id) {
|
if (current_son_id == scheduled_son_id) {
|
||||||
|
|
||||||
|
|
@ -390,7 +392,7 @@ void peerplays_sidechain_plugin_impl::son_processing() {
|
||||||
|
|
||||||
create_son_deregister_proposals();
|
create_son_deregister_proposals();
|
||||||
|
|
||||||
recreate_primary_wallet();
|
process_active_sons_change();
|
||||||
|
|
||||||
process_deposits();
|
process_deposits();
|
||||||
|
|
||||||
|
|
@ -400,13 +402,6 @@ void peerplays_sidechain_plugin_impl::son_processing() {
|
||||||
|
|
||||||
send_sidechain_transactions();
|
send_sidechain_transactions();
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// Tasks that are executed by previously active SONs
|
|
||||||
// E.g. sending approvals and signing that SON was required to do while it was active
|
|
||||||
//approve_leftover_proposals(); ???
|
|
||||||
//process_leftover_sidechain_transactions(); ???
|
|
||||||
approve_proposals();
|
|
||||||
process_sidechain_transactions();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -423,27 +418,6 @@ bool peerplays_sidechain_plugin_impl::is_valid_son_proposal(const chain::proposa
|
||||||
if (op_idx_0 == chain::operation::tag<chain::son_delete_operation>::value) {
|
if (op_idx_0 == chain::operation::tag<chain::son_delete_operation>::value) {
|
||||||
return is_son_delete_op_valid(op);
|
return is_son_delete_op_valid(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (op_idx_0 == chain::operation::tag<chain::son_wallet_update_operation>::value) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (op_idx_0 == chain::operation::tag<chain::sidechain_transaction_create_operation>::value) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else if (proposal.proposed_transaction.operations.size() == 2) {
|
|
||||||
int32_t op_idx_0 = proposal.proposed_transaction.operations[0].which();
|
|
||||||
int32_t op_idx_1 = proposal.proposed_transaction.operations[1].which();
|
|
||||||
|
|
||||||
if ((op_idx_0 == chain::operation::tag<chain::son_wallet_deposit_process_operation>::value) &&
|
|
||||||
(op_idx_1 == chain::operation::tag<chain::asset_issue_operation>::value)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if ((op_idx_0 == chain::operation::tag<chain::son_wallet_withdraw_process_operation>::value) &&
|
|
||||||
(op_idx_1 == chain::operation::tag<chain::asset_reserve_operation>::value)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -588,8 +562,12 @@ void peerplays_sidechain_plugin_impl::create_son_deregister_proposals() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void peerplays_sidechain_plugin_impl::recreate_primary_wallet() {
|
void peerplays_sidechain_plugin_impl::process_proposals() {
|
||||||
net_manager->recreate_primary_wallet();
|
net_manager->process_proposals();
|
||||||
|
}
|
||||||
|
|
||||||
|
void peerplays_sidechain_plugin_impl::process_active_sons_change() {
|
||||||
|
net_manager->process_active_sons_change();
|
||||||
}
|
}
|
||||||
|
|
||||||
void peerplays_sidechain_plugin_impl::process_deposits() {
|
void peerplays_sidechain_plugin_impl::process_deposits() {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include <fc/log/logger.hpp>
|
#include <fc/log/logger.hpp>
|
||||||
#include <fc/smart_ref_fwd.hpp>
|
#include <fc/smart_ref_fwd.hpp>
|
||||||
|
#include <graphene/chain/chain_property_object.hpp>
|
||||||
|
#include <graphene/chain/proposal_object.hpp>
|
||||||
|
|
||||||
namespace graphene { namespace peerplays_sidechain {
|
namespace graphene { namespace peerplays_sidechain {
|
||||||
|
|
||||||
|
|
@ -51,9 +53,30 @@ std::string sidechain_net_handler::get_private_key(std::string public_key) {
|
||||||
return std::string();
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool sidechain_net_handler::approve_proposal(const proposal_id_type &proposal_id, const son_id_type &son_id) {
|
||||||
|
|
||||||
|
proposal_update_operation op;
|
||||||
|
op.fee_paying_account = plugin.get_son_object(son_id).son_account;
|
||||||
|
op.proposal = proposal_id;
|
||||||
|
op.active_approvals_to_add = {plugin.get_son_object(son_id).son_account};
|
||||||
|
|
||||||
|
signed_transaction tx = database.create_signed_transaction(plugin.get_private_key(son_id), op);
|
||||||
|
try {
|
||||||
|
database.push_transaction(tx, database::validation_steps::skip_block_size_check);
|
||||||
|
if (plugin.app().p2p_node())
|
||||||
|
plugin.app().p2p_node()->broadcast(net::trx_message(tx));
|
||||||
|
return true;
|
||||||
|
} catch (fc::exception e) {
|
||||||
|
elog("Sending approval from ${son_id} for proposal ${proposal_id} failed with exception ${e}",
|
||||||
|
("son_id", son_id)("proposal_id", proposal_id)("e", e.what()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void sidechain_net_handler::sidechain_event_data_received(const sidechain_event_data &sed) {
|
void sidechain_net_handler::sidechain_event_data_received(const sidechain_event_data &sed) {
|
||||||
ilog("sidechain_event_data:");
|
ilog("sidechain_event_data:");
|
||||||
ilog(" timestamp: ${timestamp}", ("timestamp", sed.timestamp));
|
ilog(" timestamp: ${timestamp}", ("timestamp", sed.timestamp));
|
||||||
|
ilog(" block_num: ${block_num}", ("block_num", sed.block_num));
|
||||||
ilog(" sidechain: ${sidechain}", ("sidechain", sed.sidechain));
|
ilog(" sidechain: ${sidechain}", ("sidechain", sed.sidechain));
|
||||||
ilog(" sidechain_uid: ${uid}", ("uid", sed.sidechain_uid));
|
ilog(" sidechain_uid: ${uid}", ("uid", sed.sidechain_uid));
|
||||||
ilog(" sidechain_transaction_id: ${transaction_id}", ("transaction_id", sed.sidechain_transaction_id));
|
ilog(" sidechain_transaction_id: ${transaction_id}", ("transaction_id", sed.sidechain_transaction_id));
|
||||||
|
|
@ -67,8 +90,13 @@ void sidechain_net_handler::sidechain_event_data_received(const sidechain_event_
|
||||||
|
|
||||||
const chain::global_property_object &gpo = database.get_global_properties();
|
const chain::global_property_object &gpo = database.get_global_properties();
|
||||||
|
|
||||||
|
asset_id_type btc_asset_id = database.get_global_properties().parameters.btc_asset();
|
||||||
|
std::string btc_asset_id_str = fc::to_string(btc_asset_id.space_id) + "." +
|
||||||
|
fc::to_string(btc_asset_id.type_id) + "." +
|
||||||
|
fc::to_string((uint64_t)btc_asset_id.instance);
|
||||||
|
|
||||||
// Deposit request
|
// Deposit request
|
||||||
if ((sed.peerplays_from == gpo.parameters.son_account()) && (sed.sidechain_currency != fc::variant(gpo.parameters.btc_asset(), 1).as<std::string>(1))) {
|
if ((sed.peerplays_to == gpo.parameters.son_account()) && (sed.sidechain_currency.compare(btc_asset_id_str) != 0)) {
|
||||||
|
|
||||||
for (son_id_type son_id : plugin.get_sons()) {
|
for (son_id_type son_id : plugin.get_sons()) {
|
||||||
if (plugin.is_active_son(son_id)) {
|
if (plugin.is_active_son(son_id)) {
|
||||||
|
|
@ -77,6 +105,7 @@ void sidechain_net_handler::sidechain_event_data_received(const sidechain_event_
|
||||||
op.payer = plugin.get_son_object(son_id).son_account;
|
op.payer = plugin.get_son_object(son_id).son_account;
|
||||||
op.son_id = son_id;
|
op.son_id = son_id;
|
||||||
op.timestamp = sed.timestamp;
|
op.timestamp = sed.timestamp;
|
||||||
|
op.block_num = sed.block_num;
|
||||||
op.sidechain = sed.sidechain;
|
op.sidechain = sed.sidechain;
|
||||||
op.sidechain_uid = sed.sidechain_uid;
|
op.sidechain_uid = sed.sidechain_uid;
|
||||||
op.sidechain_transaction_id = sed.sidechain_transaction_id;
|
op.sidechain_transaction_id = sed.sidechain_transaction_id;
|
||||||
|
|
@ -102,7 +131,7 @@ void sidechain_net_handler::sidechain_event_data_received(const sidechain_event_
|
||||||
}
|
}
|
||||||
|
|
||||||
// Withdrawal request
|
// Withdrawal request
|
||||||
if ((sed.peerplays_to == gpo.parameters.son_account()) && (sed.sidechain_currency == fc::variant(gpo.parameters.btc_asset(), 1).as<std::string>(1))) {
|
if ((sed.peerplays_to == gpo.parameters.son_account()) && (sed.sidechain_currency.compare(btc_asset_id_str) == 0)) {
|
||||||
// BTC Payout only (for now)
|
// BTC Payout only (for now)
|
||||||
const auto &sidechain_addresses_idx = database.get_index_type<sidechain_address_index>().indices().get<by_account_and_sidechain>();
|
const auto &sidechain_addresses_idx = database.get_index_type<sidechain_address_index>().indices().get<by_account_and_sidechain>();
|
||||||
const auto &addr_itr = sidechain_addresses_idx.find(std::make_tuple(sed.peerplays_from, sidechain_type::bitcoin));
|
const auto &addr_itr = sidechain_addresses_idx.find(std::make_tuple(sed.peerplays_from, sidechain_type::bitcoin));
|
||||||
|
|
@ -116,15 +145,18 @@ void sidechain_net_handler::sidechain_event_data_received(const sidechain_event_
|
||||||
op.payer = plugin.get_son_object(son_id).son_account;
|
op.payer = plugin.get_son_object(son_id).son_account;
|
||||||
op.son_id = son_id;
|
op.son_id = son_id;
|
||||||
op.timestamp = sed.timestamp;
|
op.timestamp = sed.timestamp;
|
||||||
|
op.block_num = sed.block_num;
|
||||||
op.sidechain = sed.sidechain;
|
op.sidechain = sed.sidechain;
|
||||||
op.peerplays_uid = sed.sidechain_uid;
|
op.peerplays_uid = sed.sidechain_uid;
|
||||||
op.peerplays_transaction_id = sed.sidechain_transaction_id;
|
op.peerplays_transaction_id = sed.sidechain_transaction_id;
|
||||||
op.peerplays_from = sed.peerplays_from;
|
op.peerplays_from = sed.peerplays_from;
|
||||||
op.peerplays_asset = sed.peerplays_asset;
|
op.peerplays_asset = sed.peerplays_asset;
|
||||||
op.withdraw_sidechain = sidechain_type::bitcoin; // BTC payout only (for now)
|
// BTC payout only (for now)
|
||||||
op.withdraw_address = addr_itr->withdraw_address; // BTC payout only (for now)
|
op.withdraw_sidechain = sidechain_type::bitcoin;
|
||||||
op.withdraw_currency = "BTC"; // BTC payout only (for now)
|
op.withdraw_address = addr_itr->withdraw_address;
|
||||||
op.withdraw_amount = sed.peerplays_asset.amount; // BTC payout only (for now)
|
op.withdraw_currency = "BTC";
|
||||||
|
price btc_price = database.get<asset_object>(database.get_global_properties().parameters.btc_asset()).options.core_exchange_rate;
|
||||||
|
op.withdraw_amount = sed.peerplays_asset.amount * btc_price.quote.amount / btc_price.base.amount;
|
||||||
|
|
||||||
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(son_id), op);
|
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(son_id), op);
|
||||||
try {
|
try {
|
||||||
|
|
@ -142,6 +174,100 @@ void sidechain_net_handler::sidechain_event_data_received(const sidechain_event_
|
||||||
FC_ASSERT(false, "Invalid sidechain event");
|
FC_ASSERT(false, "Invalid sidechain event");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sidechain_net_handler::process_proposals() {
|
||||||
|
const auto &idx = database.get_index_type<proposal_index>().indices().get<by_id>();
|
||||||
|
vector<proposal_id_type> proposals;
|
||||||
|
for (const auto &proposal : idx) {
|
||||||
|
proposals.push_back(proposal.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto proposal_id : proposals) {
|
||||||
|
const auto &idx = database.get_index_type<proposal_index>().indices().get<by_id>();
|
||||||
|
const auto po = idx.find(proposal_id);
|
||||||
|
if (po != idx.end()) {
|
||||||
|
|
||||||
|
ilog("Proposal to process: ${po}, SON id ${son_id}", ("po", (*po).id)("son_id", plugin.get_current_son_id()));
|
||||||
|
|
||||||
|
if (po->available_active_approvals.find(plugin.get_current_son_object().son_account) != po->available_active_approvals.end()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool should_process = false;
|
||||||
|
|
||||||
|
int32_t op_idx_0 = -1;
|
||||||
|
chain::operation op_obj_idx_0;
|
||||||
|
int32_t op_idx_1 = -1;
|
||||||
|
chain::operation op_obj_idx_1;
|
||||||
|
|
||||||
|
if (po->proposed_transaction.operations.size() >= 1) {
|
||||||
|
op_idx_0 = po->proposed_transaction.operations[0].which();
|
||||||
|
op_obj_idx_0 = po->proposed_transaction.operations[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (po->proposed_transaction.operations.size() >= 2) {
|
||||||
|
op_idx_1 = po->proposed_transaction.operations[1].which();
|
||||||
|
op_obj_idx_1 = po->proposed_transaction.operations[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (op_idx_0) {
|
||||||
|
case chain::operation::tag<chain::son_wallet_update_operation>::value: {
|
||||||
|
should_process = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case chain::operation::tag<chain::son_wallet_deposit_process_operation>::value: {
|
||||||
|
son_wallet_deposit_id_type swdo_id = op_obj_idx_0.get<son_wallet_deposit_process_operation>().son_wallet_deposit_id;
|
||||||
|
const auto &idx = database.get_index_type<son_wallet_deposit_index>().indices().get<by_id>();
|
||||||
|
const auto swdo = idx.find(swdo_id);
|
||||||
|
if (swdo != idx.end()) {
|
||||||
|
should_process = (swdo->sidechain == sidechain);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case chain::operation::tag<chain::son_wallet_withdraw_process_operation>::value: {
|
||||||
|
son_wallet_withdraw_id_type swwo_id = op_obj_idx_0.get<son_wallet_withdraw_process_operation>().son_wallet_withdraw_id;
|
||||||
|
const auto &idx = database.get_index_type<son_wallet_withdraw_index>().indices().get<by_id>();
|
||||||
|
const auto swwo = idx.find(swwo_id);
|
||||||
|
if (swwo != idx.end()) {
|
||||||
|
should_process = (swwo->sidechain == sidechain);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case chain::operation::tag<chain::sidechain_transaction_create_operation>::value: {
|
||||||
|
sidechain_type sc = op_obj_idx_0.get<sidechain_transaction_create_operation>().sidechain;
|
||||||
|
should_process = (sc == sidechain);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
should_process = false;
|
||||||
|
ilog("==================================================");
|
||||||
|
ilog("Proposal not processed ${po}", ("po", *po));
|
||||||
|
ilog("==================================================");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (should_process) {
|
||||||
|
ilog("Proposal ${po} will be processed by sidechain handler ${sidechain}", ("po", (*po).id)("sidechain", sidechain));
|
||||||
|
bool should_approve = process_proposal(*po);
|
||||||
|
if (should_approve) {
|
||||||
|
ilog("Proposal ${po} will be approved", ("po", *po));
|
||||||
|
approve_proposal(po->id, plugin.get_current_son_id());
|
||||||
|
} else {
|
||||||
|
ilog("Proposal ${po} is not approved", ("po", (*po).id));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ilog("Proposal ${po} will not be processed by sidechain handler ${sidechain}", ("po", (*po).id)("sidechain", sidechain));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sidechain_net_handler::process_active_sons_change() {
|
||||||
|
process_primary_wallet();
|
||||||
|
}
|
||||||
|
|
||||||
void sidechain_net_handler::process_deposits() {
|
void sidechain_net_handler::process_deposits() {
|
||||||
if (database.get_global_properties().active_sons.size() < database.get_chain_properties().immutable_parameters.min_son_count) {
|
if (database.get_global_properties().active_sons.size() < database.get_chain_properties().immutable_parameters.min_son_count) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -166,16 +292,17 @@ void sidechain_net_handler::process_deposits() {
|
||||||
swdp_op.payer = gpo.parameters.son_account();
|
swdp_op.payer = gpo.parameters.son_account();
|
||||||
swdp_op.son_wallet_deposit_id = swdo.id;
|
swdp_op.son_wallet_deposit_id = swdo.id;
|
||||||
|
|
||||||
asset_issue_operation i_op;
|
asset_issue_operation ai_op;
|
||||||
i_op.fee = asset(2001000);
|
ai_op.fee = asset(2001000);
|
||||||
i_op.issuer = gpo.parameters.son_account();
|
ai_op.issuer = gpo.parameters.son_account();
|
||||||
i_op.asset_to_issue = swdo.peerplays_asset;
|
price btc_price = database.get<asset_object>(database.get_global_properties().parameters.btc_asset()).options.core_exchange_rate;
|
||||||
i_op.issue_to_account = swdo.peerplays_to;
|
ai_op.asset_to_issue = asset(swdo.peerplays_asset.amount * btc_price.quote.amount / btc_price.base.amount, database.get_global_properties().parameters.btc_asset());
|
||||||
|
ai_op.issue_to_account = swdo.peerplays_from;
|
||||||
|
|
||||||
proposal_create_operation proposal_op;
|
proposal_create_operation proposal_op;
|
||||||
proposal_op.fee_paying_account = plugin.get_current_son_object().son_account;
|
proposal_op.fee_paying_account = plugin.get_current_son_object().son_account;
|
||||||
proposal_op.proposed_ops.emplace_back(swdp_op);
|
proposal_op.proposed_ops.emplace_back(swdp_op);
|
||||||
proposal_op.proposed_ops.emplace_back(i_op);
|
proposal_op.proposed_ops.emplace_back(ai_op);
|
||||||
uint32_t lifetime = (gpo.parameters.block_interval * gpo.active_witnesses.size()) * 3;
|
uint32_t lifetime = (gpo.parameters.block_interval * gpo.active_witnesses.size()) * 3;
|
||||||
proposal_op.expiration_time = time_point_sec(database.head_block_time().sec_since_epoch() + lifetime);
|
proposal_op.expiration_time = time_point_sec(database.head_block_time().sec_since_epoch() + lifetime);
|
||||||
|
|
||||||
|
|
@ -186,7 +313,7 @@ void sidechain_net_handler::process_deposits() {
|
||||||
if (plugin.app().p2p_node())
|
if (plugin.app().p2p_node())
|
||||||
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
|
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
|
||||||
} catch (fc::exception e) {
|
} catch (fc::exception e) {
|
||||||
elog("Sending proposal for deposit sidechain transaction create operation failed with exception ${e}", ("e", e.what()));
|
elog("Sending proposal for son wallet deposit process operation failed with exception ${e}", ("e", e.what()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -215,16 +342,15 @@ void sidechain_net_handler::process_withdrawals() {
|
||||||
swwp_op.payer = gpo.parameters.son_account();
|
swwp_op.payer = gpo.parameters.son_account();
|
||||||
swwp_op.son_wallet_withdraw_id = swwo.id;
|
swwp_op.son_wallet_withdraw_id = swwo.id;
|
||||||
|
|
||||||
asset_reserve_operation r_op;
|
asset_reserve_operation ar_op;
|
||||||
r_op.fee = asset(2001000);
|
ar_op.fee = asset(2001000);
|
||||||
r_op.payer = gpo.parameters.son_account();
|
ar_op.payer = gpo.parameters.son_account();
|
||||||
asset_object btc_asset_obj = gpo.parameters.btc_asset()(database);
|
ar_op.amount_to_reserve = asset(swwo.withdraw_amount, database.get_global_properties().parameters.btc_asset());
|
||||||
r_op.amount_to_reserve = btc_asset_obj.amount(swwo.withdraw_amount);
|
|
||||||
|
|
||||||
proposal_create_operation proposal_op;
|
proposal_create_operation proposal_op;
|
||||||
proposal_op.fee_paying_account = plugin.get_current_son_object().son_account;
|
proposal_op.fee_paying_account = plugin.get_current_son_object().son_account;
|
||||||
proposal_op.proposed_ops.emplace_back(swwp_op);
|
proposal_op.proposed_ops.emplace_back(swwp_op);
|
||||||
proposal_op.proposed_ops.emplace_back(r_op);
|
proposal_op.proposed_ops.emplace_back(ar_op);
|
||||||
uint32_t lifetime = (gpo.parameters.block_interval * gpo.active_witnesses.size()) * 3;
|
uint32_t lifetime = (gpo.parameters.block_interval * gpo.active_witnesses.size()) * 3;
|
||||||
proposal_op.expiration_time = time_point_sec(database.head_block_time().sec_since_epoch() + lifetime);
|
proposal_op.expiration_time = time_point_sec(database.head_block_time().sec_since_epoch() + lifetime);
|
||||||
|
|
||||||
|
|
@ -235,7 +361,7 @@ void sidechain_net_handler::process_withdrawals() {
|
||||||
if (plugin.app().p2p_node())
|
if (plugin.app().p2p_node())
|
||||||
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
|
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
|
||||||
} catch (fc::exception e) {
|
} catch (fc::exception e) {
|
||||||
elog("Sending proposal for withdraw sidechain transaction create operation failed with exception ${e}", ("e", e.what()));
|
elog("Sending proposal for son wallet withdraw process operation failed with exception ${e}", ("e", e.what()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -245,13 +371,13 @@ void sidechain_net_handler::process_sidechain_transactions() {
|
||||||
const auto &idx_range = idx.equal_range(std::make_tuple(sidechain, false));
|
const auto &idx_range = idx.equal_range(std::make_tuple(sidechain, false));
|
||||||
|
|
||||||
std::for_each(idx_range.first, idx_range.second, [&](const sidechain_transaction_object &sto) {
|
std::for_each(idx_range.first, idx_range.second, [&](const sidechain_transaction_object &sto) {
|
||||||
ilog("Sidechain transaction to process: ${sto}", ("sto", sto));
|
ilog("Sidechain transaction to process: ${sto}", ("sto", sto.id));
|
||||||
|
|
||||||
bool complete = false;
|
bool complete = false;
|
||||||
std::string processed_sidechain_tx = process_sidechain_transaction(sto, complete);
|
std::string processed_sidechain_tx = process_sidechain_transaction(sto, complete);
|
||||||
|
|
||||||
if (processed_sidechain_tx.empty()) {
|
if (processed_sidechain_tx.empty()) {
|
||||||
wlog("Sidechain transaction not processed: ${sto}", ("sto", sto));
|
wlog("Sidechain transaction not processed: ${sto}", ("sto", sto.id));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -278,13 +404,13 @@ void sidechain_net_handler::send_sidechain_transactions() {
|
||||||
const auto &idx_range = idx.equal_range(std::make_tuple(sidechain, true, false));
|
const auto &idx_range = idx.equal_range(std::make_tuple(sidechain, true, false));
|
||||||
|
|
||||||
std::for_each(idx_range.first, idx_range.second, [&](const sidechain_transaction_object &sto) {
|
std::for_each(idx_range.first, idx_range.second, [&](const sidechain_transaction_object &sto) {
|
||||||
ilog("Sidechain transaction to send: ${sto}", ("sto", sto));
|
ilog("Sidechain transaction to send: ${sto}", ("sto", sto.id));
|
||||||
|
|
||||||
std::string sidechain_transaction = "";
|
std::string sidechain_transaction = "";
|
||||||
bool sent = send_sidechain_transaction(sto, sidechain_transaction);
|
bool sent = send_sidechain_transaction(sto, sidechain_transaction);
|
||||||
|
|
||||||
if (!sent) {
|
if (!sent) {
|
||||||
wlog("Sidechain transaction not sent: ${sto}", ("sto", sto));
|
wlog("Sidechain transaction not sent: ${sto}", ("sto", sto.id));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -305,8 +431,12 @@ void sidechain_net_handler::send_sidechain_transactions() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void sidechain_net_handler::recreate_primary_wallet() {
|
bool sidechain_net_handler::process_proposal(const proposal_object &po) {
|
||||||
FC_ASSERT(false, "recreate_primary_wallet not implemented");
|
FC_ASSERT(false, "process_proposal not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
void sidechain_net_handler::process_primary_wallet() {
|
||||||
|
FC_ASSERT(false, "process_primary_wallet not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sidechain_net_handler::process_deposit(const son_wallet_deposit_object &swdo) {
|
bool sidechain_net_handler::process_deposit(const son_wallet_deposit_object &swdo) {
|
||||||
|
|
|
||||||
|
|
@ -300,14 +300,12 @@ std::string bitcoin_rpc_client::encryptwallet(const std::string &passphrase) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t bitcoin_rpc_client::estimatesmartfee() {
|
uint64_t bitcoin_rpc_client::estimatesmartfee(uint16_t conf_target) {
|
||||||
static const auto confirmation_target_blocks = 6;
|
|
||||||
|
|
||||||
const auto body = std::string("{\"jsonrpc\": \"1.0\", \"id\":\"estimatesmartfee\", "
|
const auto body = std::string("{\"jsonrpc\": \"1.0\", \"id\":\"estimatesmartfee\", "
|
||||||
"\"method\": \"estimatesmartfee\", \"params\": [") +
|
"\"method\": \"estimatesmartfee\", \"params\": [" +
|
||||||
std::to_string(confirmation_target_blocks) + std::string("] }");
|
std::to_string(conf_target) + std::string("] }"));
|
||||||
|
|
||||||
const auto reply = send_post_request(body);
|
const auto reply = send_post_request(body, true);
|
||||||
|
|
||||||
if (reply.body.empty()) {
|
if (reply.body.empty()) {
|
||||||
wlog("Bitcoin RPC call ${function} failed", ("function", __FUNCTION__));
|
wlog("Bitcoin RPC call ${function} failed", ("function", __FUNCTION__));
|
||||||
|
|
@ -421,10 +419,36 @@ std::string bitcoin_rpc_client::getblock(const std::string &block_hash, int32_t
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string bitcoin_rpc_client::gettransaction(const std::string &txid, const bool include_watch_only) {
|
||||||
|
std::string body = std::string("{\"jsonrpc\": \"1.0\", \"id\":\"gettransaction\", \"method\": "
|
||||||
|
"\"gettransaction\", \"params\": [\"" +
|
||||||
|
txid + "\"] }");
|
||||||
|
|
||||||
|
const auto reply = send_post_request(body, true);
|
||||||
|
|
||||||
|
if (reply.body.empty()) {
|
||||||
|
wlog("Bitcoin RPC call ${function} failed", ("function", __FUNCTION__));
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stringstream ss(std::string(reply.body.begin(), reply.body.end()));
|
||||||
|
boost::property_tree::ptree json;
|
||||||
|
boost::property_tree::read_json(ss, json);
|
||||||
|
|
||||||
|
if (reply.status == 200) {
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (json.count("error") && !json.get_child("error").empty()) {
|
||||||
|
wlog("Bitcoin RPC call ${function} with body ${body} failed with reply '${msg}'", ("function", __FUNCTION__)("body", body)("msg", ss.str()));
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
void bitcoin_rpc_client::importaddress(const std::string &address_or_script) {
|
void bitcoin_rpc_client::importaddress(const std::string &address_or_script) {
|
||||||
const auto body = std::string("{\"jsonrpc\": \"1.0\", \"id\":\"importaddress\", "
|
const auto body = std::string("{\"jsonrpc\": \"1.0\", \"id\":\"importaddress\", "
|
||||||
"\"method\": \"importaddress\", \"params\": [") +
|
"\"method\": \"importaddress\", \"params\": [" +
|
||||||
std::string("\"") + address_or_script + std::string("\"") + std::string("] }");
|
std::string("\"") + address_or_script + std::string("\"") + std::string("] }"));
|
||||||
|
|
||||||
const auto reply = send_post_request(body);
|
const auto reply = send_post_request(body);
|
||||||
|
|
||||||
|
|
@ -444,9 +468,10 @@ void bitcoin_rpc_client::importaddress(const std::string &address_or_script) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<btc_txout> bitcoin_rpc_client::listunspent() {
|
std::vector<btc_txout> bitcoin_rpc_client::listunspent(const uint32_t minconf, const uint32_t maxconf) {
|
||||||
const auto body = std::string("{\"jsonrpc\": \"1.0\", \"id\":\"pp_plugin\", \"method\": "
|
const auto body = std::string("{\"jsonrpc\": \"1.0\", \"id\":\"pp_plugin\", \"method\": "
|
||||||
"\"listunspent\", \"params\": [] }");
|
"\"listunspent\", \"params\": [" +
|
||||||
|
std::to_string(minconf) + "," + std::to_string(maxconf) + "] }");
|
||||||
|
|
||||||
const auto reply = send_post_request(body);
|
const auto reply = send_post_request(body);
|
||||||
|
|
||||||
|
|
@ -477,14 +502,15 @@ std::vector<btc_txout> bitcoin_rpc_client::listunspent() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<btc_txout> bitcoin_rpc_client::listunspent_by_address_and_amount(const std::string &address, double minimum_amount) {
|
std::vector<btc_txout> bitcoin_rpc_client::listunspent_by_address_and_amount(const std::string &address, double minimum_amount, const uint32_t minconf, const uint32_t maxconf) {
|
||||||
std::string body = std::string("{\"jsonrpc\": \"1.0\", \"id\":\"pp_plugin\", \"method\": "
|
std::string body = std::string("{\"jsonrpc\": \"1.0\", \"id\":\"pp_plugin\", \"method\": "
|
||||||
"\"listunspent\", \"params\": [");
|
"\"listunspent\", \"params\": [" +
|
||||||
body += std::string("1,999999,[\"");
|
std::to_string(minconf) + "," + std::to_string(maxconf) + ",");
|
||||||
|
body += std::string("[\"");
|
||||||
body += address;
|
body += address;
|
||||||
body += std::string("\"],true,{\"minimumAmount\":");
|
body += std::string("\"],true,{\"minimumAmount\":");
|
||||||
body += std::to_string(minimum_amount);
|
body += std::to_string(minimum_amount);
|
||||||
body += std::string("}] }");
|
body += std::string("} ] }");
|
||||||
|
|
||||||
const auto reply = send_post_request(body);
|
const auto reply = send_post_request(body);
|
||||||
|
|
||||||
|
|
@ -840,7 +866,98 @@ sidechain_net_handler_bitcoin::~sidechain_net_handler_bitcoin() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sidechain_net_handler_bitcoin::recreate_primary_wallet() {
|
bool sidechain_net_handler_bitcoin::process_proposal(const proposal_object &po) {
|
||||||
|
|
||||||
|
ilog("Proposal to process: ${po}, SON id ${son_id}", ("po", po.id)("son_id", plugin.get_current_son_id()));
|
||||||
|
|
||||||
|
bool should_approve = false;
|
||||||
|
|
||||||
|
const chain::global_property_object &gpo = database.get_global_properties();
|
||||||
|
|
||||||
|
int32_t op_idx_0 = -1;
|
||||||
|
chain::operation op_obj_idx_0;
|
||||||
|
//int32_t op_idx_1 = -1;
|
||||||
|
//chain::operation op_obj_idx_1;
|
||||||
|
|
||||||
|
if (po.proposed_transaction.operations.size() >= 1) {
|
||||||
|
op_idx_0 = po.proposed_transaction.operations[0].which();
|
||||||
|
op_obj_idx_0 = po.proposed_transaction.operations[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (po.proposed_transaction.operations.size() >= 2) {
|
||||||
|
//op_idx_1 = po.proposed_transaction.operations[1].which();
|
||||||
|
//op_obj_idx_1 = po.proposed_transaction.operations[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (op_idx_0) {
|
||||||
|
|
||||||
|
case chain::operation::tag<chain::son_wallet_update_operation>::value: {
|
||||||
|
should_approve = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case chain::operation::tag<chain::son_wallet_deposit_process_operation>::value: {
|
||||||
|
son_wallet_deposit_id_type swdo_id = op_obj_idx_0.get<son_wallet_deposit_process_operation>().son_wallet_deposit_id;
|
||||||
|
const auto &idx = database.get_index_type<son_wallet_deposit_index>().indices().get<by_id>();
|
||||||
|
const auto swdo = idx.find(swdo_id);
|
||||||
|
if (swdo != idx.end()) {
|
||||||
|
|
||||||
|
std::string swdo_txid = swdo->sidechain_transaction_id;
|
||||||
|
std::string swdo_address = swdo->sidechain_to;
|
||||||
|
uint64_t swdo_amount = swdo->sidechain_amount.value;
|
||||||
|
uint64_t swdo_vout = std::stoll(swdo->sidechain_uid.substr(swdo->sidechain_uid.find_last_of("-") + 1));
|
||||||
|
|
||||||
|
std::string tx_str = bitcoin_client->gettransaction(swdo_txid);
|
||||||
|
std::stringstream tx_ss(tx_str);
|
||||||
|
boost::property_tree::ptree tx_json;
|
||||||
|
boost::property_tree::read_json(tx_ss, tx_json);
|
||||||
|
|
||||||
|
if (tx_json.count("error") && tx_json.get_child("error").empty()) {
|
||||||
|
|
||||||
|
std::string tx_txid = tx_json.get<std::string>("result.txid");
|
||||||
|
uint32_t tx_confirmations = tx_json.get<uint32_t>("result.confirmations");
|
||||||
|
std::string tx_address = "";
|
||||||
|
uint64_t tx_amount = 0;
|
||||||
|
uint64_t tx_vout = 0;
|
||||||
|
|
||||||
|
for (auto &input : tx_json.get_child("result.details")) {
|
||||||
|
tx_address = input.second.get<std::string>("address");
|
||||||
|
std::string tx_amount_s = input.second.get<std::string>("amount");
|
||||||
|
tx_amount_s.erase(std::remove(tx_amount_s.begin(), tx_amount_s.end(), '.'), tx_amount_s.end());
|
||||||
|
tx_amount = std::stoll(tx_amount_s);
|
||||||
|
std::string tx_vout_s = input.second.get<std::string>("vout");
|
||||||
|
tx_vout = std::stoll(tx_vout_s);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
should_approve = (swdo_txid == tx_txid) &&
|
||||||
|
(swdo_address == tx_address) &&
|
||||||
|
(swdo_amount == tx_amount) &&
|
||||||
|
(swdo_vout == tx_vout) &&
|
||||||
|
(gpo.parameters.son_bitcoin_min_tx_confirmations() <= tx_confirmations);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case chain::operation::tag<chain::son_wallet_withdraw_process_operation>::value: {
|
||||||
|
should_approve = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case chain::operation::tag<chain::sidechain_transaction_create_operation>::value: {
|
||||||
|
should_approve = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
should_approve = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return should_approve;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sidechain_net_handler_bitcoin::process_primary_wallet() {
|
||||||
const auto &swi = database.get_index_type<son_wallet_index>().indices().get<by_id>();
|
const auto &swi = database.get_index_type<son_wallet_index>().indices().get<by_id>();
|
||||||
const auto &active_sw = swi.rbegin();
|
const auto &active_sw = swi.rbegin();
|
||||||
if (active_sw != swi.rend()) {
|
if (active_sw != swi.rend()) {
|
||||||
|
|
@ -1403,6 +1520,7 @@ void sidechain_net_handler_bitcoin::handle_event(const std::string &event_data)
|
||||||
|
|
||||||
sidechain_event_data sed;
|
sidechain_event_data sed;
|
||||||
sed.timestamp = database.head_block_time();
|
sed.timestamp = database.head_block_time();
|
||||||
|
sed.block_num = database.head_block_num();
|
||||||
sed.sidechain = addr_itr->sidechain;
|
sed.sidechain = addr_itr->sidechain;
|
||||||
sed.sidechain_uid = sidechain_uid;
|
sed.sidechain_uid = sidechain_uid;
|
||||||
sed.sidechain_transaction_id = v.out.hash_tx;
|
sed.sidechain_transaction_id = v.out.hash_tx;
|
||||||
|
|
@ -1410,11 +1528,10 @@ void sidechain_net_handler_bitcoin::handle_event(const std::string &event_data)
|
||||||
sed.sidechain_to = v.address;
|
sed.sidechain_to = v.address;
|
||||||
sed.sidechain_currency = "BTC";
|
sed.sidechain_currency = "BTC";
|
||||||
sed.sidechain_amount = v.out.amount;
|
sed.sidechain_amount = v.out.amount;
|
||||||
sed.peerplays_from = database.get_global_properties().parameters.son_account();
|
sed.peerplays_from = addr_itr->sidechain_address_account;
|
||||||
sed.peerplays_to = addr_itr->sidechain_address_account;
|
sed.peerplays_to = database.get_global_properties().parameters.son_account();
|
||||||
asset_id_type btc_asset_id = database.get_global_properties().parameters.btc_asset();
|
price btc_price = database.get<asset_object>(database.get_global_properties().parameters.btc_asset()).options.core_exchange_rate;
|
||||||
asset_object btc_asset = btc_asset_id(database);
|
sed.peerplays_asset = asset(sed.sidechain_amount * btc_price.base.amount / btc_price.quote.amount);
|
||||||
sed.peerplays_asset = btc_asset.amount(sed.sidechain_amount);
|
|
||||||
sidechain_event_data_received(sed);
|
sidechain_event_data_received(sed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,111 @@ sidechain_net_handler_peerplays::sidechain_net_handler_peerplays(peerplays_sidec
|
||||||
sidechain_net_handler_peerplays::~sidechain_net_handler_peerplays() {
|
sidechain_net_handler_peerplays::~sidechain_net_handler_peerplays() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void sidechain_net_handler_peerplays::recreate_primary_wallet() {
|
bool sidechain_net_handler_peerplays::process_proposal(const proposal_object &po) {
|
||||||
|
|
||||||
|
ilog("Proposal to process: ${po}, SON id ${son_id}", ("po", po.id)("son_id", plugin.get_current_son_id()));
|
||||||
|
|
||||||
|
bool should_approve = false;
|
||||||
|
|
||||||
|
const chain::global_property_object &gpo = database.get_global_properties();
|
||||||
|
|
||||||
|
int32_t op_idx_0 = -1;
|
||||||
|
chain::operation op_obj_idx_0;
|
||||||
|
//int32_t op_idx_1 = -1;
|
||||||
|
//chain::operation op_obj_idx_1;
|
||||||
|
|
||||||
|
if (po.proposed_transaction.operations.size() >= 1) {
|
||||||
|
op_idx_0 = po.proposed_transaction.operations[0].which();
|
||||||
|
op_obj_idx_0 = po.proposed_transaction.operations[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (po.proposed_transaction.operations.size() >= 2) {
|
||||||
|
//op_idx_1 = po.proposed_transaction.operations[1].which();
|
||||||
|
//op_obj_idx_1 = po.proposed_transaction.operations[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (op_idx_0) {
|
||||||
|
|
||||||
|
case chain::operation::tag<chain::son_wallet_update_operation>::value: {
|
||||||
|
should_approve = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case chain::operation::tag<chain::son_wallet_deposit_process_operation>::value: {
|
||||||
|
son_wallet_deposit_id_type swdo_id = op_obj_idx_0.get<son_wallet_deposit_process_operation>().son_wallet_deposit_id;
|
||||||
|
const auto &idx = database.get_index_type<son_wallet_deposit_index>().indices().get<by_id>();
|
||||||
|
const auto swdo = idx.find(swdo_id);
|
||||||
|
if (swdo != idx.end()) {
|
||||||
|
|
||||||
|
uint32_t swdo_block_num = swdo->block_num;
|
||||||
|
std::string swdo_sidechain_transaction_id = swdo->sidechain_transaction_id;
|
||||||
|
uint32_t swdo_op_idx = std::stoll(swdo->sidechain_uid.substr(swdo->sidechain_uid.find_last_of("-") + 1));
|
||||||
|
|
||||||
|
const auto &block = database.fetch_block_by_number(swdo_block_num);
|
||||||
|
|
||||||
|
for (const auto &tx : block->transactions) {
|
||||||
|
if (tx.id().str() == swdo_sidechain_transaction_id) {
|
||||||
|
operation op = tx.operations[swdo_op_idx];
|
||||||
|
transfer_operation t_op = op.get<transfer_operation>();
|
||||||
|
|
||||||
|
asset sidechain_asset = asset(swdo->sidechain_amount, fc::variant(swdo->sidechain_currency, 1).as<asset_id_type>(1));
|
||||||
|
price sidechain_asset_price = database.get<asset_object>(sidechain_asset.asset_id).options.core_exchange_rate;
|
||||||
|
asset peerplays_asset = asset(sidechain_asset.amount * sidechain_asset_price.base.amount / sidechain_asset_price.quote.amount);
|
||||||
|
|
||||||
|
should_approve = (gpo.parameters.son_account() == t_op.to) &&
|
||||||
|
(swdo->peerplays_from == t_op.from) &&
|
||||||
|
(sidechain_asset == t_op.amount) &&
|
||||||
|
(swdo->peerplays_asset == peerplays_asset);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case chain::operation::tag<chain::son_wallet_withdraw_process_operation>::value: {
|
||||||
|
son_wallet_withdraw_id_type swwo_id = op_obj_idx_0.get<son_wallet_withdraw_process_operation>().son_wallet_withdraw_id;
|
||||||
|
const auto &idx = database.get_index_type<son_wallet_withdraw_index>().indices().get<by_id>();
|
||||||
|
const auto swwo = idx.find(swwo_id);
|
||||||
|
if (swwo != idx.end()) {
|
||||||
|
|
||||||
|
uint32_t swwo_block_num = swwo->block_num;
|
||||||
|
std::string swwo_peerplays_transaction_id = swwo->peerplays_transaction_id;
|
||||||
|
uint32_t swwo_op_idx = std::stoll(swwo->peerplays_uid.substr(swwo->peerplays_uid.find_last_of("-") + 1));
|
||||||
|
|
||||||
|
const auto &block = database.fetch_block_by_number(swwo_block_num);
|
||||||
|
|
||||||
|
for (const auto &tx : block->transactions) {
|
||||||
|
if (tx.id().str() == swwo_peerplays_transaction_id) {
|
||||||
|
operation op = tx.operations[swwo_op_idx];
|
||||||
|
transfer_operation t_op = op.get<transfer_operation>();
|
||||||
|
|
||||||
|
price asset_price = database.get<asset_object>(t_op.amount.asset_id).options.core_exchange_rate;
|
||||||
|
asset peerplays_asset = asset(t_op.amount.amount * asset_price.base.amount / asset_price.quote.amount);
|
||||||
|
|
||||||
|
should_approve = (t_op.to == gpo.parameters.son_account()) &&
|
||||||
|
(swwo->peerplays_from == t_op.from) &&
|
||||||
|
(swwo->peerplays_asset == peerplays_asset);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case chain::operation::tag<chain::sidechain_transaction_create_operation>::value: {
|
||||||
|
should_approve = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
should_approve = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return should_approve;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sidechain_net_handler_peerplays::process_primary_wallet() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,9 +165,6 @@ void sidechain_net_handler_peerplays::on_applied_block(const signed_block &b) {
|
||||||
if (transfer_op.to != plugin.database().get_global_properties().parameters.son_account()) {
|
if (transfer_op.to != plugin.database().get_global_properties().parameters.son_account()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// only bitcoin withdraws acepted for now
|
|
||||||
if (transfer_op.amount.asset_id != plugin.database().get_global_properties().parameters.btc_asset())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "peerplays"
|
ss << "peerplays"
|
||||||
|
|
@ -72,16 +173,18 @@ void sidechain_net_handler_peerplays::on_applied_block(const signed_block &b) {
|
||||||
|
|
||||||
sidechain_event_data sed;
|
sidechain_event_data sed;
|
||||||
sed.timestamp = database.head_block_time();
|
sed.timestamp = database.head_block_time();
|
||||||
|
sed.block_num = database.head_block_num();
|
||||||
sed.sidechain = sidechain_type::peerplays;
|
sed.sidechain = sidechain_type::peerplays;
|
||||||
sed.sidechain_uid = sidechain_uid;
|
sed.sidechain_uid = sidechain_uid;
|
||||||
sed.sidechain_transaction_id = trx.id().str();
|
sed.sidechain_transaction_id = trx.id().str();
|
||||||
sed.sidechain_from = fc::to_string(transfer_op.from.space_id) + "." + fc::to_string(transfer_op.from.type_id) + "." + fc::to_string((uint64_t)transfer_op.from.instance);
|
sed.sidechain_from = fc::to_string(transfer_op.from.space_id) + "." + fc::to_string(transfer_op.from.type_id) + "." + fc::to_string((uint64_t)transfer_op.from.instance);
|
||||||
sed.sidechain_to = fc::to_string(transfer_op.to.space_id) + "." + fc::to_string(transfer_op.to.type_id) + "." + fc::to_string((uint64_t)transfer_op.to.instance);
|
sed.sidechain_to = fc::to_string(transfer_op.to.space_id) + "." + fc::to_string(transfer_op.to.type_id) + "." + fc::to_string((uint64_t)transfer_op.to.instance);
|
||||||
sed.sidechain_currency = fc::to_string(transfer_op.amount.asset_id.space_id) + "." + fc::to_string(transfer_op.amount.asset_id.type_id) + "." + fc::to_string((uint64_t)transfer_op.amount.asset_id.instance); //transfer_op.amount.asset_id(database).symbol;
|
sed.sidechain_currency = fc::to_string(transfer_op.amount.asset_id.space_id) + "." + fc::to_string(transfer_op.amount.asset_id.type_id) + "." + fc::to_string((uint64_t)transfer_op.amount.asset_id.instance);
|
||||||
sed.sidechain_amount = transfer_op.amount.amount;
|
sed.sidechain_amount = transfer_op.amount.amount;
|
||||||
sed.peerplays_from = transfer_op.from;
|
sed.peerplays_from = transfer_op.from;
|
||||||
sed.peerplays_to = transfer_op.to;
|
sed.peerplays_to = transfer_op.to;
|
||||||
sed.peerplays_asset = transfer_op.amount;
|
price asset_price = database.get<asset_object>(transfer_op.amount.asset_id).options.core_exchange_rate;
|
||||||
|
sed.peerplays_asset = asset(transfer_op.amount.amount * asset_price.base.amount / asset_price.quote.amount);
|
||||||
sidechain_event_data_received(sed);
|
sidechain_event_data_received(sed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,9 +39,15 @@ bool sidechain_net_manager::create_handler(sidechain_type sidechain, const boost
|
||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sidechain_net_manager::recreate_primary_wallet() {
|
void sidechain_net_manager::process_proposals() {
|
||||||
for (size_t i = 0; i < net_handlers.size(); i++) {
|
for (size_t i = 0; i < net_handlers.size(); i++) {
|
||||||
net_handlers.at(i)->recreate_primary_wallet();
|
net_handlers.at(i)->process_proposals();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sidechain_net_manager::process_active_sons_change() {
|
||||||
|
for (size_t i = 0; i < net_handlers.size(); i++) {
|
||||||
|
net_handlers.at(i)->process_active_sons_change();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue