PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal
This commit is contained in:
parent
95b515c09a
commit
afcb1ace1b
11 changed files with 100 additions and 120 deletions
|
|
@ -316,15 +316,12 @@ struct get_impacted_account_visitor
|
||||||
void operator()( const son_maintenance_operation& op ){
|
void operator()( const son_maintenance_operation& op ){
|
||||||
_impacted.insert( op.owner_account );
|
_impacted.insert( op.owner_account );
|
||||||
}
|
}
|
||||||
void operator()( const son_wallet_create_operation& op ){
|
void operator()( const son_wallet_recreate_operation& op ){
|
||||||
_impacted.insert( op.payer );
|
_impacted.insert( op.payer );
|
||||||
}
|
}
|
||||||
void operator()( const son_wallet_update_operation& op ){
|
void operator()( const son_wallet_update_operation& op ){
|
||||||
_impacted.insert( op.payer );
|
_impacted.insert( op.payer );
|
||||||
}
|
}
|
||||||
void operator()( const son_wallet_close_operation& op ){
|
|
||||||
_impacted.insert( op.payer );
|
|
||||||
}
|
|
||||||
void operator()( const son_wallet_transfer_create_operation& op ){
|
void operator()( const son_wallet_transfer_create_operation& op ){
|
||||||
_impacted.insert( op.payer );
|
_impacted.insert( op.payer );
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -256,9 +256,8 @@ void database::initialize_evaluators()
|
||||||
register_evaluator<son_heartbeat_evaluator>();
|
register_evaluator<son_heartbeat_evaluator>();
|
||||||
register_evaluator<son_report_down_evaluator>();
|
register_evaluator<son_report_down_evaluator>();
|
||||||
register_evaluator<son_maintenance_evaluator>();
|
register_evaluator<son_maintenance_evaluator>();
|
||||||
register_evaluator<create_son_wallet_evaluator>();
|
register_evaluator<recreate_son_wallet_evaluator>();
|
||||||
register_evaluator<update_son_wallet_evaluator>();
|
register_evaluator<update_son_wallet_evaluator>();
|
||||||
register_evaluator<close_son_wallet_evaluator>();
|
|
||||||
register_evaluator<create_son_wallet_transfer_evaluator>();
|
register_evaluator<create_son_wallet_transfer_evaluator>();
|
||||||
register_evaluator<add_sidechain_address_evaluator>();
|
register_evaluator<add_sidechain_address_evaluator>();
|
||||||
register_evaluator<update_sidechain_address_evaluator>();
|
register_evaluator<update_sidechain_address_evaluator>();
|
||||||
|
|
|
||||||
|
|
@ -471,21 +471,39 @@ void database::update_active_sons()
|
||||||
} else {
|
} else {
|
||||||
ilog( "Active SONs set CHANGED" );
|
ilog( "Active SONs set CHANGED" );
|
||||||
|
|
||||||
|
bool should_recreate_pw = true;
|
||||||
|
|
||||||
// Expire for current son_wallet_object wallet, if exists
|
// Expire for current son_wallet_object wallet, if exists
|
||||||
const auto& idx_swi = get_index_type<son_wallet_index>().indices().get<by_id>();
|
const auto& idx_swi = get_index_type<son_wallet_index>().indices().get<by_id>();
|
||||||
auto obj = idx_swi.rbegin();
|
auto obj = idx_swi.rbegin();
|
||||||
if (obj != idx_swi.rend()) {
|
if (obj != idx_swi.rend()) {
|
||||||
modify(*obj, [&, obj](son_wallet_object &swo) {
|
// Compare current wallet SONs and to-be lists of active sons
|
||||||
swo.expires = head_block_time();
|
auto cur_wallet_sons = (*obj).sons;
|
||||||
});
|
|
||||||
|
bool wallet_son_sets_equal = (cur_wallet_sons.size() == new_active_sons.size());
|
||||||
|
if (wallet_son_sets_equal) {
|
||||||
|
for( size_t i = 0; i < cur_wallet_sons.size(); i++ ) {
|
||||||
|
wallet_son_sets_equal = wallet_son_sets_equal && cur_wallet_sons.at(i) == new_active_sons.at(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
should_recreate_pw = !wallet_son_sets_equal;
|
||||||
|
|
||||||
|
if (should_recreate_pw) {
|
||||||
|
modify(*obj, [&, obj](son_wallet_object &swo) {
|
||||||
|
swo.expires = head_block_time();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create new son_wallet_object, to initiate wallet recreation
|
if (should_recreate_pw) {
|
||||||
create<son_wallet_object>( [&]( son_wallet_object& obj ) {
|
// Create new son_wallet_object, to initiate wallet recreation
|
||||||
obj.valid_from = head_block_time();
|
create<son_wallet_object>( [&]( son_wallet_object& obj ) {
|
||||||
obj.expires = time_point_sec::maximum();
|
obj.valid_from = head_block_time();
|
||||||
obj.sons.insert(obj.sons.end(), new_active_sons.begin(), new_active_sons.end());
|
obj.expires = time_point_sec::maximum();
|
||||||
});
|
obj.sons.insert(obj.sons.end(), new_active_sons.begin(), new_active_sons.end());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
vector<son_info> sons_to_remove;
|
vector<son_info> sons_to_remove;
|
||||||
// find all cur_active_sons members that is not in new_active_sons
|
// find all cur_active_sons members that is not in new_active_sons
|
||||||
|
|
|
||||||
|
|
@ -303,15 +303,12 @@ struct get_impacted_account_visitor
|
||||||
void operator()( const son_maintenance_operation& op ) {
|
void operator()( const son_maintenance_operation& op ) {
|
||||||
_impacted.insert( op.owner_account );
|
_impacted.insert( op.owner_account );
|
||||||
}
|
}
|
||||||
void operator()( const son_wallet_create_operation& op ) {
|
void operator()( const son_wallet_recreate_operation& op ) {
|
||||||
_impacted.insert( op.payer );
|
_impacted.insert( op.payer );
|
||||||
}
|
}
|
||||||
void operator()( const son_wallet_update_operation& op ) {
|
void operator()( const son_wallet_update_operation& op ) {
|
||||||
_impacted.insert( op.payer );
|
_impacted.insert( op.payer );
|
||||||
}
|
}
|
||||||
void operator()( const son_wallet_close_operation& op ) {
|
|
||||||
_impacted.insert( op.payer );
|
|
||||||
}
|
|
||||||
void operator()( const son_wallet_transfer_create_operation& op ) {
|
void operator()( const son_wallet_transfer_create_operation& op ) {
|
||||||
_impacted.insert( op.payer );
|
_impacted.insert( op.payer );
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -146,9 +146,8 @@ namespace graphene { namespace chain {
|
||||||
son_heartbeat_operation,
|
son_heartbeat_operation,
|
||||||
son_report_down_operation,
|
son_report_down_operation,
|
||||||
son_maintenance_operation,
|
son_maintenance_operation,
|
||||||
son_wallet_create_operation,
|
son_wallet_recreate_operation,
|
||||||
son_wallet_update_operation,
|
son_wallet_update_operation,
|
||||||
son_wallet_close_operation,
|
|
||||||
son_wallet_transfer_create_operation,
|
son_wallet_transfer_create_operation,
|
||||||
sidechain_address_add_operation,
|
sidechain_address_add_operation,
|
||||||
sidechain_address_update_operation,
|
sidechain_address_update_operation,
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,18 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <graphene/chain/protocol/base.hpp>
|
#include <graphene/chain/protocol/base.hpp>
|
||||||
|
#include <graphene/chain/son_info.hpp>
|
||||||
|
|
||||||
namespace graphene { namespace chain {
|
namespace graphene { namespace chain {
|
||||||
|
|
||||||
struct son_wallet_create_operation : public base_operation
|
struct son_wallet_recreate_operation : public base_operation
|
||||||
{
|
{
|
||||||
struct fee_parameters_type { uint64_t fee = 0; };
|
struct fee_parameters_type { uint64_t fee = 0; };
|
||||||
|
|
||||||
asset fee;
|
asset fee;
|
||||||
account_id_type payer;
|
account_id_type payer;
|
||||||
|
|
||||||
|
vector<son_info> sons;
|
||||||
|
|
||||||
account_id_type fee_payer()const { return payer; }
|
account_id_type fee_payer()const { return payer; }
|
||||||
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
||||||
};
|
};
|
||||||
|
|
@ -28,23 +31,9 @@ namespace graphene { namespace chain {
|
||||||
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct son_wallet_close_operation : public base_operation
|
|
||||||
{
|
|
||||||
struct fee_parameters_type { uint64_t fee = 0; };
|
|
||||||
|
|
||||||
asset fee;
|
|
||||||
account_id_type payer;
|
|
||||||
son_wallet_id_type son_wallet_id;
|
|
||||||
|
|
||||||
account_id_type fee_payer()const { return payer; }
|
|
||||||
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
|
||||||
};
|
|
||||||
|
|
||||||
} } // namespace graphene::chain
|
} } // namespace graphene::chain
|
||||||
|
|
||||||
FC_REFLECT(graphene::chain::son_wallet_create_operation::fee_parameters_type, (fee) )
|
FC_REFLECT(graphene::chain::son_wallet_recreate_operation::fee_parameters_type, (fee) )
|
||||||
FC_REFLECT(graphene::chain::son_wallet_create_operation, (fee)(payer) )
|
FC_REFLECT(graphene::chain::son_wallet_recreate_operation, (fee)(payer)(sons) )
|
||||||
FC_REFLECT(graphene::chain::son_wallet_update_operation::fee_parameters_type, (fee) )
|
FC_REFLECT(graphene::chain::son_wallet_update_operation::fee_parameters_type, (fee) )
|
||||||
FC_REFLECT(graphene::chain::son_wallet_update_operation, (fee)(payer)(son_wallet_id)(sidechain)(address) )
|
FC_REFLECT(graphene::chain::son_wallet_update_operation, (fee)(payer)(son_wallet_id)(sidechain)(address) )
|
||||||
FC_REFLECT(graphene::chain::son_wallet_close_operation::fee_parameters_type, (fee) )
|
|
||||||
FC_REFLECT(graphene::chain::son_wallet_close_operation, (fee)(payer)(son_wallet_id) )
|
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,13 @@
|
||||||
|
|
||||||
namespace graphene { namespace chain {
|
namespace graphene { namespace chain {
|
||||||
|
|
||||||
class create_son_wallet_evaluator : public evaluator<create_son_wallet_evaluator>
|
class recreate_son_wallet_evaluator : public evaluator<recreate_son_wallet_evaluator>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef son_wallet_create_operation operation_type;
|
typedef son_wallet_recreate_operation operation_type;
|
||||||
|
|
||||||
void_result do_evaluate(const son_wallet_create_operation& o);
|
void_result do_evaluate(const son_wallet_recreate_operation& o);
|
||||||
object_id_type do_apply(const son_wallet_create_operation& o);
|
object_id_type do_apply(const son_wallet_recreate_operation& o);
|
||||||
};
|
};
|
||||||
|
|
||||||
class update_son_wallet_evaluator : public evaluator<update_son_wallet_evaluator>
|
class update_son_wallet_evaluator : public evaluator<update_son_wallet_evaluator>
|
||||||
|
|
@ -22,13 +22,4 @@ public:
|
||||||
object_id_type do_apply(const son_wallet_update_operation& o);
|
object_id_type do_apply(const son_wallet_update_operation& o);
|
||||||
};
|
};
|
||||||
|
|
||||||
class close_son_wallet_evaluator : public evaluator<close_son_wallet_evaluator>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef son_wallet_close_operation operation_type;
|
|
||||||
|
|
||||||
void_result do_evaluate(const son_wallet_close_operation& o);
|
|
||||||
object_id_type do_apply(const son_wallet_close_operation& o);
|
|
||||||
};
|
|
||||||
|
|
||||||
} } // namespace graphene::chain
|
} } // namespace graphene::chain
|
||||||
|
|
|
||||||
|
|
@ -5,21 +5,51 @@
|
||||||
|
|
||||||
namespace graphene { namespace chain {
|
namespace graphene { namespace chain {
|
||||||
|
|
||||||
void_result create_son_wallet_evaluator::do_evaluate(const son_wallet_create_operation& op)
|
void_result recreate_son_wallet_evaluator::do_evaluate(const son_wallet_recreate_operation& op)
|
||||||
{ try{
|
{ try{
|
||||||
FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK");
|
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(db().get_global_properties().parameters.get_son_btc_account_id() != GRAPHENE_NULL_ACCOUNT, "SON paying account not set.");
|
||||||
|
|
||||||
|
const auto& idx = db().get_index_type<son_wallet_index>().indices().get<by_id>();
|
||||||
|
auto itr = idx.rbegin();
|
||||||
|
if(itr != idx.rend())
|
||||||
|
{
|
||||||
|
// Compare current wallet SONs and to-be lists of active sons
|
||||||
|
auto cur_wallet_sons = (*itr).sons;
|
||||||
|
auto new_wallet_sons = op.sons;
|
||||||
|
|
||||||
|
bool son_sets_equal = (cur_wallet_sons.size() == new_wallet_sons.size());
|
||||||
|
if (son_sets_equal) {
|
||||||
|
for( size_t i = 0; i < cur_wallet_sons.size(); i++ ) {
|
||||||
|
son_sets_equal = son_sets_equal && cur_wallet_sons.at(i) == new_wallet_sons.at(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FC_ASSERT(son_sets_equal == false, "Wallet recreation not needed, active SONs set is not changed.");
|
||||||
|
}
|
||||||
|
|
||||||
return void_result();
|
return void_result();
|
||||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||||
|
|
||||||
object_id_type create_son_wallet_evaluator::do_apply(const son_wallet_create_operation& op)
|
object_id_type recreate_son_wallet_evaluator::do_apply(const son_wallet_recreate_operation& op)
|
||||||
{ try {
|
{ try {
|
||||||
const auto& new_son_wallet_object = db().create<son_wallet_object>( [&]( son_wallet_object& obj ){
|
FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK");
|
||||||
obj.valid_from = db().head_block_time();
|
|
||||||
obj.expires = time_point_sec::maximum();
|
const auto& idx = db().get_index_type<son_wallet_index>().indices().get<by_id>();
|
||||||
obj.sons = db().get_global_properties().active_sons;
|
auto itr = idx.rbegin();
|
||||||
});
|
if(itr != idx.rend())
|
||||||
return new_son_wallet_object.id;
|
{
|
||||||
|
db().modify(*itr, [&, op](son_wallet_object &swo) {
|
||||||
|
swo.expires = db().head_block_time();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& new_son_wallet_object = db().create<son_wallet_object>( [&]( son_wallet_object& obj ){
|
||||||
|
obj.valid_from = db().head_block_time();
|
||||||
|
obj.expires = time_point_sec::maximum();
|
||||||
|
obj.sons = op.sons;
|
||||||
|
});
|
||||||
|
return new_son_wallet_object.id;
|
||||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||||
|
|
||||||
void_result update_son_wallet_evaluator::do_evaluate(const son_wallet_update_operation& op)
|
void_result update_son_wallet_evaluator::do_evaluate(const son_wallet_update_operation& op)
|
||||||
|
|
@ -46,25 +76,4 @@ object_id_type update_son_wallet_evaluator::do_apply(const son_wallet_update_ope
|
||||||
return op.son_wallet_id;
|
return op.son_wallet_id;
|
||||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||||
|
|
||||||
void_result close_son_wallet_evaluator::do_evaluate(const son_wallet_close_operation& op)
|
|
||||||
{ try{
|
|
||||||
FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK");
|
|
||||||
const auto& idx = db().get_index_type<son_wallet_index>().indices().get<by_id>();
|
|
||||||
FC_ASSERT( idx.find(op.son_wallet_id) != idx.end() );
|
|
||||||
return void_result();
|
|
||||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
|
||||||
|
|
||||||
object_id_type close_son_wallet_evaluator::do_apply(const son_wallet_close_operation& op)
|
|
||||||
{ try {
|
|
||||||
const auto& idx = db().get_index_type<son_wallet_index>().indices().get<by_id>();
|
|
||||||
auto itr = idx.find(op.son_wallet_id);
|
|
||||||
if(itr != idx.end())
|
|
||||||
{
|
|
||||||
db().modify(*itr, [&, op](son_wallet_object &swo) {
|
|
||||||
swo.expires = db().head_block_time();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return op.son_wallet_id;
|
|
||||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
|
||||||
|
|
||||||
} } // namespace graphene::chain
|
} } // namespace graphene::chain
|
||||||
|
|
|
||||||
|
|
@ -425,6 +425,11 @@ void peerplays_sidechain_plugin_impl::on_objects_new(const vector<object_id_type
|
||||||
&& proposal->proposed_transaction.operations[0].which() == chain::operation::tag<chain::son_report_down_operation>::value) {
|
&& proposal->proposed_transaction.operations[0].which() == chain::operation::tag<chain::son_report_down_operation>::value) {
|
||||||
approve_proposal( proposal->id );
|
approve_proposal( proposal->id );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(proposal->proposed_transaction.operations.size() == 1
|
||||||
|
&& proposal->proposed_transaction.operations[0].which() == chain::operation::tag<chain::son_wallet_update_operation>::value) {
|
||||||
|
approve_proposal( proposal->id );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -260,7 +260,10 @@ void sidechain_net_handler_bitcoin::recreate_primary_wallet() {
|
||||||
|
|
||||||
if ((obj->addresses.find(sidechain_type::bitcoin) == obj->addresses.end()) ||
|
if ((obj->addresses.find(sidechain_type::bitcoin) == obj->addresses.end()) ||
|
||||||
(obj->addresses.at(sidechain_type::bitcoin).empty())) {
|
(obj->addresses.at(sidechain_type::bitcoin).empty())) {
|
||||||
auto active_sons = database.get_global_properties().active_sons;
|
|
||||||
|
const chain::global_property_object& gpo = database.get_global_properties();
|
||||||
|
|
||||||
|
auto active_sons = gpo.active_sons;
|
||||||
vector<string> son_pubkeys_bitcoin;
|
vector<string> son_pubkeys_bitcoin;
|
||||||
for ( const son_info& si : active_sons ) {
|
for ( const son_info& si : active_sons ) {
|
||||||
son_pubkeys_bitcoin.push_back(si.sidechain_public_keys.at(sidechain_type::bitcoin));
|
son_pubkeys_bitcoin.push_back(si.sidechain_public_keys.at(sidechain_type::bitcoin));
|
||||||
|
|
@ -279,17 +282,22 @@ void sidechain_net_handler_bitcoin::recreate_primary_wallet() {
|
||||||
boost::property_tree::json_parser::write_json(res, pt.get_child("result"));
|
boost::property_tree::json_parser::write_json(res, pt.get_child("result"));
|
||||||
|
|
||||||
son_wallet_update_operation op;
|
son_wallet_update_operation op;
|
||||||
op.payer = plugin.get_son_object().son_account;
|
op.payer = gpo.parameters.get_son_btc_account_id();
|
||||||
op.son_wallet_id = (*obj).id;
|
op.son_wallet_id = (*obj).id;
|
||||||
op.sidechain = sidechain_type::bitcoin;
|
op.sidechain = sidechain_type::bitcoin;
|
||||||
op.address = res.str();
|
op.address = res.str();
|
||||||
|
|
||||||
signed_transaction trx = database.create_signed_transaction(plugin.get_private_keys().begin()->second, op);
|
proposal_create_operation proposal_op;
|
||||||
|
proposal_op.fee_paying_account = plugin.get_son_object().son_account;
|
||||||
|
proposal_op.proposed_ops.push_back( op_wrapper( op ) );
|
||||||
|
uint32_t lifetime = ( gpo.parameters.block_interval * gpo.active_witnesses.size() ) * 3;
|
||||||
|
proposal_op.expiration_time = time_point_sec( database.head_block_time().sec_since_epoch() + lifetime );
|
||||||
|
|
||||||
|
signed_transaction trx = database.create_signed_transaction(plugin.get_private_keys().begin()->second, proposal_op);
|
||||||
try {
|
try {
|
||||||
database.push_transaction(trx);
|
database.push_transaction(trx);
|
||||||
} catch (fc::exception e) {
|
} catch(fc::exception e){
|
||||||
ilog("sidechain_net_handler_bitcoin: sending son wallet update operation failed with exception ${e}",("e", e.what()));
|
ilog("sidechain_net_handler: sending proposal for son wallet update operation failed with exception ${e}",("e", e.what()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,15 +24,15 @@ BOOST_AUTO_TEST_CASE( son_wallet_create_test ) {
|
||||||
set_expiration(db, trx);
|
set_expiration(db, trx);
|
||||||
|
|
||||||
{
|
{
|
||||||
BOOST_TEST_MESSAGE("Send son_wallet_create_operation");
|
BOOST_TEST_MESSAGE("Send son_wallet_recreate_operation");
|
||||||
|
|
||||||
son_wallet_create_operation op;
|
son_wallet_recreate_operation op;
|
||||||
|
|
||||||
op.payer = db.get_global_properties().parameters.get_son_btc_account_id();
|
op.payer = db.get_global_properties().parameters.get_son_btc_account_id();
|
||||||
|
|
||||||
trx.operations.push_back(op);
|
trx.operations.push_back(op);
|
||||||
sign(trx, alice_private_key);
|
sign(trx, alice_private_key);
|
||||||
PUSH_TX(db, trx, ~0);
|
//PUSH_TX(db, trx, ~0);
|
||||||
}
|
}
|
||||||
generate_block();
|
generate_block();
|
||||||
|
|
||||||
|
|
@ -79,36 +79,4 @@ BOOST_AUTO_TEST_CASE( son_wallet_update_test ) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( son_wallet_close_test ) {
|
|
||||||
|
|
||||||
BOOST_TEST_MESSAGE("son_wallet_close_test");
|
|
||||||
|
|
||||||
INVOKE(son_wallet_create_test);
|
|
||||||
GET_ACTOR(alice);
|
|
||||||
|
|
||||||
{
|
|
||||||
BOOST_TEST_MESSAGE("Send son_wallet_close_operation");
|
|
||||||
|
|
||||||
son_wallet_close_operation op;
|
|
||||||
|
|
||||||
op.payer = db.get_global_properties().parameters.get_son_btc_account_id();
|
|
||||||
op.son_wallet_id = son_wallet_id_type(0);
|
|
||||||
|
|
||||||
trx.operations.push_back(op);
|
|
||||||
sign(trx, alice_private_key);
|
|
||||||
PUSH_TX(db, trx, ~0);
|
|
||||||
}
|
|
||||||
generate_block();
|
|
||||||
|
|
||||||
{
|
|
||||||
BOOST_TEST_MESSAGE("Check son_wallet_close_operation results");
|
|
||||||
|
|
||||||
const auto& idx = db.get_index_type<son_wallet_index>().indices().get<by_id>();
|
|
||||||
BOOST_REQUIRE( idx.size() == 1 );
|
|
||||||
auto obj = idx.find(son_wallet_id_type(0));
|
|
||||||
BOOST_REQUIRE( obj->expires != time_point_sec::maximum() );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue