diff --git a/tests/tests/son_operations_tests.cpp b/tests/tests/son_operations_tests.cpp index 3740335c..6b0378e8 100644 --- a/tests/tests/son_operations_tests.cpp +++ b/tests/tests/son_operations_tests.cpp @@ -736,4 +736,118 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) { BOOST_CHECK( son_stats_obj->last_active_timestamp == op.ts); } } FC_LOG_AND_RETHROW() +} + +BOOST_AUTO_TEST_CASE( son_report_down_test ) { + + try + { + INVOKE(son_heartbeat_test); + GET_ACTOR(alice); + GET_ACTOR(bob); + + generate_block(); + + const auto& idx = db.get_index_type().indices().get(); + BOOST_REQUIRE( idx.size() == 1 ); + auto obj = idx.find( alice_id ); + BOOST_REQUIRE( obj != idx.end() ); + + const auto& sidx = db.get_index_type().indices().get(); + BOOST_REQUIRE( sidx.size() == 1 ); + auto son_stats_obj = sidx.find( obj->statistics ); + BOOST_REQUIRE( son_stats_obj != sidx.end() ); + + BOOST_CHECK( obj->status == son_status::active); + + const auto& son_btc_account = db.create( [&]( account_object& obj ) { + obj.name = "son_btc_account"; + obj.statistics = db.create([&]( account_statistics_object& acc_stat ){ acc_stat.owner = obj.id; }).id; + obj.membership_expiration_date = time_point_sec::maximum(); + obj.network_fee_percentage = GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE; + obj.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT - GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE; + + obj.owner.add_authority( bob_id, 1 ); + obj.active.add_authority( bob_id, 1 ); + obj.active.weight_threshold = 1; + obj.owner.weight_threshold = 1; + }); + + db.modify( db.get_global_properties(), [&]( global_property_object& _gpo ) + { + _gpo.parameters.extensions.value.son_pay_daily_max = 200; + _gpo.parameters.witness_pay_per_block = 0; + + _gpo.parameters.extensions.value.son_btc_account = son_btc_account.get_id(); + if( _gpo.pending_parameters ) + _gpo.pending_parameters->extensions.value.son_btc_account = son_btc_account.get_id(); + }); + + { + // Check that transaction fails if down_ts < last_active_timestamp + generate_block(); + // Send Report Down Operation for an active status SON + son_report_down_operation op; + op.payer = db.get_global_properties().parameters.get_son_btc_account_id(); + op.son_id = son_id_type(0); + op.down_ts = fc::time_point_sec(son_stats_obj->last_active_timestamp - fc::seconds(1)); + + trx.operations.push_back(op); + sign(trx, bob_private_key); + // Expect an exception + GRAPHENE_REQUIRE_THROW(PUSH_TX( db, trx, ~0), fc::exception); + trx.clear(); + } + + { + // Check that transaction fails if payer is not son_btc_account. + generate_block(); + // Send Report Down Operation for an active status SON + son_report_down_operation op; + op.payer = alice_id; + op.son_id = son_id_type(0); + op.down_ts = son_stats_obj->last_active_timestamp; + + trx.operations.push_back(op); + sign(trx, alice_private_key); + // Expect an exception + GRAPHENE_REQUIRE_THROW(PUSH_TX( db, trx, ~0), fc::exception); + trx.clear(); + } + + { + // Check that transaction succeeds after getting enough approvals on son_btc_account. + generate_block(); + // Send Report Down Operation for an active status SON + son_report_down_operation op; + op.payer = db.get_global_properties().parameters.get_son_btc_account_id(); + op.son_id = son_id_type(0); + op.down_ts = son_stats_obj->last_active_timestamp; + + trx.operations.push_back(op); + sign(trx, bob_private_key); + PUSH_TX( db, trx, ~0); + generate_block(); + trx.clear(); + + BOOST_CHECK( obj->status == son_status::in_maintenance); + BOOST_CHECK( son_stats_obj->last_down_timestamp == op.down_ts); + } + + { + // Check that transaction fails if report down sent for an in_maintenance SON. + generate_block(); + // Send Report Down Operation for an active status SON + son_report_down_operation op; + op.payer = db.get_global_properties().parameters.get_son_btc_account_id(); + op.son_id = son_id_type(0); + op.down_ts = son_stats_obj->last_active_timestamp; + + trx.operations.push_back(op); + sign(trx, bob_private_key); + // Expect an exception + GRAPHENE_REQUIRE_THROW(PUSH_TX( db, trx, ~0), fc::exception); + trx.clear(); + } + } FC_LOG_AND_RETHROW() } BOOST_AUTO_TEST_SUITE_END()