SON connection pool.

This commit is contained in:
timur 2022-11-16 07:32:17 -04:00
commit 94b518cb7a
22 changed files with 220 additions and 33 deletions

View file

@ -1912,7 +1912,7 @@ map<son_id_type, string> database_api_impl::get_son_network_status_by_sidechain(
if (time_point_sec(sso.last_active_timestamp.at(sidechain) + fc::seconds(gpo.parameters.son_down_time())) > _db.head_block_time()) {
status = "OK, irregular SON heartbeat, but not triggering SON down proposal";
} else {
status = "NOT OK, irregular SON heartbeat, triggering SON down proposal]";
status = "NOT OK, irregular SON heartbeat, triggering SON down proposal";
}
}
} else {

View file

@ -236,7 +236,7 @@ std::set<son_id_type> database::get_sons_to_be_deregistered()
// TODO : We need to add a function that returns if we can deregister SON
// i.e. with introduction of PW code, we have to make a decision if the SON
// is needed for release of funds from the PW
if (head_block_time() - stats.last_down_timestamp.at(sidechain) < fc::seconds(get_global_properties().parameters.son_deregister_time())) {
if (head_block_time() - stats.last_active_timestamp.at(sidechain) < fc::seconds(get_global_properties().parameters.son_deregister_time())) {
need_to_be_deregistered = false;
}
}
@ -311,7 +311,7 @@ bool database::is_son_dereg_valid( son_id_type son_id )
if(status_son_dereg_valid)
{
if(head_block_time() - son->statistics(*this).last_down_timestamp.at(sidechain) < fc::seconds(get_global_properties().parameters.son_deregister_time()))
if(head_block_time() - son->statistics(*this).last_active_timestamp.at(sidechain) < fc::seconds(get_global_properties().parameters.son_deregister_time()))
{
status_son_dereg_valid = false;
}

View file

@ -0,0 +1,7 @@
#ifndef HARDFORK_SIDECHAIN_DELETE_TIME
#ifdef BUILD_PEERPLAYS_TESTNET
#define HARDFORK_SIDECHAIN_DELETE_TIME (fc::time_point_sec::from_iso_string("2022-11-16T02:00:00"))
#else
#define HARDFORK_SIDECHAIN_DELETE_TIME (fc::time_point_sec::from_iso_string("2022-11-16T02:00:00"))
#endif
#endif

View file

@ -22,12 +22,14 @@ object_id_type add_sidechain_address_evaluator::do_apply(const sidechain_address
const auto &sidechain_addresses_idx = db().get_index_type<sidechain_address_index>().indices().get<by_account_and_sidechain_and_expires>();
const auto &addr_itr = sidechain_addresses_idx.find(std::make_tuple(op.sidechain_address_account, op.sidechain, time_point_sec::maximum()));
if (addr_itr != sidechain_addresses_idx.end())
{
//db().modify(*addr_itr, [&](sidechain_address_object &sao) {
// sao.expires = db().head_block_time();
//});
db().remove(*addr_itr);
if (addr_itr != sidechain_addresses_idx.end()) {
if (db().head_block_time() >= HARDFORK_SIDECHAIN_DELETE_TIME) {
db().remove(*addr_itr);
} else {
db().modify(*addr_itr, [&](sidechain_address_object &sao) {
sao.expires = db().head_block_time();
});
}
}
const auto& new_sidechain_address_object = db().create<sidechain_address_object>( [&]( sidechain_address_object& obj ){
@ -106,11 +108,14 @@ void_result delete_sidechain_address_evaluator::do_apply(const sidechain_address
{ try {
const auto& idx = db().get_index_type<sidechain_address_index>().indices().get<by_id>();
auto sidechain_address = idx.find(op.sidechain_address_id);
if(sidechain_address != idx.end()) {
//db().modify(*sidechain_address, [&](sidechain_address_object &sao) {
// sao.expires = db().head_block_time();
//});
db().remove(*sidechain_address);
if (sidechain_address != idx.end()) {
if (db().head_block_time() >= HARDFORK_SIDECHAIN_DELETE_TIME) {
db().remove(*sidechain_address);
} else {
db().modify(*sidechain_address, [&](sidechain_address_object &sao) {
sao.expires = db().head_block_time();
});
}
}
return void_result();
} FC_CAPTURE_AND_RETHROW( (op) ) }

View file

@ -54,6 +54,7 @@ public:
void log_son_proposal_retry(sidechain_type sidechain, int op_type, object_id_type object_id);
bool can_son_participate(sidechain_type sidechain, int op_type, object_id_type object_id);
std::map<sidechain_type, std::vector<std::string>> get_son_listener_log();
optional<asset> estimate_withdrawal_transaction_fee(sidechain_type sidechain);
};
}} // namespace graphene::peerplays_sidechain

View file

@ -26,9 +26,10 @@ public:
std::shared_ptr<detail::sidechain_api_impl> my;
std::map<sidechain_type, std::vector<std::string>> get_son_listener_log();
optional<asset> estimate_withdrawal_transaction_fee(sidechain_type sidechain);
};
}} // namespace graphene::peerplays_sidechain
FC_API(graphene::peerplays_sidechain::sidechain_api,
(get_son_listener_log))
(get_son_listener_log)(estimate_withdrawal_transaction_fee))

View file

@ -51,6 +51,7 @@ public:
void add_to_son_listener_log(std::string trx_id);
std::vector<std::string> get_son_listener_log();
virtual optional<asset> estimate_withdrawal_transaction_fee() const = 0;
protected:
peerplays_sidechain_plugin &plugin;

View file

@ -106,6 +106,7 @@ public:
std::string process_sidechain_transaction(const sidechain_transaction_object &sto);
std::string send_sidechain_transaction(const sidechain_transaction_object &sto);
bool settle_sidechain_transaction(const sidechain_transaction_object &sto, asset &settle_amount);
virtual optional<asset> estimate_withdrawal_transaction_fee() const override;
void select_active_rpc_client();
private:

View file

@ -22,12 +22,14 @@ public:
std::string net_version();
std::string eth_get_transaction_count(const std::string &params);
std::string eth_gas_price();
std::string eth_estimateGas(const std::string &params);
std::string get_chain_id();
std::string get_network_id();
std::string get_nonce(const std::string &address);
std::string get_gas_price();
std::string get_gas_limit();
std::string get_estimate_gas(const std::string &params);
std::string eth_send_transaction(const std::string &params);
std::string eth_send_raw_transaction(const std::string &params);
@ -47,6 +49,7 @@ public:
std::string process_sidechain_transaction(const sidechain_transaction_object &sto);
std::string send_sidechain_transaction(const sidechain_transaction_object &sto);
bool settle_sidechain_transaction(const sidechain_transaction_object &sto, asset &settle_amount);
virtual optional<asset> estimate_withdrawal_transaction_fee() const override;
void select_active_rpc_client();
private:

View file

@ -45,6 +45,7 @@ public:
std::string process_sidechain_transaction(const sidechain_transaction_object &sto);
std::string send_sidechain_transaction(const sidechain_transaction_object &sto);
bool settle_sidechain_transaction(const sidechain_transaction_object &sto, asset &settle_amount);
virtual optional<asset> estimate_withdrawal_transaction_fee() const override;
void select_active_rpc_client();
private:

View file

@ -19,6 +19,7 @@ public:
std::string process_sidechain_transaction(const sidechain_transaction_object &sto);
std::string send_sidechain_transaction(const sidechain_transaction_object &sto);
bool settle_sidechain_transaction(const sidechain_transaction_object &sto, asset &settle_amount);
virtual optional<asset> estimate_withdrawal_transaction_fee() const override;
void select_active_rpc_client();
private:

View file

@ -48,6 +48,7 @@ public:
void log_son_proposal_retry(sidechain_type sidechain, int op_type, object_id_type object_id);
bool can_son_participate(sidechain_type sidechain, int op_type, object_id_type object_id);
std::map<sidechain_type, std::vector<std::string>> get_son_listener_log();
optional<asset> estimate_withdrawal_transaction_fee(sidechain_type sidechain);
void schedule_heartbeat_loop();
void heartbeat_loop();
@ -641,6 +642,15 @@ std::map<sidechain_type, std::vector<std::string>> peerplays_sidechain_plugin_im
return result;
}
optional<asset> peerplays_sidechain_plugin_impl::estimate_withdrawal_transaction_fee(sidechain_type sidechain) {
if (!net_handlers.at(sidechain)) {
wlog("Net handler is null for sidechain: ${sidechain}", ("sidechain", sidechain));
return optional<asset>();
}
return net_handlers.at(sidechain)->estimate_withdrawal_transaction_fee();
}
void peerplays_sidechain_plugin_impl::approve_proposals(sidechain_type sidechain) {
// prevent approving duplicate proposals with lock for parallel execution.
// We can have the same propsals, but in the case of parallel execution we can run
@ -957,4 +967,8 @@ std::map<sidechain_type, std::vector<std::string>> peerplays_sidechain_plugin::g
return my->get_son_listener_log();
}
optional<asset> peerplays_sidechain_plugin::estimate_withdrawal_transaction_fee(sidechain_type sidechain) {
return my->estimate_withdrawal_transaction_fee(sidechain);
}
}} // namespace graphene::peerplays_sidechain

