Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
sub_chain_plugin.cpp
Go to the documentation of this file.
3#include <fc/log/logger.hpp>
4#include <vector>
5#include <variant>
7#include <fc/io/raw.hpp>
9
10namespace sysio {
11 static appbase::abstract_plugin& _sub_chain_plugin = app().register_plugin<sub_chain_plugin>();
12
13using namespace chain;
14
17
18void sub_chain_plugin::set_program_options(options_description&, options_description& cfg) {
19 cfg.add_options()
20 ("s-chain-contract", bpo::value<std::string>()->default_value("settle.wns"), "Contract name for identifying relevant S-transactions.")
21 ("s-chain-actions", bpo::value<std::vector<std::string>>()->composing(), "List of action names for relevant S-transactions for a given s-chain-contract");
22}
23void sub_chain_plugin::plugin_initialize(const variables_map& options) {
24 try {
25 if (!options.count("s-chain-contract") || !options.count("s-chain-actions")) {
26 SYS_ASSERT(false, plugin_config_exception, "sub_chain_plugin requires both --s-chain-contract and --s-chain-actions to be set");
27 }
28 else {
29 std::string contract_name_str = options.at("s-chain-contract").as<std::string>();
30 my->contract_name = sysio::chain::name(contract_name_str); // Convert std::string to sysio::chain::name
31
32 std::vector<std::string> actions = options.at("s-chain-actions").as<std::vector<std::string>>();
33 my->action_names.clear();
34 for (const std::string& action_name : actions) {
35 my->action_names.push_back(sysio::chain::name(action_name)); // Convert std::string to action_name
36 }
37 }
38 // my->chain_plug = app().find_plugin<chain_plugin>();
39 // SYS_ASSERT( my->chain_plug, chain::missing_chain_plugin_exception, "" );
40
42}
44 ilog("sub_chain_plugin starting up, adding /v3/sub_chain/get_last_s_id");
45
46 app().get_plugin<http_plugin>().add_api({
47 {"/v3/sub_chain/get_last_s_id", [this](string, string body, auto cb) { // Ensure correct use of auto for callback type inference
48 try {
49 checksum256_type last_s_id = get_prev_s_id();
50 cb(200, last_s_id.str());
51 } catch (fc::exception& e) {
52 cb(500, "{\"error\": \"internal_error\", \"details\": \"" + e.to_detail_string() + "\"}");
53 }
54 }}
55 });
56}
58 ilog("sub_chain_plugin shutting down");
59 // Cleanup code
60}
61
63 return my->contract_name;
64}
66 return my->prev_s_id;
67}
69 ilog("Updating OLD prev_s_id: \t${prev_s_id}", ("prev_s_id", my->prev_s_id));
70 my->prev_s_id = new_s_id;
71 ilog("Updated NEW prev_s_id: \t${prev_s_id}", ("prev_s_id", my->prev_s_id));
72}
73
84checksum256_type sub_chain_plugin::calculate_s_root(const std::vector<transaction>& transactions) {
85 // Build s-leaves from relevant s-transactions
86 vector<digest_type> s_leaves;
87 for( const auto& trx : transactions ){
88 s_leaves.emplace_back( trx.id() );
89 }
90 // Create and return the merkle S-Root
91 return merkle( move(s_leaves) );
92}
93
101// auto s_id_data = s_id.data();
102// return fc::endian_reverse_u32(s_id_data[0]);
103
104 // Extract the pointer to the data from the checksum.
105 auto s_id_data = s_id.data();
106
107 // Since we are dealing with a checksum256_type, which is typically an array of bytes,
108 // we need to correctly handle the conversion to uint32_t considering endianess.
109 uint32_t s_block_number;
110
111 // Copy the first 4 bytes of the data into a uint32_t variable.
112 // memcpy ensures that we handle any alignment issues.
113 std::memcpy(&s_block_number, s_id_data, sizeof(uint32_t));
114
115 // Reverse the endianess if necessary.
116 // You might need to adjust this based on how the data is stored (big-endian vs little-endian).
117 return fc::endian_reverse_u32(s_block_number);
118}
119
128 // ilog("Computing new S-ID from \n\tcurr_s_root: ${curr_s_root}\n\t${prev_s_id}", ("curr_s_root", curr_s_root)("prev_s_id", my->prev_s_id));
129
130 // Serialize both the previous S-ID and the current S-Root
131 auto data = fc::raw::pack(std::make_pair(my->prev_s_id, curr_s_root));
132 // Hash the serialized data to generate the new S-ID
134
135 ilog("Computed interim S-ID: ${curr_s_id}", ("curr_s_id", curr_s_id));
136 // Extract the block number from the previous S-ID and increment it by 1
137 uint32_t prev_s_block_number = sub_chain_plugin::extract_s_block_number(my->prev_s_id);
138 uint32_t next_s_block_number = prev_s_block_number + 1;
139
140 ilog("Extracted prev_s_block_number from prev_s_id: ${prev_s_block_number}, next: ${next_s_block_number}",
141 ("prev_s_block_number", prev_s_block_number)("next_s_block_number", next_s_block_number));
142
143 // Modify the first 4 bytes directly
144 uint32_t next_s_block_number_reversed = fc::endian_reverse_u32(next_s_block_number);
145 std::memcpy(curr_s_id.data(), &next_s_block_number_reversed, sizeof(uint32_t)); // Modify the first 4 bytes
146
147 // ilog("Computed curr_s_id with block number embedded: ${c}", ("c", curr_s_id.str()));
148 return curr_s_id;
149}
150
156std::vector<sysio::chain::transaction> sub_chain_plugin::find_relevant_transactions(sysio::chain::controller& curr_chain) {
157 std::vector<sysio::chain::transaction> relevant_transactions;
158 auto& pending_trx_receipts = curr_chain.get_pending_trx_receipts(); // Access pending transactions directly
159 for (const auto& trx_receipt : pending_trx_receipts) {
160 if (std::holds_alternative<sysio::chain::packed_transaction>(trx_receipt.trx)) {
161 const auto& packed_trx = std::get<sysio::chain::packed_transaction>(trx_receipt.trx);
162 const auto& trx = packed_trx.get_transaction();
164 relevant_transactions.push_back(trx);
165 }
166 }
167 }
168 return relevant_transactions;
169}
170
177 for (const auto& action : trx.actions) {
178 if (action.account == my->contract_name && std::find(my->action_names.begin(), my->action_names.end(), action.name) != my->action_names.end()){
179 return true;
180 }
181 }
182 return false;
183}
184
185} // namespace sysio
#define SYS_ASSERT(expr, exc_type, FORMAT,...)
Definition exceptions.hpp:7
abstract_plugin & get_plugin(const string &name) const
Used to generate a useful error report when an exception is thrown.
Definition exception.hpp:58
std::string to_detail_string(log_level ll=log_level::all) const
static sha256 hash(const char *d, uint32_t dlen)
Definition sha256.cpp:44
string str() const
Definition sha256.cpp:26
const char * data() const
Definition sha256.cpp:31
const vector< transaction_receipt > & get_pending_trx_receipts() const
sysio::chain::account_name & get_contract_name() const
void plugin_initialize(const variables_map &options)
virtual void set_program_options(options_description &, options_description &cfg) override
bool is_relevant_s_root_transaction(const sysio::chain::transaction &trx)
sysio::chain::checksum256_type & get_prev_s_id() const
void update_prev_s_id(const sysio::chain::checksum256_type &new_s_id)
uint32_t extract_s_block_number(const sysio::chain::checksum256_type &s_id)
sysio::chain::checksum256_type compute_curr_s_id(const sysio::chain::checksum256_type &curr_s_root)
std::vector< sysio::chain::transaction > find_relevant_transactions(sysio::chain::controller &curr_chain)
sysio::chain::checksum256_type calculate_s_root(const std::vector< sysio::chain::transaction > &transactions)
#define FC_LOG_AND_RETHROW()
#define ilog(FORMAT,...)
Definition logger.hpp:118
application & app()
void pack(Stream &s, const std::deque< T > &value)
Definition raw.hpp:531
std::string string
Definition string.hpp:10
uint32_t endian_reverse_u32(uint32_t x)
Definition bitutil.hpp:19
sysio::chain::action_name action_name
digest_type merkle(vector< digest_type > ids)
Definition merkle.cpp:35
unsigned int uint32_t
Definition stdint.h:126
Immutable except for fc::from_variant.
Definition name.hpp:43
vector< action > actions