Merge branch 'feature/SONs-base' into SON261
This commit is contained in:
commit
b9bc186aa1
45 changed files with 1022 additions and 425 deletions
|
|
@ -322,10 +322,16 @@ struct get_impacted_account_visitor
|
|||
void operator()( const son_wallet_update_operation& op ){
|
||||
_impacted.insert( op.payer );
|
||||
}
|
||||
void operator()( const son_wallet_transfer_create_operation& op ){
|
||||
void operator()( const son_wallet_deposit_create_operation& op ){
|
||||
_impacted.insert( op.payer );
|
||||
}
|
||||
void operator()( const son_wallet_transfer_process_operation& op ){
|
||||
void operator()( const son_wallet_deposit_process_operation& op ){
|
||||
_impacted.insert( op.payer );
|
||||
}
|
||||
void operator()( const son_wallet_withdraw_create_operation& op ){
|
||||
_impacted.insert( op.payer );
|
||||
}
|
||||
void operator()( const son_wallet_withdraw_process_operation& op ){
|
||||
_impacted.insert( op.payer );
|
||||
}
|
||||
void operator()( const sidechain_address_add_operation& op ){
|
||||
|
|
|
|||
3
libraries/chain/CMakeLists.txt
Normal file → Executable file
3
libraries/chain/CMakeLists.txt
Normal file → Executable file
|
|
@ -118,7 +118,8 @@ add_library( graphene_chain
|
|||
son_object.cpp
|
||||
|
||||
son_wallet_evaluator.cpp
|
||||
son_wallet_transfer_evaluator.cpp
|
||||
son_wallet_deposit_evaluator.cpp
|
||||
son_wallet_withdraw_evaluator.cpp
|
||||
|
||||
sidechain_address_evaluator.cpp
|
||||
sidechain_transaction_evaluator.cpp
|
||||
|
|
|
|||
|
|
@ -57,7 +57,8 @@
|
|||
#include <graphene/chain/son_object.hpp>
|
||||
#include <graphene/chain/son_proposal_object.hpp>
|
||||
#include <graphene/chain/son_wallet_object.hpp>
|
||||
#include <graphene/chain/son_wallet_transfer_object.hpp>
|
||||
#include <graphene/chain/son_wallet_deposit_object.hpp>
|
||||
#include <graphene/chain/son_wallet_withdraw_object.hpp>
|
||||
#include <graphene/chain/sidechain_address_object.hpp>
|
||||
#include <graphene/chain/sidechain_transaction_object.hpp>
|
||||
|
||||
|
|
@ -83,7 +84,8 @@
|
|||
#include <graphene/chain/tournament_evaluator.hpp>
|
||||
#include <graphene/chain/son_evaluator.hpp>
|
||||
#include <graphene/chain/son_wallet_evaluator.hpp>
|
||||
#include <graphene/chain/son_wallet_transfer_evaluator.hpp>
|
||||
#include <graphene/chain/son_wallet_deposit_evaluator.hpp>
|
||||
#include <graphene/chain/son_wallet_withdraw_evaluator.hpp>
|
||||
#include <graphene/chain/sidechain_address_evaluator.hpp>
|
||||
#include <graphene/chain/sidechain_transaction_evaluator.hpp>
|
||||
|
||||
|
|
@ -260,8 +262,10 @@ void database::initialize_evaluators()
|
|||
register_evaluator<son_maintenance_evaluator>();
|
||||
register_evaluator<recreate_son_wallet_evaluator>();
|
||||
register_evaluator<update_son_wallet_evaluator>();
|
||||
register_evaluator<create_son_wallet_transfer_evaluator>();
|
||||
register_evaluator<process_son_wallet_transfer_evaluator>();
|
||||
register_evaluator<create_son_wallet_deposit_evaluator>();
|
||||
register_evaluator<process_son_wallet_deposit_evaluator>();
|
||||
register_evaluator<create_son_wallet_withdraw_evaluator>();
|
||||
register_evaluator<process_son_wallet_withdraw_evaluator>();
|
||||
register_evaluator<add_sidechain_address_evaluator>();
|
||||
register_evaluator<update_sidechain_address_evaluator>();
|
||||
register_evaluator<delete_sidechain_address_evaluator>();
|
||||
|
|
@ -313,7 +317,8 @@ void database::initialize_indexes()
|
|||
add_index< primary_index<son_proposal_index> >();
|
||||
|
||||
add_index< primary_index<son_wallet_index> >();
|
||||
add_index< primary_index<son_wallet_transfer_index> >();
|
||||
add_index< primary_index<son_wallet_deposit_index> >();
|
||||
add_index< primary_index<son_wallet_withdraw_index> >();
|
||||
|
||||
add_index< primary_index<sidechain_address_index> >();
|
||||
add_index< primary_index<bitcoin_transaction_index> >();
|
||||
|
|
|
|||
|
|
@ -457,8 +457,9 @@ void database::update_active_sons()
|
|||
a.active.account_auths[weight.first] += votes;
|
||||
a.active.weight_threshold += votes;
|
||||
}
|
||||
|
||||
a.active.weight_threshold /= 2;
|
||||
|
||||
a.active.weight_threshold *= 2;
|
||||
a.active.weight_threshold /= 3;
|
||||
a.active.weight_threshold += 1;
|
||||
}
|
||||
else
|
||||
|
|
@ -466,12 +467,11 @@ void database::update_active_sons()
|
|||
vote_counter vc;
|
||||
for( const son_object& son : sons )
|
||||
vc.add( son.son_account, std::max(_vote_tally_buffer[son.vote_id], UINT64_C(1)) );
|
||||
vc.finish( a.active );
|
||||
vc.finish_2_3( a.active );
|
||||
}
|
||||
} );
|
||||
|
||||
// Compare current and to-be lists of active sons
|
||||
//const global_property_object& gpo = get_global_properties();
|
||||
auto cur_active_sons = gpo.active_sons;
|
||||
vector<son_info> new_active_sons;
|
||||
for( const son_object& son : sons ) {
|
||||
|
|
@ -602,83 +602,6 @@ void database::update_active_sons()
|
|||
|
||||
update_son_metrics();
|
||||
|
||||
if(gpo.active_sons.size() > 0 ) {
|
||||
if(gpo.parameters.get_son_btc_account_id() == GRAPHENE_NULL_ACCOUNT) {
|
||||
const auto& son_btc_account = create<account_object>( [&]( account_object& obj ) {
|
||||
uint64_t total_votes = 0;
|
||||
obj.name = "son_btc_account";
|
||||
obj.statistics = create<account_statistics_object>([&]( account_statistics_object& acc_stat ){ acc_stat.owner = obj.id; }).id;
|
||||
obj.membership_expiration_date = time_point_sec::maximum();
|
||||
obj.network_fee_percentage = GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE;
|
||||
obj.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT - GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE;
|
||||
|
||||
for( const auto& son_info : gpo.active_sons )
|
||||
{
|
||||
const son_object& son = get(son_info.son_id);
|
||||
total_votes += _vote_tally_buffer[son.vote_id];
|
||||
}
|
||||
// total_votes is 64 bits. Subtract the number of leading low bits from 64 to get the number of useful bits,
|
||||
// then I want to keep the most significant 16 bits of what's left.
|
||||
int8_t bits_to_drop = std::max(int(boost::multiprecision::detail::find_msb(total_votes)) - 15, 0);
|
||||
|
||||
for( const auto& son_info : gpo.active_sons )
|
||||
{
|
||||
// Ensure that everyone has at least one vote. Zero weights aren't allowed.
|
||||
const son_object& son = get(son_info.son_id);
|
||||
uint16_t votes = std::max((_vote_tally_buffer[son.vote_id] >> bits_to_drop), uint64_t(1) );
|
||||
obj.owner.account_auths[son.son_account] += votes;
|
||||
obj.owner.weight_threshold += votes;
|
||||
obj.active.account_auths[son.son_account] += votes;
|
||||
obj.active.weight_threshold += votes;
|
||||
}
|
||||
obj.owner.weight_threshold *= 2;
|
||||
obj.owner.weight_threshold /= 3;
|
||||
obj.owner.weight_threshold += 1;
|
||||
obj.active.weight_threshold *= 2;
|
||||
obj.active.weight_threshold /= 3;
|
||||
obj.active.weight_threshold += 1;
|
||||
});
|
||||
|
||||
modify( gpo, [&]( global_property_object& gpo ) {
|
||||
gpo.parameters.extensions.value.son_btc_account = son_btc_account.get_id();
|
||||
if( gpo.pending_parameters )
|
||||
gpo.pending_parameters->extensions.value.son_btc_account = son_btc_account.get_id();
|
||||
});
|
||||
} else {
|
||||
modify( get(gpo.parameters.get_son_btc_account_id()), [&]( account_object& obj )
|
||||
{
|
||||
uint64_t total_votes = 0;
|
||||
obj.owner.weight_threshold = 0;
|
||||
obj.owner.account_auths.clear();
|
||||
obj.active.weight_threshold = 0;
|
||||
obj.active.account_auths.clear();
|
||||
for( const auto& son_info : gpo.active_sons )
|
||||
{
|
||||
const son_object& son = get(son_info.son_id);
|
||||
total_votes += _vote_tally_buffer[son.vote_id];
|
||||
}
|
||||
// total_votes is 64 bits. Subtract the number of leading low bits from 64 to get the number of useful bits,
|
||||
// then I want to keep the most significant 16 bits of what's left.
|
||||
int8_t bits_to_drop = std::max(int(boost::multiprecision::detail::find_msb(total_votes)) - 15, 0);
|
||||
for( const auto& son_info : gpo.active_sons )
|
||||
{
|
||||
// Ensure that everyone has at least one vote. Zero weights aren't allowed.
|
||||
const son_object& son = get(son_info.son_id);
|
||||
uint16_t votes = std::max((_vote_tally_buffer[son.vote_id] >> bits_to_drop), uint64_t(1) );
|
||||
obj.owner.account_auths[son.son_account] += votes;
|
||||
obj.owner.weight_threshold += votes;
|
||||
obj.active.account_auths[son.son_account] += votes;
|
||||
obj.active.weight_threshold += votes;
|
||||
}
|
||||
obj.owner.weight_threshold *= 2;
|
||||
obj.owner.weight_threshold /= 3;
|
||||
obj.owner.weight_threshold += 1;
|
||||
obj.active.weight_threshold *= 2;
|
||||
obj.active.weight_threshold /= 3;
|
||||
obj.active.weight_threshold += 1;
|
||||
});
|
||||
}
|
||||
}
|
||||
} FC_CAPTURE_AND_RETHROW() }
|
||||
|
||||
void database::initialize_budget_record( fc::time_point_sec now, budget_record& rec )const
|
||||
|
|
|
|||
|
|
@ -309,10 +309,16 @@ struct get_impacted_account_visitor
|
|||
void operator()( const son_wallet_update_operation& op ) {
|
||||
_impacted.insert( op.payer );
|
||||
}
|
||||
void operator()( const son_wallet_transfer_create_operation& op ) {
|
||||
void operator()( const son_wallet_deposit_create_operation& op ) {
|
||||
_impacted.insert( op.payer );
|
||||
}
|
||||
void operator()( const son_wallet_transfer_process_operation& op ) {
|
||||
void operator()( const son_wallet_deposit_process_operation& op ) {
|
||||
_impacted.insert( op.payer );
|
||||
}
|
||||
void operator()( const son_wallet_withdraw_create_operation& op ) {
|
||||
_impacted.insert( op.payer );
|
||||
}
|
||||
void operator()( const son_wallet_withdraw_process_operation& op ) {
|
||||
_impacted.insert( op.payer );
|
||||
}
|
||||
void operator()( const sidechain_address_add_operation& op ) {
|
||||
|
|
@ -428,7 +434,9 @@ void get_relevant_accounts( const object* obj, flat_set<account_id_type>& accoun
|
|||
break;
|
||||
} case son_wallet_object_type:{
|
||||
break;
|
||||
} case son_wallet_transfer_object_type:{
|
||||
} case son_wallet_deposit_object_type:{
|
||||
break;
|
||||
} case son_wallet_withdraw_object_type:{
|
||||
break;
|
||||
} case sidechain_address_object_type:{
|
||||
const auto& aobj = dynamic_cast<const sidechain_address_object*>(obj);
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ namespace graphene { namespace chain {
|
|||
optional < uint32_t > son_vesting_amount;
|
||||
optional < uint32_t > son_vesting_period;
|
||||
optional < uint32_t > son_pay_daily_max;
|
||||
optional < account_id_type > son_btc_account;
|
||||
};
|
||||
|
||||
struct chain_parameters
|
||||
|
|
@ -139,9 +138,6 @@ namespace graphene { namespace chain {
|
|||
inline uint16_t son_pay_daily_max()const {
|
||||
return extensions.value.son_pay_daily_max.valid() ? *extensions.value.son_pay_daily_max : MIN_SON_PAY_DAILY_MAX;
|
||||
}
|
||||
inline account_id_type get_son_btc_account_id() const {
|
||||
return extensions.value.son_btc_account.valid() ? *extensions.value.son_btc_account : GRAPHENE_NULL_ACCOUNT;
|
||||
}
|
||||
};
|
||||
|
||||
} } // graphene::chain
|
||||
|
|
@ -159,7 +155,6 @@ FC_REFLECT( graphene::chain::parameter_extension,
|
|||
(son_vesting_amount)
|
||||
(son_vesting_period)
|
||||
(son_pay_daily_max)
|
||||
(son_btc_account)
|
||||
)
|
||||
|
||||
FC_REFLECT( graphene::chain::chain_parameters,
|
||||
|
|
|
|||
|
|
@ -48,7 +48,8 @@
|
|||
#include <graphene/chain/protocol/son.hpp>
|
||||
#include <graphene/chain/protocol/sidechain_address.hpp>
|
||||
#include <graphene/chain/protocol/son_wallet.hpp>
|
||||
#include <graphene/chain/protocol/son_wallet_transfer.hpp>
|
||||
#include <graphene/chain/protocol/son_wallet_deposit.hpp>
|
||||
#include <graphene/chain/protocol/son_wallet_withdraw.hpp>
|
||||
#include <graphene/chain/protocol/sidechain_transaction.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
|
@ -149,8 +150,10 @@ namespace graphene { namespace chain {
|
|||
son_maintenance_operation,
|
||||
son_wallet_recreate_operation,
|
||||
son_wallet_update_operation,
|
||||
son_wallet_transfer_create_operation,
|
||||
son_wallet_transfer_process_operation,
|
||||
son_wallet_deposit_create_operation,
|
||||
son_wallet_deposit_process_operation,
|
||||
son_wallet_withdraw_create_operation,
|
||||
son_wallet_withdraw_process_operation,
|
||||
sidechain_address_add_operation,
|
||||
sidechain_address_update_operation,
|
||||
sidechain_address_delete_operation,
|
||||
|
|
|
|||
|
|
@ -12,9 +12,8 @@ namespace graphene { namespace chain {
|
|||
asset fee;
|
||||
account_id_type sidechain_address_account;
|
||||
graphene::peerplays_sidechain::sidechain_type sidechain;
|
||||
string address;
|
||||
string private_key;
|
||||
string public_key;
|
||||
string deposit_address;
|
||||
string withdraw_address;
|
||||
|
||||
account_id_type fee_payer()const { return sidechain_address_account; }
|
||||
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
||||
|
|
@ -28,9 +27,8 @@ namespace graphene { namespace chain {
|
|||
sidechain_address_id_type sidechain_address_id;
|
||||
account_id_type sidechain_address_account;
|
||||
graphene::peerplays_sidechain::sidechain_type sidechain;
|
||||
optional<string> address;
|
||||
optional<string> private_key;
|
||||
optional<string> public_key;
|
||||
optional<string> deposit_address;
|
||||
optional<string> withdraw_address;
|
||||
|
||||
account_id_type fee_payer()const { return sidechain_address_account; }
|
||||
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
||||
|
|
@ -53,12 +51,12 @@ namespace graphene { namespace chain {
|
|||
|
||||
FC_REFLECT(graphene::chain::sidechain_address_add_operation::fee_parameters_type, (fee) )
|
||||
FC_REFLECT(graphene::chain::sidechain_address_add_operation, (fee)
|
||||
(sidechain_address_account)(sidechain)(address)(private_key)(public_key) )
|
||||
(sidechain_address_account)(sidechain)(deposit_address)(withdraw_address) )
|
||||
|
||||
FC_REFLECT(graphene::chain::sidechain_address_update_operation::fee_parameters_type, (fee) )
|
||||
FC_REFLECT(graphene::chain::sidechain_address_update_operation, (fee)
|
||||
(sidechain_address_id)
|
||||
(sidechain_address_account)(sidechain)(address)(private_key)(public_key) )
|
||||
(sidechain_address_account)(sidechain)(deposit_address)(withdraw_address) )
|
||||
|
||||
FC_REFLECT(graphene::chain::sidechain_address_delete_operation::fee_parameters_type, (fee) )
|
||||
FC_REFLECT(graphene::chain::sidechain_address_delete_operation, (fee)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
#pragma once
|
||||
#include <graphene/chain/protocol/base.hpp>
|
||||
|
||||
#include <fc/safe.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
struct son_wallet_transfer_create_operation : public base_operation
|
||||
struct son_wallet_deposit_create_operation : public base_operation
|
||||
{
|
||||
struct fee_parameters_type { uint64_t fee = 0; };
|
||||
|
||||
|
|
@ -16,23 +18,24 @@ namespace graphene { namespace chain {
|
|||
std::string sidechain_transaction_id;
|
||||
std::string sidechain_from;
|
||||
std::string sidechain_to;
|
||||
int64_t sidechain_amount;
|
||||
std::string sidechain_currency;
|
||||
fc::safe<int64_t> sidechain_amount;
|
||||
chain::account_id_type peerplays_from;
|
||||
chain::account_id_type peerplays_to;
|
||||
chain::asset peerplays_amount;
|
||||
chain::asset peerplays_asset;
|
||||
|
||||
account_id_type fee_payer()const { return payer; }
|
||||
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
||||
};
|
||||
|
||||
struct son_wallet_transfer_process_operation : public base_operation
|
||||
struct son_wallet_deposit_process_operation : public base_operation
|
||||
{
|
||||
struct fee_parameters_type { uint64_t fee = 0; };
|
||||
|
||||
asset fee;
|
||||
account_id_type payer;
|
||||
|
||||
son_wallet_transfer_id_type son_wallet_transfer_id;
|
||||
son_wallet_deposit_id_type son_wallet_deposit_id;
|
||||
|
||||
account_id_type fee_payer()const { return payer; }
|
||||
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
||||
|
|
@ -40,9 +43,9 @@ namespace graphene { namespace chain {
|
|||
|
||||
} } // namespace graphene::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)
|
||||
(timestamp) (sidechain) (sidechain_uid) (sidechain_transaction_id) (sidechain_from) (sidechain_to) (sidechain_amount) (peerplays_from) (peerplays_to) (peerplays_amount))
|
||||
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))
|
||||
FC_REFLECT(graphene::chain::son_wallet_deposit_create_operation::fee_parameters_type, (fee) )
|
||||
FC_REFLECT(graphene::chain::son_wallet_deposit_create_operation, (fee)(payer)
|
||||
(timestamp) (sidechain) (sidechain_uid) (sidechain_transaction_id) (sidechain_from) (sidechain_to) (sidechain_currency) (sidechain_amount) (peerplays_from) (peerplays_to) (peerplays_asset))
|
||||
FC_REFLECT(graphene::chain::son_wallet_deposit_process_operation::fee_parameters_type, (fee) )
|
||||
FC_REFLECT(graphene::chain::son_wallet_deposit_process_operation, (fee)(payer)
|
||||
(son_wallet_deposit_id))
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
#pragma once
|
||||
#include <graphene/chain/protocol/base.hpp>
|
||||
|
||||
#include <fc/safe.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
struct son_wallet_withdraw_create_operation : public base_operation
|
||||
{
|
||||
struct fee_parameters_type { uint64_t fee = 0; };
|
||||
|
||||
asset fee;
|
||||
account_id_type payer;
|
||||
|
||||
fc::time_point_sec timestamp;
|
||||
peerplays_sidechain::sidechain_type sidechain;
|
||||
std::string peerplays_uid;
|
||||
std::string peerplays_transaction_id;
|
||||
chain::account_id_type peerplays_from;
|
||||
chain::asset peerplays_asset;
|
||||
peerplays_sidechain::sidechain_type withdraw_sidechain;
|
||||
std::string withdraw_address;
|
||||
std::string withdraw_currency;
|
||||
safe<int64_t> withdraw_amount;
|
||||
|
||||
account_id_type fee_payer()const { return payer; }
|
||||
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
||||
};
|
||||
|
||||
struct son_wallet_withdraw_process_operation : public base_operation
|
||||
{
|
||||
struct fee_parameters_type { uint64_t fee = 0; };
|
||||
|
||||
asset fee;
|
||||
account_id_type payer;
|
||||
|
||||
son_wallet_withdraw_id_type son_wallet_withdraw_id;
|
||||
|
||||
account_id_type fee_payer()const { return payer; }
|
||||
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
||||
};
|
||||
|
||||
} } // namespace graphene::chain
|
||||
|
||||
FC_REFLECT(graphene::chain::son_wallet_withdraw_create_operation::fee_parameters_type, (fee) )
|
||||
FC_REFLECT(graphene::chain::son_wallet_withdraw_create_operation, (fee)(payer)
|
||||
(timestamp) (sidechain) (peerplays_uid) (peerplays_transaction_id) (peerplays_from) (peerplays_asset) (withdraw_sidechain) (withdraw_address) (withdraw_currency) (withdraw_amount) )
|
||||
FC_REFLECT(graphene::chain::son_wallet_withdraw_process_operation::fee_parameters_type, (fee) )
|
||||
FC_REFLECT(graphene::chain::son_wallet_withdraw_process_operation, (fee)(payer)
|
||||
(son_wallet_withdraw_id))
|
||||
|
|
@ -148,7 +148,8 @@ namespace graphene { namespace chain {
|
|||
son_object_type,
|
||||
son_proposal_object_type,
|
||||
son_wallet_object_type,
|
||||
son_wallet_transfer_object_type,
|
||||
son_wallet_deposit_object_type,
|
||||
son_wallet_withdraw_object_type,
|
||||
sidechain_address_object_type,
|
||||
bitcoin_transaction_object_type,
|
||||
OBJECT_TYPE_COUNT ///< Sentry value which contains the number of different object types
|
||||
|
|
@ -215,7 +216,8 @@ namespace graphene { namespace chain {
|
|||
class son_object;
|
||||
class son_proposal_object;
|
||||
class son_wallet_object;
|
||||
class son_wallet_transfer_object;
|
||||
class son_wallet_deposit_object;
|
||||
class son_wallet_withdraw_object;
|
||||
class sidechain_address_object;
|
||||
class bitcoin_transaction_object;
|
||||
|
||||
|
|
@ -247,7 +249,8 @@ namespace graphene { namespace chain {
|
|||
typedef object_id< protocol_ids, son_object_type, son_object> son_id_type;
|
||||
typedef object_id< protocol_ids, son_proposal_object_type, son_proposal_object> son_proposal_id_type;
|
||||
typedef object_id< protocol_ids, son_wallet_object_type, son_wallet_object> son_wallet_id_type;
|
||||
typedef object_id< protocol_ids, son_wallet_transfer_object_type, son_wallet_transfer_object> son_wallet_transfer_id_type;
|
||||
typedef object_id< protocol_ids, son_wallet_deposit_object_type, son_wallet_deposit_object> son_wallet_deposit_id_type;
|
||||
typedef object_id< protocol_ids, son_wallet_withdraw_object_type, son_wallet_withdraw_object> son_wallet_withdraw_id_type;
|
||||
typedef object_id< protocol_ids, sidechain_address_object_type, sidechain_address_object> sidechain_address_id_type;
|
||||
typedef object_id< protocol_ids, bitcoin_transaction_object_type,bitcoin_transaction_object> bitcoin_transaction_id_type;
|
||||
|
||||
|
|
@ -437,7 +440,8 @@ FC_REFLECT_ENUM( graphene::chain::object_type,
|
|||
(son_object_type)
|
||||
(son_proposal_object_type)
|
||||
(son_wallet_object_type)
|
||||
(son_wallet_transfer_object_type)
|
||||
(son_wallet_deposit_object_type)
|
||||
(son_wallet_withdraw_object_type)
|
||||
(sidechain_address_object_type)
|
||||
(bitcoin_transaction_object_type)
|
||||
(OBJECT_TYPE_COUNT)
|
||||
|
|
@ -514,7 +518,8 @@ FC_REFLECT_TYPENAME( graphene::chain::tournament_details_id_type )
|
|||
FC_REFLECT_TYPENAME( graphene::chain::son_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::son_proposal_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::son_wallet_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::son_wallet_transfer_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::son_wallet_deposit_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::son_wallet_withdraw_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::sidechain_address_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::bitcoin_transaction_id_type )
|
||||
|
||||
|
|
|
|||
|
|
@ -21,21 +21,19 @@ namespace graphene { namespace chain {
|
|||
|
||||
account_id_type sidechain_address_account;
|
||||
graphene::peerplays_sidechain::sidechain_type sidechain;
|
||||
string address;
|
||||
string private_key;
|
||||
string public_key;
|
||||
string deposit_address;
|
||||
string withdraw_address;
|
||||
|
||||
sidechain_address_object() :
|
||||
sidechain(graphene::peerplays_sidechain::sidechain_type::bitcoin),
|
||||
address(""),
|
||||
private_key(""),
|
||||
public_key("") {}
|
||||
deposit_address(""),
|
||||
withdraw_address("") {}
|
||||
};
|
||||
|
||||
struct by_account;
|
||||
struct by_sidechain;
|
||||
struct by_account_and_sidechain;
|
||||
struct by_sidechain_and_address;
|
||||
struct by_sidechain_and_deposit_address;
|
||||
using sidechain_address_multi_index_type = multi_index_container<
|
||||
sidechain_address_object,
|
||||
indexed_by<
|
||||
|
|
@ -54,10 +52,10 @@ namespace graphene { namespace chain {
|
|||
member<sidechain_address_object, peerplays_sidechain::sidechain_type, &sidechain_address_object::sidechain>
|
||||
>
|
||||
>,
|
||||
ordered_unique< tag<by_sidechain_and_address>,
|
||||
ordered_unique< tag<by_sidechain_and_deposit_address>,
|
||||
composite_key<sidechain_address_object,
|
||||
member<sidechain_address_object, peerplays_sidechain::sidechain_type, &sidechain_address_object::sidechain>,
|
||||
member<sidechain_address_object, std::string, &sidechain_address_object::address>
|
||||
member<sidechain_address_object, std::string, &sidechain_address_object::deposit_address>
|
||||
>
|
||||
>
|
||||
>
|
||||
|
|
@ -67,4 +65,4 @@ namespace graphene { namespace chain {
|
|||
} } // graphene::chain
|
||||
|
||||
FC_REFLECT_DERIVED( graphene::chain::sidechain_address_object, (graphene::db::object),
|
||||
(sidechain_address_account)(sidechain)(address)(private_key)(public_key) )
|
||||
(sidechain_address_account) (sidechain) (deposit_address) (withdraw_address) )
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
#pragma once
|
||||
#include <graphene/chain/evaluator.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
class create_son_wallet_deposit_evaluator : public evaluator<create_son_wallet_deposit_evaluator>
|
||||
{
|
||||
public:
|
||||
typedef son_wallet_deposit_create_operation operation_type;
|
||||
|
||||
void_result do_evaluate(const son_wallet_deposit_create_operation& o);
|
||||
object_id_type do_apply(const son_wallet_deposit_create_operation& o);
|
||||
};
|
||||
|
||||
class process_son_wallet_deposit_evaluator : public evaluator<process_son_wallet_deposit_evaluator>
|
||||
{
|
||||
public:
|
||||
typedef son_wallet_deposit_process_operation operation_type;
|
||||
|
||||
void_result do_evaluate(const son_wallet_deposit_process_operation& o);
|
||||
object_id_type do_apply(const son_wallet_deposit_process_operation& o);
|
||||
};
|
||||
|
||||
} } // namespace graphene::chain
|
||||
|
|
@ -6,15 +6,15 @@ namespace graphene { namespace chain {
|
|||
using namespace graphene::db;
|
||||
|
||||
/**
|
||||
* @class son_wallet_transfer_object
|
||||
* @brief tracks information about a SON wallet transfer.
|
||||
* @class son_wallet_deposit_object
|
||||
* @brief tracks information about a SON wallet deposit.
|
||||
* @ingroup object
|
||||
*/
|
||||
class son_wallet_transfer_object : public abstract_object<son_wallet_transfer_object>
|
||||
class son_wallet_deposit_object : public abstract_object<son_wallet_deposit_object>
|
||||
{
|
||||
public:
|
||||
static const uint8_t space_id = protocol_ids;
|
||||
static const uint8_t type_id = son_wallet_transfer_object_type;
|
||||
static const uint8_t type_id = son_wallet_deposit_object_type;
|
||||
|
||||
time_point_sec timestamp;
|
||||
peerplays_sidechain::sidechain_type sidechain;
|
||||
|
|
@ -23,10 +23,11 @@ namespace graphene { namespace chain {
|
|||
std::string sidechain_transaction_id;
|
||||
std::string sidechain_from;
|
||||
std::string sidechain_to;
|
||||
int64_t sidechain_amount;
|
||||
std::string sidechain_currency;
|
||||
safe<int64_t> sidechain_amount;
|
||||
chain::account_id_type peerplays_from;
|
||||
chain::account_id_type peerplays_to;
|
||||
chain::asset peerplays_amount;
|
||||
chain::asset peerplays_asset;
|
||||
|
||||
bool processed;
|
||||
};
|
||||
|
|
@ -35,34 +36,34 @@ namespace graphene { namespace chain {
|
|||
struct by_sidechain_uid;
|
||||
struct by_processed;
|
||||
struct by_sidechain_and_processed;
|
||||
using son_wallet_transfer_multi_index_type = multi_index_container<
|
||||
son_wallet_transfer_object,
|
||||
using son_wallet_deposit_multi_index_type = multi_index_container<
|
||||
son_wallet_deposit_object,
|
||||
indexed_by<
|
||||
ordered_unique< tag<by_id>,
|
||||
member<object, object_id_type, &object::id>
|
||||
>,
|
||||
ordered_non_unique< tag<by_sidechain>,
|
||||
member<son_wallet_transfer_object, peerplays_sidechain::sidechain_type, &son_wallet_transfer_object::sidechain>
|
||||
member<son_wallet_deposit_object, peerplays_sidechain::sidechain_type, &son_wallet_deposit_object::sidechain>
|
||||
>,
|
||||
ordered_unique< tag<by_sidechain_uid>,
|
||||
member<son_wallet_transfer_object, std::string, &son_wallet_transfer_object::sidechain_uid>
|
||||
member<son_wallet_deposit_object, std::string, &son_wallet_deposit_object::sidechain_uid>
|
||||
>,
|
||||
ordered_non_unique< tag<by_processed>,
|
||||
member<son_wallet_transfer_object, bool, &son_wallet_transfer_object::processed>
|
||||
member<son_wallet_deposit_object, bool, &son_wallet_deposit_object::processed>
|
||||
>,
|
||||
ordered_non_unique< tag<by_sidechain_and_processed>,
|
||||
composite_key<son_wallet_transfer_object,
|
||||
member<son_wallet_transfer_object, peerplays_sidechain::sidechain_type, &son_wallet_transfer_object::sidechain>,
|
||||
member<son_wallet_transfer_object, bool, &son_wallet_transfer_object::processed>
|
||||
composite_key<son_wallet_deposit_object,
|
||||
member<son_wallet_deposit_object, peerplays_sidechain::sidechain_type, &son_wallet_deposit_object::sidechain>,
|
||||
member<son_wallet_deposit_object, bool, &son_wallet_deposit_object::processed>
|
||||
>
|
||||
>
|
||||
>
|
||||
>;
|
||||
using son_wallet_transfer_index = generic_index<son_wallet_transfer_object, son_wallet_transfer_multi_index_type>;
|
||||
using son_wallet_deposit_index = generic_index<son_wallet_deposit_object, son_wallet_deposit_multi_index_type>;
|
||||
} } // graphene::chain
|
||||
|
||||
FC_REFLECT_DERIVED( graphene::chain::son_wallet_transfer_object, (graphene::db::object),
|
||||
FC_REFLECT_DERIVED( graphene::chain::son_wallet_deposit_object, (graphene::db::object),
|
||||
(timestamp) (sidechain) (confirmations)
|
||||
(sidechain_uid) (sidechain_transaction_id) (sidechain_from) (sidechain_to) (sidechain_amount)
|
||||
(peerplays_from) (peerplays_to) (peerplays_amount)
|
||||
(sidechain_uid) (sidechain_transaction_id) (sidechain_from) (sidechain_to) (sidechain_currency) (sidechain_amount)
|
||||
(peerplays_from) (peerplays_to) (peerplays_asset)
|
||||
(processed) )
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
#pragma once
|
||||
#include <graphene/chain/evaluator.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
class create_son_wallet_transfer_evaluator : public evaluator<create_son_wallet_transfer_evaluator>
|
||||
{
|
||||
public:
|
||||
typedef son_wallet_transfer_create_operation operation_type;
|
||||
|
||||
void_result do_evaluate(const son_wallet_transfer_create_operation& o);
|
||||
object_id_type do_apply(const son_wallet_transfer_create_operation& o);
|
||||
};
|
||||
|
||||
class process_son_wallet_transfer_evaluator : public evaluator<process_son_wallet_transfer_evaluator>
|
||||
{
|
||||
public:
|
||||
typedef son_wallet_transfer_process_operation operation_type;
|
||||
|
||||
void_result do_evaluate(const son_wallet_transfer_process_operation& o);
|
||||
object_id_type do_apply(const son_wallet_transfer_process_operation& o);
|
||||
};
|
||||
|
||||
} } // namespace graphene::chain
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
#pragma once
|
||||
#include <graphene/chain/evaluator.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
class create_son_wallet_withdraw_evaluator : public evaluator<create_son_wallet_withdraw_evaluator>
|
||||
{
|
||||
public:
|
||||
typedef son_wallet_withdraw_create_operation operation_type;
|
||||
|
||||
void_result do_evaluate(const son_wallet_withdraw_create_operation& o);
|
||||
object_id_type do_apply(const son_wallet_withdraw_create_operation& o);
|
||||
};
|
||||
|
||||
class process_son_wallet_withdraw_evaluator : public evaluator<process_son_wallet_withdraw_evaluator>
|
||||
{
|
||||
public:
|
||||
typedef son_wallet_withdraw_process_operation operation_type;
|
||||
|
||||
void_result do_evaluate(const son_wallet_withdraw_process_operation& o);
|
||||
object_id_type do_apply(const son_wallet_withdraw_process_operation& o);
|
||||
};
|
||||
|
||||
} } // namespace graphene::chain
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
#pragma once
|
||||
#include <graphene/chain/protocol/types.hpp>
|
||||
#include <graphene/peerplays_sidechain/defs.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
using namespace graphene::db;
|
||||
|
||||
/**
|
||||
* @class son_wallet_withdraw_object
|
||||
* @brief tracks information about a SON wallet withdrawal.
|
||||
* @ingroup object
|
||||
*/
|
||||
class son_wallet_withdraw_object : public abstract_object<son_wallet_withdraw_object>
|
||||
{
|
||||
public:
|
||||
static const uint8_t space_id = protocol_ids;
|
||||
static const uint8_t type_id = son_wallet_withdraw_object_type;
|
||||
|
||||
time_point_sec timestamp;
|
||||
peerplays_sidechain::sidechain_type sidechain;
|
||||
int64_t confirmations;
|
||||
std::string peerplays_uid;
|
||||
std::string peerplays_transaction_id;
|
||||
chain::account_id_type peerplays_from;
|
||||
chain::asset peerplays_asset;
|
||||
peerplays_sidechain::sidechain_type withdraw_sidechain;
|
||||
std::string withdraw_address;
|
||||
std::string withdraw_currency;
|
||||
safe<int64_t> withdraw_amount;
|
||||
bool processed;
|
||||
};
|
||||
|
||||
struct by_peerplays_uid;
|
||||
struct by_withdraw_sidechain;
|
||||
struct by_processed;
|
||||
struct by_withdraw_sidechain_and_processed;
|
||||
using son_wallet_withdraw_multi_index_type = multi_index_container<
|
||||
son_wallet_withdraw_object,
|
||||
indexed_by<
|
||||
ordered_unique< tag<by_id>,
|
||||
member<object, object_id_type, &object::id>
|
||||
>,
|
||||
ordered_unique< tag<by_peerplays_uid>,
|
||||
member<son_wallet_withdraw_object, std::string, &son_wallet_withdraw_object::peerplays_uid>
|
||||
>,
|
||||
ordered_non_unique< tag<by_withdraw_sidechain>,
|
||||
member<son_wallet_withdraw_object, peerplays_sidechain::sidechain_type, &son_wallet_withdraw_object::withdraw_sidechain>
|
||||
>,
|
||||
ordered_non_unique< tag<by_processed>,
|
||||
member<son_wallet_withdraw_object, bool, &son_wallet_withdraw_object::processed>
|
||||
>,
|
||||
ordered_non_unique< tag<by_withdraw_sidechain_and_processed>,
|
||||
composite_key<son_wallet_withdraw_object,
|
||||
member<son_wallet_withdraw_object, peerplays_sidechain::sidechain_type, &son_wallet_withdraw_object::withdraw_sidechain>,
|
||||
member<son_wallet_withdraw_object, bool, &son_wallet_withdraw_object::processed>
|
||||
>
|
||||
>
|
||||
>
|
||||
>;
|
||||
using son_wallet_withdraw_index = generic_index<son_wallet_withdraw_object, son_wallet_withdraw_multi_index_type>;
|
||||
} } // graphene::chain
|
||||
|
||||
FC_REFLECT_DERIVED( graphene::chain::son_wallet_withdraw_object, (graphene::db::object),
|
||||
(timestamp) (sidechain) (confirmations)
|
||||
(peerplays_uid) (peerplays_transaction_id) (peerplays_from) (peerplays_asset)
|
||||
(withdraw_sidechain) (withdraw_address) (withdraw_currency) (withdraw_amount)
|
||||
(processed) )
|
||||
|
|
@ -63,6 +63,17 @@ struct vote_counter
|
|||
out_auth = auth;
|
||||
}
|
||||
|
||||
void finish_2_3( authority& out_auth )
|
||||
{
|
||||
if( total_votes == 0 )
|
||||
return;
|
||||
assert( total_votes <= std::numeric_limits<uint32_t>::max() );
|
||||
uint32_t weight = uint32_t( total_votes );
|
||||
weight = (weight * 2 / 3) + 1;
|
||||
auth.weight_threshold = weight;
|
||||
out_auth = auth;
|
||||
}
|
||||
|
||||
bool is_empty()const
|
||||
{
|
||||
return (total_votes == 0);
|
||||
|
|
|
|||
|
|
@ -19,9 +19,8 @@ object_id_type add_sidechain_address_evaluator::do_apply(const sidechain_address
|
|||
const auto& new_sidechain_address_object = db().create<sidechain_address_object>( [&]( sidechain_address_object& obj ){
|
||||
obj.sidechain_address_account = op.sidechain_address_account;
|
||||
obj.sidechain = op.sidechain;
|
||||
obj.address = op.address;
|
||||
obj.private_key = op.private_key;
|
||||
obj.public_key = op.public_key;
|
||||
obj.deposit_address = op.deposit_address;
|
||||
obj.withdraw_address = op.withdraw_address;
|
||||
});
|
||||
return new_sidechain_address_object.id;
|
||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||
|
|
@ -41,9 +40,8 @@ object_id_type update_sidechain_address_evaluator::do_apply(const sidechain_addr
|
|||
if(itr != idx.end())
|
||||
{
|
||||
db().modify(*itr, [&op](sidechain_address_object &sao) {
|
||||
if(op.address.valid()) sao.address = *op.address;
|
||||
if(op.private_key.valid()) sao.private_key = *op.private_key;
|
||||
if(op.public_key.valid()) sao.public_key = *op.public_key;
|
||||
if(op.deposit_address.valid()) sao.deposit_address = *op.deposit_address;
|
||||
if(op.withdraw_address.valid()) sao.withdraw_address = *op.withdraw_address;
|
||||
});
|
||||
}
|
||||
return op.sidechain_address_id;
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ object_id_type son_heartbeat_evaluator::do_apply(const son_heartbeat_operation&
|
|||
void_result son_report_down_evaluator::do_evaluate(const son_report_down_operation& op)
|
||||
{ try {
|
||||
FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK"); // can be removed after HF date pass
|
||||
FC_ASSERT(op.payer == db().get_global_properties().parameters.get_son_btc_account_id(), "Payer should be the son btc account");
|
||||
FC_ASSERT(op.payer == GRAPHENE_SON_ACCOUNT, "SON paying account must be set as payer.");
|
||||
const auto& idx = db().get_index_type<son_index>().indices().get<by_id>();
|
||||
FC_ASSERT( idx.find(op.son_id) != idx.end() );
|
||||
auto itr = idx.find(op.son_id);
|
||||
|
|
|
|||
|
|
@ -1,28 +1,27 @@
|
|||
#include <graphene/chain/son_wallet_transfer_evaluator.hpp>
|
||||
#include <graphene/chain/son_wallet_deposit_evaluator.hpp>
|
||||
|
||||
#include <graphene/chain/database.hpp>
|
||||
#include <graphene/chain/is_authorized_asset.hpp>
|
||||
#include <graphene/chain/son_wallet_transfer_object.hpp>
|
||||
#include <graphene/chain/son_wallet_deposit_object.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
void_result create_son_wallet_transfer_evaluator::do_evaluate(const son_wallet_transfer_create_operation& op)
|
||||
void_result create_son_wallet_deposit_evaluator::do_evaluate(const son_wallet_deposit_create_operation& op)
|
||||
{ try{
|
||||
FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK");
|
||||
//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(), "SON paying account must be set as payer." );
|
||||
FC_ASSERT( op.payer == GRAPHENE_SON_ACCOUNT, "SON paying account must be set as payer." );
|
||||
|
||||
//const auto& idx = db().get_index_type<son_wallet_transfer_index>().indices().get<by_sidechain_uid>();
|
||||
//const auto& idx = db().get_index_type<son_wallet_deposit_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)
|
||||
object_id_type create_son_wallet_deposit_evaluator::do_apply(const son_wallet_deposit_create_operation& op)
|
||||
{ try {
|
||||
const auto& idx = db().get_index_type<son_wallet_transfer_index>().indices().get<by_sidechain_uid>();
|
||||
const auto& idx = db().get_index_type<son_wallet_deposit_index>().indices().get<by_sidechain_uid>();
|
||||
auto itr = idx.find(op.sidechain_uid);
|
||||
if (itr == idx.end()) {
|
||||
const auto& new_son_wallet_transfer_object = db().create<son_wallet_transfer_object>( [&]( son_wallet_transfer_object& swto ){
|
||||
const auto& new_son_wallet_deposit_object = db().create<son_wallet_deposit_object>( [&]( son_wallet_deposit_object& swto ){
|
||||
swto.timestamp = op.timestamp;
|
||||
swto.sidechain = op.sidechain;
|
||||
swto.confirmations = 1;
|
||||
|
|
@ -33,26 +32,25 @@ object_id_type create_son_wallet_transfer_evaluator::do_apply(const son_wallet_t
|
|||
swto.sidechain_amount = op.sidechain_amount;
|
||||
swto.peerplays_from = op.peerplays_from;
|
||||
swto.peerplays_to = op.peerplays_to;
|
||||
swto.peerplays_amount = op.peerplays_amount;
|
||||
swto.peerplays_asset = op.peerplays_asset;
|
||||
swto.processed = false;
|
||||
});
|
||||
return new_son_wallet_transfer_object.id;
|
||||
return new_son_wallet_deposit_object.id;
|
||||
} else {
|
||||
db().modify(*itr, [&op](son_wallet_transfer_object &swto) {
|
||||
db().modify(*itr, [&op](son_wallet_deposit_object &swto) {
|
||||
swto.confirmations = swto.confirmations + 1;
|
||||
});
|
||||
return (*itr).id;
|
||||
}
|
||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||
|
||||
void_result process_son_wallet_transfer_evaluator::do_evaluate(const son_wallet_transfer_process_operation& op)
|
||||
void_result process_son_wallet_deposit_evaluator::do_evaluate(const son_wallet_deposit_process_operation& op)
|
||||
{ try{
|
||||
FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK");
|
||||
//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(), "SON paying account must be set as payer." );
|
||||
FC_ASSERT( op.payer == GRAPHENE_SON_ACCOUNT, "SON paying account must be set as payer." );
|
||||
|
||||
const auto& idx = db().get_index_type<son_wallet_transfer_index>().indices().get<by_id>();
|
||||
const auto& itr = idx.find(op.son_wallet_transfer_id);
|
||||
const auto& idx = db().get_index_type<son_wallet_deposit_index>().indices().get<by_id>();
|
||||
const auto& itr = idx.find(op.son_wallet_deposit_id);
|
||||
FC_ASSERT(itr != idx.end(), "Son wallet transfer not found");
|
||||
//FC_ASSERT(itr->processed == false, "Son wallet transfer is already processed");
|
||||
|
||||
|
|
@ -60,7 +58,7 @@ void_result process_son_wallet_transfer_evaluator::do_evaluate(const son_wallet_
|
|||
|
||||
const account_object& from_account = itr->peerplays_to(d); // reversed, for deposit
|
||||
const account_object& to_account = itr->peerplays_from(d); // reversed, for deposit
|
||||
const asset_object& asset_type = itr->peerplays_amount.asset_id(d);
|
||||
const asset_object& asset_type = itr->peerplays_asset.asset_id(d);
|
||||
|
||||
try {
|
||||
|
||||
|
|
@ -69,14 +67,14 @@ void_result process_son_wallet_transfer_evaluator::do_evaluate(const son_wallet_
|
|||
transfer_from_account_not_whitelisted,
|
||||
"'from' account ${from} is not whitelisted for asset ${asset}",
|
||||
("from",from_account.id)
|
||||
("asset",itr->peerplays_amount.asset_id)
|
||||
("asset",itr->peerplays_asset.asset_id)
|
||||
);
|
||||
GRAPHENE_ASSERT(
|
||||
is_authorized_asset( d, to_account, asset_type ),
|
||||
transfer_to_account_not_whitelisted,
|
||||
"'to' account ${to} is not whitelisted for asset ${asset}",
|
||||
("to",to_account.id)
|
||||
("asset",itr->peerplays_amount.asset_id)
|
||||
("asset",itr->peerplays_asset.asset_id)
|
||||
);
|
||||
|
||||
if( asset_type.is_transfer_restricted() )
|
||||
|
|
@ -85,38 +83,38 @@ void_result process_son_wallet_transfer_evaluator::do_evaluate(const son_wallet_
|
|||
from_account.id == asset_type.issuer || to_account.id == asset_type.issuer,
|
||||
transfer_restricted_transfer_asset,
|
||||
"Asset {asset} has transfer_restricted flag enabled",
|
||||
("asset", itr->peerplays_amount.asset_id)
|
||||
("asset", itr->peerplays_asset.asset_id)
|
||||
);
|
||||
}
|
||||
|
||||
bool insufficient_balance = d.get_balance( from_account, asset_type ).amount >= itr->peerplays_amount.amount;
|
||||
bool insufficient_balance = d.get_balance( from_account, asset_type ).amount >= itr->peerplays_asset.amount;
|
||||
FC_ASSERT( insufficient_balance,
|
||||
"Insufficient Balance: ${balance}, unable to transfer '${total_transfer}' from account '${a}' to '${t}'",
|
||||
("a",from_account.name)("t",to_account.name)("total_transfer",d.to_pretty_string(itr->peerplays_amount))("balance",d.to_pretty_string(d.get_balance(from_account, asset_type))) );
|
||||
("a",from_account.name)("t",to_account.name)("total_transfer",d.to_pretty_string(itr->peerplays_asset))("balance",d.to_pretty_string(d.get_balance(from_account, asset_type))) );
|
||||
|
||||
return void_result();
|
||||
} FC_RETHROW_EXCEPTIONS( error, "Unable to transfer ${a} from ${f} to ${t}", ("a",d.to_pretty_string(itr->peerplays_amount))("f",from_account.name)("t",to_account.name) );
|
||||
} FC_RETHROW_EXCEPTIONS( error, "Unable to transfer ${a} from ${f} to ${t}", ("a",d.to_pretty_string(itr->peerplays_asset))("f",from_account.name)("t",to_account.name) );
|
||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||
|
||||
object_id_type process_son_wallet_transfer_evaluator::do_apply(const son_wallet_transfer_process_operation& op)
|
||||
object_id_type process_son_wallet_deposit_evaluator::do_apply(const son_wallet_deposit_process_operation& op)
|
||||
{ try {
|
||||
const auto& idx = db().get_index_type<son_wallet_transfer_index>().indices().get<by_id>();
|
||||
auto itr = idx.find(op.son_wallet_transfer_id);
|
||||
const auto& idx = db().get_index_type<son_wallet_deposit_index>().indices().get<by_id>();
|
||||
auto itr = idx.find(op.son_wallet_deposit_id);
|
||||
if(itr != idx.end())
|
||||
{
|
||||
if (itr->processed == false) {
|
||||
db().modify(*itr, [&op](son_wallet_transfer_object &swto) {
|
||||
db().modify(*itr, [&op](son_wallet_deposit_object &swto) {
|
||||
swto.processed = true;
|
||||
});
|
||||
|
||||
const account_id_type from_account = itr->peerplays_to; // reversed, for deposit
|
||||
const account_id_type to_account = itr->peerplays_from; // reversed, for deposit
|
||||
|
||||
db().adjust_balance( from_account, -itr->peerplays_amount );
|
||||
db().adjust_balance( to_account, itr->peerplays_amount );
|
||||
db().adjust_balance( from_account, -itr->peerplays_asset );
|
||||
db().adjust_balance( to_account, itr->peerplays_asset );
|
||||
}
|
||||
}
|
||||
return op.son_wallet_transfer_id;
|
||||
return op.son_wallet_deposit_id;
|
||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||
|
||||
} } // namespace graphene::chain
|
||||
|
|
@ -8,8 +8,7 @@ namespace graphene { namespace chain {
|
|||
void_result recreate_son_wallet_evaluator::do_evaluate(const son_wallet_recreate_operation& op)
|
||||
{ try{
|
||||
FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK");
|
||||
//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(), "SON paying account must be set as payer." );
|
||||
FC_ASSERT( op.payer == GRAPHENE_SON_ACCOUNT, "SON paying account must be set as payer." );
|
||||
|
||||
const auto& idx = db().get_index_type<son_wallet_index>().indices().get<by_id>();
|
||||
auto itr = idx.rbegin();
|
||||
|
|
@ -54,8 +53,7 @@ object_id_type recreate_son_wallet_evaluator::do_apply(const son_wallet_recreate
|
|||
void_result update_son_wallet_evaluator::do_evaluate(const son_wallet_update_operation& op)
|
||||
{ try{
|
||||
FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK");
|
||||
//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(), "SON paying account must be set as payer." );
|
||||
FC_ASSERT( op.payer == GRAPHENE_SON_ACCOUNT, "SON paying account must be set as payer." );
|
||||
|
||||
const auto& idx = db().get_index_type<son_wallet_index>().indices().get<by_id>();
|
||||
FC_ASSERT( idx.find(op.son_wallet_id) != idx.end() );
|
||||
|
|
|
|||
70
libraries/chain/son_wallet_withdraw_evaluator.cpp
Normal file
70
libraries/chain/son_wallet_withdraw_evaluator.cpp
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
#include <graphene/chain/son_wallet_withdraw_evaluator.hpp>
|
||||
|
||||
#include <graphene/chain/database.hpp>
|
||||
#include <graphene/chain/is_authorized_asset.hpp>
|
||||
#include <graphene/chain/son_wallet_withdraw_object.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
void_result create_son_wallet_withdraw_evaluator::do_evaluate(const son_wallet_withdraw_create_operation& op)
|
||||
{ try{
|
||||
FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK");
|
||||
FC_ASSERT( op.payer == GRAPHENE_SON_ACCOUNT, "SON paying account must be set as payer." );
|
||||
|
||||
return void_result();
|
||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||
|
||||
object_id_type create_son_wallet_withdraw_evaluator::do_apply(const son_wallet_withdraw_create_operation& op)
|
||||
{ try {
|
||||
const auto& idx = db().get_index_type<son_wallet_withdraw_index>().indices().get<by_peerplays_uid>();
|
||||
auto itr = idx.find(op.peerplays_uid);
|
||||
if (itr == idx.end()) {
|
||||
const auto& new_son_wallet_withdraw_object = db().create<son_wallet_withdraw_object>( [&]( son_wallet_withdraw_object& swwo ){
|
||||
swwo.timestamp = op.timestamp;
|
||||
swwo.sidechain = op.sidechain;
|
||||
swwo.confirmations = 1;
|
||||
swwo.peerplays_uid = op.peerplays_uid;
|
||||
swwo.peerplays_transaction_id = op.peerplays_transaction_id;
|
||||
swwo.peerplays_from = op.peerplays_from;
|
||||
swwo.peerplays_asset = op.peerplays_asset;
|
||||
swwo.withdraw_sidechain = op.withdraw_sidechain;
|
||||
swwo.withdraw_address = op.withdraw_address;
|
||||
swwo.withdraw_currency = op.withdraw_currency;
|
||||
swwo.withdraw_amount = op.withdraw_amount;
|
||||
swwo.processed = false;
|
||||
});
|
||||
return new_son_wallet_withdraw_object.id;
|
||||
} else {
|
||||
db().modify(*itr, [&op](son_wallet_withdraw_object &swto) {
|
||||
swto.confirmations = swto.confirmations + 1;
|
||||
});
|
||||
return (*itr).id;
|
||||
}
|
||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||
|
||||
void_result process_son_wallet_withdraw_evaluator::do_evaluate(const son_wallet_withdraw_process_operation& op)
|
||||
{ try{
|
||||
FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK");
|
||||
FC_ASSERT( op.payer == GRAPHENE_SON_ACCOUNT, "SON paying account must be set as payer." );
|
||||
|
||||
const auto& idx = db().get_index_type<son_wallet_withdraw_index>().indices().get<by_id>();
|
||||
const auto& itr = idx.find(op.son_wallet_withdraw_id);
|
||||
FC_ASSERT(itr != idx.end(), "Son wallet withdraw not found");
|
||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||
|
||||
object_id_type process_son_wallet_withdraw_evaluator::do_apply(const son_wallet_withdraw_process_operation& op)
|
||||
{ try {
|
||||
const auto& idx = db().get_index_type<son_wallet_withdraw_index>().indices().get<by_id>();
|
||||
auto itr = idx.find(op.son_wallet_withdraw_id);
|
||||
if(itr != idx.end())
|
||||
{
|
||||
if (itr->processed == false) {
|
||||
db().modify(*itr, [&op](son_wallet_withdraw_object &swto) {
|
||||
swto.processed = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
return op.son_wallet_withdraw_id;
|
||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||
|
||||
} } // namespace graphene::chain
|
||||
1
libraries/plugins/peerplays_sidechain/CMakeLists.txt
Normal file → Executable file
1
libraries/plugins/peerplays_sidechain/CMakeLists.txt
Normal file → Executable file
|
|
@ -5,6 +5,7 @@ add_library( peerplays_sidechain
|
|||
sidechain_net_manager.cpp
|
||||
sidechain_net_handler.cpp
|
||||
sidechain_net_handler_bitcoin.cpp
|
||||
sidechain_net_handler_peerplays.cpp
|
||||
bitcoin_utils.cpp
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -586,7 +586,7 @@ bytes der_sign(const fc::ecc::private_key& priv_key, const fc::sha256& digest)
|
|||
return bytes(result.begin(), result.begin() + size);
|
||||
}
|
||||
|
||||
std::vector<bytes> signature_for_raw_transaction(const bytes& unsigned_tx,
|
||||
std::vector<bytes> signatures_for_raw_transaction(const bytes& unsigned_tx,
|
||||
std::vector<uint64_t> in_amounts,
|
||||
const bytes& redeem_script,
|
||||
const fc::ecc::private_key& priv_key)
|
||||
|
|
@ -645,7 +645,7 @@ bytes sign_pw_transfer_transaction(const bytes &unsigned_tx, std::vector<uint64_
|
|||
{
|
||||
if(key)
|
||||
{
|
||||
std::vector<bytes> signatures = signature_for_raw_transaction(unsigned_tx, in_amounts, redeem_script, *key);
|
||||
std::vector<bytes> signatures = signatures_for_raw_transaction(unsigned_tx, in_amounts, redeem_script, *key);
|
||||
FC_ASSERT(signatures.size() == tx.vin.size(), "Invalid signatures number");
|
||||
// push signatures in reverse order because script starts to check the top signature on the stack first
|
||||
for(unsigned int i = 0; i < tx.vin.size(); i++)
|
||||
|
|
@ -699,7 +699,7 @@ bytes partially_sign_pw_transfer_transaction(const bytes& partially_signed_tx,
|
|||
tx.fill_from_bytes(partially_signed_tx);
|
||||
FC_ASSERT(tx.vin.size() > 0);
|
||||
bytes redeem_script = tx.vin[0].scriptWitness.back();
|
||||
std::vector<bytes> signatures = signature_for_raw_transaction(partially_signed_tx, in_amounts, redeem_script, priv_key);
|
||||
std::vector<bytes> signatures = signatures_for_raw_transaction(partially_signed_tx, in_amounts, redeem_script, priv_key);
|
||||
FC_ASSERT(signatures.size() == tx.vin.size(), "Invalid signatures number");
|
||||
// push signatures in reverse order because script starts to check the top signature on the stack first
|
||||
unsigned witness_idx = tx.vin[0].scriptWitness.size() - 2 - key_idx;
|
||||
|
|
@ -710,4 +710,29 @@ bytes partially_sign_pw_transfer_transaction(const bytes& partially_signed_tx,
|
|||
return ret;
|
||||
}
|
||||
|
||||
bytes add_signatures_to_unsigned_tx(const bytes &unsigned_tx, const std::vector<std::vector<bytes> > &signature_set, const bytes &redeem_script)
|
||||
{
|
||||
btc_tx tx;
|
||||
tx.fill_from_bytes(unsigned_tx);
|
||||
bytes dummy_data;
|
||||
for(unsigned int i = 0; i < signature_set.size(); i++)
|
||||
{
|
||||
std::vector<bytes> signatures = signature_set[i];
|
||||
FC_ASSERT(signatures.size() == tx.vin.size(), "Invalid signatures number");
|
||||
// push signatures in reverse order because script starts to check the top signature on the stack first
|
||||
for(unsigned int i = 0; i < tx.vin.size(); i++)
|
||||
tx.vin[i].scriptWitness.insert(tx.vin[i].scriptWitness.begin(), signatures[i]);
|
||||
}
|
||||
|
||||
for(auto& in: tx.vin)
|
||||
{
|
||||
in.scriptWitness.push_back(redeem_script);
|
||||
}
|
||||
|
||||
tx.hasWitness = true;
|
||||
bytes ret;
|
||||
tx.to_bytes(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,11 @@ std::string p2wsh_address_from_redeem_script(const bytes& script, bitcoin_networ
|
|||
bytes lock_script_for_redeem_script(const bytes& script);
|
||||
|
||||
|
||||
std::vector<bytes> signatures_for_raw_transaction(const bytes& unsigned_tx,
|
||||
std::vector<uint64_t> in_amounts,
|
||||
const bytes& redeem_script,
|
||||
const fc::ecc::private_key& priv_key);
|
||||
|
||||
/*
|
||||
* unsigned_tx - tx, all inputs of which are spends of the PW P2SH address
|
||||
* returns signed transaction
|
||||
|
|
@ -24,15 +29,42 @@ bytes sign_pw_transfer_transaction(const bytes& unsigned_tx,
|
|||
const bytes& redeem_script,
|
||||
const std::vector<fc::optional<fc::ecc::private_key>>& priv_keys);
|
||||
|
||||
///
|
||||
////// \brief Adds dummy signatures instead of real signatures
|
||||
////// \param unsigned_tx
|
||||
////// \param redeem_script
|
||||
////// \param key_count
|
||||
////// \return can be used as partially signed tx
|
||||
bytes add_dummy_signatures_for_pw_transfer(const bytes& unsigned_tx,
|
||||
const bytes& redeem_script,
|
||||
unsigned int key_count);
|
||||
|
||||
///
|
||||
/// \brief replaces dummy sgnatures in partially signed tx with real tx
|
||||
/// \param partially_signed_tx
|
||||
/// \param in_amounts
|
||||
/// \param priv_key
|
||||
/// \param key_idx
|
||||
/// \return
|
||||
///
|
||||
bytes partially_sign_pw_transfer_transaction(const bytes& partially_signed_tx,
|
||||
std::vector<uint64_t> in_amounts,
|
||||
const fc::ecc::private_key& priv_key,
|
||||
unsigned int key_idx);
|
||||
|
||||
///
|
||||
/// \brief Creates ready to publish bitcoin transaction from unsigned tx and
|
||||
/// full set of the signatures. This is alternative way to create tx
|
||||
/// with partially_sign_pw_transfer_transaction
|
||||
/// \param unsigned_tx
|
||||
/// \param signatures
|
||||
/// \param redeem_script
|
||||
/// \return
|
||||
///
|
||||
bytes add_signatures_to_unsigned_tx(const bytes& unsigned_tx,
|
||||
const std::vector<std::vector<bytes> >& signatures,
|
||||
const bytes& redeem_script);
|
||||
|
||||
struct btc_outpoint
|
||||
{
|
||||
fc::uint256 hash;
|
||||
|
|
|
|||
|
|
@ -4,9 +4,11 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <fc/safe.hpp>
|
||||
#include <fc/time.hpp>
|
||||
#include <fc/crypto/sha256.hpp>
|
||||
|
||||
#include <graphene/chain/protocol/asset.hpp>
|
||||
#include <graphene/chain/protocol/types.hpp>
|
||||
|
||||
namespace graphene { namespace peerplays_sidechain {
|
||||
|
|
@ -70,9 +72,11 @@ struct sidechain_event_data {
|
|||
std::string sidechain_transaction_id;
|
||||
std::string sidechain_from;
|
||||
std::string sidechain_to;
|
||||
int64_t sidechain_amount;
|
||||
std::string sidechain_currency;
|
||||
fc::safe<int64_t> sidechain_amount;
|
||||
chain::account_id_type peerplays_from;
|
||||
chain::account_id_type peerplays_to;
|
||||
chain::asset peerplays_asset;
|
||||
};
|
||||
|
||||
} } // graphene::peerplays_sidechain
|
||||
|
|
|
|||
|
|
@ -16,11 +16,16 @@ public:
|
|||
virtual ~sidechain_net_handler();
|
||||
|
||||
graphene::peerplays_sidechain::sidechain_type get_sidechain();
|
||||
std::vector<std::string> get_sidechain_addresses();
|
||||
std::vector<std::string> get_sidechain_deposit_addresses();
|
||||
std::vector<std::string> get_sidechain_withdraw_addresses();
|
||||
|
||||
void sidechain_event_data_received(const sidechain_event_data& sed);
|
||||
|
||||
virtual void recreate_primary_wallet() = 0;
|
||||
virtual void process_deposits() = 0;
|
||||
virtual void process_deposit(const son_wallet_deposit_object& swdo) = 0;
|
||||
virtual void process_withdrawals() = 0;
|
||||
virtual void process_withdrawal(const son_wallet_withdraw_object& swwo) = 0;
|
||||
|
||||
protected:
|
||||
peerplays_sidechain_plugin& plugin;
|
||||
|
|
@ -34,8 +39,6 @@ protected:
|
|||
virtual std::string transfer_deposit_to_primary_wallet (const sidechain_event_data& sed) = 0;
|
||||
virtual std::string transfer_withdrawal_from_primary_wallet(const std::string& user_address, double sidechain_amount) = 0;
|
||||
|
||||
virtual void handle_event( const std::string& event_data ) = 0;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
#include <fc/signals.hpp>
|
||||
#include <fc/network/http/connection.hpp>
|
||||
#include <graphene/chain/database.hpp>
|
||||
|
||||
namespace graphene { namespace peerplays_sidechain {
|
||||
|
||||
|
|
@ -76,8 +75,10 @@ public:
|
|||
virtual ~sidechain_net_handler_bitcoin();
|
||||
|
||||
void recreate_primary_wallet();
|
||||
|
||||
bool connection_is_not_defined() const;
|
||||
void process_deposits();
|
||||
void process_deposit(const son_wallet_deposit_object& swdo);
|
||||
void process_withdrawals();
|
||||
void process_withdrawal(const son_wallet_withdraw_object& swwo);
|
||||
|
||||
std::string create_multisignature_wallet( const std::vector<std::string> public_keys );
|
||||
std::string transfer( const std::string& from, const std::string& to, const uint64_t amount );
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
#pragma once
|
||||
|
||||
#include <graphene/peerplays_sidechain/sidechain_net_handler.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <fc/signals.hpp>
|
||||
|
||||
namespace graphene { namespace peerplays_sidechain {
|
||||
|
||||
class sidechain_net_handler_peerplays : public sidechain_net_handler {
|
||||
public:
|
||||
sidechain_net_handler_peerplays(peerplays_sidechain_plugin& _plugin, const boost::program_options::variables_map& options);
|
||||
virtual ~sidechain_net_handler_peerplays();
|
||||
|
||||
void recreate_primary_wallet();
|
||||
void process_deposits();
|
||||
void process_deposit(const son_wallet_deposit_object& swdo);
|
||||
void process_withdrawals();
|
||||
void process_withdrawal(const son_wallet_withdraw_object& swwo);
|
||||
|
||||
std::string create_multisignature_wallet( const std::vector<std::string> public_keys );
|
||||
std::string transfer( const std::string& from, const std::string& to, const uint64_t amount );
|
||||
std::string sign_transaction( const std::string& transaction );
|
||||
std::string send_transaction( const std::string& transaction );
|
||||
|
||||
private:
|
||||
|
||||
void on_block_applied(const signed_block& b);
|
||||
|
||||
};
|
||||
|
||||
} } // graphene::peerplays_sidechain
|
||||
|
||||
|
|
@ -17,6 +17,8 @@ public:
|
|||
|
||||
bool create_handler(peerplays_sidechain::sidechain_type sidechain, const boost::program_options::variables_map& options);
|
||||
void recreate_primary_wallet();
|
||||
void process_deposits();
|
||||
void process_withdrawals();
|
||||
private:
|
||||
peerplays_sidechain_plugin& plugin;
|
||||
graphene::chain::database& database;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
#include <graphene/chain/proposal_object.hpp>
|
||||
#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/son_wallet_withdraw_object.hpp>
|
||||
#include <graphene/chain/protocol/transfer.hpp>
|
||||
#include <graphene/peerplays_sidechain/sidechain_net_manager.hpp>
|
||||
#include <graphene/utilities/key_conversion.hpp>
|
||||
|
|
@ -46,27 +46,30 @@ class peerplays_sidechain_plugin_impl
|
|||
void create_son_down_proposals();
|
||||
void recreate_primary_wallet();
|
||||
void process_deposits();
|
||||
//void process_withdrawals();
|
||||
void on_block_applied( const signed_block& b );
|
||||
void on_objects_new(const vector<object_id_type>& new_object_ids);
|
||||
void process_withdrawals();
|
||||
|
||||
private:
|
||||
peerplays_sidechain_plugin& plugin;
|
||||
|
||||
bool config_ready_son;
|
||||
bool config_ready_bitcoin;
|
||||
bool config_ready_peerplays;
|
||||
|
||||
std::unique_ptr<peerplays_sidechain::sidechain_net_manager> net_manager;
|
||||
std::map<chain::public_key_type, fc::ecc::private_key> _private_keys;
|
||||
std::set<chain::son_id_type> _sons;
|
||||
fc::future<void> _heartbeat_task;
|
||||
|
||||
void on_block_applied( const signed_block& b );
|
||||
void on_objects_new(const vector<object_id_type>& new_object_ids);
|
||||
|
||||
};
|
||||
|
||||
peerplays_sidechain_plugin_impl::peerplays_sidechain_plugin_impl(peerplays_sidechain_plugin& _plugin) :
|
||||
plugin(_plugin),
|
||||
config_ready_son(false),
|
||||
config_ready_bitcoin(false),
|
||||
config_ready_peerplays(false),
|
||||
net_manager(nullptr)
|
||||
{
|
||||
}
|
||||
|
|
@ -180,6 +183,14 @@ void peerplays_sidechain_plugin_impl::plugin_initialize(const boost::program_opt
|
|||
// wlog("Haven't set up Ethereum sidechain parameters");
|
||||
//}
|
||||
|
||||
config_ready_peerplays = true;
|
||||
if (config_ready_peerplays) {
|
||||
net_manager->create_handler(sidechain_type::peerplays, options);
|
||||
ilog("Peerplays sidechain handler created");
|
||||
} else {
|
||||
wlog("Haven't set up Peerplays sidechain parameters");
|
||||
}
|
||||
|
||||
if (!(config_ready_bitcoin /*&& config_ready_ethereum*/)) {
|
||||
wlog("Haven't set up any sidechain parameters");
|
||||
throw;
|
||||
|
|
@ -203,6 +214,10 @@ void peerplays_sidechain_plugin_impl::plugin_startup()
|
|||
//if (config_ready_ethereum) {
|
||||
// ilog("Ethereum sidechain handler running");
|
||||
//}
|
||||
|
||||
if (config_ready_peerplays) {
|
||||
ilog("Peerplays sidechain handler running");
|
||||
}
|
||||
}
|
||||
|
||||
std::set<chain::son_id_type>& peerplays_sidechain_plugin_impl::get_sons()
|
||||
|
|
@ -310,7 +325,7 @@ void peerplays_sidechain_plugin_impl::create_son_down_proposals()
|
|||
auto son_obj = idx.find( my_son_id );
|
||||
|
||||
chain::son_report_down_operation son_down_op;
|
||||
son_down_op.payer = gpo.parameters.get_son_btc_account_id();
|
||||
son_down_op.payer = GRAPHENE_SON_ACCOUNT;
|
||||
son_down_op.son_id = son_id;
|
||||
son_down_op.down_ts = last_active_ts;
|
||||
|
||||
|
|
@ -363,47 +378,15 @@ void peerplays_sidechain_plugin_impl::recreate_primary_wallet()
|
|||
net_manager->recreate_primary_wallet();
|
||||
}
|
||||
|
||||
void peerplays_sidechain_plugin_impl::process_deposits() {
|
||||
|
||||
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();
|
||||
|
||||
for (son_id_type son_id : plugin.get_sons()) {
|
||||
if (plugin.is_active_son(son_id)) {
|
||||
|
||||
son_wallet_transfer_process_operation p_op;
|
||||
p_op.payer = gpo.parameters.get_son_btc_account_id();
|
||||
p_op.son_wallet_transfer_id = swto.id;
|
||||
|
||||
proposal_create_operation proposal_op;
|
||||
proposal_op.fee_paying_account = plugin.get_son_object(son_id).son_account;
|
||||
proposal_op.proposed_ops.emplace_back( op_wrapper( p_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 );
|
||||
|
||||
ilog("sidechain_net_handler: sending proposal for transfer operation ${swto} by ${son}", ("swto", swto.id) ("son", son_id));
|
||||
signed_transaction trx = plugin.database().create_signed_transaction(plugin.get_private_key(son_id), proposal_op);
|
||||
trx.validate();
|
||||
ilog("sidechain_net_handler: transaction validated ${swto} by ${son}", ("swto", swto.id) ("son", son_id));
|
||||
try {
|
||||
plugin.database().push_transaction(trx, database::validation_steps::skip_block_size_check);
|
||||
if(plugin.app().p2p_node())
|
||||
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
|
||||
} catch(fc::exception e){
|
||||
ilog("sidechain_net_handler: sending proposal for transfer operation failed with exception ${e}",("e", e.what()));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
void peerplays_sidechain_plugin_impl::process_deposits()
|
||||
{
|
||||
net_manager->process_deposits();
|
||||
}
|
||||
|
||||
//void peerplays_sidechain_plugin_impl::process_withdrawals() {
|
||||
//}
|
||||
void peerplays_sidechain_plugin_impl::process_withdrawals()
|
||||
{
|
||||
net_manager->process_withdrawals();
|
||||
}
|
||||
|
||||
void peerplays_sidechain_plugin_impl::on_block_applied( const signed_block& b )
|
||||
{
|
||||
|
|
@ -426,7 +409,7 @@ void peerplays_sidechain_plugin_impl::on_block_applied( const signed_block& b )
|
|||
|
||||
process_deposits();
|
||||
|
||||
//process_withdrawals();
|
||||
process_withdrawals();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -484,13 +467,25 @@ void peerplays_sidechain_plugin_impl::on_objects_new(const vector<object_id_type
|
|||
}
|
||||
|
||||
if(proposal->proposed_transaction.operations.size() == 1
|
||||
&& proposal->proposed_transaction.operations[0].which() == chain::operation::tag<chain::son_wallet_transfer_create_operation>::value) {
|
||||
&& proposal->proposed_transaction.operations[0].which() == chain::operation::tag<chain::son_wallet_deposit_create_operation>::value) {
|
||||
approve_proposal( son_id, proposal->id );
|
||||
continue;
|
||||
}
|
||||
|
||||
if(proposal->proposed_transaction.operations.size() == 1
|
||||
&& proposal->proposed_transaction.operations[0].which() == chain::operation::tag<chain::son_wallet_transfer_process_operation>::value) {
|
||||
&& proposal->proposed_transaction.operations[0].which() == chain::operation::tag<chain::son_wallet_deposit_process_operation>::value) {
|
||||
approve_proposal( son_id, proposal->id );
|
||||
continue;
|
||||
}
|
||||
|
||||
if(proposal->proposed_transaction.operations.size() == 1
|
||||
&& proposal->proposed_transaction.operations[0].which() == chain::operation::tag<chain::son_wallet_withdraw_create_operation>::value) {
|
||||
approve_proposal( son_id, proposal->id );
|
||||
continue;
|
||||
}
|
||||
|
||||
if(proposal->proposed_transaction.operations.size() == 1
|
||||
&& proposal->proposed_transaction.operations[0].which() == chain::operation::tag<chain::son_wallet_withdraw_process_operation>::value) {
|
||||
approve_proposal( son_id, proposal->id );
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#include <graphene/peerplays_sidechain/sidechain_net_handler.hpp>
|
||||
|
||||
#include <graphene/chain/sidechain_address_object.hpp>
|
||||
#include <graphene/chain/son_wallet_deposit_object.hpp>
|
||||
#include <graphene/chain/son_wallet_withdraw_object.hpp>
|
||||
|
||||
#include <fc/log/logger.hpp>
|
||||
|
||||
|
|
@ -19,25 +21,29 @@ graphene::peerplays_sidechain::sidechain_type sidechain_net_handler::get_sidecha
|
|||
return sidechain;
|
||||
}
|
||||
|
||||
std::vector<std::string> sidechain_net_handler::get_sidechain_addresses() {
|
||||
std::vector<std::string> sidechain_net_handler::get_sidechain_deposit_addresses() {
|
||||
std::vector<std::string> result;
|
||||
|
||||
switch (sidechain) {
|
||||
case sidechain_type::bitcoin:
|
||||
{
|
||||
const auto& sidechain_addresses_idx = database.get_index_type<sidechain_address_index>();
|
||||
const auto& sidechain_addresses_by_sidechain_idx = sidechain_addresses_idx.indices().get<by_sidechain>();
|
||||
const auto& sidechain_addresses_by_sidechain_range = sidechain_addresses_by_sidechain_idx.equal_range(sidechain);
|
||||
std::for_each(sidechain_addresses_by_sidechain_range.first, sidechain_addresses_by_sidechain_range.second,
|
||||
[&result] (const sidechain_address_object& sao) {
|
||||
result.push_back(sao.address);
|
||||
});
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
const auto& sidechain_addresses_idx = database.get_index_type<sidechain_address_index>();
|
||||
const auto& sidechain_addresses_by_sidechain_idx = sidechain_addresses_idx.indices().get<by_sidechain>();
|
||||
const auto& sidechain_addresses_by_sidechain_range = sidechain_addresses_by_sidechain_idx.equal_range(sidechain);
|
||||
std::for_each(sidechain_addresses_by_sidechain_range.first, sidechain_addresses_by_sidechain_range.second,
|
||||
[&result] (const sidechain_address_object& sao) {
|
||||
result.push_back(sao.deposit_address);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::string> sidechain_net_handler::get_sidechain_withdraw_addresses() {
|
||||
std::vector<std::string> result;
|
||||
|
||||
const auto& sidechain_addresses_idx = database.get_index_type<sidechain_address_index>();
|
||||
const auto& sidechain_addresses_by_sidechain_idx = sidechain_addresses_idx.indices().get<by_sidechain>();
|
||||
const auto& sidechain_addresses_by_sidechain_range = sidechain_addresses_by_sidechain_idx.equal_range(sidechain);
|
||||
std::for_each(sidechain_addresses_by_sidechain_range.first, sidechain_addresses_by_sidechain_range.second,
|
||||
[&result] (const sidechain_address_object& sao) {
|
||||
result.push_back(sao.withdraw_address);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -49,46 +55,184 @@ void sidechain_net_handler::sidechain_event_data_received(const sidechain_event_
|
|||
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_currency: ${currency}", ( "currency", sed.sidechain_currency ) );
|
||||
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 ) );
|
||||
ilog( " peerplays_asset: ${peerplays_asset}", ( "peerplays_asset", sed.peerplays_asset ) );
|
||||
|
||||
const chain::global_property_object& gpo = database.get_global_properties();
|
||||
|
||||
transfer_deposit_to_primary_wallet(sed);
|
||||
// Deposit request
|
||||
if ((sed.peerplays_to == GRAPHENE_SON_ACCOUNT) && (sed.sidechain_currency.compare("1.3.0") != 0)) {
|
||||
|
||||
son_wallet_transfer_create_operation op;
|
||||
op.payer = gpo.parameters.get_son_btc_account_id();
|
||||
op.timestamp = sed.timestamp;
|
||||
op.sidechain = sed.sidechain;
|
||||
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;
|
||||
op.peerplays_amount = asset(sed.sidechain_amount / 1000); // For Bitcoin, the exchange rate is 1:1, for others, get the exchange rate from market
|
||||
transfer_deposit_to_primary_wallet(sed);
|
||||
|
||||
for (son_id_type son_id : plugin.get_sons()) {
|
||||
if (plugin.is_active_son(son_id)) {
|
||||
proposal_create_operation proposal_op;
|
||||
proposal_op.fee_paying_account = plugin.get_son_object(son_id).son_account;
|
||||
proposal_op.proposed_ops.emplace_back( op_wrapper( op ) );
|
||||
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 );
|
||||
son_wallet_deposit_create_operation op;
|
||||
op.payer = GRAPHENE_SON_ACCOUNT;
|
||||
op.timestamp = sed.timestamp;
|
||||
op.sidechain = sed.sidechain;
|
||||
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_currency = sed.sidechain_currency;
|
||||
op.sidechain_amount = sed.sidechain_amount;
|
||||
op.peerplays_from = sed.peerplays_from;
|
||||
op.peerplays_to = sed.peerplays_to;
|
||||
op.peerplays_asset = sed.peerplays_asset;
|
||||
|
||||
ilog("sidechain_net_handler: sending proposal for son wallet transfer create operation by ${son}", ("son", son_id));
|
||||
signed_transaction trx = plugin.database().create_signed_transaction(plugin.get_private_key(son_id), proposal_op);
|
||||
try {
|
||||
database.push_transaction(trx, database::validation_steps::skip_block_size_check);
|
||||
if(plugin.app().p2p_node())
|
||||
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
|
||||
} catch(fc::exception e){
|
||||
ilog("sidechain_net_handler: sending proposal for son wallet transfer create operation by ${son} failed with exception ${e}", ("son", son_id) ("e", e.what()));
|
||||
for (son_id_type son_id : plugin.get_sons()) {
|
||||
if (plugin.is_active_son(son_id)) {
|
||||
proposal_create_operation proposal_op;
|
||||
proposal_op.fee_paying_account = plugin.get_son_object(son_id).son_account;
|
||||
proposal_op.proposed_ops.emplace_back( op_wrapper( op ) );
|
||||
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 );
|
||||
|
||||
ilog("sidechain_net_handler: sending proposal for son wallet deposit create operation by ${son}", ("son", son_id));
|
||||
signed_transaction trx = plugin.database().create_signed_transaction(plugin.get_private_key(son_id), proposal_op);
|
||||
try {
|
||||
database.push_transaction(trx, database::validation_steps::skip_block_size_check);
|
||||
if(plugin.app().p2p_node())
|
||||
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
|
||||
} catch(fc::exception e){
|
||||
ilog("sidechain_net_handler: sending proposal for son wallet deposit create operation by ${son} failed with exception ${e}", ("son", son_id) ("e", e.what()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Withdrawal request
|
||||
if ((sed.peerplays_to == GRAPHENE_SON_ACCOUNT) && (sed.sidechain_currency.compare("1.3.0") == 0)) {
|
||||
// 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& addr_itr = sidechain_addresses_idx.find(std::make_tuple(sed.peerplays_from, sidechain_type::bitcoin));
|
||||
if ( addr_itr == sidechain_addresses_idx.end() )
|
||||
return;
|
||||
|
||||
son_wallet_withdraw_create_operation op;
|
||||
op.payer = GRAPHENE_SON_ACCOUNT;
|
||||
op.timestamp = sed.timestamp;
|
||||
op.sidechain = sed.sidechain;
|
||||
op.peerplays_uid = sed.sidechain_uid;
|
||||
op.peerplays_transaction_id = sed.sidechain_transaction_id;
|
||||
op.peerplays_from = sed.peerplays_from;
|
||||
op.peerplays_asset = sed.peerplays_asset;
|
||||
op.withdraw_sidechain = sidechain_type::bitcoin; // BTC payout only (for now)
|
||||
op.withdraw_address = addr_itr->withdraw_address; // BTC payout only (for now)
|
||||
op.withdraw_currency = "BTC"; // BTC payout only (for now)
|
||||
op.withdraw_amount = sed.peerplays_asset.amount * 1000; // BTC payout only (for now)
|
||||
|
||||
for (son_id_type son_id : plugin.get_sons()) {
|
||||
if (plugin.is_active_son(son_id)) {
|
||||
proposal_create_operation proposal_op;
|
||||
proposal_op.fee_paying_account = plugin.get_son_object(son_id).son_account;
|
||||
proposal_op.proposed_ops.emplace_back( op_wrapper( op ) );
|
||||
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 );
|
||||
|
||||
ilog("sidechain_net_handler: sending proposal for son wallet withdraw create operation by ${son}", ("son", son_id));
|
||||
signed_transaction trx = plugin.database().create_signed_transaction(plugin.get_private_key(son_id), proposal_op);
|
||||
try {
|
||||
database.push_transaction(trx, database::validation_steps::skip_block_size_check);
|
||||
if(plugin.app().p2p_node())
|
||||
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
|
||||
} catch(fc::exception e){
|
||||
ilog("sidechain_net_handler: sending proposal for son wallet withdraw create operation by ${son} failed with exception ${e}", ("son", son_id) ("e", e.what()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
FC_ASSERT(false, "Invalid sidechain event");
|
||||
}
|
||||
|
||||
void sidechain_net_handler::recreate_primary_wallet() {
|
||||
FC_ASSERT(false, "recreate_primary_wallet not implemented");
|
||||
}
|
||||
|
||||
void sidechain_net_handler::process_deposits() {
|
||||
const auto& idx = plugin.database().get_index_type<son_wallet_deposit_index>().indices().get<by_sidechain_and_processed>();
|
||||
const auto& idx_range = idx.equal_range(std::make_tuple(sidechain, false));
|
||||
|
||||
std::for_each(idx_range.first, idx_range.second,
|
||||
[&] (const son_wallet_deposit_object& swdo) {
|
||||
|
||||
process_deposit(swdo);
|
||||
|
||||
const chain::global_property_object& gpo = plugin.database().get_global_properties();
|
||||
|
||||
for (son_id_type son_id : plugin.get_sons()) {
|
||||
if (plugin.is_active_son(son_id)) {
|
||||
|
||||
son_wallet_deposit_process_operation p_op;
|
||||
p_op.payer = GRAPHENE_SON_ACCOUNT;
|
||||
p_op.son_wallet_deposit_id = swdo.id;
|
||||
|
||||
proposal_create_operation proposal_op;
|
||||
proposal_op.fee_paying_account = plugin.get_son_object(son_id).son_account;
|
||||
proposal_op.proposed_ops.emplace_back( op_wrapper( p_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 );
|
||||
|
||||
ilog("sidechain_net_handler: sending proposal for transfer operation ${swdo} by ${son}", ("swdo", swdo.id) ("son", son_id));
|
||||
signed_transaction trx = plugin.database().create_signed_transaction(plugin.get_private_key(son_id), proposal_op);
|
||||
trx.validate();
|
||||
ilog("sidechain_net_handler: transaction validated ${swdo} by ${son}", ("swdo", swdo.id) ("son", son_id));
|
||||
try {
|
||||
plugin.database().push_transaction(trx, database::validation_steps::skip_block_size_check);
|
||||
if(plugin.app().p2p_node())
|
||||
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
|
||||
} catch(fc::exception e){
|
||||
ilog("sidechain_net_handler: sending proposal for transfer operation failed with exception ${e}",("e", e.what()));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void sidechain_net_handler::process_withdrawals() {
|
||||
const auto& idx = plugin.database().get_index_type<son_wallet_withdraw_index>().indices().get<by_withdraw_sidechain_and_processed>();
|
||||
const auto& idx_range = idx.equal_range(std::make_tuple(sidechain, false));
|
||||
|
||||
std::for_each(idx_range.first, idx_range.second,
|
||||
[&] (const son_wallet_withdraw_object& swwo) {
|
||||
|
||||
process_withdrawal(swwo);
|
||||
|
||||
const chain::global_property_object& gpo = plugin.database().get_global_properties();
|
||||
|
||||
for (son_id_type son_id : plugin.get_sons()) {
|
||||
if (plugin.is_active_son(son_id)) {
|
||||
|
||||
ilog("SON ${son_id}: Withdraw to process: ${swwo}", ("son_id", son_id) ("swwo", swwo));
|
||||
//son_wallet_withdraw_process_operation p_op;
|
||||
//p_op.payer = GRAPHENE_SON_ACCOUNT;
|
||||
//p_op.son_wallet_withdraw_id = swwo.id;
|
||||
//
|
||||
//proposal_create_operation proposal_op;
|
||||
//proposal_op.fee_paying_account = plugin.get_son_object(son_id).son_account;
|
||||
//proposal_op.proposed_ops.emplace_back( op_wrapper( p_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 );
|
||||
//
|
||||
//ilog("sidechain_net_handler: sending proposal for transfer operation ${swwo} by ${son}", ("swwo", swwo.id) ("son", son_id));
|
||||
//signed_transaction trx = plugin.database().create_signed_transaction(plugin.get_private_key(son_id), proposal_op);
|
||||
//trx.validate();
|
||||
//ilog("sidechain_net_handler: transaction validated ${swwo} by ${son}", ("swwo", swwo.id) ("son", son_id));
|
||||
//try {
|
||||
// plugin.database().push_transaction(trx, database::validation_steps::skip_block_size_check);
|
||||
// if(plugin.app().p2p_node())
|
||||
// plugin.app().p2p_node()->broadcast(net::trx_message(trx));
|
||||
//} catch(fc::exception e){
|
||||
// ilog("sidechain_net_handler: sending proposal for transfer operation failed with exception ${e}",("e", e.what()));
|
||||
//}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
} } // graphene::peerplays_sidechain
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@
|
|||
#include <graphene/chain/sidechain_address_object.hpp>
|
||||
#include <graphene/chain/son_info.hpp>
|
||||
#include <graphene/chain/son_wallet_object.hpp>
|
||||
#include <graphene/chain/son_wallet_deposit_object.hpp>
|
||||
#include <graphene/chain/son_wallet_withdraw_object.hpp>
|
||||
#include <graphene/chain/protocol/son_wallet.hpp>
|
||||
|
||||
namespace graphene { namespace peerplays_sidechain {
|
||||
|
|
@ -524,7 +526,7 @@ void sidechain_net_handler_bitcoin::recreate_primary_wallet() {
|
|||
boost::property_tree::json_parser::write_json(res, pt.get_child("result"));
|
||||
|
||||
son_wallet_update_operation op;
|
||||
op.payer = gpo.parameters.get_son_btc_account_id();
|
||||
op.payer = GRAPHENE_SON_ACCOUNT;
|
||||
op.son_wallet_id = (*obj).id;
|
||||
op.sidechain = sidechain_type::bitcoin;
|
||||
op.address = res.str();
|
||||
|
|
@ -550,28 +552,33 @@ void sidechain_net_handler_bitcoin::recreate_primary_wallet() {
|
|||
}
|
||||
}
|
||||
|
||||
bool sidechain_net_handler_bitcoin::connection_is_not_defined() const
|
||||
{
|
||||
return listener->connection_is_not_defined() && bitcoin_client->connection_is_not_defined();
|
||||
void sidechain_net_handler_bitcoin::process_deposits() {
|
||||
sidechain_net_handler::process_deposits();
|
||||
}
|
||||
|
||||
std::string sidechain_net_handler_bitcoin::create_multisignature_wallet( const std::vector<std::string> public_keys )
|
||||
{
|
||||
void sidechain_net_handler_bitcoin::process_deposit(const son_wallet_deposit_object& swdo) {
|
||||
}
|
||||
|
||||
void sidechain_net_handler_bitcoin::process_withdrawals() {
|
||||
sidechain_net_handler::process_withdrawals();
|
||||
}
|
||||
|
||||
void sidechain_net_handler_bitcoin::process_withdrawal(const son_wallet_withdraw_object& swwo) {
|
||||
}
|
||||
|
||||
std::string sidechain_net_handler_bitcoin::create_multisignature_wallet( const std::vector<std::string> public_keys ) {
|
||||
return bitcoin_client->add_multisig_address(public_keys);
|
||||
}
|
||||
|
||||
std::string sidechain_net_handler_bitcoin::transfer( const std::string& from, const std::string& to, const uint64_t amount )
|
||||
{
|
||||
std::string sidechain_net_handler_bitcoin::transfer( const std::string& from, const std::string& to, const uint64_t amount ) {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string sidechain_net_handler_bitcoin::sign_transaction( const std::string& transaction )
|
||||
{
|
||||
std::string sidechain_net_handler_bitcoin::sign_transaction( const std::string& transaction ) {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string sidechain_net_handler_bitcoin::send_transaction( const std::string& transaction )
|
||||
{
|
||||
std::string sidechain_net_handler_bitcoin::send_transaction( const std::string& transaction ) {
|
||||
return "";
|
||||
}
|
||||
|
||||
|
|
@ -740,17 +747,14 @@ std::string sidechain_net_handler_bitcoin::transfer_withdrawal_from_primary_wall
|
|||
}
|
||||
|
||||
void sidechain_net_handler_bitcoin::handle_event( const std::string& event_data ) {
|
||||
ilog("peerplays sidechain plugin: sidechain_net_handler_bitcoin::handle_event");
|
||||
ilog(" event_data: ${event_data}", ("event_data", event_data));
|
||||
|
||||
std::string block = bitcoin_client->receive_full_block( event_data );
|
||||
if( block != "" ) {
|
||||
const auto& vins = extract_info_from_block( block );
|
||||
|
||||
const auto& sidechain_addresses_idx = database.get_index_type<sidechain_address_index>().indices().get<by_sidechain_and_address>();
|
||||
const auto& sidechain_addresses_idx = database.get_index_type<sidechain_address_index>().indices().get<by_sidechain_and_deposit_address>();
|
||||
|
||||
for( const auto& v : vins ) {
|
||||
const auto& addr_itr = sidechain_addresses_idx.find(std::make_tuple(sidechain_type::bitcoin, v.address));
|
||||
const auto& addr_itr = sidechain_addresses_idx.find(std::make_tuple(sidechain, v.address));
|
||||
if ( addr_itr == sidechain_addresses_idx.end() )
|
||||
continue;
|
||||
|
||||
|
|
@ -765,16 +769,17 @@ void sidechain_net_handler_bitcoin::handle_event( const std::string& event_data
|
|||
sed.sidechain_transaction_id = v.out.hash_tx;
|
||||
sed.sidechain_from = "";
|
||||
sed.sidechain_to = v.address;
|
||||
sed.sidechain_currency = "BTC";
|
||||
sed.sidechain_amount = v.out.amount;
|
||||
sed.peerplays_from = addr_itr->sidechain_address_account;
|
||||
sed.peerplays_to = GRAPHENE_SON_ACCOUNT;
|
||||
sed.peerplays_asset = asset(sed.sidechain_amount / 1000); // For Bitcoin, the exchange rate is 1:1, for others, get the exchange rate from market
|
||||
sidechain_event_data_received(sed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<info_for_vin> sidechain_net_handler_bitcoin::extract_info_from_block( const std::string& _block )
|
||||
{
|
||||
std::vector<info_for_vin> sidechain_net_handler_bitcoin::extract_info_from_block( const std::string& _block ) {
|
||||
std::stringstream ss( _block );
|
||||
boost::property_tree::ptree block;
|
||||
boost::property_tree::read_json( ss, block );
|
||||
|
|
|
|||
|
|
@ -0,0 +1,99 @@
|
|||
#include <graphene/peerplays_sidechain/sidechain_net_handler_peerplays.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <thread>
|
||||
|
||||
#include <boost/algorithm/hex.hpp>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
|
||||
#include <fc/crypto/base64.hpp>
|
||||
#include <fc/log/logger.hpp>
|
||||
#include <fc/network/ip.hpp>
|
||||
|
||||
#include <graphene/chain/account_object.hpp>
|
||||
#include <graphene/chain/sidechain_address_object.hpp>
|
||||
#include <graphene/chain/son_info.hpp>
|
||||
#include <graphene/chain/son_wallet_object.hpp>
|
||||
#include <graphene/chain/protocol/son_wallet.hpp>
|
||||
|
||||
namespace graphene { namespace peerplays_sidechain {
|
||||
|
||||
sidechain_net_handler_peerplays::sidechain_net_handler_peerplays(peerplays_sidechain_plugin& _plugin, const boost::program_options::variables_map& options) :
|
||||
sidechain_net_handler(_plugin, options) {
|
||||
sidechain = sidechain_type::peerplays;
|
||||
plugin.database().applied_block.connect( [&] (const signed_block& b) { on_block_applied(b); } );
|
||||
}
|
||||
|
||||
sidechain_net_handler_peerplays::~sidechain_net_handler_peerplays() {
|
||||
}
|
||||
|
||||
void sidechain_net_handler_peerplays::recreate_primary_wallet() {
|
||||
}
|
||||
|
||||
void sidechain_net_handler_peerplays::process_deposits() {
|
||||
sidechain_net_handler::process_deposits();
|
||||
}
|
||||
|
||||
void sidechain_net_handler_peerplays::process_deposit(const son_wallet_deposit_object& swdo) {
|
||||
}
|
||||
|
||||
void sidechain_net_handler_peerplays::process_withdrawals() {
|
||||
sidechain_net_handler::process_withdrawals();
|
||||
}
|
||||
|
||||
void sidechain_net_handler_peerplays::process_withdrawal(const son_wallet_withdraw_object& swwo) {
|
||||
}
|
||||
|
||||
std::string sidechain_net_handler_peerplays::create_multisignature_wallet( const std::vector<std::string> public_keys ) {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string sidechain_net_handler_peerplays::transfer( const std::string& from, const std::string& to, const uint64_t amount ) {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string sidechain_net_handler_peerplays::sign_transaction( const std::string& transaction ) {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string sidechain_net_handler_peerplays::send_transaction( const std::string& transaction ) {
|
||||
return "";
|
||||
}
|
||||
|
||||
void sidechain_net_handler_peerplays::on_block_applied(const signed_block& b) {
|
||||
for (const auto& trx: b.transactions) {
|
||||
size_t operation_index = -1;
|
||||
for (auto op: trx.operations) {
|
||||
operation_index = operation_index + 1;
|
||||
if (op.which() == operation::tag<transfer_operation>::value){
|
||||
transfer_operation transfer_op = op.get<transfer_operation>();
|
||||
if (transfer_op.to != GRAPHENE_SON_ACCOUNT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "peerplays" << "-" << trx.id().str() << "-" << operation_index;
|
||||
std::string sidechain_uid = ss.str();
|
||||
|
||||
sidechain_event_data sed;
|
||||
sed.timestamp = plugin.database().head_block_time();
|
||||
sed.sidechain = sidechain_type::peerplays;
|
||||
sed.sidechain_uid = sidechain_uid;
|
||||
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_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(plugin.database()).symbol;
|
||||
sed.sidechain_amount = transfer_op.amount.amount;
|
||||
sed.peerplays_from = transfer_op.from;
|
||||
sed.peerplays_to = transfer_op.to;
|
||||
// We should calculate exchange rate between CORE/TEST and other Peerplays asset
|
||||
sed.peerplays_asset = asset(transfer_op.amount.amount / transfer_op.amount.asset_id(plugin.database()).options.core_exchange_rate.quote.amount);
|
||||
sidechain_event_data_received(sed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} } // graphene::peerplays_sidechain
|
||||
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
#include <fc/log/logger.hpp>
|
||||
#include <graphene/chain/son_wallet_object.hpp>
|
||||
#include <graphene/peerplays_sidechain/sidechain_net_handler_bitcoin.hpp>
|
||||
#include <graphene/peerplays_sidechain/sidechain_net_handler_peerplays.hpp>
|
||||
|
||||
namespace graphene { namespace peerplays_sidechain {
|
||||
|
||||
|
|
@ -26,6 +27,12 @@ bool sidechain_net_manager::create_handler(peerplays_sidechain::sidechain_type s
|
|||
ret_val = true;
|
||||
break;
|
||||
}
|
||||
case sidechain_type::peerplays: {
|
||||
std::unique_ptr<sidechain_net_handler> h = std::unique_ptr<sidechain_net_handler>(new sidechain_net_handler_peerplays(plugin, options));
|
||||
net_handlers.push_back(std::move(h));
|
||||
ret_val = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
|
|
@ -39,5 +46,17 @@ void sidechain_net_manager::recreate_primary_wallet() {
|
|||
}
|
||||
}
|
||||
|
||||
void sidechain_net_manager::process_deposits() {
|
||||
for ( size_t i = 0; i < net_handlers.size(); i++ ) {
|
||||
net_handlers.at(i)->process_deposits();
|
||||
}
|
||||
}
|
||||
|
||||
void sidechain_net_manager::process_withdrawals() {
|
||||
for ( size_t i = 0; i < net_handlers.size(); i++ ) {
|
||||
net_handlers.at(i)->process_withdrawals();
|
||||
}
|
||||
}
|
||||
|
||||
} } // graphene::peerplays_sidechain
|
||||
|
||||
|
|
|
|||
|
|
@ -1416,17 +1416,15 @@ class wallet_api
|
|||
*
|
||||
* @param account the name or id of the account who owns the address
|
||||
* @param sidechain a sidechain to whom address belongs
|
||||
* @param address sidechain address
|
||||
* @param private_key private key for sidechain address
|
||||
* @param public_key public key for sidechain address
|
||||
* @param deposit_address sidechain address for deposits
|
||||
* @param withdraw_address sidechain address for withdrawals
|
||||
* @param broadcast true to broadcast the transaction on the network
|
||||
* @returns the signed transaction adding sidechain address
|
||||
*/
|
||||
signed_transaction add_sidechain_address(string account,
|
||||
peerplays_sidechain::sidechain_type sidechain,
|
||||
string address,
|
||||
string private_key,
|
||||
string public_key,
|
||||
string deposit_address,
|
||||
string withdraw_address,
|
||||
bool broadcast = false);
|
||||
|
||||
/** Updates existing sidechain address owned by the given account for a given sidechain.
|
||||
|
|
@ -1435,17 +1433,15 @@ class wallet_api
|
|||
*
|
||||
* @param account the name or id of the account who owns the address
|
||||
* @param sidechain a sidechain to whom address belongs
|
||||
* @param address sidechain address
|
||||
* @param private_key private key for sidechain address
|
||||
* @param public_key public key for sidechain address
|
||||
* @param deposit_address sidechain address for deposits
|
||||
* @param withdraw_address sidechain address for withdrawals
|
||||
* @param broadcast true to broadcast the transaction on the network
|
||||
* @returns the signed transaction updating sidechain address
|
||||
*/
|
||||
signed_transaction update_sidechain_address(string account,
|
||||
peerplays_sidechain::sidechain_type sidechain,
|
||||
string address,
|
||||
string private_key,
|
||||
string public_key,
|
||||
string deposit_address,
|
||||
string withdraw_address,
|
||||
bool broadcast = false);
|
||||
|
||||
/** Deletes existing sidechain address owned by the given account for a given sidechain.
|
||||
|
|
|
|||
|
|
@ -1988,19 +1988,22 @@ public:
|
|||
});
|
||||
std::vector<fc::optional<son_object>> son_objects = _remote_db->get_sons(son_ids);
|
||||
vector<account_id_type> owners;
|
||||
owners.resize(son_objects.size());
|
||||
std::transform(son_objects.begin(), son_objects.end(), owners.begin(),
|
||||
[](const fc::optional<son_object>& obj) {
|
||||
FC_ASSERT(obj, "Invalid active SONs list in global properties.");
|
||||
return obj->son_account;
|
||||
});
|
||||
for(auto obj: son_objects)
|
||||
{
|
||||
if (obj)
|
||||
owners.push_back(obj->son_account);
|
||||
}
|
||||
vector<fc::optional<account_object>> accs = _remote_db->get_accounts(owners);
|
||||
std::remove_if(son_objects.begin(), son_objects.end(),
|
||||
[](const fc::optional<son_object>& obj) -> bool { return obj.valid(); });
|
||||
map<string, son_id_type> result;
|
||||
std::transform(accs.begin(), accs.end(), son_ids.begin(),
|
||||
std::transform(accs.begin(), accs.end(), son_objects.begin(),
|
||||
std::inserter(result, result.end()),
|
||||
[](fc::optional<account_object>& acct, son_id_type& sid) {
|
||||
[](fc::optional<account_object>& acct, fc::optional<son_object> son) {
|
||||
FC_ASSERT(acct, "Invalid active SONs list in global properties.");
|
||||
return std::make_pair<string, son_id_type>(string(acct->name), std::move(sid));
|
||||
if (son.valid())
|
||||
return std::make_pair<string, son_id_type>(string(acct->name), std::move(son->id));
|
||||
return std::make_pair<string, son_id_type>(string(acct->name), std::move(son_id_type()));
|
||||
});
|
||||
return result;
|
||||
} FC_CAPTURE_AND_RETHROW() }
|
||||
|
|
@ -2022,9 +2025,8 @@ public:
|
|||
|
||||
signed_transaction add_sidechain_address(string account,
|
||||
peerplays_sidechain::sidechain_type sidechain,
|
||||
string address,
|
||||
string private_key,
|
||||
string public_key,
|
||||
string deposit_address,
|
||||
string withdraw_address,
|
||||
bool broadcast /* = false */)
|
||||
{ try {
|
||||
account_id_type sidechain_address_account_id = get_account_id(account);
|
||||
|
|
@ -2032,9 +2034,8 @@ public:
|
|||
sidechain_address_add_operation op;
|
||||
op.sidechain_address_account = sidechain_address_account_id;
|
||||
op.sidechain = sidechain;
|
||||
op.address = address;
|
||||
op.private_key = private_key;
|
||||
op.public_key = public_key;
|
||||
op.deposit_address = deposit_address;
|
||||
op.withdraw_address = withdraw_address;
|
||||
|
||||
signed_transaction tx;
|
||||
tx.operations.push_back( op );
|
||||
|
|
@ -2046,9 +2047,8 @@ public:
|
|||
|
||||
signed_transaction update_sidechain_address(string account,
|
||||
peerplays_sidechain::sidechain_type sidechain,
|
||||
string address,
|
||||
string private_key,
|
||||
string public_key,
|
||||
string deposit_address,
|
||||
string withdraw_address,
|
||||
bool broadcast /* = false */)
|
||||
{ try {
|
||||
account_id_type sidechain_address_account_id = get_account_id(account);
|
||||
|
|
@ -2060,9 +2060,8 @@ public:
|
|||
op.sidechain_address_id = sao->id;
|
||||
op.sidechain_address_account = sidechain_address_account_id;
|
||||
op.sidechain = sidechain;
|
||||
op.address = address;
|
||||
op.private_key = private_key;
|
||||
op.public_key = public_key;
|
||||
op.deposit_address = deposit_address;
|
||||
op.withdraw_address = withdraw_address;
|
||||
|
||||
signed_transaction tx;
|
||||
tx.operations.push_back( op );
|
||||
|
|
@ -4501,22 +4500,20 @@ vector<optional<son_wallet_object>> wallet_api::get_son_wallets(uint32_t limit)
|
|||
|
||||
signed_transaction wallet_api::add_sidechain_address(string account,
|
||||
peerplays_sidechain::sidechain_type sidechain,
|
||||
string address,
|
||||
string private_key,
|
||||
string public_key,
|
||||
string deposit_address,
|
||||
string withdraw_address,
|
||||
bool broadcast /* = false */)
|
||||
{
|
||||
return my->add_sidechain_address(account, sidechain, address, private_key, public_key, broadcast);
|
||||
return my->add_sidechain_address(account, sidechain, deposit_address, withdraw_address, broadcast);
|
||||
}
|
||||
|
||||
signed_transaction wallet_api::update_sidechain_address(string account,
|
||||
peerplays_sidechain::sidechain_type sidechain,
|
||||
string address,
|
||||
string private_key,
|
||||
string public_key,
|
||||
string deposit_address,
|
||||
string withdraw_address,
|
||||
bool broadcast /* = false */)
|
||||
{
|
||||
return my->update_sidechain_address(account, sidechain, address, private_key, public_key, broadcast);
|
||||
return my->update_sidechain_address(account, sidechain, deposit_address, withdraw_address, broadcast);
|
||||
}
|
||||
|
||||
signed_transaction wallet_api::delete_sidechain_address(string account,
|
||||
|
|
|
|||
|
|
@ -45,7 +45,8 @@
|
|||
#include <graphene/chain/game_object.hpp>
|
||||
#include <graphene/chain/son_object.hpp>
|
||||
#include <graphene/chain/son_wallet_object.hpp>
|
||||
#include <graphene/chain/son_wallet_transfer_object.hpp>
|
||||
#include <graphene/chain/son_wallet_deposit_object.hpp>
|
||||
#include <graphene/chain/son_wallet_withdraw_object.hpp>
|
||||
#include <graphene/chain/sidechain_address_object.hpp>
|
||||
#include <graphene/chain/sidechain_transaction_object.hpp>
|
||||
|
||||
|
|
|
|||
|
|
@ -650,6 +650,9 @@ BOOST_FIXTURE_TEST_CASE( cli_list_active_sons, cli_fixture )
|
|||
BOOST_CHECK(active_sons.find(name) != active_sons.end());
|
||||
}
|
||||
|
||||
// check list_active_son after SON deletion
|
||||
con.wallet_api_ptr->delete_son("sonaccount1", true);
|
||||
BOOST_CHECK_NO_THROW(con.wallet_api_ptr->list_active_sons());
|
||||
} catch( fc::exception& e ) {
|
||||
BOOST_TEST_MESSAGE("SON cli wallet tests exception");
|
||||
edump((e.to_detail_string()));
|
||||
|
|
|
|||
|
|
@ -220,6 +220,108 @@ BOOST_AUTO_TEST_CASE(pw_separate_sign)
|
|||
BOOST_CHECK(fc::to_hex((char*)&partially_signed_tx[0], partially_signed_tx.size()) == "020000000001016617ba8fec01d942ef23dfa26c99badceb682050c5e67ec5b76de65dd6368a500000000000ffffffff01384a0000000000002200201650311c6711dad4d81f3d0b4695f814d1ac925b35783f47f0a8414f4905282f10473044022028cf6df7ed5c2761d7aa2af20717c8b5ace168a7800d6a566f2c1ae28160cae502205e01a3d91f5b9870577e36fbc26ce0cecc3e628cc376c7016364ec3f370703140147304402205c9a88cbe41eb9c6a16ba1d747456222cbe951d04739d21309ef0c0cf00727f202202d06db830ee5823882c7b6f82b708111a8f37741878896cd3558fb91efe8076401473044022009c3184fc0385eb7ed8dc0374791cbdace0eff0dc27dd80ac68f8cb81110f700022042267e8a8788c314347234ea10db6c1ec21a2d423b784cbfbaadf3b2393c44630147304402202363ce306570dc0bbf6d18d41b67c6488a014a91d8e24c03670b4f65523aca12022029d04c114b8e93d982cadee89d80bb25c5c8bc437d6cd2bfce8e0d83a08d14410148304502210087b4742e5cf9c77ca9f99928e7c7087e7d786e09216485628509e4e0b2f29d7e02207daf2eaee9fe8bf117074be137b7ae4b8503a4f6d263424e8e6a16405d5b723c0147304402204f1c3ed8cf595bfaf79d90f4c55c04c17bb6d446e3b9beca7ee6ee7895c6b752022022ac032f219a81b2845d0a1abfb904e40036a3ad332e7dfada6fda21ef7080b501483045022100d020eca4ba1aa77de9caf98f3a29f74f55268276860b9fa35fa16cfc00219dd8022028237de6ad063116cf8182d2dd45a09cb90c2ec8104d793eb3635a1290027cd6014730440220322193b0feba7356651465b86463c7619cd3d96729df6242e9571c74ff1c3c2902206e1de8e77b71c7b6031a934b52321134b6a8d138e2124e90f6345decbd543efb01483045022100d70ade49b3f17812785a41711e107b27c3d4981f8e12253629c07ec46ee511af02203e1ea9059ed9165eeff827002c7399a30c478a9b6f2b958621bfbc6713ab4dd30147304402206f7f10d9993c7019360276bbe790ab587adadeab08088593a9a0c56524aca4df02207c147fe2e51484801a4e059e611e7514729d685a5df892dcf02ba59d455e678101483045022100d5071b8039364bfaa53ef5e22206f773539b082f28bd1fbaaea995fa28aae0f5022056edf7a7bdd8a9a54273a667be5bcd11191fc871798fb44f6e1e35c95d86a81201483045022100a39f8ffbcd9c3f0591fc731a9856c8e024041017cba20c9935f13e4abcf9e9dc0220786823b8cd55664ff9ad6277899aacfd56fa8e48c38881482418b7d50ca27211014730440220361d3b87fcc2b1c12a9e7c684c78192ccb7fe51b90c281b7058384b0b036927a0220434c9b403ee3802b4e5b53feb9bb37d2a9d8746c3688da993549dd9d9954c6800147304402206dc4c3a4407fe9cbffb724928aa0597148c14a20d0d7fbb36ad5d3e2a3abf85e022039ef7baebbf08494495a038b009c6d4ff4b91c38db840673b87f6c27c3b53e7e01483045022100cadac495ea78d0ce9678a4334b8c43f7fafeea5a59413cc2a0144addb63485f9022078ca133e020e3afd0e79936337afefc21d84d3839f5a225a0f3d3eebc15f959901fd5c02007c21030e88484f2bb5dcfc0b326e9eb565c27c8291efb064d060d226916857a2676e62ac635193687c2102151ad794a3aeb3cf9c190120da3d13d36cd8bdf21ca1ccb15debd61c601314b0ac635293687c2103b45a5955ea7847d121225c752edaeb4a5d731a056a951a876caaf6d1f69adb7dac635393687c2102def03a6ffade4ffb0017c8d93859a247badd60e2d76d00e2a3713f6621932ec1ac635493687c21035f17aa7d58b8c3ee0d87240fded52b27f3f12768a0a54ba2595e0a929dd87155ac635593687c2103c8582ac6b0bd20cc1b02c6a86bad2ea10cadb758fedd754ba0d97be85b63b5a7ac635693687c21028148a1f9669fc4471e76f7a371d7cc0563b26e0821d9633fd37649744ff54edaac635793687c2102f0313701b0035f0365a59ce1a3d7ae7045e1f2fb25c4656c08071e5baf51483dac635893687c21024c4c25d08173b3c4d4e1375f8107fd7040c2dc0691ae1bf6fe82b8c88a85185fac635993687c210360fe2daa8661a3d25d0df79875d70b1c3d443ade731caafda7488cb68b4071b0ac635a93687c210250e41a6a4abd7b0b3a49eaec24a6fafa99e5aa7b1e3a5aabe60664276df3d937ac635b93687c2103045a32125930ca103c7d7c79b6f379754796cd4ea7fb0059da926e415e3877d3ac635c93687c210344943249d7ca9b47316fef0c2a413dda3a75416a449a29f310ab7fc9d052ed70ac635d93687c2103c62967320b63df5136ff1ef4c7959ef5917ee5a44f75c83e870bc488143d4d69ac635e93687c21020429f776e15770e4dc52bd6f72e6ed6908d51de1c4a64878433c4e3860a48dc4ac635f93680150a000000000");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(pw_separate_sign2)
|
||||
{
|
||||
// key set for the old Primary Wallet
|
||||
std::vector<fc::ecc::private_key> priv_old;
|
||||
for(unsigned i = 0; i < 15; ++i)
|
||||
{
|
||||
const char* seed = reinterpret_cast<const char*>(&i);
|
||||
fc::sha256 h = fc::sha256::hash(seed, sizeof(i));
|
||||
priv_old.push_back(fc::ecc::private_key::generate_from_seed(h));
|
||||
}
|
||||
// print old keys
|
||||
for(auto key: priv_old)
|
||||
{
|
||||
fc::sha256 secret = key.get_secret();
|
||||
bytes data({239});
|
||||
data.insert(data.end(), secret.data(), secret.data() + secret.data_size());
|
||||
fc::sha256 cs = fc::sha256::hash(fc::sha256::hash((char*)&data[0], data.size()));
|
||||
data.insert(data.end(), cs.data(), cs.data() + 4);
|
||||
}
|
||||
std::vector<fc::ecc::public_key> pub_old;
|
||||
for(auto& key: priv_old)
|
||||
pub_old.push_back(key.get_public_key());
|
||||
// old key weights
|
||||
std::vector<std::pair<fc::ecc::public_key, int> > weights_old;
|
||||
for(unsigned i = 0; i < 15; ++i)
|
||||
weights_old.push_back(std::make_pair(pub_old[i], i + 1));
|
||||
// redeem script for old PW
|
||||
bytes redeem_old =generate_redeem_script(weights_old);
|
||||
|
||||
// Old PW address
|
||||
std::string old_pw = p2wsh_address_from_redeem_script(redeem_old, bitcoin_network::testnet);
|
||||
// This address was filled with testnet transaction 508a36d65de66db7c57ee6c5502068ebdcba996ca2df23ef42d901ec8fba1766
|
||||
BOOST_REQUIRE(old_pw == "tb1qfhstznulf5cmjzahlkmnuuvs0tkjtwjlme3ugz8jzfjanf8h5rwsp45t7e");
|
||||
|
||||
bytes scriptPubKey = lock_script_for_redeem_script(redeem_old);
|
||||
|
||||
// key set for the new Primary Wallet
|
||||
std::vector<fc::ecc::private_key> priv_new;
|
||||
for(unsigned i = 16; i < 31; ++i)
|
||||
{
|
||||
const char* seed = reinterpret_cast<const char*>(&i);
|
||||
fc::sha256 h = fc::sha256::hash(seed, sizeof(i));
|
||||
priv_new.push_back(fc::ecc::private_key::generate_from_seed(h));
|
||||
}
|
||||
std::vector<fc::ecc::public_key> pub_new;
|
||||
for(auto& key: priv_new)
|
||||
pub_new.push_back(key.get_public_key());
|
||||
// new key weights
|
||||
std::vector<std::pair<fc::ecc::public_key, int> > weights_new;
|
||||
for(unsigned i = 0; i < 15; ++i)
|
||||
weights_new.push_back(std::make_pair(pub_new[i], 16 - i));
|
||||
// redeem script for new PW
|
||||
bytes redeem_new =generate_redeem_script(weights_new);
|
||||
// New PW address
|
||||
std::string new_pw = p2wsh_address_from_redeem_script(redeem_new, bitcoin_network::testnet);
|
||||
BOOST_REQUIRE(new_pw == "tb1qzegrz8r8z8ddfkql8595d90czng6eyjmx4ur73ls4pq57jg99qhsh9fd2y");
|
||||
|
||||
// try to move funds from old wallet to new one
|
||||
|
||||
// get unspent outputs for old wallet with list_uspent (address should be
|
||||
// added to wallet with import_address before). It should return
|
||||
// 1 UTXO: [508a36d65de66db7c57ee6c5502068ebdcba996ca2df23ef42d901ec8fba1766:0]
|
||||
// with 20000 satoshis
|
||||
// So, we creating a raw transaction with 1 input and one output that gets
|
||||
// 20000 - fee satoshis with createrawtransaction call (bitcoin_rpc_client::prepare_tx)
|
||||
// Here we just serialize the transaction without scriptSig in inputs then sign it.
|
||||
btc_outpoint outpoint;
|
||||
outpoint.hash = fc::uint256("508a36d65de66db7c57ee6c5502068ebdcba996ca2df23ef42d901ec8fba1766");
|
||||
// reverse hash due to the different from_hex algo
|
||||
std::reverse(outpoint.hash.data(), outpoint.hash.data() + outpoint.hash.data_size());
|
||||
outpoint.n = 0;
|
||||
btc_in input;
|
||||
input.prevout = outpoint;
|
||||
input.nSequence = 0xffffffff;
|
||||
btc_out output;
|
||||
output.nValue = 19000;
|
||||
output.scriptPubKey = lock_script_for_redeem_script(redeem_new);
|
||||
btc_tx tx;
|
||||
tx.nVersion = 2;
|
||||
tx.nLockTime = 0;
|
||||
tx.hasWitness = false;
|
||||
tx.vin.push_back(input);
|
||||
tx.vout.push_back(output);
|
||||
bytes unsigned_tx;
|
||||
tx.to_bytes(unsigned_tx);
|
||||
std::vector<uint64_t> in_amounts({20000});
|
||||
|
||||
// gather all signatures from all SONs separatelly
|
||||
std::vector<std::vector<bytes> > signature_set;
|
||||
for(auto key: priv_old)
|
||||
{
|
||||
std::vector<bytes> signatures = signatures_for_raw_transaction(unsigned_tx, in_amounts, redeem_old, key);
|
||||
signature_set.push_back(signatures);
|
||||
}
|
||||
|
||||
// create signed tx with all signatures
|
||||
bytes signed_tx = add_signatures_to_unsigned_tx(unsigned_tx, signature_set, redeem_old);
|
||||
|
||||
// now this is real testnet tx with id 1734a2f6192c3953c90f9fd7f69eba16eeb0922207f81f3af32d6534a6f8e850
|
||||
BOOST_CHECK(fc::to_hex((char*)&signed_tx[0], signed_tx.size()) == "020000000001016617ba8fec01d942ef23dfa26c99badceb682050c5e67ec5b76de65dd6368a500000000000ffffffff01384a0000000000002200201650311c6711dad4d81f3d0b4695f814d1ac925b35783f47f0a8414f4905282f10473044022028cf6df7ed5c2761d7aa2af20717c8b5ace168a7800d6a566f2c1ae28160cae502205e01a3d91f5b9870577e36fbc26ce0cecc3e628cc376c7016364ec3f370703140147304402205c9a88cbe41eb9c6a16ba1d747456222cbe951d04739d21309ef0c0cf00727f202202d06db830ee5823882c7b6f82b708111a8f37741878896cd3558fb91efe8076401473044022009c3184fc0385eb7ed8dc0374791cbdace0eff0dc27dd80ac68f8cb81110f700022042267e8a8788c314347234ea10db6c1ec21a2d423b784cbfbaadf3b2393c44630147304402202363ce306570dc0bbf6d18d41b67c6488a014a91d8e24c03670b4f65523aca12022029d04c114b8e93d982cadee89d80bb25c5c8bc437d6cd2bfce8e0d83a08d14410148304502210087b4742e5cf9c77ca9f99928e7c7087e7d786e09216485628509e4e0b2f29d7e02207daf2eaee9fe8bf117074be137b7ae4b8503a4f6d263424e8e6a16405d5b723c0147304402204f1c3ed8cf595bfaf79d90f4c55c04c17bb6d446e3b9beca7ee6ee7895c6b752022022ac032f219a81b2845d0a1abfb904e40036a3ad332e7dfada6fda21ef7080b501483045022100d020eca4ba1aa77de9caf98f3a29f74f55268276860b9fa35fa16cfc00219dd8022028237de6ad063116cf8182d2dd45a09cb90c2ec8104d793eb3635a1290027cd6014730440220322193b0feba7356651465b86463c7619cd3d96729df6242e9571c74ff1c3c2902206e1de8e77b71c7b6031a934b52321134b6a8d138e2124e90f6345decbd543efb01483045022100d70ade49b3f17812785a41711e107b27c3d4981f8e12253629c07ec46ee511af02203e1ea9059ed9165eeff827002c7399a30c478a9b6f2b958621bfbc6713ab4dd30147304402206f7f10d9993c7019360276bbe790ab587adadeab08088593a9a0c56524aca4df02207c147fe2e51484801a4e059e611e7514729d685a5df892dcf02ba59d455e678101483045022100d5071b8039364bfaa53ef5e22206f773539b082f28bd1fbaaea995fa28aae0f5022056edf7a7bdd8a9a54273a667be5bcd11191fc871798fb44f6e1e35c95d86a81201483045022100a39f8ffbcd9c3f0591fc731a9856c8e024041017cba20c9935f13e4abcf9e9dc0220786823b8cd55664ff9ad6277899aacfd56fa8e48c38881482418b7d50ca27211014730440220361d3b87fcc2b1c12a9e7c684c78192ccb7fe51b90c281b7058384b0b036927a0220434c9b403ee3802b4e5b53feb9bb37d2a9d8746c3688da993549dd9d9954c6800147304402206dc4c3a4407fe9cbffb724928aa0597148c14a20d0d7fbb36ad5d3e2a3abf85e022039ef7baebbf08494495a038b009c6d4ff4b91c38db840673b87f6c27c3b53e7e01483045022100cadac495ea78d0ce9678a4334b8c43f7fafeea5a59413cc2a0144addb63485f9022078ca133e020e3afd0e79936337afefc21d84d3839f5a225a0f3d3eebc15f959901fd5c02007c21030e88484f2bb5dcfc0b326e9eb565c27c8291efb064d060d226916857a2676e62ac635193687c2102151ad794a3aeb3cf9c190120da3d13d36cd8bdf21ca1ccb15debd61c601314b0ac635293687c2103b45a5955ea7847d121225c752edaeb4a5d731a056a951a876caaf6d1f69adb7dac635393687c2102def03a6ffade4ffb0017c8d93859a247badd60e2d76d00e2a3713f6621932ec1ac635493687c21035f17aa7d58b8c3ee0d87240fded52b27f3f12768a0a54ba2595e0a929dd87155ac635593687c2103c8582ac6b0bd20cc1b02c6a86bad2ea10cadb758fedd754ba0d97be85b63b5a7ac635693687c21028148a1f9669fc4471e76f7a371d7cc0563b26e0821d9633fd37649744ff54edaac635793687c2102f0313701b0035f0365a59ce1a3d7ae7045e1f2fb25c4656c08071e5baf51483dac635893687c21024c4c25d08173b3c4d4e1375f8107fd7040c2dc0691ae1bf6fe82b8c88a85185fac635993687c210360fe2daa8661a3d25d0df79875d70b1c3d443ade731caafda7488cb68b4071b0ac635a93687c210250e41a6a4abd7b0b3a49eaec24a6fafa99e5aa7b1e3a5aabe60664276df3d937ac635b93687c2103045a32125930ca103c7d7c79b6f379754796cd4ea7fb0059da926e415e3877d3ac635c93687c210344943249d7ca9b47316fef0c2a413dda3a75416a449a29f310ab7fc9d052ed70ac635d93687c2103c62967320b63df5136ff1ef4c7959ef5917ee5a44f75c83e870bc488143d4d69ac635e93687c21020429f776e15770e4dc52bd6f72e6ed6908d51de1c4a64878433c4e3860a48dc4ac635f93680150a000000000");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(pw_partially_sign)
|
||||
{
|
||||
// key set for the old Primary Wallet
|
||||
|
|
|
|||
0
tests/tests/history_api_tests.cpp
Executable file → Normal file
0
tests/tests/history_api_tests.cpp
Executable file → Normal file
|
|
@ -30,9 +30,8 @@ BOOST_AUTO_TEST_CASE( sidechain_address_add_test ) {
|
|||
|
||||
op.sidechain_address_account = alice_id;
|
||||
op.sidechain = graphene::peerplays_sidechain::sidechain_type::bitcoin;
|
||||
op.address = "address";
|
||||
op.private_key = "private_key";
|
||||
op.public_key = "public_key";
|
||||
op.deposit_address = "deposit_address";
|
||||
op.withdraw_address = "withdraw_address";
|
||||
|
||||
trx.operations.push_back(op);
|
||||
sign(trx, alice_private_key);
|
||||
|
|
@ -48,9 +47,8 @@ BOOST_AUTO_TEST_CASE( sidechain_address_add_test ) {
|
|||
BOOST_REQUIRE( obj != idx.end() );
|
||||
BOOST_CHECK( obj->sidechain_address_account == alice_id );
|
||||
BOOST_CHECK( obj->sidechain == graphene::peerplays_sidechain::sidechain_type::bitcoin );
|
||||
BOOST_CHECK( obj->address == "address" );
|
||||
BOOST_CHECK( obj->private_key == "private_key" );
|
||||
BOOST_CHECK( obj->public_key == "public_key" );
|
||||
BOOST_CHECK( obj->deposit_address == "deposit_address" );
|
||||
BOOST_CHECK( obj->withdraw_address == "withdraw_address" );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( sidechain_address_update_test ) {
|
||||
|
|
@ -66,9 +64,8 @@ BOOST_AUTO_TEST_CASE( sidechain_address_update_test ) {
|
|||
auto obj = idx.find( boost::make_tuple( alice_id, graphene::peerplays_sidechain::sidechain_type::bitcoin ) );
|
||||
BOOST_REQUIRE( obj != idx.end() );
|
||||
|
||||
std::string new_address = "new_address";
|
||||
std::string new_private_key = "new_private_key";
|
||||
std::string new_public_key = "new_public_key";
|
||||
std::string new_deposit_address = "new_deposit_address";
|
||||
std::string new_withdraw_address = "new_withdraw_address";
|
||||
|
||||
{
|
||||
BOOST_TEST_MESSAGE("Send sidechain_address_update_operation");
|
||||
|
|
@ -77,9 +74,8 @@ BOOST_AUTO_TEST_CASE( sidechain_address_update_test ) {
|
|||
op.sidechain_address_id = sidechain_address_id_type(0);
|
||||
op.sidechain_address_account = obj->sidechain_address_account;
|
||||
op.sidechain = obj->sidechain;
|
||||
op.address = new_address;
|
||||
op.private_key = new_private_key;
|
||||
op.public_key = new_public_key;
|
||||
op.deposit_address = new_deposit_address;
|
||||
op.withdraw_address = new_withdraw_address;
|
||||
|
||||
trx.operations.push_back(op);
|
||||
sign(trx, alice_private_key);
|
||||
|
|
@ -96,9 +92,8 @@ BOOST_AUTO_TEST_CASE( sidechain_address_update_test ) {
|
|||
BOOST_REQUIRE( obj != idx.end() );
|
||||
BOOST_CHECK( obj->sidechain_address_account == obj->sidechain_address_account );
|
||||
BOOST_CHECK( obj->sidechain == obj->sidechain );
|
||||
BOOST_CHECK( obj->address == new_address );
|
||||
BOOST_CHECK( obj->private_key == new_private_key );
|
||||
BOOST_CHECK( obj->public_key == new_public_key );
|
||||
BOOST_CHECK( obj->deposit_address == new_deposit_address );
|
||||
BOOST_CHECK( obj->withdraw_address == new_withdraw_address );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -843,35 +843,12 @@ BOOST_AUTO_TEST_CASE( son_report_down_test ) {
|
|||
|
||||
BOOST_CHECK( obj->status == son_status::active);
|
||||
|
||||
const auto& son_btc_account = db.create<account_object>( [&]( account_object& obj ) {
|
||||
obj.name = "son_btc_account";
|
||||
obj.statistics = db.create<account_statistics_object>([&]( account_statistics_object& acc_stat ){ acc_stat.owner = obj.id; }).id;
|
||||
obj.membership_expiration_date = time_point_sec::maximum();
|
||||
obj.network_fee_percentage = GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE;
|
||||
obj.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT - GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE;
|
||||
|
||||
obj.owner.add_authority( bob_id, 1 );
|
||||
obj.active.add_authority( bob_id, 1 );
|
||||
obj.active.weight_threshold = 1;
|
||||
obj.owner.weight_threshold = 1;
|
||||
});
|
||||
|
||||
db.modify( db.get_global_properties(), [&]( global_property_object& _gpo )
|
||||
{
|
||||
_gpo.parameters.extensions.value.son_pay_daily_max = 200;
|
||||
_gpo.parameters.witness_pay_per_block = 0;
|
||||
|
||||
_gpo.parameters.extensions.value.son_btc_account = son_btc_account.get_id();
|
||||
if( _gpo.pending_parameters )
|
||||
_gpo.pending_parameters->extensions.value.son_btc_account = son_btc_account.get_id();
|
||||
});
|
||||
|
||||
{
|
||||
// Check that transaction fails if down_ts < last_active_timestamp
|
||||
generate_block();
|
||||
// Send Report Down Operation for an active status SON
|
||||
son_report_down_operation op;
|
||||
op.payer = db.get_global_properties().parameters.get_son_btc_account_id();
|
||||
op.payer = GRAPHENE_SON_ACCOUNT;
|
||||
op.son_id = son_id_type(0);
|
||||
op.down_ts = fc::time_point_sec(son_stats_obj->last_active_timestamp - fc::seconds(1));
|
||||
|
||||
|
|
@ -884,7 +861,7 @@ BOOST_AUTO_TEST_CASE( son_report_down_test ) {
|
|||
}
|
||||
|
||||
{
|
||||
// Check that transaction fails if payer is not son_btc_account.
|
||||
// Check that transaction fails if payer is not GRAPHENE_SON_ACCOUNT.
|
||||
generate_block();
|
||||
// Send Report Down Operation for an active status SON
|
||||
son_report_down_operation op;
|
||||
|
|
@ -901,11 +878,11 @@ BOOST_AUTO_TEST_CASE( son_report_down_test ) {
|
|||
}
|
||||
|
||||
{
|
||||
// Check that transaction succeeds after getting enough approvals on son_btc_account.
|
||||
// Check that transaction succeeds after getting enough approvals on GRAPHENE_SON_ACCOUNT.
|
||||
generate_block();
|
||||
// Send Report Down Operation for an active status SON
|
||||
son_report_down_operation op;
|
||||
op.payer = db.get_global_properties().parameters.get_son_btc_account_id();
|
||||
op.payer = GRAPHENE_SON_ACCOUNT;
|
||||
op.son_id = son_id_type(0);
|
||||
op.down_ts = son_stats_obj->last_active_timestamp;
|
||||
|
||||
|
|
@ -925,7 +902,7 @@ BOOST_AUTO_TEST_CASE( son_report_down_test ) {
|
|||
generate_block();
|
||||
// Send Report Down Operation for an active status SON
|
||||
son_report_down_operation op;
|
||||
op.payer = db.get_global_properties().parameters.get_son_btc_account_id();
|
||||
op.payer = GRAPHENE_SON_ACCOUNT;
|
||||
op.son_id = son_id_type(0);
|
||||
op.down_ts = son_stats_obj->last_active_timestamp;
|
||||
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ BOOST_AUTO_TEST_CASE( son_wallet_recreate_test ) {
|
|||
|
||||
son_wallet_recreate_operation op;
|
||||
|
||||
op.payer = db.get_global_properties().parameters.get_son_btc_account_id();
|
||||
op.payer = GRAPHENE_SON_ACCOUNT;
|
||||
|
||||
{
|
||||
son_info si;
|
||||
|
|
@ -199,7 +199,7 @@ BOOST_AUTO_TEST_CASE( son_wallet_update_test ) {
|
|||
|
||||
son_wallet_update_operation op;
|
||||
|
||||
op.payer = db.get_global_properties().parameters.get_son_btc_account_id();
|
||||
op.payer = GRAPHENE_SON_ACCOUNT;
|
||||
op.son_wallet_id = son_wallet_id_type(0);
|
||||
op.sidechain = graphene::peerplays_sidechain::sidechain_type::bitcoin;
|
||||
op.address = "bitcoin address";
|
||||
|
|
|
|||
Loading…
Reference in a new issue