View file

@ -12,6 +12,7 @@ public:
std::shared_ptr<graphene::peerplays_sidechain::peerplays_sidechain_plugin> get_plugin();
std::map<sidechain_type, std::vector<std::string>> get_son_listener_log();
optional<asset> estimate_withdrawal_transaction_fee(sidechain_type sidechain);
private:
app::application &app;
@ -32,6 +33,10 @@ std::map<sidechain_type, std::vector<std::string>> sidechain_api_impl::get_son_l
return get_plugin()->get_son_listener_log();
}
optional<asset> sidechain_api_impl::estimate_withdrawal_transaction_fee(sidechain_type sidechain) {
return get_plugin()->estimate_withdrawal_transaction_fee(sidechain);
}
} // namespace detail
sidechain_api::sidechain_api(graphene::app::application &_app) :
@ -45,4 +50,8 @@ std::map<sidechain_type, std::vector<std::string>> sidechain_api::get_son_listen
return my->get_son_listener_log();
}
optional<asset> sidechain_api::estimate_withdrawal_transaction_fee(sidechain_type sidechain) {
return my->estimate_withdrawal_transaction_fee(sidechain);
}
}} // namespace graphene::peerplays_sidechain

View file

@ -1002,6 +1002,11 @@ bool sidechain_net_handler_bitcoin::settle_sidechain_transaction(const sidechain
return false;
}
optional<asset> sidechain_net_handler_bitcoin::estimate_withdrawal_transaction_fee() const {
wlog("estimate_withdrawal_transaction_fee not implemented for sidechain: ${sidechain}", ("sidechain", sidechain));
return optional<asset>{};
}
std::string sidechain_net_handler_bitcoin::create_primary_wallet_address(const std::vector<son_info> &son_pubkeys) {
using namespace bitcoin;

View file

@ -60,6 +60,10 @@ std::string ethereum_rpc_client::eth_gas_price() {
return send_post_request("eth_gasPrice", "", debug_rpc_calls);
}
std::string ethereum_rpc_client::eth_estimateGas(const std::string &params) {
return send_post_request("eth_estimateGas", params, debug_rpc_calls);
}
std::string ethereum_rpc_client::get_chain_id() {
const std::string reply_str = eth_chainId();
const auto chain_id_string = retrieve_value_from_reply(reply_str, "");
@ -100,6 +104,11 @@ std::string ethereum_rpc_client::get_gas_limit() {
return std::string{};
}
std::string ethereum_rpc_client::get_estimate_gas(const std::string &params) {
const std::string reply_str = eth_estimateGas(params);
return retrieve_value_from_reply(reply_str, "");
}
std::string ethereum_rpc_client::eth_send_transaction(const std::string &params) {
return send_post_request("eth_sendTransaction", "[" + params + "]", debug_rpc_calls);
}
@ -651,6 +660,44 @@ bool sidechain_net_handler_ethereum::settle_sidechain_transaction(const sidechai
return false;
}
optional<asset> sidechain_net_handler_ethereum::estimate_withdrawal_transaction_fee() const {
const auto &gpo = database.get_global_properties();
if (gpo.active_sons.at(sidechain).empty()) {
wlog("No active sons for sidechain: ${sidechain}", ("sidechain", sidechain));
return optional<asset>{};
}
const auto &active_son = gpo.active_sons.at(sidechain).at(0);
const auto &s_idx = database.get_index_type<son_index>().indices().get<by_id>();
const auto son = s_idx.find(active_son.son_id);
if (son == s_idx.end()) {
wlog("Can't find son for id: ${son_id}", ("son_id", active_son.son_id));
return optional<asset>{};
}
if (!son->sidechain_public_keys.contains(sidechain)) {
wlog("No public keys for current son: ${account_id}", ("account_id", son->son_account));
return optional<asset>{};
}
const auto &assets_by_symbol = database.get_index_type<asset_index>().indices().get<by_symbol>();
auto asset_itr = assets_by_symbol.find("ETH");
if (asset_itr == assets_by_symbol.end()) {
wlog("Could not find asset matching ETH");
return optional<asset>{};
}
const auto &public_key = son->sidechain_public_keys.at(sidechain);
const ethereum::withdrawal_encoder encoder;
const auto data = encoder.encode(public_key, 1 * 10000000000, son_wallet_withdraw_id_type{0}.operator object_id_type().operator std::string());
const std::string params = "[{\"from\":\"" + ethereum::add_0x(public_key) + "\", \"to\":\"" + wallet_contract_address + "\", \"data\":\"" + data + "\"}]";
const auto estimate_gas = ethereum::from_hex<int64_t>(rpc_client->get_estimate_gas(params));
const auto gas_price = ethereum::from_hex<int64_t>(rpc_client->get_gas_price());
const auto eth_gas_fee = double(estimate_gas * gas_price) / double{1000000000000000000};
return asset_itr->amount_from_string(std::to_string(eth_gas_fee));
}
std::string sidechain_net_handler_ethereum::create_primary_wallet_transaction(const std::vector<son_info> &son_pubkeys, const std::string &object_id) {
std::vector<std::pair<std::string, uint16_t>> owners_weights;
for (auto &son : son_pubkeys) {

View file

@ -819,6 +819,11 @@ bool sidechain_net_handler_hive::settle_sidechain_transaction(const sidechain_tr
return false;
}
optional<asset> sidechain_net_handler_hive::estimate_withdrawal_transaction_fee() const {
wlog("estimate_withdrawal_transaction_fee not implemented for sidechain: ${sidechain}", ("sidechain", sidechain));
return optional<asset>{};
}
void sidechain_net_handler_hive::schedule_hive_listener() {
fc::time_point now = fc::time_point::now();
int64_t time_to_next = 1000;

View file

@ -290,8 +290,12 @@ bool sidechain_net_handler_peerplays::settle_sidechain_transaction(const sidecha
return true;
}
void sidechain_net_handler_peerplays::select_active_rpc_client()
{
optional<asset> sidechain_net_handler_peerplays::estimate_withdrawal_transaction_fee() const {
wlog("estimate_withdrawal_transaction_fee not implemented for sidechain: ${sidechain}", ("sidechain", sidechain));
return optional<asset>{};
}
void sidechain_net_handler_peerplays::select_active_rpc_client() {
}
}} // namespace graphene::peerplays_sidechain

View file

@ -2676,6 +2676,19 @@ class wallet_api
*/
std::map<sidechain_type, std::vector<std::string>> get_son_listener_log() const;
/**
* @brief Estimate transaction fee for withdrawal
* @param sidechain Sidechain type (bitcoin, HIVE, etc)
* @return Transaction fee
*/
optional<asset> estimate_withdrawal_transaction_fee(sidechain_type sidechain) const;
/**
* @brief Estimate gas fee for withdrawal transaction for ETH
* @return Gas fee in ETH
*/
std::string eth_estimate_withdrawal_transaction_fee() const;
fc::signal<void(bool)> lock_changed;
std::shared_ptr<detail::wallet_api_impl> my;
void encrypt_keys();
@ -2976,4 +2989,6 @@ FC_API( graphene::wallet::wallet_api,
(get_voters_by_id)
(get_voters)
(get_son_listener_log)
(estimate_withdrawal_transaction_fee)
(eth_estimate_withdrawal_transaction_fee)
)

View file

@ -3291,6 +3291,25 @@ public:
return sign_transaction(trx, broadcast);
} FC_CAPTURE_AND_RETHROW((order_id)) }
sidechain_type get_sidechain_type_from_asset(asset_id_type asset_id) const
{
const auto& gpo = _remote_db->get_global_properties();
if(asset_id == gpo.parameters.btc_asset())
return sidechain_type::bitcoin;
if(asset_id == gpo.parameters.eth_asset())
return sidechain_type::ethereum;
if(asset_id == gpo.parameters.hbd_asset())
return sidechain_type::hive;
if(asset_id == gpo.parameters.hive_asset())
return sidechain_type::hive;
return sidechain_type::unknown;
}
signed_transaction transfer(string from, string to, string amount,
string asset_symbol, string memo, bool broadcast = false)
{ try {
@ -3323,6 +3342,19 @@ public:
set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees);
tx.validate();
//! For sidechain withdrawal check if amount is greater than fee
if(to_id == _remote_db->get_global_properties().parameters.son_account()) {
const auto sidechain = get_sidechain_type_from_asset(asset_obj->id);
const auto transaction_fee = estimate_withdrawal_transaction_fee(sidechain);
if(transaction_fee) {
if (*transaction_fee >= xfer_op.amount) {
FC_THROW("Transaction fee: ${sidechain_fee}, would be grater than transfer amount ${amount}",
("sidechain_fee", get_asset(transaction_fee->asset_id).amount_to_pretty_string(transaction_fee->amount))("amount", get_asset(xfer_op.amount.asset_id).amount_to_pretty_string(xfer_op.amount.amount)));
}
}
}
return sign_transaction(tx, broadcast);
} FC_CAPTURE_AND_RETHROW( (from)(to)(amount)(asset_symbol)(memo)(broadcast) ) }
@ -4222,6 +4254,31 @@ public:
FC_CAPTURE_AND_RETHROW()
}
optional<asset> estimate_withdrawal_transaction_fee(sidechain_type sidechain)
{
use_sidechain_api();
try
{
return (*_remote_sidechain)->estimate_withdrawal_transaction_fee(sidechain);
}
FC_CAPTURE_AND_RETHROW()
}
std::string eth_estimate_withdrawal_transaction_fee()
{
try
{
const auto transaction_fee = estimate_withdrawal_transaction_fee(sidechain_type::ethereum);
if(transaction_fee)
{
return get_asset(transaction_fee->asset_id).amount_to_pretty_string(transaction_fee->amount);
}
return "Can't get fee value";
}
FC_CAPTURE_AND_RETHROW()
}
string _wallet_filename;
wallet_data _wallet;
@ -7273,6 +7330,16 @@ std::map<sidechain_type, std::vector<std::string>> wallet_api::get_son_listener_
return my->get_son_listener_log();
}
optional<asset> wallet_api::estimate_withdrawal_transaction_fee(sidechain_type sidechain) const
{
return my->estimate_withdrawal_transaction_fee(sidechain);
}
std::string wallet_api::eth_estimate_withdrawal_transaction_fee() const
{
return my->eth_estimate_withdrawal_transaction_fee();
}
// default ctor necessary for FC_REFLECT
signed_block_with_info::signed_block_with_info( const signed_block& block )
: signed_block( block )

View file

@ -1313,7 +1313,7 @@ BOOST_FIXTURE_TEST_CASE( get_son_network_status, cli_fixture )
(inner_iter->first == gpo.active_sons.at(sidechain_type::ethereum).at(0).son_id))
{
BOOST_TEST_MESSAGE("status: "<< inner_iter->second);
BOOST_CHECK(inner_iter->second == "NOT OK, irregular SON heartbeat, triggering SON down proposal]");
BOOST_CHECK(inner_iter->second == "NOT OK, irregular SON heartbeat, triggering SON down proposal");
}
else if((inner_iter->first == gpo.active_sons.at(sidechain_type::bitcoin).at(1).son_id) &&
(inner_iter->first == gpo.active_sons.at(sidechain_type::hive).at(1).son_id) &&
@ -1342,14 +1342,14 @@ BOOST_FIXTURE_TEST_CASE( get_son_network_status, cli_fixture )
(inner_iter->first == gpo.active_sons.at(sidechain_type::ethereum).at(0).son_id))
{
BOOST_TEST_MESSAGE("status: "<< inner_iter->second);
BOOST_CHECK(inner_iter->second == "NOT OK, irregular SON heartbeat, triggering SON down proposal]");
BOOST_CHECK(inner_iter->second == "NOT OK, irregular SON heartbeat, triggering SON down proposal");
}
else if((inner_iter->first == gpo.active_sons.at(sidechain_type::bitcoin).at(1).son_id) &&
(inner_iter->first == gpo.active_sons.at(sidechain_type::hive).at(1).son_id) &&
(inner_iter->first == gpo.active_sons.at(sidechain_type::ethereum).at(1).son_id))
{
BOOST_TEST_MESSAGE("status: "<< inner_iter->second);
BOOST_CHECK(inner_iter->second == "NOT OK, irregular SON heartbeat, triggering SON down proposal]");
BOOST_CHECK(inner_iter->second == "NOT OK, irregular SON heartbeat, triggering SON down proposal");
}
else{
BOOST_TEST_MESSAGE("status: "<< inner_iter->second);
@ -1517,7 +1517,7 @@ BOOST_FIXTURE_TEST_CASE( get_son_network_status_by_sidechain, cli_fixture )
(iter->first == gpo.active_sons.at(sidechain_type::ethereum).at(0).son_id))
{
BOOST_TEST_MESSAGE("status: "<< iter->second);
BOOST_CHECK(iter->second == "NOT OK, irregular SON heartbeat, triggering SON down proposal]");
BOOST_CHECK(iter->second == "NOT OK, irregular SON heartbeat, triggering SON down proposal");
}
else if((iter->first == gpo.active_sons.at(sidechain_type::bitcoin).at(1).son_id) &&
(iter->first == gpo.active_sons.at(sidechain_type::hive).at(1).son_id) &&
@ -1545,14 +1545,14 @@ BOOST_FIXTURE_TEST_CASE( get_son_network_status_by_sidechain, cli_fixture )
(iter->first == gpo.active_sons.at(sidechain_type::ethereum).at(0).son_id))
{
BOOST_TEST_MESSAGE("status: "<< iter->second);
BOOST_CHECK(iter->second == "NOT OK, irregular SON heartbeat, triggering SON down proposal]");
BOOST_CHECK(iter->second == "NOT OK, irregular SON heartbeat, triggering SON down proposal");
}
else if((iter->first == gpo.active_sons.at(sidechain_type::bitcoin).at(1).son_id) &&
(iter->first == gpo.active_sons.at(sidechain_type::hive).at(1).son_id) &&
(iter->first == gpo.active_sons.at(sidechain_type::ethereum).at(1).son_id))
{
BOOST_TEST_MESSAGE("status: "<< iter->second);
BOOST_CHECK(iter->second == "NOT OK, irregular SON heartbeat, triggering SON down proposal]");
BOOST_CHECK(iter->second == "NOT OK, irregular SON heartbeat, triggering SON down proposal");
}
else{
BOOST_TEST_MESSAGE("status: "<< iter->second);

View file

@ -244,6 +244,9 @@ BOOST_AUTO_TEST_CASE( sidechain_address_delete_test ) {
BOOST_TEST_MESSAGE("sidechain_address_delete_test");
generate_blocks(HARDFORK_SIDECHAIN_DELETE_TIME);
generate_block();
INVOKE(sidechain_address_add_test);
GET_ACTOR(alice);
@ -266,18 +269,12 @@ BOOST_AUTO_TEST_CASE( sidechain_address_delete_test ) {
sign(trx, alice_private_key);
PUSH_TX(db, trx, ~0);
}
//time_point_sec now = db.head_block_time();
generate_block();
generate_block();
{
BOOST_TEST_MESSAGE("Check sidechain_address_delete_operation results");
const auto& idx = db.get_index_type<sidechain_address_index>().indices().get<by_account_and_sidechain_and_expires>();
//BOOST_REQUIRE( idx.size() == 1 );
//auto obj = idx.find( boost::make_tuple( alice_id, sidechain_type::bitcoin, time_point_sec::maximum() ) );
//BOOST_REQUIRE( obj == idx.end() );
//auto expired_obj = idx.find( boost::make_tuple( alice_id, sidechain_type::bitcoin, now ) );
//BOOST_REQUIRE( expired_obj != idx.end() );
BOOST_REQUIRE( idx.size() == 0 );
}
}
@ -286,6 +283,9 @@ BOOST_AUTO_TEST_CASE(sidechain_address_delete_create_test) {
BOOST_TEST_MESSAGE("sidechain_address_delete_create_test");
generate_blocks(HARDFORK_SIDECHAIN_DELETE_TIME);
generate_block();
INVOKE(sidechain_address_add_test);
GET_ACTOR(alice);

View file

@ -208,9 +208,9 @@ try {
db.modify( *son_stats_obj, [&]( son_statistics_object& _s)
{
_s.last_down_timestamp[sidechain_type::bitcoin] = fc::time_point_sec(db.head_block_time() - db.get_global_properties().parameters.son_deregister_time());
_s.last_down_timestamp[sidechain_type::hive] = fc::time_point_sec(db.head_block_time() - db.get_global_properties().parameters.son_deregister_time());
_s.last_down_timestamp[sidechain_type::ethereum] = fc::time_point_sec(db.head_block_time() - db.get_global_properties().parameters.son_deregister_time());
_s.last_active_timestamp[sidechain_type::bitcoin] = fc::time_point_sec(db.head_block_time() - db.get_global_properties().parameters.son_deregister_time());
_s.last_active_timestamp[sidechain_type::hive] = fc::time_point_sec(db.head_block_time() - db.get_global_properties().parameters.son_deregister_time());
_s.last_active_timestamp[sidechain_type::ethereum] = fc::time_point_sec(db.head_block_time() - db.get_global_properties().parameters.son_deregister_time());
});
auto deposit_vesting = db.get<vesting_balance_object>(vesting_balance_id_type(0));