Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
test_control_plugin.cpp
Go to the documentation of this file.
2
3namespace fc { class variant; }
4
5namespace sysio {
6
7static appbase::abstract_plugin& _test_control_plugin = app().register_plugin<test_control_plugin>();
8
10public:
11 explicit test_control_plugin_impl(chain::controller& c) : _chain(c) {}
12 void connect();
13 void disconnect();
14 void kill_on_lib(account_name prod, uint32_t where_in_seq);
15 void kill_on_head(account_name prod, uint32_t where_in_seq);
16
17private:
18 void accepted_block(const chain::block_state_ptr& bsp);
19 void applied_irreversible_block(const chain::block_state_ptr& bsp);
20 void process_next_block_state(const chain::block_state_ptr& bsp);
21
22 std::optional<boost::signals2::scoped_connection> _accepted_block_connection;
23 std::optional<boost::signals2::scoped_connection> _irreversible_block_connection;
24 chain::controller& _chain;
25 account_name _producer;
26 uint32_t _where_in_sequence{};
27 bool _clean_producer_sequence{false};
28 bool _started_production_round{false};
29 bool _track_lib{false};
30 bool _track_head{false};
31};
32
34 _irreversible_block_connection.emplace(
35 _chain.irreversible_block.connect( [&]( const chain::block_state_ptr& bs ) {
36 applied_irreversible_block( bs );
37 } ));
38 _accepted_block_connection =
39 _chain.accepted_block.connect( [&]( const chain::block_state_ptr& bs ) {
40 accepted_block( bs );
41 } );
42}
43
45 _accepted_block_connection.reset();
46 _irreversible_block_connection.reset();
47}
48
49void test_control_plugin_impl::applied_irreversible_block(const chain::block_state_ptr& bsp) {
50 if (_track_lib)
51 process_next_block_state(bsp);
52}
53
54void test_control_plugin_impl::accepted_block(const chain::block_state_ptr& bsp) {
55 if (_track_head)
56 process_next_block_state(bsp);
57}
58
59void test_control_plugin_impl::process_next_block_state(const chain::block_state_ptr& bsp) {
60 // Tests expect the shutdown only after signaling a producer shutdown and seeing a full production cycle
61 const auto block_time = _chain.head_block_time() + fc::microseconds(chain::config::block_interval_us);
62 const auto& producer_authority = bsp->get_scheduled_producer(block_time);
63 const auto producer_name = producer_authority.producer_name;
64 const auto slot = bsp->block->timestamp.slot % chain::config::producer_repetitions;
65 if (_producer != account_name()) {
66 if( _producer != producer_name ) _clean_producer_sequence = true;
67 if( _clean_producer_sequence ) {
68 ilog( "producer ${cprod} slot ${pslot}, looking for ${lprod} slot ${slot}",
69 ("cprod", producer_name)("pslot", slot)("lprod", _producer)("slot", _where_in_sequence) );
70 } else {
71 ilog( "producer ${cprod} slot ${pslot}, looking for start of ${lprod} production round",
72 ("cprod", producer_name)("pslot", slot)("lprod", _producer) );
73 }
74 }
75
76 // check started_production_round in case where producer does not produce a full round, still want to shut down
77 if( _clean_producer_sequence && (producer_name == _producer || _started_production_round) ) {
78 _started_production_round = true;
79 const auto current_slot = chain::block_timestamp_type( block_time ).slot % chain::config::producer_repetitions;
80 ilog( "producer ${prod} slot: ${slot}", ("prod", producer_name)("slot", slot) );
81
82 if( current_slot >= _where_in_sequence || producer_name != _producer ) {
83 ilog("shutting down");
84 app().quit();
85 }
86 }
87}
88
90 _track_head = false;
91 _producer = prod;
92 _where_in_sequence = where_in_seq;
93 _clean_producer_sequence = false;
94 _started_production_round = false;
95 _track_lib = true;
96}
97
99 _track_lib = false;
100 _producer = prod;
101 _where_in_sequence = where_in_seq;
102 _clean_producer_sequence = false;
103 _started_production_round = false;
104 _track_head = true;
105}
106
108
109void test_control_plugin::set_program_options(options_description& cli, options_description& cfg) {
110}
111
112void test_control_plugin::plugin_initialize(const variables_map& options) {
113}
114
116 ilog("test_control_plugin starting up");
117 my.reset(new test_control_plugin_impl(app().get_plugin<chain_plugin>().chain()));
118 my->connect();
119}
120
122 my->disconnect();
123 ilog("test_control_plugin shutting down");
124}
125
126namespace test_control_apis {
128
129 if (params.based_on_lib) {
130 ilog("kill on lib for producer: ${p} at their ${s} slot in sequence", ("p", params.producer.to_string())("s", params.where_in_sequence));
131 my->kill_on_lib(params.producer, params.where_in_sequence);
132 } else {
133 ilog("kill on head for producer: ${p} at their ${s} slot in sequence", ("p", params.producer.to_string())("s", params.where_in_sequence));
134 my->kill_on_head(params.producer, params.where_in_sequence);
135 }
137}
138
139} // namespace test_control_apis
140
141} // namespace sysio
signal< void(const block_state_ptr &)> accepted_block
signal< void(const block_state_ptr &)> irreversible_block
time_point head_block_time() const
kill_node_on_producer_results kill_node_on_producer(const kill_node_on_producer_params &params) const
test_control_plugin_impl(chain::controller &c)
void kill_on_lib(account_name prod, uint32_t where_in_seq)
void kill_on_head(account_name prod, uint32_t where_in_seq)
virtual void set_program_options(options_description &cli, options_description &cfg) override
void plugin_initialize(const variables_map &options)
#define ilog(FORMAT,...)
Definition logger.hpp:118
application & app()
namespace sysio::chain
Definition authority.cpp:3
block_timestamp< config::block_interval_ms, config::block_timestamp_epoch > block_timestamp_type
std::shared_ptr< block_state > block_state_ptr
name account_name
Definition types.hpp:120
producer_name(block_signing_key)) FC_REFLECT(producer_set_def
unsigned int uint32_t
Definition stdint.h:126
Immutable except for fc::from_variant.
Definition name.hpp:43
void cli()
yubihsm_pkcs11_slot * slot