Deposit/Withdrawal sidechain transactions prepared for partial signing
This commit is contained in:
parent
fd3ac1766c
commit
5897442112
17 changed files with 786 additions and 689 deletions
|
|
@ -343,15 +343,15 @@ struct get_impacted_account_visitor
|
||||||
void operator()( const sidechain_address_delete_operation& op ){
|
void operator()( const sidechain_address_delete_operation& op ){
|
||||||
_impacted.insert( op.sidechain_address_account );
|
_impacted.insert( op.sidechain_address_account );
|
||||||
}
|
}
|
||||||
void operator()( const bitcoin_transaction_send_operation& op ){
|
void operator()( const sidechain_transaction_create_operation& op ){
|
||||||
_impacted.insert( op.payer );
|
|
||||||
}
|
|
||||||
void operator()( const bitcoin_transaction_sign_operation& op ){
|
|
||||||
_impacted.insert( op.payer );
|
|
||||||
}
|
|
||||||
void operator()( const bitcoin_send_transaction_process_operation& op ){
|
|
||||||
_impacted.insert( op.payer );
|
_impacted.insert( op.payer );
|
||||||
}
|
}
|
||||||
|
// void operator()( const sidechain_transaction_sign_operation& op ){
|
||||||
|
// _impacted.insert( op.payer );
|
||||||
|
// }
|
||||||
|
// void operator()( const sidechain_transaction_send_operation& op ){
|
||||||
|
// _impacted.insert( op.payer );
|
||||||
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
void operation_get_impacted_accounts( const operation& op, flat_set<account_id_type>& result )
|
void operation_get_impacted_accounts( const operation& op, flat_set<account_id_type>& result )
|
||||||
|
|
|
||||||
|
|
@ -269,9 +269,9 @@ void database::initialize_evaluators()
|
||||||
register_evaluator<add_sidechain_address_evaluator>();
|
register_evaluator<add_sidechain_address_evaluator>();
|
||||||
register_evaluator<update_sidechain_address_evaluator>();
|
register_evaluator<update_sidechain_address_evaluator>();
|
||||||
register_evaluator<delete_sidechain_address_evaluator>();
|
register_evaluator<delete_sidechain_address_evaluator>();
|
||||||
register_evaluator<bitcoin_transaction_send_evaluator>();
|
register_evaluator<sidechain_transaction_create_evaluator>();
|
||||||
register_evaluator<bitcoin_transaction_sign_evaluator>();
|
// register_evaluator<sidechain_transaction_sign_evaluator>();
|
||||||
register_evaluator<bitcoin_send_transaction_process_evaluator>();
|
// register_evaluator<sidechain_transaction_send_evaluator>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void database::initialize_indexes()
|
void database::initialize_indexes()
|
||||||
|
|
@ -321,7 +321,7 @@ void database::initialize_indexes()
|
||||||
add_index< primary_index<son_wallet_withdraw_index> >();
|
add_index< primary_index<son_wallet_withdraw_index> >();
|
||||||
|
|
||||||
add_index< primary_index<sidechain_address_index> >();
|
add_index< primary_index<sidechain_address_index> >();
|
||||||
add_index< primary_index<bitcoin_transaction_index> >();
|
add_index< primary_index<sidechain_transaction_index> >();
|
||||||
|
|
||||||
//Implementation object indexes
|
//Implementation object indexes
|
||||||
add_index< primary_index<transaction_index > >();
|
add_index< primary_index<transaction_index > >();
|
||||||
|
|
|
||||||
|
|
@ -330,15 +330,15 @@ struct get_impacted_account_visitor
|
||||||
void operator()( const sidechain_address_delete_operation& op ) {
|
void operator()( const sidechain_address_delete_operation& op ) {
|
||||||
_impacted.insert( op.sidechain_address_account );
|
_impacted.insert( op.sidechain_address_account );
|
||||||
}
|
}
|
||||||
void operator()( const bitcoin_transaction_send_operation& op ) {
|
void operator()( const sidechain_transaction_create_operation& op ) {
|
||||||
_impacted.insert( op.payer );
|
|
||||||
}
|
|
||||||
void operator()( const bitcoin_transaction_sign_operation& op ) {
|
|
||||||
_impacted.insert( op.payer );
|
|
||||||
}
|
|
||||||
void operator()( const bitcoin_send_transaction_process_operation& op ) {
|
|
||||||
_impacted.insert( op.payer );
|
_impacted.insert( op.payer );
|
||||||
}
|
}
|
||||||
|
// void operator()( const sidechain_transaction_sign_operation& op ) {
|
||||||
|
// _impacted.insert( op.payer );
|
||||||
|
// }
|
||||||
|
// void operator()( const sidechain_transaction_send_operation& op ) {
|
||||||
|
// _impacted.insert( op.payer );
|
||||||
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
void operation_get_impacted_accounts( const operation& op, flat_set<account_id_type>& result )
|
void operation_get_impacted_accounts( const operation& op, flat_set<account_id_type>& result )
|
||||||
|
|
|
||||||
|
|
@ -157,9 +157,9 @@ namespace graphene { namespace chain {
|
||||||
sidechain_address_add_operation,
|
sidechain_address_add_operation,
|
||||||
sidechain_address_update_operation,
|
sidechain_address_update_operation,
|
||||||
sidechain_address_delete_operation,
|
sidechain_address_delete_operation,
|
||||||
bitcoin_transaction_send_operation,
|
sidechain_transaction_create_operation//,
|
||||||
bitcoin_transaction_sign_operation,
|
//sidechain_transaction_sign_operation,
|
||||||
bitcoin_send_transaction_process_operation
|
//sidechain_transaction_send_operation
|
||||||
> operation;
|
> operation;
|
||||||
|
|
||||||
/// @} // operations group
|
/// @} // operations group
|
||||||
|
|
|
||||||
|
|
@ -5,56 +5,66 @@
|
||||||
|
|
||||||
namespace graphene { namespace chain {
|
namespace graphene { namespace chain {
|
||||||
|
|
||||||
struct bitcoin_transaction_send_operation : public base_operation
|
struct sidechain_transaction_create_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;
|
||||||
|
|
||||||
// TODO: BTC Transaction Structs go here
|
graphene::peerplays_sidechain::sidechain_type sidechain;
|
||||||
fc::flat_map<son_id_type, std::vector<peerplays_sidechain::bytes>> signatures;
|
optional<son_wallet_id_type> son_wallet_id;
|
||||||
|
optional<son_wallet_deposit_id_type> son_wallet_deposit_id;
|
||||||
|
optional<son_wallet_withdraw_id_type> son_wallet_withdraw_id;
|
||||||
|
std::string transaction;
|
||||||
|
std::vector<std::pair<son_id_type, bool>> signatures;
|
||||||
|
|
||||||
account_id_type fee_payer()const { return payer; }
|
account_id_type fee_payer()const { return payer; }
|
||||||
void validate()const {}
|
void validate()const {}
|
||||||
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 bitcoin_transaction_sign_operation : public base_operation
|
// struct sidechain_transaction_sign_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;
|
||||||
proposal_id_type proposal_id;
|
// proposal_id_type proposal_id;
|
||||||
std::vector<peerplays_sidechain::bytes> signatures;
|
// std::vector<peerplays_sidechain::bytes> signatures;
|
||||||
|
//
|
||||||
account_id_type fee_payer()const { return payer; }
|
// account_id_type fee_payer()const { return payer; }
|
||||||
void validate()const {}
|
// void validate()const {}
|
||||||
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 bitcoin_send_transaction_process_operation : public base_operation
|
// struct sidechain_transaction_send_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;
|
||||||
|
//
|
||||||
bitcoin_transaction_id_type bitcoin_transaction_id;
|
// sidechain_transaction_id_type sidechain_transaction_id;
|
||||||
|
//
|
||||||
account_id_type fee_payer()const { return payer; }
|
// account_id_type fee_payer()const { return payer; }
|
||||||
void validate()const {}
|
// void validate()const {}
|
||||||
share_type calculate_fee( const fee_parameters_type& k )const { return 0; }
|
// share_type calculate_fee( const fee_parameters_type& k )const { return 0; }
|
||||||
};
|
// };
|
||||||
|
|
||||||
} } // graphene::chain
|
} } // graphene::chain
|
||||||
|
|
||||||
FC_REFLECT( graphene::chain::bitcoin_transaction_send_operation::fee_parameters_type, (fee) )
|
FC_REFLECT( graphene::chain::sidechain_transaction_create_operation::fee_parameters_type, (fee) )
|
||||||
FC_REFLECT( graphene::chain::bitcoin_transaction_send_operation, (fee)(payer)(signatures) )
|
FC_REFLECT( graphene::chain::sidechain_transaction_create_operation, (fee)(payer)
|
||||||
|
(sidechain)
|
||||||
|
(son_wallet_id)
|
||||||
|
(son_wallet_deposit_id)
|
||||||
|
(son_wallet_withdraw_id)
|
||||||
|
(transaction)
|
||||||
|
(signatures) )
|
||||||
|
|
||||||
FC_REFLECT( graphene::chain::bitcoin_transaction_sign_operation::fee_parameters_type, (fee) )
|
//FC_REFLECT( graphene::chain::sidechain_transaction_sign_operation::fee_parameters_type, (fee) )
|
||||||
FC_REFLECT( graphene::chain::bitcoin_transaction_sign_operation, (fee)(payer)(proposal_id)(signatures) )
|
//FC_REFLECT( graphene::chain::sidechain_transaction_sign_operation, (fee)(payer)(proposal_id)(signatures) )
|
||||||
|
//
|
||||||
FC_REFLECT( graphene::chain::bitcoin_send_transaction_process_operation::fee_parameters_type, (fee) )
|
//FC_REFLECT( graphene::chain::sidechain_transaction_send_operation::fee_parameters_type, (fee) )
|
||||||
FC_REFLECT( graphene::chain::bitcoin_send_transaction_process_operation, (fee)(payer)(bitcoin_transaction_id) )
|
//FC_REFLECT( graphene::chain::sidechain_transaction_send_operation, (fee)(payer)(sidechain_transaction_id) )
|
||||||
|
|
@ -151,7 +151,7 @@ namespace graphene { namespace chain {
|
||||||
son_wallet_deposit_object_type,
|
son_wallet_deposit_object_type,
|
||||||
son_wallet_withdraw_object_type,
|
son_wallet_withdraw_object_type,
|
||||||
sidechain_address_object_type,
|
sidechain_address_object_type,
|
||||||
bitcoin_transaction_object_type,
|
sidechain_transaction_object_type,
|
||||||
OBJECT_TYPE_COUNT ///< Sentry value which contains the number of different object types
|
OBJECT_TYPE_COUNT ///< Sentry value which contains the number of different object types
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -219,7 +219,7 @@ namespace graphene { namespace chain {
|
||||||
class son_wallet_deposit_object;
|
class son_wallet_deposit_object;
|
||||||
class son_wallet_withdraw_object;
|
class son_wallet_withdraw_object;
|
||||||
class sidechain_address_object;
|
class sidechain_address_object;
|
||||||
class bitcoin_transaction_object;
|
class sidechain_transaction_object;
|
||||||
|
|
||||||
typedef object_id< protocol_ids, account_object_type, account_object> account_id_type;
|
typedef object_id< protocol_ids, account_object_type, account_object> account_id_type;
|
||||||
typedef object_id< protocol_ids, asset_object_type, asset_object> asset_id_type;
|
typedef object_id< protocol_ids, asset_object_type, asset_object> asset_id_type;
|
||||||
|
|
@ -252,7 +252,7 @@ namespace graphene { namespace chain {
|
||||||
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_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, 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, 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;
|
typedef object_id< protocol_ids, sidechain_transaction_object_type,sidechain_transaction_object> sidechain_transaction_id_type;
|
||||||
|
|
||||||
// implementation types
|
// implementation types
|
||||||
class global_property_object;
|
class global_property_object;
|
||||||
|
|
@ -443,7 +443,7 @@ FC_REFLECT_ENUM( graphene::chain::object_type,
|
||||||
(son_wallet_deposit_object_type)
|
(son_wallet_deposit_object_type)
|
||||||
(son_wallet_withdraw_object_type)
|
(son_wallet_withdraw_object_type)
|
||||||
(sidechain_address_object_type)
|
(sidechain_address_object_type)
|
||||||
(bitcoin_transaction_object_type)
|
(sidechain_transaction_object_type)
|
||||||
(OBJECT_TYPE_COUNT)
|
(OBJECT_TYPE_COUNT)
|
||||||
)
|
)
|
||||||
FC_REFLECT_ENUM( graphene::chain::impl_object_type,
|
FC_REFLECT_ENUM( graphene::chain::impl_object_type,
|
||||||
|
|
@ -521,7 +521,7 @@ FC_REFLECT_TYPENAME( graphene::chain::son_wallet_id_type )
|
||||||
FC_REFLECT_TYPENAME( graphene::chain::son_wallet_deposit_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::son_wallet_withdraw_id_type )
|
||||||
FC_REFLECT_TYPENAME( graphene::chain::sidechain_address_id_type )
|
FC_REFLECT_TYPENAME( graphene::chain::sidechain_address_id_type )
|
||||||
FC_REFLECT_TYPENAME( graphene::chain::bitcoin_transaction_id_type )
|
FC_REFLECT_TYPENAME( graphene::chain::sidechain_transaction_id_type )
|
||||||
|
|
||||||
|
|
||||||
FC_REFLECT( graphene::chain::void_t, )
|
FC_REFLECT( graphene::chain::void_t, )
|
||||||
|
|
|
||||||
|
|
@ -4,32 +4,32 @@
|
||||||
|
|
||||||
namespace graphene { namespace chain {
|
namespace graphene { namespace chain {
|
||||||
|
|
||||||
class bitcoin_transaction_send_evaluator : public evaluator<bitcoin_transaction_send_evaluator>
|
class sidechain_transaction_create_evaluator : public evaluator<sidechain_transaction_create_evaluator>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef bitcoin_transaction_send_operation operation_type;
|
typedef sidechain_transaction_create_operation operation_type;
|
||||||
|
|
||||||
void_result do_evaluate(const bitcoin_transaction_send_operation& o);
|
void_result do_evaluate(const sidechain_transaction_create_operation& o);
|
||||||
object_id_type do_apply(const bitcoin_transaction_send_operation& o);
|
object_id_type do_apply(const sidechain_transaction_create_operation& o);
|
||||||
};
|
};
|
||||||
|
|
||||||
class bitcoin_transaction_sign_evaluator : public evaluator<bitcoin_transaction_sign_evaluator>
|
//class sidechain_transaction_sign_evaluator : public evaluator<sidechain_transaction_sign_evaluator>
|
||||||
{
|
//{
|
||||||
public:
|
//public:
|
||||||
typedef bitcoin_transaction_sign_operation operation_type;
|
// typedef sidechain_transaction_sign_operation operation_type;
|
||||||
|
//
|
||||||
void_result do_evaluate(const bitcoin_transaction_sign_operation& o);
|
// void_result do_evaluate(const sidechain_transaction_sign_operation& o);
|
||||||
object_id_type do_apply(const bitcoin_transaction_sign_operation& o);
|
// object_id_type do_apply(const sidechain_transaction_sign_operation& o);
|
||||||
void update_proposal( const bitcoin_transaction_sign_operation& o );
|
// void update_proposal( const sidechain_transaction_sign_operation& o );
|
||||||
};
|
//};
|
||||||
|
//
|
||||||
class bitcoin_send_transaction_process_evaluator : public evaluator<bitcoin_send_transaction_process_evaluator>
|
//class sidechain_transaction_send_evaluator : public evaluator<sidechain_transaction_send_evaluator>
|
||||||
{
|
//{
|
||||||
public:
|
//public:
|
||||||
typedef bitcoin_send_transaction_process_operation operation_type;
|
// typedef sidechain_transaction_send_operation operation_type;
|
||||||
|
//
|
||||||
void_result do_evaluate(const bitcoin_send_transaction_process_operation& o);
|
// void_result do_evaluate(const sidechain_transaction_send_operation& o);
|
||||||
object_id_type do_apply(const bitcoin_send_transaction_process_operation& o);
|
// object_id_type do_apply(const sidechain_transaction_send_operation& o);
|
||||||
};
|
//};
|
||||||
|
|
||||||
} } // namespace graphene::chain
|
} } // namespace graphene::chain
|
||||||
|
|
@ -6,34 +6,60 @@ namespace graphene { namespace chain {
|
||||||
using namespace graphene::db;
|
using namespace graphene::db;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class bitcoin_transaction_object
|
* @class sidechain_transaction_object
|
||||||
* @brief tracks state of bitcoin transaction.
|
* @brief tracks state of sidechain transaction during signing process.
|
||||||
* @ingroup object
|
* @ingroup object
|
||||||
*/
|
*/
|
||||||
class bitcoin_transaction_object : public abstract_object<bitcoin_transaction_object>
|
class sidechain_transaction_object : public abstract_object<sidechain_transaction_object>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static const uint8_t space_id = protocol_ids;
|
static const uint8_t space_id = protocol_ids;
|
||||||
static const uint8_t type_id = bitcoin_transaction_object_type;
|
static const uint8_t type_id = sidechain_transaction_object_type;
|
||||||
// Bitcoin structs go here.
|
|
||||||
bool processed = false;
|
graphene::peerplays_sidechain::sidechain_type sidechain;
|
||||||
fc::flat_map<son_id_type, std::vector<peerplays_sidechain::bytes>> signatures;
|
optional<son_wallet_id_type> son_wallet_id;
|
||||||
|
optional<son_wallet_deposit_id_type> son_wallet_deposit_id;
|
||||||
|
optional<son_wallet_withdraw_id_type> son_wallet_withdraw_id;
|
||||||
|
std::string transaction;
|
||||||
|
std::vector<std::pair<son_id_type, bool>> signatures;
|
||||||
|
|
||||||
|
bool valid = false;
|
||||||
|
bool completed = false;
|
||||||
|
bool sent = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct by_processed;
|
struct by_sidechain_and_completed;
|
||||||
using bitcoin_transaction_multi_index_type = multi_index_container<
|
struct by_sidechain_and_sent;
|
||||||
bitcoin_transaction_object,
|
using sidechain_transaction_multi_index_type = multi_index_container<
|
||||||
|
sidechain_transaction_object,
|
||||||
indexed_by<
|
indexed_by<
|
||||||
ordered_unique< tag<by_id>,
|
ordered_unique< tag<by_id>,
|
||||||
member<object, object_id_type, &object::id>
|
member<object, object_id_type, &object::id>
|
||||||
>,
|
>,
|
||||||
ordered_non_unique< tag<by_processed>,
|
ordered_non_unique< tag<by_sidechain_and_completed>,
|
||||||
member<bitcoin_transaction_object, bool, &bitcoin_transaction_object::processed>
|
composite_key<sidechain_transaction_object,
|
||||||
|
member<sidechain_transaction_object, peerplays_sidechain::sidechain_type, &sidechain_transaction_object::sidechain>,
|
||||||
|
member<sidechain_transaction_object, bool, &sidechain_transaction_object::completed>
|
||||||
|
>
|
||||||
|
>,
|
||||||
|
ordered_non_unique< tag<by_sidechain_and_sent>,
|
||||||
|
composite_key<sidechain_transaction_object,
|
||||||
|
member<sidechain_transaction_object, peerplays_sidechain::sidechain_type, &sidechain_transaction_object::sidechain>,
|
||||||
|
member<sidechain_transaction_object, bool, &sidechain_transaction_object::sent>
|
||||||
|
>
|
||||||
>
|
>
|
||||||
>
|
>
|
||||||
>;
|
>;
|
||||||
using bitcoin_transaction_index = generic_index<bitcoin_transaction_object, bitcoin_transaction_multi_index_type>;
|
using sidechain_transaction_index = generic_index<sidechain_transaction_object, sidechain_transaction_multi_index_type>;
|
||||||
} } // graphene::chain
|
} } // graphene::chain
|
||||||
|
|
||||||
FC_REFLECT_DERIVED( graphene::chain::bitcoin_transaction_object, (graphene::db::object),
|
FC_REFLECT_DERIVED( graphene::chain::sidechain_transaction_object, (graphene::db::object ),
|
||||||
(processed)(signatures) )
|
(sidechain)
|
||||||
|
(son_wallet_id)
|
||||||
|
(son_wallet_deposit_id)
|
||||||
|
(son_wallet_withdraw_id)
|
||||||
|
(transaction)
|
||||||
|
(signatures)
|
||||||
|
(valid)
|
||||||
|
(completed)
|
||||||
|
(sent) )
|
||||||
|
|
|
||||||
|
|
@ -6,135 +6,138 @@
|
||||||
#include <graphene/chain/proposal_object.hpp>
|
#include <graphene/chain/proposal_object.hpp>
|
||||||
#include <graphene/chain/hardfork.hpp>
|
#include <graphene/chain/hardfork.hpp>
|
||||||
|
|
||||||
namespace graphene
|
namespace graphene { namespace chain {
|
||||||
{
|
|
||||||
namespace chain
|
|
||||||
{
|
|
||||||
|
|
||||||
void_result bitcoin_transaction_send_evaluator::do_evaluate(const bitcoin_transaction_send_operation &op)
|
void_result sidechain_transaction_create_evaluator::do_evaluate(const sidechain_transaction_create_operation &op)
|
||||||
{
|
{ try {
|
||||||
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." );
|
||||||
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 bitcoin_transaction_send_evaluator::do_apply(const bitcoin_transaction_send_operation &op)
|
//FC_ASSERT( (!op.son_wallet_id && !op.son_wallet_deposit_id && !op.son_wallet_withdraw_id), "Sidechain transaction origin not set." );
|
||||||
{
|
//FC_ASSERT( op.son_wallet_id && op.son_wallet_deposit_id, "Sidechain transaction origin ambiguous. Single origin required." );
|
||||||
try
|
//FC_ASSERT( op.son_wallet_id && op.son_wallet_withdraw_id, "Sidechain transaction origin ambiguous. Single origin required." );
|
||||||
{
|
//FC_ASSERT( op.son_wallet_deposit_id && op.son_wallet_withdraw_id, "Sidechain transaction origin ambiguous. Single origin required." );
|
||||||
const auto &new_bitcoin_transaction_object = db().create<bitcoin_transaction_object>([&](bitcoin_transaction_object &obj) {
|
FC_ASSERT( !op.transaction.empty(), "Sidechain transaction data not set." );
|
||||||
obj.processed = false;
|
|
||||||
obj.signatures = op.signatures;
|
|
||||||
});
|
|
||||||
return new_bitcoin_transaction_object.id;
|
|
||||||
}
|
|
||||||
FC_CAPTURE_AND_RETHROW((op))
|
|
||||||
}
|
|
||||||
|
|
||||||
void_result bitcoin_transaction_sign_evaluator::do_evaluate(const bitcoin_transaction_sign_operation &op)
|
return void_result();
|
||||||
{
|
} FC_CAPTURE_AND_RETHROW( ( op ) ) }
|
||||||
try
|
|
||||||
{
|
|
||||||
FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK"); // can be removed after HF date pass
|
|
||||||
const auto &proposal_idx = db().get_index_type<proposal_index>().indices().get<by_id>();
|
|
||||||
const auto &proposal_itr = proposal_idx.find(op.proposal_id);
|
|
||||||
FC_ASSERT(proposal_idx.end() != proposal_itr, "proposal not found");
|
|
||||||
// Checks can this SON approve this proposal
|
|
||||||
auto can_this_son_approve_this_proposal = [&]() {
|
|
||||||
const auto &sidx = db().get_index_type<son_index>().indices().get<graphene::chain::by_account>();
|
|
||||||
auto son_obj = sidx.find(op.payer);
|
|
||||||
if (son_obj == sidx.end())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// TODO: Check if the SON is included in the PW script.
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
FC_ASSERT(can_this_son_approve_this_proposal(), "Invalid approval received");
|
object_id_type sidechain_transaction_create_evaluator::do_apply(const sidechain_transaction_create_operation &op)
|
||||||
return void_result();
|
{ try {
|
||||||
}
|
const auto &new_sidechain_transaction_object = db().create<sidechain_transaction_object>([&](sidechain_transaction_object &sto) {
|
||||||
FC_CAPTURE_AND_RETHROW((op))
|
sto.sidechain = op.sidechain;
|
||||||
}
|
sto.son_wallet_id = op.son_wallet_id;
|
||||||
|
sto.son_wallet_deposit_id = op.son_wallet_deposit_id;
|
||||||
|
sto.son_wallet_withdraw_id = op.son_wallet_withdraw_id;
|
||||||
|
sto.transaction = op.transaction;
|
||||||
|
sto.signatures = op.signatures;
|
||||||
|
sto.valid = true;
|
||||||
|
sto.completed = false;
|
||||||
|
sto.sent = false;
|
||||||
|
});
|
||||||
|
return new_sidechain_transaction_object.id;
|
||||||
|
} FC_CAPTURE_AND_RETHROW( ( op ) ) }
|
||||||
|
|
||||||
object_id_type bitcoin_transaction_sign_evaluator::do_apply(const bitcoin_transaction_sign_operation &op)
|
//void_result sidechain_transaction_sign_evaluator::do_evaluate(const sidechain_transaction_sign_operation &op)
|
||||||
{
|
//{
|
||||||
try
|
// try
|
||||||
{
|
// {
|
||||||
const auto &proposal = op.proposal_id(db());
|
// FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK"); // can be removed after HF date pass
|
||||||
const auto &sidx = db().get_index_type<son_index>().indices().get<graphene::chain::by_account>();
|
// const auto &proposal_idx = db().get_index_type<proposal_index>().indices().get<by_id>();
|
||||||
auto son_obj = sidx.find(op.payer);
|
// const auto &proposal_itr = proposal_idx.find(op.proposal_id);
|
||||||
|
// FC_ASSERT(proposal_idx.end() != proposal_itr, "proposal not found");
|
||||||
db().modify(proposal, [&](proposal_object &po) {
|
// // Checks can this SON approve this proposal
|
||||||
auto bitcoin_transaction_send_op = po.proposed_transaction.operations[0].get<bitcoin_transaction_send_operation>();
|
// auto can_this_son_approve_this_proposal = [&]() {
|
||||||
bitcoin_transaction_send_op.signatures[son_obj->id] = op.signatures;
|
// const auto &sidx = db().get_index_type<son_index>().indices().get<graphene::chain::by_account>();
|
||||||
po.proposed_transaction.operations[0] = bitcoin_transaction_send_op;
|
// auto son_obj = sidx.find(op.payer);
|
||||||
});
|
// if (son_obj == sidx.end())
|
||||||
|
// {
|
||||||
db().modify( son_obj->statistics( db() ), [&]( son_statistics_object& sso ) {
|
// return false;
|
||||||
sso.txs_signed += 1;
|
// }
|
||||||
} );
|
// // TODO: Check if the SON is included in the PW script.
|
||||||
|
// return true;
|
||||||
update_proposal(op);
|
// };
|
||||||
}
|
//
|
||||||
FC_CAPTURE_AND_RETHROW((op))
|
// FC_ASSERT(can_this_son_approve_this_proposal(), "Invalid approval received");
|
||||||
}
|
// return void_result();
|
||||||
|
// }
|
||||||
void bitcoin_transaction_sign_evaluator::update_proposal(const bitcoin_transaction_sign_operation &op)
|
// FC_CAPTURE_AND_RETHROW((op))
|
||||||
{
|
//}
|
||||||
database &d = db();
|
//
|
||||||
proposal_update_operation update_op;
|
//object_id_type sidechain_transaction_sign_evaluator::do_apply(const sidechain_transaction_sign_operation &op)
|
||||||
|
//{
|
||||||
update_op.fee_paying_account = op.payer;
|
// try
|
||||||
update_op.proposal = op.proposal_id;
|
// {
|
||||||
update_op.active_approvals_to_add = {op.payer};
|
// const auto &proposal = op.proposal_id(db());
|
||||||
|
// const auto &sidx = db().get_index_type<son_index>().indices().get<graphene::chain::by_account>();
|
||||||
bool skip_fee_old = trx_state->skip_fee;
|
// auto son_obj = sidx.find(op.payer);
|
||||||
bool skip_fee_schedule_check_old = trx_state->skip_fee_schedule_check;
|
//
|
||||||
trx_state->skip_fee = true;
|
// db().modify(proposal, [&](proposal_object &po) {
|
||||||
trx_state->skip_fee_schedule_check = true;
|
// auto sidechain_transaction_send_op = po.proposed_transaction.operations[0].get<sidechain_transaction_create_operation>();
|
||||||
|
// sidechain_transaction_send_op.signatures[son_obj->id] = op.signatures;
|
||||||
d.apply_operation(*trx_state, update_op);
|
// po.proposed_transaction.operations[0] = sidechain_transaction_send_op;
|
||||||
|
// });
|
||||||
trx_state->skip_fee = skip_fee_old;
|
//
|
||||||
trx_state->skip_fee_schedule_check = skip_fee_schedule_check_old;
|
// db().modify( son_obj->statistics( db() ), [&]( son_statistics_object& sso ) {
|
||||||
}
|
// sso.txs_signed += 1;
|
||||||
|
// } );
|
||||||
void_result bitcoin_send_transaction_process_evaluator::do_evaluate(const bitcoin_send_transaction_process_operation &op)
|
//
|
||||||
{
|
// update_proposal(op);
|
||||||
try
|
// }
|
||||||
{
|
// FC_CAPTURE_AND_RETHROW((op))
|
||||||
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& btidx = db().get_index_type<bitcoin_transaction_index>().indices().get<by_id>();
|
//void sidechain_transaction_sign_evaluator::update_proposal(const sidechain_transaction_sign_operation &op)
|
||||||
const auto btobj = btidx.find(op.bitcoin_transaction_id);
|
//{
|
||||||
FC_ASSERT(btobj != btidx.end(), "Bitcoin Transaction Object not found");
|
// database &d = db();
|
||||||
FC_ASSERT(btobj->processed == false, "Bitcoin Transaction already processed");
|
// proposal_update_operation update_op;
|
||||||
return void_result();
|
//
|
||||||
}
|
// update_op.fee_paying_account = op.payer;
|
||||||
FC_CAPTURE_AND_RETHROW((op))
|
// update_op.proposal = op.proposal_id;
|
||||||
}
|
// update_op.active_approvals_to_add = {op.payer};
|
||||||
|
//
|
||||||
object_id_type bitcoin_send_transaction_process_evaluator::do_apply(const bitcoin_send_transaction_process_operation &op)
|
// bool skip_fee_old = trx_state->skip_fee;
|
||||||
{
|
// bool skip_fee_schedule_check_old = trx_state->skip_fee_schedule_check;
|
||||||
try
|
// trx_state->skip_fee = true;
|
||||||
{
|
// trx_state->skip_fee_schedule_check = true;
|
||||||
const auto &btidx = db().get_index_type<bitcoin_transaction_index>().indices().get<by_id>();
|
//
|
||||||
auto btobj = btidx.find(op.bitcoin_transaction_id);
|
// d.apply_operation(*trx_state, update_op);
|
||||||
if (btobj != btidx.end())
|
//
|
||||||
{
|
// trx_state->skip_fee = skip_fee_old;
|
||||||
db().modify(*btobj, [&op](bitcoin_transaction_object &bto) {
|
// trx_state->skip_fee_schedule_check = skip_fee_schedule_check_old;
|
||||||
bto.processed = true;
|
//}
|
||||||
});
|
//
|
||||||
}
|
//void_result sidechain_transaction_send_evaluator::do_evaluate(const sidechain_transaction_send_operation &op)
|
||||||
return op.bitcoin_transaction_id;
|
//{
|
||||||
}
|
// try
|
||||||
FC_CAPTURE_AND_RETHROW((op))
|
// {
|
||||||
}
|
// 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& btidx = db().get_index_type<sidechain_transaction_index>().indices().get<by_id>();
|
||||||
|
// const auto btobj = btidx.find(op.sidechain_transaction_id);
|
||||||
|
// FC_ASSERT(btobj != btidx.end(), "Bitcoin Transaction Object not found");
|
||||||
|
// FC_ASSERT(btobj->processed == false, "Bitcoin Transaction already processed");
|
||||||
|
// return void_result();
|
||||||
|
// }
|
||||||
|
// FC_CAPTURE_AND_RETHROW((op))
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//object_id_type sidechain_transaction_send_evaluator::do_apply(const sidechain_transaction_send_operation &op)
|
||||||
|
//{
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// const auto &btidx = db().get_index_type<sidechain_transaction_index>().indices().get<by_id>();
|
||||||
|
// auto btobj = btidx.find(op.sidechain_transaction_id);
|
||||||
|
// if (btobj != btidx.end())
|
||||||
|
// {
|
||||||
|
// db().modify(*btobj, [&op](sidechain_transaction_object &bto) {
|
||||||
|
// bto.processed = true;
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// return op.sidechain_transaction_id;
|
||||||
|
// }
|
||||||
|
// FC_CAPTURE_AND_RETHROW((op))
|
||||||
|
//}
|
||||||
|
|
||||||
} // namespace chain
|
} // namespace chain
|
||||||
} // namespace graphene
|
} // namespace graphene
|
||||||
|
|
|
||||||
|
|
@ -23,10 +23,11 @@ public:
|
||||||
void sidechain_event_data_received(const sidechain_event_data &sed);
|
void sidechain_event_data_received(const sidechain_event_data &sed);
|
||||||
void process_deposits();
|
void process_deposits();
|
||||||
void process_withdrawals();
|
void process_withdrawals();
|
||||||
|
void save_transaction();
|
||||||
|
|
||||||
virtual void recreate_primary_wallet() = 0;
|
virtual std::string recreate_primary_wallet() = 0;
|
||||||
virtual void process_deposit(const son_wallet_deposit_object &swdo) = 0;
|
virtual std::string process_deposit(const son_wallet_deposit_object &swdo) = 0;
|
||||||
virtual void process_withdrawal(const son_wallet_withdraw_object &swwo) = 0;
|
virtual std::string process_withdrawal(const son_wallet_withdraw_object &swwo) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
peerplays_sidechain_plugin &plugin;
|
peerplays_sidechain_plugin &plugin;
|
||||||
|
|
|
||||||
|
|
@ -84,9 +84,9 @@ public:
|
||||||
sidechain_net_handler_bitcoin(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options);
|
sidechain_net_handler_bitcoin(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options);
|
||||||
virtual ~sidechain_net_handler_bitcoin();
|
virtual ~sidechain_net_handler_bitcoin();
|
||||||
|
|
||||||
void recreate_primary_wallet();
|
std::string recreate_primary_wallet();
|
||||||
void process_deposit(const son_wallet_deposit_object &swdo);
|
std::string process_deposit(const son_wallet_deposit_object &swdo);
|
||||||
void process_withdrawal(const son_wallet_withdraw_object &swwo);
|
std::string process_withdrawal(const son_wallet_withdraw_object &swwo);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string ip;
|
std::string ip;
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,9 @@ public:
|
||||||
sidechain_net_handler_peerplays(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options);
|
sidechain_net_handler_peerplays(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options);
|
||||||
virtual ~sidechain_net_handler_peerplays();
|
virtual ~sidechain_net_handler_peerplays();
|
||||||
|
|
||||||
void recreate_primary_wallet();
|
std::string recreate_primary_wallet();
|
||||||
void process_deposit(const son_wallet_deposit_object &swdo);
|
std::string process_deposit(const son_wallet_deposit_object &swdo);
|
||||||
void process_withdrawal(const son_wallet_withdraw_object &swwo);
|
std::string process_withdrawal(const son_wallet_withdraw_object &swwo);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void on_applied_block(const signed_block &b);
|
void on_applied_block(const signed_block &b);
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@ private:
|
||||||
fc::future<void> _heartbeat_task;
|
fc::future<void> _heartbeat_task;
|
||||||
fc::future<void> _son_processing_task;
|
fc::future<void> _son_processing_task;
|
||||||
|
|
||||||
|
bool first_block_skipped;
|
||||||
void on_applied_block(const signed_block &b);
|
void on_applied_block(const signed_block &b);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -76,7 +77,8 @@ peerplays_sidechain_plugin_impl::peerplays_sidechain_plugin_impl(peerplays_sidec
|
||||||
config_ready_bitcoin(false),
|
config_ready_bitcoin(false),
|
||||||
config_ready_peerplays(false),
|
config_ready_peerplays(false),
|
||||||
current_son_id(son_id_type(std::numeric_limits<uint32_t>().max())),
|
current_son_id(son_id_type(std::numeric_limits<uint32_t>().max())),
|
||||||
net_manager(nullptr) {
|
net_manager(nullptr),
|
||||||
|
first_block_skipped(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
peerplays_sidechain_plugin_impl::~peerplays_sidechain_plugin_impl() {
|
peerplays_sidechain_plugin_impl::~peerplays_sidechain_plugin_impl() {
|
||||||
|
|
@ -428,6 +430,8 @@ void peerplays_sidechain_plugin_impl::approve_proposals() {
|
||||||
approve_proposal(son_id, proposal.id);
|
approve_proposal(son_id, proposal.id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
approve_proposal(son_id, proposal.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -535,7 +539,11 @@ void peerplays_sidechain_plugin_impl::process_withdrawals() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void peerplays_sidechain_plugin_impl::on_applied_block(const signed_block &b) {
|
void peerplays_sidechain_plugin_impl::on_applied_block(const signed_block &b) {
|
||||||
schedule_son_processing();
|
if (first_block_skipped) {
|
||||||
|
schedule_son_processing();
|
||||||
|
} else {
|
||||||
|
first_block_skipped = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace detail
|
} // end namespace detail
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,8 @@
|
||||||
|
|
||||||
#include <fc/log/logger.hpp>
|
#include <fc/log/logger.hpp>
|
||||||
|
|
||||||
namespace graphene { namespace peerplays_sidechain {
|
namespace graphene {
|
||||||
|
namespace peerplays_sidechain {
|
||||||
|
|
||||||
sidechain_net_handler::sidechain_net_handler(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options) :
|
sidechain_net_handler::sidechain_net_handler(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options) :
|
||||||
plugin(_plugin),
|
plugin(_plugin),
|
||||||
|
|
@ -164,80 +165,120 @@ 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 = 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));
|
const auto &idx_range = idx.equal_range(std::make_tuple(sidechain, false));
|
||||||
|
|
||||||
std::for_each(idx_range.first, idx_range.second,
|
std::for_each(idx_range.first, idx_range.second, [&](const son_wallet_deposit_object &swdo) {
|
||||||
[&](const son_wallet_deposit_object &swdo) {
|
ilog("Deposit to process: ${swdo}", ("swdo", swdo));
|
||||||
ilog("Deposit to process: ${swdo}", ("swdo", swdo));
|
|
||||||
|
|
||||||
process_deposit(swdo);
|
std::string sidechain_tx = process_deposit(swdo);
|
||||||
|
|
||||||
const chain::global_property_object &gpo = plugin.database().get_global_properties();
|
if (sidechain_tx.empty()) {
|
||||||
|
ilog("Deposit not processed: ${swdo}", ("swdo", swdo));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
son_wallet_deposit_process_operation p_op;
|
const chain::global_property_object &gpo = database.get_global_properties();
|
||||||
p_op.payer = GRAPHENE_SON_ACCOUNT;
|
|
||||||
p_op.son_wallet_deposit_id = swdo.id;
|
|
||||||
|
|
||||||
proposal_create_operation proposal_op;
|
auto active_sons = gpo.active_sons;
|
||||||
proposal_op.fee_paying_account = plugin.get_son_object(plugin.get_current_son_id()).son_account;
|
std::vector<std::pair<son_id_type, bool>> signatures;
|
||||||
proposal_op.proposed_ops.emplace_back(op_wrapper(p_op));
|
for (const son_info &si : active_sons) {
|
||||||
uint32_t lifetime = (gpo.parameters.block_interval * gpo.active_witnesses.size()) * 3;
|
signatures.push_back(std::make_pair(si.son_id, false));
|
||||||
proposal_op.expiration_time = time_point_sec(plugin.database().head_block_time().sec_since_epoch() + lifetime);
|
}
|
||||||
|
|
||||||
signed_transaction trx = plugin.database().create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), proposal_op);
|
sidechain_transaction_create_operation stc_op;
|
||||||
trx.validate();
|
stc_op.payer = GRAPHENE_SON_ACCOUNT;
|
||||||
try {
|
//stc_op.son_wallet_id = ; // not set, not needed
|
||||||
plugin.database().push_transaction(trx, database::validation_steps::skip_block_size_check);
|
stc_op.son_wallet_deposit_id = swdo.id;
|
||||||
if (plugin.app().p2p_node())
|
//stc_op.son_wallet_withdraw_id = ; // not set, not needed
|
||||||
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
|
stc_op.sidechain = sidechain;
|
||||||
} catch (fc::exception e) {
|
stc_op.transaction = sidechain_tx;
|
||||||
ilog("sidechain_net_handler: sending proposal for transfer operation failed with exception ${e}", ("e", e.what()));
|
stc_op.signatures = signatures;
|
||||||
}
|
|
||||||
});
|
son_wallet_deposit_process_operation swdp_op;
|
||||||
|
swdp_op.payer = GRAPHENE_SON_ACCOUNT;
|
||||||
|
swdp_op.son_wallet_deposit_id = swdo.id;
|
||||||
|
|
||||||
|
proposal_create_operation proposal_op;
|
||||||
|
proposal_op.fee_paying_account = plugin.get_son_object(plugin.get_current_son_id()).son_account;
|
||||||
|
proposal_op.proposed_ops.emplace_back(op_wrapper(stc_op));
|
||||||
|
proposal_op.proposed_ops.emplace_back(op_wrapper(swdp_op));
|
||||||
|
uint32_t lifetime = (gpo.parameters.block_interval * gpo.active_witnesses.size()) * 3;
|
||||||
|
proposal_op.expiration_time = time_point_sec(plugin.database().head_block_time().sec_since_epoch() + lifetime);
|
||||||
|
|
||||||
|
signed_transaction trx = plugin.database().create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), proposal_op);
|
||||||
|
trx.validate();
|
||||||
|
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() {
|
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 = 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));
|
const auto &idx_range = idx.equal_range(std::make_tuple(sidechain, false));
|
||||||
|
|
||||||
std::for_each(idx_range.first, idx_range.second,
|
std::for_each(idx_range.first, idx_range.second, [&](const son_wallet_withdraw_object &swwo) {
|
||||||
[&](const son_wallet_withdraw_object &swwo) {
|
ilog("Withdraw to process: ${swwo}", ("swwo", swwo));
|
||||||
ilog("Withdraw to process: ${swwo}", ("swwo", swwo));
|
|
||||||
|
|
||||||
process_withdrawal(swwo);
|
std::string sidechain_tx = process_withdrawal(swwo);
|
||||||
|
|
||||||
const chain::global_property_object &gpo = plugin.database().get_global_properties();
|
if (sidechain_tx.empty()) {
|
||||||
|
ilog("Withdraw not processed: ${swwo}", ("swwo", swwo));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
son_wallet_withdraw_process_operation p_op;
|
const chain::global_property_object &gpo = database.get_global_properties();
|
||||||
p_op.payer = GRAPHENE_SON_ACCOUNT;
|
|
||||||
p_op.son_wallet_withdraw_id = swwo.id;
|
|
||||||
|
|
||||||
proposal_create_operation proposal_op;
|
auto active_sons = gpo.active_sons;
|
||||||
proposal_op.fee_paying_account = plugin.get_son_object(plugin.get_current_son_id()).son_account;
|
std::vector<std::pair<son_id_type, bool>> signatures;
|
||||||
proposal_op.proposed_ops.emplace_back(op_wrapper(p_op));
|
for (const son_info &si : active_sons) {
|
||||||
uint32_t lifetime = (gpo.parameters.block_interval * gpo.active_witnesses.size()) * 3;
|
signatures.push_back(std::make_pair(si.son_id, false));
|
||||||
proposal_op.expiration_time = time_point_sec(plugin.database().head_block_time().sec_since_epoch() + lifetime);
|
}
|
||||||
|
|
||||||
signed_transaction trx = plugin.database().create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), proposal_op);
|
sidechain_transaction_create_operation stc_op;
|
||||||
trx.validate();
|
stc_op.payer = GRAPHENE_SON_ACCOUNT;
|
||||||
try {
|
//stc_op.son_wallet_id = ; // not set, not needed
|
||||||
plugin.database().push_transaction(trx, database::validation_steps::skip_block_size_check);
|
//stc_op.son_wallet_deposit_id = ; // not set, not needed
|
||||||
if (plugin.app().p2p_node())
|
stc_op.son_wallet_withdraw_id = swwo.id;
|
||||||
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
|
stc_op.sidechain = sidechain;
|
||||||
} catch (fc::exception e) {
|
stc_op.transaction = sidechain_tx;
|
||||||
ilog("sidechain_net_handler: sending proposal for transfer operation failed with exception ${e}", ("e", e.what()));
|
stc_op.signatures = signatures;
|
||||||
}
|
|
||||||
});
|
son_wallet_withdraw_process_operation swwp_op;
|
||||||
|
swwp_op.payer = GRAPHENE_SON_ACCOUNT;
|
||||||
|
swwp_op.son_wallet_withdraw_id = swwo.id;
|
||||||
|
|
||||||
|
proposal_create_operation proposal_op;
|
||||||
|
proposal_op.fee_paying_account = plugin.get_son_object(plugin.get_current_son_id()).son_account;
|
||||||
|
proposal_op.proposed_ops.emplace_back(op_wrapper(stc_op));
|
||||||
|
proposal_op.proposed_ops.emplace_back(op_wrapper(swwp_op));
|
||||||
|
uint32_t lifetime = (gpo.parameters.block_interval * gpo.active_witnesses.size()) * 3;
|
||||||
|
proposal_op.expiration_time = time_point_sec(plugin.database().head_block_time().sec_since_epoch() + lifetime);
|
||||||
|
|
||||||
|
signed_transaction trx = plugin.database().create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), proposal_op);
|
||||||
|
trx.validate();
|
||||||
|
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::recreate_primary_wallet() {
|
std::string sidechain_net_handler::recreate_primary_wallet() {
|
||||||
FC_ASSERT(false, "recreate_primary_wallet not implemented");
|
FC_ASSERT(false, "recreate_primary_wallet not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
void sidechain_net_handler::process_deposit(const son_wallet_deposit_object &swdo) {
|
std::string sidechain_net_handler::process_deposit(const son_wallet_deposit_object &swdo) {
|
||||||
FC_ASSERT(false, "process_deposit not implemented");
|
FC_ASSERT(false, "process_deposit not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
void sidechain_net_handler::process_withdrawal(const son_wallet_withdraw_object &swwo) {
|
std::string sidechain_net_handler::process_withdrawal(const son_wallet_withdraw_object &swwo) {
|
||||||
FC_ASSERT(false, "process_withdrawal not implemented");
|
FC_ASSERT(false, "process_withdrawal not implemented");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}} // namespace graphene::peerplays_sidechain
|
} // namespace graphene::peerplays_sidechain
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
#include <fc/network/ip.hpp>
|
#include <fc/network/ip.hpp>
|
||||||
|
|
||||||
#include <graphene/chain/account_object.hpp>
|
#include <graphene/chain/account_object.hpp>
|
||||||
|
#include <graphene/chain/protocol/sidechain_transaction.hpp>
|
||||||
#include <graphene/chain/protocol/son_wallet.hpp>
|
#include <graphene/chain/protocol/son_wallet.hpp>
|
||||||
#include <graphene/chain/sidechain_address_object.hpp>
|
#include <graphene/chain/sidechain_address_object.hpp>
|
||||||
#include <graphene/chain/son_info.hpp>
|
#include <graphene/chain/son_info.hpp>
|
||||||
|
|
@ -771,7 +772,8 @@ sidechain_net_handler_bitcoin::sidechain_net_handler_bitcoin(peerplays_sidechain
|
||||||
sidechain_net_handler_bitcoin::~sidechain_net_handler_bitcoin() {
|
sidechain_net_handler_bitcoin::~sidechain_net_handler_bitcoin() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void sidechain_net_handler_bitcoin::recreate_primary_wallet() {
|
std::string sidechain_net_handler_bitcoin::recreate_primary_wallet() {
|
||||||
|
std::string tx = "";
|
||||||
const auto &swi = database.get_index_type<son_wallet_index>().indices().get<by_id>();
|
const auto &swi = database.get_index_type<son_wallet_index>().indices().get<by_id>();
|
||||||
const auto &active_sw = swi.rbegin();
|
const auto &active_sw = swi.rbegin();
|
||||||
if (active_sw != swi.rend()) {
|
if (active_sw != swi.rend()) {
|
||||||
|
|
@ -815,7 +817,7 @@ void sidechain_net_handler_bitcoin::recreate_primary_wallet() {
|
||||||
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
|
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
|
||||||
} catch (fc::exception e) {
|
} catch (fc::exception e) {
|
||||||
ilog("sidechain_net_handler: sending proposal for 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()));
|
||||||
return;
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto &prev_sw = std::next(active_sw);
|
const auto &prev_sw = std::next(active_sw);
|
||||||
|
|
@ -827,19 +829,25 @@ void sidechain_net_handler_bitcoin::recreate_primary_wallet() {
|
||||||
std::string active_pw_address = active_pw_pt.get_child("result").get<std::string>("address");
|
std::string active_pw_address = active_pw_pt.get_child("result").get<std::string>("address");
|
||||||
std::string prev_pw_address = prev_sw_pt.get<std::string>("address");
|
std::string prev_pw_address = prev_sw_pt.get<std::string>("address");
|
||||||
|
|
||||||
transfer_all_btc(prev_pw_address, active_pw_address);
|
tx = transfer_all_btc(prev_pw_address, active_pw_address);
|
||||||
|
sign_transaction(tx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return tx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sidechain_net_handler_bitcoin::process_deposit(const son_wallet_deposit_object &swdo) {
|
std::string sidechain_net_handler_bitcoin::process_deposit(const son_wallet_deposit_object &swdo) {
|
||||||
transfer_deposit_to_primary_wallet(swdo);
|
std::string tx = transfer_deposit_to_primary_wallet(swdo);
|
||||||
|
sign_transaction(tx);
|
||||||
|
return tx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sidechain_net_handler_bitcoin::process_withdrawal(const son_wallet_withdraw_object &swwo) {
|
std::string sidechain_net_handler_bitcoin::process_withdrawal(const son_wallet_withdraw_object &swwo) {
|
||||||
transfer_withdrawal_from_primary_wallet(swwo);
|
std::string tx = transfer_withdrawal_from_primary_wallet(swwo);
|
||||||
|
sign_transaction(tx);
|
||||||
|
return tx;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates transaction in any format
|
// Creates transaction in any format
|
||||||
|
|
@ -1048,8 +1056,7 @@ std::string sidechain_net_handler_bitcoin::transfer_all_btc(const std::string &f
|
||||||
fc::flat_map<std::string, double> outputs;
|
fc::flat_map<std::string, double> outputs;
|
||||||
outputs[to_address] = total_amount - min_amount;
|
outputs[to_address] = total_amount - min_amount;
|
||||||
|
|
||||||
std::string tx = create_transaction(inputs, outputs);
|
return create_transaction(inputs, outputs);
|
||||||
return sign_transaction(tx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string sidechain_net_handler_bitcoin::transfer_deposit_to_primary_wallet(const son_wallet_deposit_object &swdo) {
|
std::string sidechain_net_handler_bitcoin::transfer_deposit_to_primary_wallet(const son_wallet_deposit_object &swdo) {
|
||||||
|
|
@ -1088,8 +1095,7 @@ std::string sidechain_net_handler_bitcoin::transfer_deposit_to_primary_wallet(co
|
||||||
|
|
||||||
outputs[pw_address] = transfer_amount;
|
outputs[pw_address] = transfer_amount;
|
||||||
|
|
||||||
std::string tx = create_transaction(inputs, outputs);
|
return create_transaction(inputs, outputs);
|
||||||
return sign_transaction(tx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string sidechain_net_handler_bitcoin::transfer_withdrawal_from_primary_wallet(const son_wallet_withdraw_object &swwo) {
|
std::string sidechain_net_handler_bitcoin::transfer_withdrawal_from_primary_wallet(const son_wallet_withdraw_object &swwo) {
|
||||||
|
|
@ -1135,8 +1141,7 @@ std::string sidechain_net_handler_bitcoin::transfer_withdrawal_from_primary_wall
|
||||||
outs[pw_address] = total_amount - min_amount;
|
outs[pw_address] = total_amount - min_amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string tx = create_transaction(unspent_utxo, outs);
|
return create_transaction(unspent_utxo, outs);
|
||||||
return sign_transaction(tx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sidechain_net_handler_bitcoin::handle_event(const std::string &event_data) {
|
void sidechain_net_handler_bitcoin::handle_event(const std::string &event_data) {
|
||||||
|
|
|
||||||
|
|
@ -30,13 +30,16 @@ sidechain_net_handler_peerplays::sidechain_net_handler_peerplays(peerplays_sidec
|
||||||
sidechain_net_handler_peerplays::~sidechain_net_handler_peerplays() {
|
sidechain_net_handler_peerplays::~sidechain_net_handler_peerplays() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void sidechain_net_handler_peerplays::recreate_primary_wallet() {
|
std::string sidechain_net_handler_peerplays::recreate_primary_wallet() {
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void sidechain_net_handler_peerplays::process_deposit(const son_wallet_deposit_object &swdo) {
|
std::string sidechain_net_handler_peerplays::process_deposit(const son_wallet_deposit_object &swdo) {
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void sidechain_net_handler_peerplays::process_withdrawal(const son_wallet_withdraw_object &swwo) {
|
std::string sidechain_net_handler_peerplays::process_withdrawal(const son_wallet_withdraw_object &swwo) {
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void sidechain_net_handler_peerplays::on_applied_block(const signed_block &b) {
|
void sidechain_net_handler_peerplays::on_applied_block(const signed_block &b) {
|
||||||
|
|
|
||||||
|
|
@ -1,386 +1,386 @@
|
||||||
#include <boost/test/unit_test.hpp>
|
//#include <boost/test/unit_test.hpp>
|
||||||
|
//
|
||||||
#include "../common/database_fixture.hpp"
|
//#include "../common/database_fixture.hpp"
|
||||||
|
//
|
||||||
#include <graphene/chain/hardfork.hpp>
|
//#include <graphene/chain/hardfork.hpp>
|
||||||
#include <graphene/chain/sidechain_transaction_object.hpp>
|
//#include <graphene/chain/sidechain_transaction_object.hpp>
|
||||||
#include <graphene/chain/proposal_object.hpp>
|
//#include <graphene/chain/proposal_object.hpp>
|
||||||
#include <graphene/chain/son_object.hpp>
|
//#include <graphene/chain/son_object.hpp>
|
||||||
#include <graphene/peerplays_sidechain/defs.hpp>
|
//#include <graphene/peerplays_sidechain/defs.hpp>
|
||||||
|
//
|
||||||
using namespace graphene;
|
//using namespace graphene;
|
||||||
using namespace graphene::chain;
|
//using namespace graphene::chain;
|
||||||
using namespace graphene::chain::test;
|
//using namespace graphene::chain::test;
|
||||||
|
//
|
||||||
BOOST_FIXTURE_TEST_SUITE(sidechain_transaction_tests, database_fixture)
|
//BOOST_FIXTURE_TEST_SUITE(sidechain_transaction_tests, database_fixture)
|
||||||
|
//
|
||||||
BOOST_AUTO_TEST_CASE(bitcoin_transaction_send_test)
|
//BOOST_AUTO_TEST_CASE(bitcoin_transaction_send_test)
|
||||||
{
|
//{
|
||||||
|
//
|
||||||
try
|
// try
|
||||||
{
|
// {
|
||||||
BOOST_TEST_MESSAGE("bitcoin_transaction_send_test");
|
// BOOST_TEST_MESSAGE("bitcoin_transaction_send_test");
|
||||||
|
//
|
||||||
generate_blocks(HARDFORK_SON_TIME);
|
// generate_blocks(HARDFORK_SON_TIME);
|
||||||
generate_block();
|
// generate_block();
|
||||||
set_expiration(db, trx);
|
// set_expiration(db, trx);
|
||||||
|
//
|
||||||
ACTORS((alice)(bob));
|
// ACTORS((alice)(bob));
|
||||||
|
//
|
||||||
upgrade_to_lifetime_member(alice);
|
// upgrade_to_lifetime_member(alice);
|
||||||
upgrade_to_lifetime_member(bob);
|
// upgrade_to_lifetime_member(bob);
|
||||||
|
//
|
||||||
transfer(committee_account, alice_id, asset(500000 * GRAPHENE_BLOCKCHAIN_PRECISION));
|
// transfer(committee_account, alice_id, asset(500000 * GRAPHENE_BLOCKCHAIN_PRECISION));
|
||||||
transfer(committee_account, bob_id, asset(500000 * GRAPHENE_BLOCKCHAIN_PRECISION));
|
// transfer(committee_account, bob_id, asset(500000 * GRAPHENE_BLOCKCHAIN_PRECISION));
|
||||||
|
//
|
||||||
generate_block();
|
// generate_block();
|
||||||
set_expiration(db, trx);
|
// set_expiration(db, trx);
|
||||||
|
//
|
||||||
std::string test_url = "https://create_son_test";
|
// std::string test_url = "https://create_son_test";
|
||||||
|
//
|
||||||
// create deposit vesting
|
// // create deposit vesting
|
||||||
vesting_balance_id_type deposit_alice;
|
// vesting_balance_id_type deposit_alice;
|
||||||
{
|
// {
|
||||||
vesting_balance_create_operation op;
|
// vesting_balance_create_operation op;
|
||||||
op.creator = alice_id;
|
// op.creator = alice_id;
|
||||||
op.owner = alice_id;
|
// op.owner = alice_id;
|
||||||
op.amount = asset(500 * GRAPHENE_BLOCKCHAIN_PRECISION);
|
// op.amount = asset(500 * GRAPHENE_BLOCKCHAIN_PRECISION);
|
||||||
op.balance_type = vesting_balance_type::son;
|
// op.balance_type = vesting_balance_type::son;
|
||||||
op.policy = dormant_vesting_policy_initializer{};
|
// op.policy = dormant_vesting_policy_initializer{};
|
||||||
trx.operations.push_back(op);
|
// trx.operations.push_back(op);
|
||||||
sign(trx, alice_private_key);
|
// sign(trx, alice_private_key);
|
||||||
processed_transaction ptx = PUSH_TX(db, trx, ~0);
|
// processed_transaction ptx = PUSH_TX(db, trx, ~0);
|
||||||
trx.clear();
|
// trx.clear();
|
||||||
deposit_alice = ptx.operation_results[0].get<object_id_type>();
|
// deposit_alice = ptx.operation_results[0].get<object_id_type>();
|
||||||
}
|
// }
|
||||||
generate_block();
|
// generate_block();
|
||||||
set_expiration(db, trx);
|
// set_expiration(db, trx);
|
||||||
|
//
|
||||||
// create payment normal vesting
|
// // create payment normal vesting
|
||||||
vesting_balance_id_type payment_alice;
|
// vesting_balance_id_type payment_alice;
|
||||||
{
|
// {
|
||||||
vesting_balance_create_operation op;
|
// vesting_balance_create_operation op;
|
||||||
op.creator = alice_id;
|
// op.creator = alice_id;
|
||||||
op.owner = alice_id;
|
// op.owner = alice_id;
|
||||||
op.amount = asset(500 * GRAPHENE_BLOCKCHAIN_PRECISION);
|
// op.amount = asset(500 * GRAPHENE_BLOCKCHAIN_PRECISION);
|
||||||
op.balance_type = vesting_balance_type::normal;
|
// op.balance_type = vesting_balance_type::normal;
|
||||||
trx.operations.push_back(op);
|
// trx.operations.push_back(op);
|
||||||
sign(trx, alice_private_key);
|
// sign(trx, alice_private_key);
|
||||||
processed_transaction ptx = PUSH_TX(db, trx, ~0);
|
// processed_transaction ptx = PUSH_TX(db, trx, ~0);
|
||||||
trx.clear();
|
// trx.clear();
|
||||||
payment_alice = ptx.operation_results[0].get<object_id_type>();
|
// payment_alice = ptx.operation_results[0].get<object_id_type>();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
generate_block();
|
// generate_block();
|
||||||
set_expiration(db, trx);
|
// set_expiration(db, trx);
|
||||||
|
//
|
||||||
// alice becomes son
|
// // alice becomes son
|
||||||
{
|
// {
|
||||||
flat_map<graphene::peerplays_sidechain::sidechain_type, string> sidechain_public_keys;
|
// flat_map<graphene::peerplays_sidechain::sidechain_type, string> sidechain_public_keys;
|
||||||
sidechain_public_keys[graphene::peerplays_sidechain::sidechain_type::bitcoin] = "bitcoin address";
|
// sidechain_public_keys[graphene::peerplays_sidechain::sidechain_type::bitcoin] = "bitcoin address";
|
||||||
|
//
|
||||||
son_create_operation op;
|
// son_create_operation op;
|
||||||
op.owner_account = alice_id;
|
// op.owner_account = alice_id;
|
||||||
op.url = test_url;
|
// op.url = test_url;
|
||||||
op.deposit = deposit_alice;
|
// op.deposit = deposit_alice;
|
||||||
op.pay_vb = payment_alice;
|
// op.pay_vb = payment_alice;
|
||||||
op.signing_key = alice_public_key;
|
// op.signing_key = alice_public_key;
|
||||||
op.sidechain_public_keys = sidechain_public_keys;
|
// op.sidechain_public_keys = sidechain_public_keys;
|
||||||
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);
|
||||||
trx.clear();
|
// trx.clear();
|
||||||
}
|
// }
|
||||||
generate_block();
|
// generate_block();
|
||||||
set_expiration(db, trx);
|
// set_expiration(db, trx);
|
||||||
|
//
|
||||||
// create deposit vesting
|
// // create deposit vesting
|
||||||
vesting_balance_id_type deposit_bob;
|
// vesting_balance_id_type deposit_bob;
|
||||||
{
|
// {
|
||||||
vesting_balance_create_operation op;
|
// vesting_balance_create_operation op;
|
||||||
op.creator = bob_id;
|
// op.creator = bob_id;
|
||||||
op.owner = bob_id;
|
// op.owner = bob_id;
|
||||||
op.amount = asset(500 * GRAPHENE_BLOCKCHAIN_PRECISION);
|
// op.amount = asset(500 * GRAPHENE_BLOCKCHAIN_PRECISION);
|
||||||
op.balance_type = vesting_balance_type::son;
|
// op.balance_type = vesting_balance_type::son;
|
||||||
op.policy = dormant_vesting_policy_initializer{};
|
// op.policy = dormant_vesting_policy_initializer{};
|
||||||
trx.operations.push_back(op);
|
// trx.operations.push_back(op);
|
||||||
sign(trx, bob_private_key);
|
// sign(trx, bob_private_key);
|
||||||
processed_transaction ptx = PUSH_TX(db, trx, ~0);
|
// processed_transaction ptx = PUSH_TX(db, trx, ~0);
|
||||||
trx.clear();
|
// trx.clear();
|
||||||
deposit_bob = ptx.operation_results[0].get<object_id_type>();
|
// deposit_bob = ptx.operation_results[0].get<object_id_type>();
|
||||||
}
|
// }
|
||||||
generate_block();
|
// generate_block();
|
||||||
set_expiration(db, trx);
|
// set_expiration(db, trx);
|
||||||
|
//
|
||||||
// create payment normal vesting
|
// // create payment normal vesting
|
||||||
vesting_balance_id_type payment_bob;
|
// vesting_balance_id_type payment_bob;
|
||||||
{
|
// {
|
||||||
vesting_balance_create_operation op;
|
// vesting_balance_create_operation op;
|
||||||
op.creator = bob_id;
|
// op.creator = bob_id;
|
||||||
op.owner = bob_id;
|
// op.owner = bob_id;
|
||||||
op.amount = asset(500 * GRAPHENE_BLOCKCHAIN_PRECISION);
|
// op.amount = asset(500 * GRAPHENE_BLOCKCHAIN_PRECISION);
|
||||||
op.balance_type = vesting_balance_type::normal;
|
// op.balance_type = vesting_balance_type::normal;
|
||||||
trx.operations.push_back(op);
|
// trx.operations.push_back(op);
|
||||||
sign(trx, bob_private_key);
|
// sign(trx, bob_private_key);
|
||||||
processed_transaction ptx = PUSH_TX(db, trx, ~0);
|
// processed_transaction ptx = PUSH_TX(db, trx, ~0);
|
||||||
trx.clear();
|
// trx.clear();
|
||||||
payment_bob = ptx.operation_results[0].get<object_id_type>();
|
// payment_bob = ptx.operation_results[0].get<object_id_type>();
|
||||||
}
|
// }
|
||||||
generate_block();
|
// generate_block();
|
||||||
set_expiration(db, trx);
|
// set_expiration(db, trx);
|
||||||
|
//
|
||||||
// bob becomes son
|
// // bob becomes son
|
||||||
{
|
// {
|
||||||
flat_map<graphene::peerplays_sidechain::sidechain_type, string> sidechain_public_keys;
|
// flat_map<graphene::peerplays_sidechain::sidechain_type, string> sidechain_public_keys;
|
||||||
sidechain_public_keys[graphene::peerplays_sidechain::sidechain_type::bitcoin] = "bitcoin address";
|
// sidechain_public_keys[graphene::peerplays_sidechain::sidechain_type::bitcoin] = "bitcoin address";
|
||||||
|
//
|
||||||
son_create_operation op;
|
// son_create_operation op;
|
||||||
op.owner_account = bob_id;
|
// op.owner_account = bob_id;
|
||||||
op.url = test_url;
|
// op.url = test_url;
|
||||||
op.deposit = deposit_bob;
|
// op.deposit = deposit_bob;
|
||||||
op.pay_vb = payment_bob;
|
// op.pay_vb = payment_bob;
|
||||||
op.signing_key = bob_public_key;
|
// op.signing_key = bob_public_key;
|
||||||
op.sidechain_public_keys = sidechain_public_keys;
|
// op.sidechain_public_keys = sidechain_public_keys;
|
||||||
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);
|
||||||
trx.clear();
|
// trx.clear();
|
||||||
}
|
// }
|
||||||
generate_block();
|
// generate_block();
|
||||||
|
//
|
||||||
generate_block();
|
// generate_block();
|
||||||
|
//
|
||||||
const auto& acc_idx = db.get_index_type<account_index>().indices().get<by_id>();
|
// const auto& acc_idx = db.get_index_type<account_index>().indices().get<by_id>();
|
||||||
auto acc_itr = acc_idx.find(GRAPHENE_SON_ACCOUNT);
|
// auto acc_itr = acc_idx.find(GRAPHENE_SON_ACCOUNT);
|
||||||
BOOST_REQUIRE(acc_itr != acc_idx.end());
|
// BOOST_REQUIRE(acc_itr != acc_idx.end());
|
||||||
db.modify(*acc_itr, [&](account_object &obj) {
|
// db.modify(*acc_itr, [&](account_object &obj) {
|
||||||
obj.active.account_auths.clear();
|
// obj.active.account_auths.clear();
|
||||||
obj.active.add_authority(bob_id, 1);
|
// obj.active.add_authority(bob_id, 1);
|
||||||
obj.active.add_authority(alice_id, 1);
|
// obj.active.add_authority(alice_id, 1);
|
||||||
obj.active.weight_threshold = 2;
|
// obj.active.weight_threshold = 2;
|
||||||
obj.owner.account_auths.clear();
|
// obj.owner.account_auths.clear();
|
||||||
obj.owner.add_authority(bob_id, 1);
|
// obj.owner.add_authority(bob_id, 1);
|
||||||
obj.owner.add_authority(alice_id, 1);
|
// obj.owner.add_authority(alice_id, 1);
|
||||||
obj.owner.weight_threshold = 2;
|
// obj.owner.weight_threshold = 2;
|
||||||
});
|
// });
|
||||||
|
//
|
||||||
/*const auto &son_btc_account = db.create<account_object>([&](account_object &obj) {
|
// /*const auto &son_btc_account = db.create<account_object>([&](account_object &obj) {
|
||||||
obj.name = "son_btc_account";
|
// obj.name = "son_btc_account";
|
||||||
obj.statistics = db.create<account_statistics_object>([&](account_statistics_object &acc_stat) { acc_stat.owner = obj.id; }).id;
|
// 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.membership_expiration_date = time_point_sec::maximum();
|
||||||
obj.network_fee_percentage = GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE;
|
// 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.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT - GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE;
|
||||||
|
//
|
||||||
obj.owner.add_authority(bob_id, 1);
|
// obj.owner.add_authority(bob_id, 1);
|
||||||
obj.active.add_authority(bob_id, 1);
|
// obj.active.add_authority(bob_id, 1);
|
||||||
obj.owner.add_authority(alice_id, 1);
|
// obj.owner.add_authority(alice_id, 1);
|
||||||
obj.active.add_authority(alice_id, 1);
|
// obj.active.add_authority(alice_id, 1);
|
||||||
obj.active.weight_threshold = 2;
|
// obj.active.weight_threshold = 2;
|
||||||
obj.owner.weight_threshold = 2;
|
// obj.owner.weight_threshold = 2;
|
||||||
});
|
// });
|
||||||
|
//
|
||||||
db.modify( db.get_global_properties(), [&]( global_property_object& _gpo )
|
// db.modify( db.get_global_properties(), [&]( global_property_object& _gpo )
|
||||||
{
|
// {
|
||||||
_gpo.parameters.extensions.value.son_btc_account = son_btc_account.get_id();
|
// _gpo.parameters.extensions.value.son_btc_account = son_btc_account.get_id();
|
||||||
if( _gpo.pending_parameters )
|
// if( _gpo.pending_parameters )
|
||||||
_gpo.pending_parameters->extensions.value.son_btc_account = son_btc_account.get_id();
|
// _gpo.pending_parameters->extensions.value.son_btc_account = son_btc_account.get_id();
|
||||||
});*/
|
// });*/
|
||||||
|
//
|
||||||
generate_block();
|
// generate_block();
|
||||||
|
//
|
||||||
const global_property_object &gpo = db.get_global_properties();
|
// const global_property_object &gpo = db.get_global_properties();
|
||||||
|
//
|
||||||
{
|
// {
|
||||||
BOOST_TEST_MESSAGE("Send bitcoin_transaction_send_operation");
|
// BOOST_TEST_MESSAGE("Send bitcoin_transaction_send_operation");
|
||||||
|
//
|
||||||
bitcoin_transaction_send_operation send_op;
|
// bitcoin_transaction_send_operation send_op;
|
||||||
|
//
|
||||||
send_op.payer = GRAPHENE_SON_ACCOUNT;
|
// send_op.payer = GRAPHENE_SON_ACCOUNT;
|
||||||
|
//
|
||||||
proposal_create_operation proposal_op;
|
// proposal_create_operation proposal_op;
|
||||||
proposal_op.fee_paying_account = alice_id;
|
// proposal_op.fee_paying_account = alice_id;
|
||||||
proposal_op.proposed_ops.push_back(op_wrapper(send_op));
|
// proposal_op.proposed_ops.push_back(op_wrapper(send_op));
|
||||||
uint32_t lifetime = (gpo.parameters.block_interval * gpo.active_witnesses.size()) * 3;
|
// uint32_t lifetime = (gpo.parameters.block_interval * gpo.active_witnesses.size()) * 3;
|
||||||
proposal_op.expiration_time = time_point_sec(db.head_block_time().sec_since_epoch() + lifetime);
|
// proposal_op.expiration_time = time_point_sec(db.head_block_time().sec_since_epoch() + lifetime);
|
||||||
|
//
|
||||||
trx.operations.push_back(proposal_op);
|
// trx.operations.push_back(proposal_op);
|
||||||
set_expiration(db, trx);
|
// set_expiration(db, trx);
|
||||||
sign(trx, alice_private_key);
|
// sign(trx, alice_private_key);
|
||||||
PUSH_TX(db, trx, ~0);
|
// PUSH_TX(db, trx, ~0);
|
||||||
trx.clear();
|
// trx.clear();
|
||||||
}
|
// }
|
||||||
generate_block();
|
// generate_block();
|
||||||
|
//
|
||||||
BOOST_TEST_MESSAGE("Check proposal results");
|
// BOOST_TEST_MESSAGE("Check proposal results");
|
||||||
|
//
|
||||||
const auto &idx = db.get_index_type<proposal_index>().indices().get<by_id>();
|
// const auto &idx = db.get_index_type<proposal_index>().indices().get<by_id>();
|
||||||
BOOST_REQUIRE(idx.size() == 1);
|
// BOOST_REQUIRE(idx.size() == 1);
|
||||||
auto obj = idx.find(proposal_id_type(0));
|
// auto obj = idx.find(proposal_id_type(0));
|
||||||
BOOST_REQUIRE(obj != idx.end());
|
// BOOST_REQUIRE(obj != idx.end());
|
||||||
|
//
|
||||||
const auto& btidx = db.get_index_type<bitcoin_transaction_index>().indices().get<by_id>();
|
// const auto& btidx = db.get_index_type<bitcoin_transaction_index>().indices().get<by_id>();
|
||||||
BOOST_REQUIRE(btidx.size() == 0);
|
// BOOST_REQUIRE(btidx.size() == 0);
|
||||||
|
//
|
||||||
std::vector<unsigned char> a1 = {'a', 'l', 'i', 'c', 'e', '1'};
|
// std::vector<unsigned char> a1 = {'a', 'l', 'i', 'c', 'e', '1'};
|
||||||
std::vector<unsigned char> a2 = {'a', 'l', 'i', 'c', 'e', '2'};
|
// std::vector<unsigned char> a2 = {'a', 'l', 'i', 'c', 'e', '2'};
|
||||||
std::vector<unsigned char> a3 = {'a', 'l', 'i', 'c', 'e', '3'};
|
// std::vector<unsigned char> a3 = {'a', 'l', 'i', 'c', 'e', '3'};
|
||||||
|
//
|
||||||
{
|
// {
|
||||||
BOOST_TEST_MESSAGE("Send bitcoin_transaction_sign_operation");
|
// BOOST_TEST_MESSAGE("Send bitcoin_transaction_sign_operation");
|
||||||
|
//
|
||||||
bitcoin_transaction_sign_operation sign_op;
|
// bitcoin_transaction_sign_operation sign_op;
|
||||||
|
//
|
||||||
sign_op.payer = alice_id;
|
// sign_op.payer = alice_id;
|
||||||
sign_op.proposal_id = proposal_id_type(0);
|
// sign_op.proposal_id = proposal_id_type(0);
|
||||||
sign_op.signatures.push_back(a1);
|
// sign_op.signatures.push_back(a1);
|
||||||
sign_op.signatures.push_back(a2);
|
// sign_op.signatures.push_back(a2);
|
||||||
sign_op.signatures.push_back(a3);
|
// sign_op.signatures.push_back(a3);
|
||||||
|
//
|
||||||
trx.operations.push_back(sign_op);
|
// trx.operations.push_back(sign_op);
|
||||||
set_expiration(db, trx);
|
// set_expiration(db, trx);
|
||||||
sign(trx, alice_private_key);
|
// sign(trx, alice_private_key);
|
||||||
PUSH_TX(db, trx, ~0);
|
// PUSH_TX(db, trx, ~0);
|
||||||
trx.clear();
|
// trx.clear();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
generate_block();
|
// generate_block();
|
||||||
|
//
|
||||||
BOOST_REQUIRE(idx.size() == 1);
|
// BOOST_REQUIRE(idx.size() == 1);
|
||||||
BOOST_REQUIRE(btidx.size() == 0);
|
// BOOST_REQUIRE(btidx.size() == 0);
|
||||||
auto pobj = idx.find(proposal_id_type(0));
|
// auto pobj = idx.find(proposal_id_type(0));
|
||||||
BOOST_REQUIRE(pobj != idx.end());
|
// BOOST_REQUIRE(pobj != idx.end());
|
||||||
|
//
|
||||||
const auto& sidx = db.get_index_type<son_index>().indices().get<graphene::chain::by_account>();
|
// const auto& sidx = db.get_index_type<son_index>().indices().get<graphene::chain::by_account>();
|
||||||
const auto son_obj1 = sidx.find( alice_id );
|
// const auto son_obj1 = sidx.find( alice_id );
|
||||||
BOOST_REQUIRE(son_obj1 != sidx.end());
|
// BOOST_REQUIRE(son_obj1 != sidx.end());
|
||||||
|
//
|
||||||
auto bitcoin_transaction_send_op = pobj->proposed_transaction.operations[0].get<bitcoin_transaction_send_operation>();
|
// auto bitcoin_transaction_send_op = pobj->proposed_transaction.operations[0].get<bitcoin_transaction_send_operation>();
|
||||||
BOOST_REQUIRE(bitcoin_transaction_send_op.signatures.size() == 1);
|
// BOOST_REQUIRE(bitcoin_transaction_send_op.signatures.size() == 1);
|
||||||
BOOST_REQUIRE(bitcoin_transaction_send_op.signatures[son_obj1->id][0] == a1);
|
// BOOST_REQUIRE(bitcoin_transaction_send_op.signatures[son_obj1->id][0] == a1);
|
||||||
BOOST_REQUIRE(bitcoin_transaction_send_op.signatures[son_obj1->id][1] == a2);
|
// BOOST_REQUIRE(bitcoin_transaction_send_op.signatures[son_obj1->id][1] == a2);
|
||||||
BOOST_REQUIRE(bitcoin_transaction_send_op.signatures[son_obj1->id][2] == a3);
|
// BOOST_REQUIRE(bitcoin_transaction_send_op.signatures[son_obj1->id][2] == a3);
|
||||||
|
//
|
||||||
std::vector<unsigned char> b1 = {'b', 'o', 'b', '1'};
|
// std::vector<unsigned char> b1 = {'b', 'o', 'b', '1'};
|
||||||
std::vector<unsigned char> b2 = {'b', 'o', 'b', '2'};
|
// std::vector<unsigned char> b2 = {'b', 'o', 'b', '2'};
|
||||||
std::vector<unsigned char> b3 = {'b', 'o', 'b', '3'};
|
// std::vector<unsigned char> b3 = {'b', 'o', 'b', '3'};
|
||||||
|
//
|
||||||
{
|
// {
|
||||||
BOOST_TEST_MESSAGE("Send bitcoin_transaction_sign_operation");
|
// BOOST_TEST_MESSAGE("Send bitcoin_transaction_sign_operation");
|
||||||
|
//
|
||||||
bitcoin_transaction_sign_operation sign_op;
|
// bitcoin_transaction_sign_operation sign_op;
|
||||||
|
//
|
||||||
sign_op.payer = bob_id;
|
// sign_op.payer = bob_id;
|
||||||
sign_op.proposal_id = proposal_id_type(0);
|
// sign_op.proposal_id = proposal_id_type(0);
|
||||||
sign_op.signatures.push_back(b1);
|
// sign_op.signatures.push_back(b1);
|
||||||
sign_op.signatures.push_back(b2);
|
// sign_op.signatures.push_back(b2);
|
||||||
sign_op.signatures.push_back(b3);
|
// sign_op.signatures.push_back(b3);
|
||||||
|
//
|
||||||
trx.operations.push_back(sign_op);
|
// trx.operations.push_back(sign_op);
|
||||||
set_expiration(db, trx);
|
// set_expiration(db, trx);
|
||||||
sign(trx, bob_private_key);
|
// sign(trx, bob_private_key);
|
||||||
PUSH_TX(db, trx, ~0);
|
// PUSH_TX(db, trx, ~0);
|
||||||
trx.clear();
|
// trx.clear();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
generate_block();
|
// generate_block();
|
||||||
|
//
|
||||||
BOOST_REQUIRE(idx.size() == 0);
|
// BOOST_REQUIRE(idx.size() == 0);
|
||||||
|
//
|
||||||
const auto son_obj2 = sidx.find( bob_id );
|
// const auto son_obj2 = sidx.find( bob_id );
|
||||||
BOOST_REQUIRE(son_obj2 != sidx.end());
|
// BOOST_REQUIRE(son_obj2 != sidx.end());
|
||||||
|
//
|
||||||
BOOST_REQUIRE(btidx.size() == 1);
|
// BOOST_REQUIRE(btidx.size() == 1);
|
||||||
|
//
|
||||||
const auto btobj = btidx.find(bitcoin_transaction_id_type(0));
|
// const auto btobj = btidx.find(bitcoin_transaction_id_type(0));
|
||||||
BOOST_REQUIRE(btobj != btidx.end());
|
// BOOST_REQUIRE(btobj != btidx.end());
|
||||||
|
//
|
||||||
BOOST_REQUIRE(btobj->processed == false);
|
// BOOST_REQUIRE(btobj->processed == false);
|
||||||
|
//
|
||||||
auto stats1 = son_obj1->statistics( db );
|
// auto stats1 = son_obj1->statistics( db );
|
||||||
auto stats2 = son_obj2->statistics( db );
|
// auto stats2 = son_obj2->statistics( db );
|
||||||
|
//
|
||||||
BOOST_REQUIRE(stats1.txs_signed == 1);
|
// BOOST_REQUIRE(stats1.txs_signed == 1);
|
||||||
BOOST_REQUIRE(stats2.txs_signed == 1);
|
// BOOST_REQUIRE(stats2.txs_signed == 1);
|
||||||
|
//
|
||||||
auto sigs = btobj->signatures;
|
// auto sigs = btobj->signatures;
|
||||||
|
//
|
||||||
BOOST_REQUIRE(sigs[son_obj1->id][0] == a1);
|
// BOOST_REQUIRE(sigs[son_obj1->id][0] == a1);
|
||||||
BOOST_REQUIRE(sigs[son_obj1->id][1] == a2);
|
// BOOST_REQUIRE(sigs[son_obj1->id][1] == a2);
|
||||||
BOOST_REQUIRE(sigs[son_obj1->id][2] == a3);
|
// BOOST_REQUIRE(sigs[son_obj1->id][2] == a3);
|
||||||
|
//
|
||||||
BOOST_REQUIRE(sigs[son_obj2->id][0] == b1);
|
// BOOST_REQUIRE(sigs[son_obj2->id][0] == b1);
|
||||||
BOOST_REQUIRE(sigs[son_obj2->id][1] == b2);
|
// BOOST_REQUIRE(sigs[son_obj2->id][1] == b2);
|
||||||
BOOST_REQUIRE(sigs[son_obj2->id][2] == b3);
|
// BOOST_REQUIRE(sigs[son_obj2->id][2] == b3);
|
||||||
|
//
|
||||||
{
|
// {
|
||||||
BOOST_TEST_MESSAGE("Send bitcoin_send_transaction_process_operation");
|
// BOOST_TEST_MESSAGE("Send bitcoin_send_transaction_process_operation");
|
||||||
|
//
|
||||||
bitcoin_send_transaction_process_operation process_op;
|
// bitcoin_send_transaction_process_operation process_op;
|
||||||
process_op.bitcoin_transaction_id = bitcoin_transaction_id_type(0);
|
// process_op.bitcoin_transaction_id = bitcoin_transaction_id_type(0);
|
||||||
process_op.payer = GRAPHENE_SON_ACCOUNT;
|
// process_op.payer = GRAPHENE_SON_ACCOUNT;
|
||||||
|
//
|
||||||
proposal_create_operation proposal_op;
|
// proposal_create_operation proposal_op;
|
||||||
proposal_op.fee_paying_account = alice_id;
|
// proposal_op.fee_paying_account = alice_id;
|
||||||
proposal_op.proposed_ops.push_back(op_wrapper(process_op));
|
// proposal_op.proposed_ops.push_back(op_wrapper(process_op));
|
||||||
uint32_t lifetime = (gpo.parameters.block_interval * gpo.active_witnesses.size()) * 3;
|
// uint32_t lifetime = (gpo.parameters.block_interval * gpo.active_witnesses.size()) * 3;
|
||||||
proposal_op.expiration_time = time_point_sec(db.head_block_time().sec_since_epoch() + lifetime);
|
// proposal_op.expiration_time = time_point_sec(db.head_block_time().sec_since_epoch() + lifetime);
|
||||||
|
//
|
||||||
trx.operations.push_back(proposal_op);
|
// trx.operations.push_back(proposal_op);
|
||||||
set_expiration(db, trx);
|
// set_expiration(db, trx);
|
||||||
sign(trx, alice_private_key);
|
// sign(trx, alice_private_key);
|
||||||
PUSH_TX(db, trx, ~0);
|
// PUSH_TX(db, trx, ~0);
|
||||||
trx.clear();
|
// trx.clear();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
generate_block();
|
// generate_block();
|
||||||
BOOST_REQUIRE(idx.size() == 1);
|
// BOOST_REQUIRE(idx.size() == 1);
|
||||||
obj = idx.find(proposal_id_type(1));
|
// obj = idx.find(proposal_id_type(1));
|
||||||
BOOST_REQUIRE(obj != idx.end());
|
// BOOST_REQUIRE(obj != idx.end());
|
||||||
|
//
|
||||||
|
//
|
||||||
{
|
// {
|
||||||
BOOST_TEST_MESSAGE("Send proposal_update_operation");
|
// BOOST_TEST_MESSAGE("Send proposal_update_operation");
|
||||||
|
//
|
||||||
proposal_update_operation puo;
|
// proposal_update_operation puo;
|
||||||
puo.fee_paying_account = bob_id;
|
// puo.fee_paying_account = bob_id;
|
||||||
puo.proposal = obj->id;
|
// puo.proposal = obj->id;
|
||||||
puo.active_approvals_to_add = { bob_id };
|
// puo.active_approvals_to_add = { bob_id };
|
||||||
|
//
|
||||||
trx.operations.push_back(puo);
|
// trx.operations.push_back(puo);
|
||||||
set_expiration(db, trx);
|
// set_expiration(db, trx);
|
||||||
sign(trx, bob_private_key);
|
// sign(trx, bob_private_key);
|
||||||
PUSH_TX(db, trx, ~0);
|
// PUSH_TX(db, trx, ~0);
|
||||||
trx.clear();
|
// trx.clear();
|
||||||
}
|
// }
|
||||||
generate_block();
|
// generate_block();
|
||||||
BOOST_REQUIRE(idx.size() == 1);
|
// BOOST_REQUIRE(idx.size() == 1);
|
||||||
obj = idx.find(proposal_id_type(1));
|
// obj = idx.find(proposal_id_type(1));
|
||||||
BOOST_REQUIRE(obj != idx.end());
|
// BOOST_REQUIRE(obj != idx.end());
|
||||||
|
//
|
||||||
BOOST_REQUIRE(btobj != btidx.end());
|
// BOOST_REQUIRE(btobj != btidx.end());
|
||||||
BOOST_REQUIRE(btobj->processed == false);
|
// BOOST_REQUIRE(btobj->processed == false);
|
||||||
|
//
|
||||||
{
|
// {
|
||||||
BOOST_TEST_MESSAGE("Send proposal_update_operation");
|
// BOOST_TEST_MESSAGE("Send proposal_update_operation");
|
||||||
|
//
|
||||||
proposal_update_operation puo;
|
// proposal_update_operation puo;
|
||||||
puo.fee_paying_account = alice_id;
|
// puo.fee_paying_account = alice_id;
|
||||||
puo.proposal = obj->id;
|
// puo.proposal = obj->id;
|
||||||
puo.active_approvals_to_add = { alice_id };
|
// puo.active_approvals_to_add = { alice_id };
|
||||||
|
//
|
||||||
trx.operations.push_back(puo);
|
// trx.operations.push_back(puo);
|
||||||
set_expiration(db, trx);
|
// set_expiration(db, trx);
|
||||||
sign(trx, alice_private_key);
|
// sign(trx, alice_private_key);
|
||||||
PUSH_TX(db, trx, ~0);
|
// PUSH_TX(db, trx, ~0);
|
||||||
trx.clear();
|
// trx.clear();
|
||||||
}
|
// }
|
||||||
generate_block();
|
// generate_block();
|
||||||
BOOST_REQUIRE(idx.size() == 0);
|
// BOOST_REQUIRE(idx.size() == 0);
|
||||||
|
//
|
||||||
BOOST_REQUIRE(btobj != btidx.end());
|
// BOOST_REQUIRE(btobj != btidx.end());
|
||||||
BOOST_REQUIRE(btobj->processed == true);
|
// BOOST_REQUIRE(btobj->processed == true);
|
||||||
}
|
// }
|
||||||
FC_LOG_AND_RETHROW()
|
// FC_LOG_AND_RETHROW()
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
//BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue