2019-10-09 20:24:36 +00:00
# include <graphene/chain/son_evaluator.hpp>
# include <graphene/chain/database.hpp>
# include <graphene/chain/son_object.hpp>
2019-10-23 16:46:04 +00:00
# include <graphene/chain/witness_object.hpp>
2019-10-09 20:24:36 +00:00
# include <graphene/chain/hardfork.hpp>
2019-10-16 00:55:48 +00:00
# include <graphene/chain/vesting_balance_object.hpp>
2019-10-09 20:24:36 +00:00
namespace graphene { namespace chain {
void_result create_son_evaluator : : do_evaluate ( const son_create_operation & op )
{ try {
FC_ASSERT ( db ( ) . head_block_time ( ) > = HARDFORK_SON_TIME , " Not allowed until SON HARDFORK " ) ;
FC_ASSERT ( db ( ) . get ( op . owner_account ) . is_lifetime_member ( ) , " Only Lifetime members may register a SON. " ) ;
2019-10-18 03:27:13 +00:00
FC_ASSERT ( op . deposit ( db ( ) ) . policy . which ( ) = = vesting_policy : : tag < dormant_vesting_policy > : : value ,
" Deposit balance must have dormant vesting policy " ) ;
return void_result ( ) ;
2019-10-09 20:24:36 +00:00
} FC_CAPTURE_AND_RETHROW ( ( op ) ) }
object_id_type create_son_evaluator : : do_apply ( const son_create_operation & op )
{ try {
vote_id_type vote_id ;
db ( ) . modify ( db ( ) . get_global_properties ( ) , [ & vote_id ] ( global_property_object & p ) {
vote_id = get_next_vote_id ( p , vote_id_type : : son ) ;
} ) ;
const auto & new_son_object = db ( ) . create < son_object > ( [ & ] ( son_object & obj ) {
obj . son_account = op . owner_account ;
obj . vote_id = vote_id ;
obj . url = op . url ;
obj . deposit = op . deposit ;
obj . signing_key = op . signing_key ;
2019-12-23 18:20:26 +00:00
obj . sidechain_public_keys = op . sidechain_public_keys ;
2019-10-09 20:24:36 +00:00
obj . pay_vb = op . pay_vb ;
2019-10-17 14:46:48 +00:00
obj . statistics = db ( ) . create < son_statistics_object > ( [ & ] ( son_statistics_object & s ) { s . owner = obj . id ; } ) . id ;
2019-10-09 20:24:36 +00:00
} ) ;
return new_son_object . id ;
} FC_CAPTURE_AND_RETHROW ( ( op ) ) }
void_result update_son_evaluator : : do_evaluate ( const son_update_operation & op )
{ try {
FC_ASSERT ( db ( ) . head_block_time ( ) > = HARDFORK_SON_TIME , " Not allowed until SON HARDFORK " ) ; // can be removed after HF date pass
FC_ASSERT ( db ( ) . get ( op . son_id ) . son_account = = op . owner_account ) ;
const auto & idx = db ( ) . get_index_type < son_index > ( ) . indices ( ) . get < by_id > ( ) ;
FC_ASSERT ( idx . find ( op . son_id ) ! = idx . end ( ) ) ;
return void_result ( ) ;
} FC_CAPTURE_AND_RETHROW ( ( op ) ) }
object_id_type update_son_evaluator : : do_apply ( const son_update_operation & op )
{ try {
const auto & idx = db ( ) . get_index_type < son_index > ( ) . indices ( ) . get < by_id > ( ) ;
auto itr = idx . find ( op . son_id ) ;
if ( itr ! = idx . end ( ) )
{
db ( ) . modify ( * itr , [ & op ] ( son_object & so ) {
if ( op . new_url . valid ( ) ) so . url = * op . new_url ;
if ( op . new_deposit . valid ( ) ) so . deposit = * op . new_deposit ;
if ( op . new_signing_key . valid ( ) ) so . signing_key = * op . new_signing_key ;
2019-12-23 18:20:26 +00:00
if ( op . new_sidechain_public_keys . valid ( ) ) so . sidechain_public_keys = * op . new_sidechain_public_keys ;
2019-10-09 20:24:36 +00:00
if ( op . new_pay_vb . valid ( ) ) so . pay_vb = * op . new_pay_vb ;
} ) ;
}
return op . son_id ;
} FC_CAPTURE_AND_RETHROW ( ( op ) ) }
void_result delete_son_evaluator : : do_evaluate ( const son_delete_operation & op )
{ try {
FC_ASSERT ( db ( ) . head_block_time ( ) > = HARDFORK_SON_TIME , " Not allowed until SON_HARDFORK " ) ; // can be removed after HF date pass
2020-02-27 20:51:04 +00:00
// Either owner can remove or consensus son account
FC_ASSERT ( op . payer = = db ( ) . get ( op . son_id ) . son_account | | ( db ( ) . is_son_dereg_valid ( op . son_id ) & & op . payer = = GRAPHENE_SON_ACCOUNT ) ) ;
2019-10-09 20:24:36 +00:00
const auto & idx = db ( ) . get_index_type < son_index > ( ) . indices ( ) . get < by_id > ( ) ;
FC_ASSERT ( idx . find ( op . son_id ) ! = idx . end ( ) ) ;
return void_result ( ) ;
} FC_CAPTURE_AND_RETHROW ( ( op ) ) }
void_result delete_son_evaluator : : do_apply ( const son_delete_operation & op )
{ try {
const auto & idx = db ( ) . get_index_type < son_index > ( ) . indices ( ) . get < by_id > ( ) ;
2019-10-16 00:55:48 +00:00
auto son = idx . find ( op . son_id ) ;
if ( son ! = idx . end ( ) ) {
vesting_balance_object deposit = son - > deposit ( db ( ) ) ;
2019-10-18 03:01:40 +00:00
linear_vesting_policy new_vesting_policy ;
2019-10-16 00:55:48 +00:00
new_vesting_policy . begin_timestamp = db ( ) . head_block_time ( ) ;
new_vesting_policy . vesting_cliff_seconds = db ( ) . get_global_properties ( ) . parameters . son_vesting_period ( ) ;
2019-12-08 06:43:05 +00:00
new_vesting_policy . begin_balance = deposit . balance . amount ;
2019-10-16 00:55:48 +00:00
db ( ) . modify ( son - > deposit ( db ( ) ) , [ & new_vesting_policy ] ( vesting_balance_object & vbo ) {
vbo . policy = new_vesting_policy ;
} ) ;
db ( ) . remove ( * son ) ;
}
2019-10-09 20:24:36 +00:00
return void_result ( ) ;
} FC_CAPTURE_AND_RETHROW ( ( op ) ) }
2019-12-12 13:06:38 +00:00
void_result son_heartbeat_evaluator : : do_evaluate ( const son_heartbeat_operation & 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 & idx = db ( ) . get_index_type < son_index > ( ) . indices ( ) . get < by_id > ( ) ;
auto itr = idx . find ( op . son_id ) ;
2020-03-14 00:08:45 +00:00
FC_ASSERT ( itr ! = idx . end ( ) ) ;
FC_ASSERT ( itr - > son_account = = op . owner_account ) ;
2019-12-12 13:06:38 +00:00
auto stats = itr - > statistics ( db ( ) ) ;
// Inactive SONs need not send heartbeats
2020-02-07 05:49:16 +00:00
FC_ASSERT ( ( itr - > status = = son_status : : active ) | | ( itr - > status = = son_status : : in_maintenance ) | | ( itr - > status = = son_status : : request_maintenance ) , " Inactive SONs need not send heartbeats " ) ;
2019-12-12 13:06:38 +00:00
// Account for network delays
fc : : time_point_sec min_ts = db ( ) . head_block_time ( ) - fc : : seconds ( 5 * db ( ) . block_interval ( ) ) ;
// Account for server ntp sync difference
2020-02-07 05:49:16 +00:00
fc : : time_point_sec max_ts = db ( ) . head_block_time ( ) + fc : : seconds ( 5 * db ( ) . block_interval ( ) ) ;
2019-12-12 13:06:38 +00:00
FC_ASSERT ( op . ts > stats . last_active_timestamp , " Heartbeat sent without waiting minimum time " ) ;
FC_ASSERT ( op . ts > stats . last_down_timestamp , " Heartbeat sent is invalid can't be <= last down timestamp " ) ;
FC_ASSERT ( op . ts > = min_ts , " Heartbeat ts is behind the min threshold " ) ;
FC_ASSERT ( op . ts < = max_ts , " Heartbeat ts is above the max threshold " ) ;
return void_result ( ) ;
} FC_CAPTURE_AND_RETHROW ( ( op ) ) }
object_id_type son_heartbeat_evaluator : : do_apply ( const son_heartbeat_operation & op )
{ try {
const auto & idx = db ( ) . get_index_type < son_index > ( ) . indices ( ) . get < by_id > ( ) ;
auto itr = idx . find ( op . son_id ) ;
if ( itr ! = idx . end ( ) )
{
2020-01-17 20:28:13 +00:00
const global_property_object & gpo = db ( ) . get_global_properties ( ) ;
vector < son_id_type > active_son_ids ;
active_son_ids . reserve ( gpo . active_sons . size ( ) ) ;
std : : transform ( gpo . active_sons . begin ( ) , gpo . active_sons . end ( ) ,
std : : inserter ( active_son_ids , active_son_ids . end ( ) ) ,
[ ] ( const son_info & swi ) {
return swi . son_id ;
} ) ;
auto it_son = std : : find ( active_son_ids . begin ( ) , active_son_ids . end ( ) , op . son_id ) ;
bool is_son_active = true ;
if ( it_son = = active_son_ids . end ( ) ) {
is_son_active = false ;
}
2019-12-12 13:06:38 +00:00
if ( itr - > status = = son_status : : in_maintenance ) {
db ( ) . modify ( itr - > statistics ( db ( ) ) , [ & ] ( son_statistics_object & sso )
{
sso . current_interval_downtime + = op . ts . sec_since_epoch ( ) - sso . last_down_timestamp . sec_since_epoch ( ) ;
sso . last_active_timestamp = op . ts ;
2020-03-20 07:30:32 +00:00
// TODO: Remove me after sidechain tx signing is finished
sso . txs_signed = sso . txs_signed + 1 ;
2019-12-12 13:06:38 +00:00
} ) ;
2020-01-17 20:28:13 +00:00
db ( ) . modify ( * itr , [ & is_son_active ] ( son_object & so ) {
if ( is_son_active ) {
so . status = son_status : : active ;
} else {
so . status = son_status : : inactive ;
}
2019-12-12 13:06:38 +00:00
} ) ;
2020-02-07 05:49:16 +00:00
} else if ( ( itr - > status = = son_status : : active ) | | ( itr - > status = = son_status : : request_maintenance ) ) {
2019-12-12 13:06:38 +00:00
db ( ) . modify ( itr - > statistics ( db ( ) ) , [ & ] ( son_statistics_object & sso )
{
sso . last_active_timestamp = op . ts ;
2020-03-20 07:30:32 +00:00
// TODO: Remove me after sidechain tx signing is finished
sso . txs_signed = sso . txs_signed + 1 ;
2019-12-12 13:06:38 +00:00
} ) ;
}
}
return op . son_id ;
} FC_CAPTURE_AND_RETHROW ( ( op ) ) }
2020-01-06 12:59:35 +00:00
void_result son_report_down_evaluator : : do_evaluate ( const son_report_down_operation & op )
{ try {
2020-02-03 13:14:39 +00:00
FC_ASSERT ( db ( ) . head_block_time ( ) > = HARDFORK_SON_TIME , " Not allowed until SON HARDFORK " ) ; // can be removed after HF date pass
[SON-260] Sidechain Token withdrawal (#286)
* Extend GPO.active_sons to contain votes and all public keys
* Introduce son_wallet_object
* son_wallet_object operations
* son_wallet_object operations
* son_wallet_object operations completed, basic tests added
* Create son_wallet_object on new set of SONs, to initiate primary wallet recreation
* son_wallet_object API and cli wallet commands
* Send RPC command to bitcoin node to recreate multisig wallet
* Send RPC command to bitcoin node to recreate multisig wallet
* Send RPC command to bitcoin node to recreate multisig wallet
* Wallet recreation by scheduled SON only, some cosmetic refactoring
* Wallet recreation by scheduled SON only, some cosmetic refactoring
* Updating wallet info through operation instead through database.modify() for persistance
* SON wallet transfer object and operations, for tracking assets deposit/withdrawal
* Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp
Co-Authored-By: gladcow <jahr@yandex.ru>
* Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp
Co-Authored-By: gladcow <jahr@yandex.ru>
* Fix #include <graphene/chain/son_wallet_transfer_object.hpp>
* SON wallet transfer object and operations, for tracking assets deposit/withdrawal
* SON wallet transfer object and operations, for tracking assets deposit/withdrawal
* Refactor primary wallet recreation
* Refactor primary wallet recreation
* PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal
* PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal
* Quickfix for checking payer in evaluator
* Quickfix for checking payer in evaluator
* Fix failing son_wallet_tests
- Check for son_btc_account is temporarely disabled
* Remove redundant file
* Squashed commit of the following:
commit a688bb93ed4e16232a907aa8c76e240c83c771bf
Author: obucinac <obucinac@users.noreply.github.com>
Date: Tue Feb 4 19:31:45 2020 +0100
son_wallet_object operations and multisig wallet recreation by RPC (#263)
* Extend GPO.active_sons to contain votes and all public keys
* Introduce son_wallet_object
* son_wallet_object operations
* Create son_wallet_object on new set of SONs, to initiate primary wallet recreation
* son_wallet_object API and cli wallet commands
* Send RPC command to bitcoin node to recreate multisig wallet
* Updating wallet info through operation instead through database.modify() for persistance
* Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp
* Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp
* Fix #include <graphene/chain/son_wallet_transfer_object.hpp>
* Refactor primary wallet recreation
* PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal
* Quickfix for checking payer in evaluator
* Fix failing son_wallet_tests
- Check for son_btc_account is temporarely disabled
* Remove redundant file
Co-authored-by: gladcow <jahr@yandex.ru>
commit 6e61d6b055eb276757e426245a3a7c23a61b3854
Author: satyakoneru <satyakoneru.iiith@gmail.com>
Date: Tue Feb 4 00:14:39 2020 +1100
SON233 - Provide correct downtime metrics to user (#278)
* Remove duplicated item in CMakeLists.txt
* Issue tokens to the user who deposited Bitcoin, WIP...
* Add son_wallet_transfer_process_operation
* Issue tokens to the user who deposited Bitcoin, WIP...
* Support multiple SON nodes per software instance
* Add is_active_son guards for sidechain events processing
* Add is_active_son guards, fix sending proposals and aprovals
* Managing GRAPHENE_SON_ACCOUNT and issuing assets on Bitcoin deposit
* Fix bad param
* Fix aprovals on already approved or invalid proposals
* Move transfer inside son_wallet_transfer_process_operation
* Fix merging issue
* Add cmake command line option SUPPORT_MULTIPLE_SONS
* Skeleton of sidechain_net_handler_peerplays
* Skeleton of Peerplays network listener
* Temoprary disable account history tests for tracking accounts
* Full Peerplays listener, use GRAPHENE_SON_ACCOUNT instead son_btc_account
* Renaming son_wallet_transfer* to son_wallet_deposit*, introducing son_wallet_withdrawal*
* Extend sidechain_address_object to contain withdrawal addresses
- Withdrawal address is the address where system will send sidechain currencies
* Rename son_wallet_withdrawal* to son_wallet_withdraw*
* Some refactoring
* Withdrawal refactoring
* Withdrawal refactoring
Co-authored-by: gladcow <jahr@yandex.ru>
2020-02-23 16:33:43 +00:00
FC_ASSERT ( op . payer = = GRAPHENE_SON_ACCOUNT , " SON paying account must be set as payer. " ) ;
2020-01-06 12:59:35 +00:00
const auto & idx = db ( ) . get_index_type < son_index > ( ) . indices ( ) . get < by_id > ( ) ;
FC_ASSERT ( idx . find ( op . son_id ) ! = idx . end ( ) ) ;
auto itr = idx . find ( op . son_id ) ;
auto stats = itr - > statistics ( db ( ) ) ;
2020-02-07 05:49:16 +00:00
FC_ASSERT ( itr - > status = = son_status : : active | | itr - > status = = son_status : : request_maintenance , " Inactive/Deregistered/in_maintenance SONs cannot be reported on as down " ) ;
2020-01-06 12:59:35 +00:00
FC_ASSERT ( op . down_ts > = stats . last_active_timestamp , " down_ts should be greater than last_active_timestamp " ) ;
return void_result ( ) ;
} FC_CAPTURE_AND_RETHROW ( ( op ) ) }
object_id_type son_report_down_evaluator : : do_apply ( const son_report_down_operation & op )
{ try {
const auto & idx = db ( ) . get_index_type < son_index > ( ) . indices ( ) . get < by_id > ( ) ;
auto itr = idx . find ( op . son_id ) ;
if ( itr ! = idx . end ( ) )
{
2020-02-07 05:49:16 +00:00
if ( ( itr - > status = = son_status : : active ) | | ( itr - > status = = son_status : : request_maintenance ) ) {
2020-01-06 12:59:35 +00:00
db ( ) . modify ( itr - > statistics ( db ( ) ) , [ & ] ( son_statistics_object & sso )
{
sso . last_down_timestamp = op . down_ts ;
} ) ;
db ( ) . modify ( * itr , [ & op ] ( son_object & so ) {
so . status = son_status : : in_maintenance ;
} ) ;
}
}
return op . son_id ;
} FC_CAPTURE_AND_RETHROW ( ( op ) ) }
2020-01-17 20:30:45 +00:00
void_result son_maintenance_evaluator : : do_evaluate ( const son_maintenance_operation & op )
{ try {
FC_ASSERT ( db ( ) . head_block_time ( ) > = HARDFORK_SON_TIME , " Not allowed until SON HARDFORK " ) ; // can be removed after HF date pass
FC_ASSERT ( db ( ) . get ( op . son_id ) . son_account = = op . owner_account ) ;
const auto & idx = db ( ) . get_index_type < son_index > ( ) . indices ( ) . get < by_id > ( ) ;
auto itr = idx . find ( op . son_id ) ;
FC_ASSERT ( itr ! = idx . end ( ) ) ;
2020-02-07 05:49:16 +00:00
// Inactive SONs can't go to maintenance, toggle between active and request_maintenance states
2020-03-06 11:49:26 +00:00
if ( op . request_type = = son_maintenance_request_type : : request_maintenance ) {
FC_ASSERT ( itr - > status = = son_status : : active , " Inactive SONs can't request for maintenance " ) ;
} else if ( op . request_type = = son_maintenance_request_type : : cancel_request_maintenance ) {
FC_ASSERT ( itr - > status = = son_status : : request_maintenance , " Only maintenance requested SONs can cancel the request " ) ;
} else {
FC_ASSERT ( false , " Invalid maintenance operation " ) ;
}
2020-01-17 20:30:45 +00:00
return void_result ( ) ;
} FC_CAPTURE_AND_RETHROW ( ( op ) ) }
object_id_type son_maintenance_evaluator : : do_apply ( const son_maintenance_operation & op )
{ try {
const auto & idx = db ( ) . get_index_type < son_index > ( ) . indices ( ) . get < by_id > ( ) ;
auto itr = idx . find ( op . son_id ) ;
if ( itr ! = idx . end ( ) )
{
2020-03-06 11:49:26 +00:00
if ( itr - > status = = son_status : : active & & op . request_type = = son_maintenance_request_type : : request_maintenance ) {
2020-01-17 20:30:45 +00:00
db ( ) . modify ( * itr , [ ] ( son_object & so ) {
2020-02-07 05:49:16 +00:00
so . status = son_status : : request_maintenance ;
} ) ;
2020-03-06 11:49:26 +00:00
} else if ( itr - > status = = son_status : : request_maintenance & & op . request_type = = son_maintenance_request_type : : cancel_request_maintenance ) {
2020-02-07 05:49:16 +00:00
db ( ) . modify ( * itr , [ ] ( son_object & so ) {
so . status = son_status : : active ;
2020-01-17 20:30:45 +00:00
} ) ;
}
}
return op . son_id ;
} FC_CAPTURE_AND_RETHROW ( ( op ) ) }
2019-10-09 20:24:36 +00:00
} } // namespace graphene::chain