From 908ad7caeb3b7cb724580fe03f46da344d72c036 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Fri, 5 Oct 2018 16:22:07 -0400 Subject: [PATCH] state history plugin: cleanup --- .../state_history_plugin/history_log.hpp | 143 +++++ .../state_history_serialization.hpp | 425 +++++++++++++ .../state_history_plugin.cpp | 568 +----------------- 3 files changed, 576 insertions(+), 560 deletions(-) create mode 100644 plugins/state_history_plugin/include/eosio/state_history_plugin/history_log.hpp create mode 100644 plugins/state_history_plugin/include/eosio/state_history_plugin/state_history_serialization.hpp diff --git a/plugins/state_history_plugin/include/eosio/state_history_plugin/history_log.hpp b/plugins/state_history_plugin/include/eosio/state_history_plugin/history_log.hpp new file mode 100644 index 000000000..a13008344 --- /dev/null +++ b/plugins/state_history_plugin/include/eosio/state_history_plugin/history_log.hpp @@ -0,0 +1,143 @@ +/** + * @file + * @copyright defined in eos/LICENSE.txt + */ +#pragma once + +#include +#include + +#include +#include + +namespace eosio { + +/* + * *.log: + * +---------+----------------+-----------+------------------+-----+---------+----------------+ + * | Entry i | Pos of Entry i | Entry i+1 | Pos of Entry i+1 | ... | Entry z | Pos of Entry z | + * +---------+----------------+-----------+------------------+-----+---------+----------------+ + * + * *.index: + * +----------------+------------------+-----+----------------+ + * | Pos of Entry i | Pos of Entry i+1 | ... | Pos of Entry z | + * +----------------+------------------+-----+----------------+ + * + * each entry: + * uint32_t block_num + * uint64_t size of payload + * uint8_t version + * payload + * + * irreversible_state payload: + * uint32_t size of deltas + * char[] deltas + */ + +struct history_log_header { + uint32_t block_num = 0; + uint64_t payload_size = 0; + uint16_t version = 0; +}; + +struct history_log { + const char* const name = ""; + std::fstream log; + std::fstream index; + uint32_t begin_block = 0; + uint32_t end_block = 0; + + void open_log(const std::string& filename) { + log.open(filename, std::ios_base::binary | std::ios_base::in | std::ios_base::out | std::ios_base::app); + uint64_t size = log.tellg(); + if (size >= sizeof(history_log_header)) { + history_log_header header; + log.seekg(0); + log.read((char*)&header, sizeof(header)); + EOS_ASSERT(header.version == 0 && sizeof(header) + header.payload_size + sizeof(uint64_t) <= size, + chain::plugin_exception, "corrupt ${name}.log (1)", ("name", name)); + begin_block = header.block_num; + + uint64_t end_pos; + log.seekg(size - sizeof(end_pos)); + log.read((char*)&end_pos, sizeof(end_pos)); + EOS_ASSERT(end_pos <= size && end_pos + sizeof(header) <= size, chain::plugin_exception, + "corrupt ${name}.log (2)", ("name", name)); + log.seekg(end_pos); + log.read((char*)&header, sizeof(header)); + EOS_ASSERT(end_pos + sizeof(header) + header.payload_size + sizeof(uint64_t) == size, chain::plugin_exception, + "corrupt ${name}.log (3)", ("name", name)); + end_block = header.block_num + 1; + + EOS_ASSERT(begin_block < end_block, chain::plugin_exception, "corrupt ${name}.log (4)", ("name", name)); + ilog("${name}.log has blocks ${b}-${e}", ("name", name)("b", begin_block)("e", end_block - 1)); + } else { + EOS_ASSERT(!size, chain::plugin_exception, "corrupt ${name}.log (5)", ("name", name)); + ilog("${name}.log is empty", ("name", name)); + } + } + + void open_index(const std::string& filename) { + index.open(filename, std::ios_base::binary | std::ios_base::in | std::ios_base::out | std::ios_base::app); + if (index.tellg() == (end_block - begin_block) * sizeof(uint64_t)) + return; + ilog("Regenerate ${name}.index", ("name", name)); + index.close(); + index.open(filename, std::ios_base::binary | std::ios_base::in | std::ios_base::out | std::ios_base::trunc); + + log.seekg(0, std::ios_base::end); + uint64_t size = log.tellg(); + uint64_t pos = 0; + while (pos < size) { + index.write((char*)&pos, sizeof(pos)); + history_log_header header; + EOS_ASSERT(pos + sizeof(header) <= size, chain::plugin_exception, "corrupt ${name}.log (6)", ("name", name)); + log.seekg(pos); + log.read((char*)&header, sizeof(header)); + uint64_t suffix_pos = pos + sizeof(header) + header.payload_size; + uint64_t suffix; + EOS_ASSERT(suffix_pos + sizeof(suffix) <= size, chain::plugin_exception, "corrupt ${name}.log (7)", + ("name", name)); + log.seekg(suffix_pos); + log.read((char*)&suffix, sizeof(suffix)); + // ilog("block ${b} at ${pos}-${end} suffix=${suffix} file_size=${fs}", + // ("b", header.block_num)("pos", pos)("end", suffix_pos + sizeof(suffix))("suffix", suffix)("fs", size)); + EOS_ASSERT(suffix == pos, chain::plugin_exception, "corrupt ${name}.log (8)", ("name", name)); + pos = suffix_pos + sizeof(suffix); + } + } + + template + void write_entry(history_log_header header, F write_payload) { + EOS_ASSERT(begin_block == end_block || header.block_num == end_block, chain::plugin_exception, + "writing unexpected block_num to ${name}.log", ("name", name)); + log.seekg(0, std::ios_base::end); + uint64_t pos = log.tellg(); + log.write((char*)&header, sizeof(header)); + write_payload(log); + uint64_t end = log.tellg(); + EOS_ASSERT(end == pos + sizeof(header) + header.payload_size, chain::plugin_exception, + "wrote payload with incorrect size to ${name}.log", ("name", name)); + log.write((char*)&pos, sizeof(pos)); + + index.seekg(0, std::ios_base::end); + index.write((char*)&pos, sizeof(pos)); + if (begin_block == end_block) + begin_block = header.block_num; + end_block = header.block_num + 1; + } + + // returns stream positioned at payload + std::fstream& get_entry(uint32_t block_num, history_log_header& header) { + EOS_ASSERT(block_num >= begin_block && block_num < end_block, chain::plugin_exception, + "read non-existing block in ${name}.log", ("name", name)); + uint64_t pos; + index.seekg((block_num - begin_block) * sizeof(pos)); + index.read((char*)&pos, sizeof(pos)); + log.seekg(pos); + log.read((char*)&header, sizeof(header)); + return log; + } +}; // history_log + +} // namespace eosio diff --git a/plugins/state_history_plugin/include/eosio/state_history_plugin/state_history_serialization.hpp b/plugins/state_history_plugin/include/eosio/state_history_plugin/state_history_serialization.hpp new file mode 100644 index 000000000..84e263d89 --- /dev/null +++ b/plugins/state_history_plugin/include/eosio/state_history_plugin/state_history_serialization.hpp @@ -0,0 +1,425 @@ +/** + * @file + * @copyright defined in eos/LICENSE.txt + */ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +template +struct history_serial_wrapper { + const T& obj; +}; + +template +history_serial_wrapper make_history_serial_wrapper(const T& obj) { + return {obj}; +} + +namespace fc { + +template +const T& as_type(const T& x) { + return x; +} + +template +void serialize_shared_vector(datastream& ds, const T& v) { + fc::raw::pack(ds, unsigned_int(v.size())); + for (auto& x : v) + ds << make_history_serial_wrapper(x); +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.id._id)); + fc::raw::pack(ds, as_type(obj.obj.name.value)); + fc::raw::pack(ds, as_type(obj.obj.vm_type)); + fc::raw::pack(ds, as_type(obj.obj.vm_version)); + fc::raw::pack(ds, as_type(obj.obj.privileged)); + fc::raw::pack(ds, as_type(obj.obj.last_code_update)); + fc::raw::pack(ds, as_type(obj.obj.code_version)); + fc::raw::pack(ds, as_type(obj.obj.creation_date)); + fc::raw::pack(ds, as_type(obj.obj.code)); + fc::raw::pack(ds, as_type(obj.obj.abi)); + return ds; +} + +template +datastream& operator<<(datastream& ds, + const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.id._id)); + fc::raw::pack(ds, as_type(obj.obj.name.value)); + fc::raw::pack(ds, as_type(obj.obj.recv_sequence)); + fc::raw::pack(ds, as_type(obj.obj.auth_sequence)); + fc::raw::pack(ds, as_type(obj.obj.code_sequence)); + fc::raw::pack(ds, as_type(obj.obj.abi_sequence)); + return ds; +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.id._id)); + fc::raw::pack(ds, as_type(obj.obj.code.value)); + fc::raw::pack(ds, as_type(obj.obj.scope.value)); + fc::raw::pack(ds, as_type(obj.obj.table.value)); + fc::raw::pack(ds, as_type(obj.obj.payer.value)); + fc::raw::pack(ds, as_type(obj.obj.count)); + return ds; +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.id._id)); + fc::raw::pack(ds, as_type(obj.obj.t_id._id)); + fc::raw::pack(ds, as_type(obj.obj.primary_key)); + fc::raw::pack(ds, as_type(obj.obj.payer.value)); + fc::raw::pack(ds, as_type(obj.obj.value)); + return ds; +} + +template +void serialize_secondary_index_data(datastream& ds, const T& obj) { + fc::raw::pack(ds, obj); +} + +template +void serialize_secondary_index_data(datastream& ds, const float64_t& obj) { + uint64_t i; + memcpy(&i, &obj, sizeof(i)); + fc::raw::pack(ds, i); +} + +template +void serialize_secondary_index_data(datastream& ds, const float128_t& obj) { + __uint128_t i; + memcpy(&i, &obj, sizeof(i)); + fc::raw::pack(ds, i); +} + +template +void serialize_secondary_index_data(datastream& ds, const eosio::chain::key256_t& obj) { + fc::raw::pack(ds, obj[0]); + fc::raw::pack(ds, obj[1]); +} + +template +datastream& serialize_secondary_index(datastream& ds, const T& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.id._id)); + fc::raw::pack(ds, as_type(obj.t_id._id)); + fc::raw::pack(ds, as_type(obj.primary_key)); + fc::raw::pack(ds, as_type(obj.payer.value)); + serialize_secondary_index_data(ds, obj.secondary_key); + return ds; +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { + return serialize_secondary_index(ds, obj.obj); +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { + return serialize_secondary_index(ds, obj.obj); +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { + return serialize_secondary_index(ds, obj.obj); +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { + return serialize_secondary_index(ds, obj.obj); +} + +template +datastream& operator<<(datastream& ds, + const history_serial_wrapper& obj) { + return serialize_secondary_index(ds, obj.obj); +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.producer_name.value)); + fc::raw::pack(ds, as_type(obj.obj.block_signing_key)); + return ds; +} + +template +datastream& operator<<(datastream& ds, + const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.version)); + serialize_shared_vector(ds, obj.obj.producers); + return ds; +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.max_block_net_usage)); + fc::raw::pack(ds, as_type(obj.obj.target_block_net_usage_pct)); + fc::raw::pack(ds, as_type(obj.obj.max_transaction_net_usage)); + fc::raw::pack(ds, as_type(obj.obj.base_per_transaction_net_usage)); + fc::raw::pack(ds, as_type(obj.obj.net_usage_leeway)); + fc::raw::pack(ds, as_type(obj.obj.context_free_discount_net_usage_num)); + fc::raw::pack(ds, as_type(obj.obj.context_free_discount_net_usage_den)); + fc::raw::pack(ds, as_type(obj.obj.max_block_cpu_usage)); + fc::raw::pack(ds, as_type(obj.obj.target_block_cpu_usage_pct)); + fc::raw::pack(ds, as_type(obj.obj.max_transaction_cpu_usage)); + fc::raw::pack(ds, as_type(obj.obj.min_transaction_cpu_usage)); + fc::raw::pack(ds, as_type(obj.obj.max_transaction_lifetime)); + fc::raw::pack(ds, as_type(obj.obj.deferred_trx_expiration_window)); + fc::raw::pack(ds, as_type(obj.obj.max_transaction_delay)); + fc::raw::pack(ds, as_type(obj.obj.max_inline_action_size)); + fc::raw::pack(ds, as_type(obj.obj.max_inline_action_depth)); + fc::raw::pack(ds, as_type(obj.obj.max_authority_depth)); + return ds; +} + +template +datastream& operator<<(datastream& ds, + const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.id._id)); + + fc::raw::pack(ds, as_type>(obj.obj.proposed_schedule_block_num)); + fc::raw::pack(ds, make_history_serial_wrapper( + as_type(obj.obj.proposed_schedule))); + fc::raw::pack(ds, make_history_serial_wrapper(as_type(obj.obj.configuration))); + + return ds; +} + +template +datastream& operator<<(datastream& ds, + const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.id._id)); + fc::raw::pack(ds, as_type(obj.obj.global_action_sequence)); + return ds; +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.id._id)); + fc::raw::pack(ds, as_type(obj.obj.block_id)); + return ds; +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.id._id)); + fc::raw::pack(ds, as_type(obj.obj.expiration)); + fc::raw::pack(ds, as_type(obj.obj.trx_id)); + return ds; +} + +template +datastream& operator<<(datastream& ds, + const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.id._id)); + fc::raw::pack(ds, as_type(obj.obj.trx_id)); + fc::raw::pack(ds, as_type(obj.obj.sender.value)); + fc::raw::pack(ds, as_type<__uint128_t>(obj.obj.sender_id)); + fc::raw::pack(ds, as_type(obj.obj.payer.value)); + fc::raw::pack(ds, as_type(obj.obj.delay_until)); + fc::raw::pack(ds, as_type(obj.obj.expiration)); + fc::raw::pack(ds, as_type(obj.obj.published)); + fc::raw::pack(ds, as_type(obj.obj.packed_trx)); + return ds; +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.key)); + fc::raw::pack(ds, as_type(obj.obj.weight)); + return ds; +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.actor.value)); + fc::raw::pack(ds, as_type(obj.obj.permission.value)); + return ds; +} + +template +datastream& operator<<(datastream& ds, + const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, make_history_serial_wrapper(as_type(obj.obj.permission))); + fc::raw::pack(ds, as_type(obj.obj.weight)); + return ds; +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.wait_sec)); + fc::raw::pack(ds, as_type(obj.obj.weight)); + return ds; +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.threshold)); + serialize_shared_vector(ds, obj.obj.keys); + serialize_shared_vector(ds, obj.obj.accounts); + serialize_shared_vector(ds, obj.obj.waits); + return ds; +} + +template +datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.id._id)); + fc::raw::pack(ds, as_type(obj.obj.usage_id._id)); + fc::raw::pack(ds, as_type(obj.obj.parent._id)); + fc::raw::pack(ds, as_type(obj.obj.owner.value)); + fc::raw::pack(ds, as_type(obj.obj.name.value)); + fc::raw::pack(ds, as_type(obj.obj.last_updated)); + fc::raw::pack(ds, make_history_serial_wrapper(as_type(obj.obj.auth))); + return ds; +} + +template +datastream& operator<<(datastream& ds, + const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.id._id)); + fc::raw::pack(ds, as_type(obj.obj.last_used)); + return ds; +} + +template +datastream& operator<<(datastream& ds, + const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.id._id)); + fc::raw::pack(ds, as_type(obj.obj.account.value)); + fc::raw::pack(ds, as_type(obj.obj.code.value)); + fc::raw::pack(ds, as_type(obj.obj.message_type.value)); + fc::raw::pack(ds, as_type(obj.obj.required_permission.value)); + return ds; +} + +template +datastream& operator<<(datastream& ds, + const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.id._id)); + fc::raw::pack(ds, as_type(obj.obj.owner.value)); + fc::raw::pack(ds, as_type(obj.obj.pending)); + fc::raw::pack(ds, as_type(obj.obj.net_weight)); + fc::raw::pack(ds, as_type(obj.obj.cpu_weight)); + fc::raw::pack(ds, as_type(obj.obj.ram_bytes)); + return ds; +} + +template +datastream& operator<<(datastream& ds, + const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.last_ordinal)); + fc::raw::pack(ds, as_type(obj.obj.value_ex)); + fc::raw::pack(ds, as_type(obj.obj.consumed)); + return ds; +} + +template +datastream& operator<<(datastream& ds, + const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.id._id)); + fc::raw::pack(ds, as_type(obj.obj.owner.value)); + fc::raw::pack( + ds, make_history_serial_wrapper(as_type(obj.obj.net_usage))); + fc::raw::pack( + ds, make_history_serial_wrapper(as_type(obj.obj.cpu_usage))); + fc::raw::pack(ds, as_type(obj.obj.ram_usage)); + return ds; +} + +template +datastream& +operator<<(datastream& ds, + const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.id._id)); + fc::raw::pack(ds, make_history_serial_wrapper( + as_type(obj.obj.average_block_net_usage))); + fc::raw::pack(ds, make_history_serial_wrapper( + as_type(obj.obj.average_block_cpu_usage))); + fc::raw::pack(ds, as_type(obj.obj.pending_net_usage)); + fc::raw::pack(ds, as_type(obj.obj.pending_cpu_usage)); + fc::raw::pack(ds, as_type(obj.obj.total_net_weight)); + fc::raw::pack(ds, as_type(obj.obj.total_cpu_weight)); + fc::raw::pack(ds, as_type(obj.obj.total_ram_bytes)); + fc::raw::pack(ds, as_type(obj.obj.virtual_net_limit)); + fc::raw::pack(ds, as_type(obj.obj.virtual_cpu_limit)); + return ds; +} + +template +datastream& operator<<(datastream& ds, + const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.numerator)); + fc::raw::pack(ds, as_type(obj.obj.denominator)); + return ds; +} + +template +datastream& operator<<(datastream& ds, + const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.target)); + fc::raw::pack(ds, as_type(obj.obj.max)); + fc::raw::pack(ds, as_type(obj.obj.periods)); + fc::raw::pack(ds, as_type(obj.obj.max_multiplier)); + fc::raw::pack(ds, make_history_serial_wrapper(as_type(obj.obj.contract_rate))); + fc::raw::pack(ds, make_history_serial_wrapper(as_type(obj.obj.expand_rate))); + return ds; +} + +template +datastream& +operator<<(datastream& ds, + const history_serial_wrapper& obj) { + fc::raw::pack(ds, fc::unsigned_int(0)); + fc::raw::pack(ds, as_type(obj.obj.id._id)); + fc::raw::pack(ds, make_history_serial_wrapper(as_type( + obj.obj.cpu_limit_parameters))); + fc::raw::pack(ds, make_history_serial_wrapper(as_type( + obj.obj.net_limit_parameters))); + fc::raw::pack(ds, as_type(obj.obj.account_cpu_usage_average_window)); + fc::raw::pack(ds, as_type(obj.obj.account_net_usage_average_window)); + return ds; +}; + +} // namespace fc diff --git a/plugins/state_history_plugin/state_history_plugin.cpp b/plugins/state_history_plugin/state_history_plugin.cpp index 4865274dc..50da245f9 100644 --- a/plugins/state_history_plugin/state_history_plugin.cpp +++ b/plugins/state_history_plugin/state_history_plugin.cpp @@ -1,16 +1,11 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +/** + * @file + * @copyright defined in eos/LICENSE.txt + */ + +#include #include +#include #include #include @@ -25,426 +20,6 @@ namespace ws = boost::beast::websocket; extern const char* const state_history_plugin_abi; -template -struct history_serial_wrapper { - const T& obj; -}; - -template -static history_serial_wrapper make_history_serial_wrapper(const T& obj) { - return {obj}; -} - -namespace fc { - -template -static const T& as_type(const T& x) { - return x; -} - -template -static void serialize_shared_vector(datastream& ds, const T& v) { - fc::raw::pack(ds, unsigned_int(v.size())); - for (auto& x : v) - ds << make_history_serial_wrapper(x); -} - -template -static datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { - fc::raw::pack(ds, fc::unsigned_int(0)); - fc::raw::pack(ds, as_type(obj.obj.id._id)); - fc::raw::pack(ds, as_type(obj.obj.name.value)); - fc::raw::pack(ds, as_type(obj.obj.vm_type)); - fc::raw::pack(ds, as_type(obj.obj.vm_version)); - fc::raw::pack(ds, as_type(obj.obj.privileged)); - fc::raw::pack(ds, as_type(obj.obj.last_code_update)); - fc::raw::pack(ds, as_type(obj.obj.code_version)); - fc::raw::pack(ds, as_type(obj.obj.creation_date)); - fc::raw::pack(ds, as_type(obj.obj.code)); - fc::raw::pack(ds, as_type(obj.obj.abi)); - return ds; -} - -template -static datastream& operator<<(datastream& ds, - const history_serial_wrapper& obj) { - fc::raw::pack(ds, fc::unsigned_int(0)); - fc::raw::pack(ds, as_type(obj.obj.id._id)); - fc::raw::pack(ds, as_type(obj.obj.name.value)); - fc::raw::pack(ds, as_type(obj.obj.recv_sequence)); - fc::raw::pack(ds, as_type(obj.obj.auth_sequence)); - fc::raw::pack(ds, as_type(obj.obj.code_sequence)); - fc::raw::pack(ds, as_type(obj.obj.abi_sequence)); - return ds; -} - -template -static datastream& operator<<(datastream& ds, - const history_serial_wrapper& obj) { - fc::raw::pack(ds, fc::unsigned_int(0)); - fc::raw::pack(ds, as_type(obj.obj.id._id)); - fc::raw::pack(ds, as_type(obj.obj.code.value)); - fc::raw::pack(ds, as_type(obj.obj.scope.value)); - fc::raw::pack(ds, as_type(obj.obj.table.value)); - fc::raw::pack(ds, as_type(obj.obj.payer.value)); - fc::raw::pack(ds, as_type(obj.obj.count)); - return ds; -} - -template -static datastream& operator<<(datastream& ds, - const history_serial_wrapper& obj) { - fc::raw::pack(ds, fc::unsigned_int(0)); - fc::raw::pack(ds, as_type(obj.obj.id._id)); - fc::raw::pack(ds, as_type(obj.obj.t_id._id)); - fc::raw::pack(ds, as_type(obj.obj.primary_key)); - fc::raw::pack(ds, as_type(obj.obj.payer.value)); - fc::raw::pack(ds, as_type(obj.obj.value)); - return ds; -} - -template -static void serialize_secondary_index_data(datastream& ds, const T& obj) { - fc::raw::pack(ds, obj); -} - -template -static void serialize_secondary_index_data(datastream& ds, const float64_t& obj) { - uint64_t i; - memcpy(&i, &obj, sizeof(i)); - fc::raw::pack(ds, i); -} - -template -static void serialize_secondary_index_data(datastream& ds, const float128_t& obj) { - __uint128_t i; - memcpy(&i, &obj, sizeof(i)); - fc::raw::pack(ds, i); -} - -template -static void serialize_secondary_index_data(datastream& ds, const eosio::chain::key256_t& obj) { - fc::raw::pack(ds, obj[0]); - fc::raw::pack(ds, obj[1]); -} - -template -static datastream& serialize_secondary_index(datastream& ds, const T& obj) { - fc::raw::pack(ds, fc::unsigned_int(0)); - fc::raw::pack(ds, as_type(obj.id._id)); - fc::raw::pack(ds, as_type(obj.t_id._id)); - fc::raw::pack(ds, as_type(obj.primary_key)); - fc::raw::pack(ds, as_type(obj.payer.value)); - serialize_secondary_index_data(ds, obj.secondary_key); - return ds; -} - -template -static datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { - return serialize_secondary_index(ds, obj.obj); -} - -template -static datastream& operator<<(datastream& ds, - const history_serial_wrapper& obj) { - return serialize_secondary_index(ds, obj.obj); -} - -template -static datastream& operator<<(datastream& ds, - const history_serial_wrapper& obj) { - return serialize_secondary_index(ds, obj.obj); -} - -template -static datastream& operator<<(datastream& ds, - const history_serial_wrapper& obj) { - return serialize_secondary_index(ds, obj.obj); -} - -template -static datastream& operator<<(datastream& ds, - const history_serial_wrapper& obj) { - return serialize_secondary_index(ds, obj.obj); -} - -template -static datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { - fc::raw::pack(ds, fc::unsigned_int(0)); - fc::raw::pack(ds, as_type(obj.obj.producer_name.value)); - fc::raw::pack(ds, as_type(obj.obj.block_signing_key)); - return ds; -} - -template -static datastream& operator<<(datastream& ds, - const history_serial_wrapper& obj) { - fc::raw::pack(ds, fc::unsigned_int(0)); - fc::raw::pack(ds, as_type(obj.obj.version)); - serialize_shared_vector(ds, obj.obj.producers); - return ds; -} - -template -static datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { - fc::raw::pack(ds, fc::unsigned_int(0)); - fc::raw::pack(ds, as_type(obj.obj.max_block_net_usage)); - fc::raw::pack(ds, as_type(obj.obj.target_block_net_usage_pct)); - fc::raw::pack(ds, as_type(obj.obj.max_transaction_net_usage)); - fc::raw::pack(ds, as_type(obj.obj.base_per_transaction_net_usage)); - fc::raw::pack(ds, as_type(obj.obj.net_usage_leeway)); - fc::raw::pack(ds, as_type(obj.obj.context_free_discount_net_usage_num)); - fc::raw::pack(ds, as_type(obj.obj.context_free_discount_net_usage_den)); - fc::raw::pack(ds, as_type(obj.obj.max_block_cpu_usage)); - fc::raw::pack(ds, as_type(obj.obj.target_block_cpu_usage_pct)); - fc::raw::pack(ds, as_type(obj.obj.max_transaction_cpu_usage)); - fc::raw::pack(ds, as_type(obj.obj.min_transaction_cpu_usage)); - fc::raw::pack(ds, as_type(obj.obj.max_transaction_lifetime)); - fc::raw::pack(ds, as_type(obj.obj.deferred_trx_expiration_window)); - fc::raw::pack(ds, as_type(obj.obj.max_transaction_delay)); - fc::raw::pack(ds, as_type(obj.obj.max_inline_action_size)); - fc::raw::pack(ds, as_type(obj.obj.max_inline_action_depth)); - fc::raw::pack(ds, as_type(obj.obj.max_authority_depth)); - return ds; -} - -template -static datastream& operator<<(datastream& ds, - const history_serial_wrapper& obj) { - fc::raw::pack(ds, fc::unsigned_int(0)); - fc::raw::pack(ds, as_type(obj.obj.id._id)); - - fc::raw::pack(ds, as_type>(obj.obj.proposed_schedule_block_num)); - fc::raw::pack(ds, make_history_serial_wrapper( - as_type(obj.obj.proposed_schedule))); - fc::raw::pack(ds, make_history_serial_wrapper(as_type(obj.obj.configuration))); - - return ds; -} - -template -static datastream& operator<<(datastream& ds, - const history_serial_wrapper& obj) { - fc::raw::pack(ds, fc::unsigned_int(0)); - fc::raw::pack(ds, as_type(obj.obj.id._id)); - fc::raw::pack(ds, as_type(obj.obj.global_action_sequence)); - return ds; -} - -template -static datastream& operator<<(datastream& ds, - const history_serial_wrapper& obj) { - fc::raw::pack(ds, fc::unsigned_int(0)); - fc::raw::pack(ds, as_type(obj.obj.id._id)); - fc::raw::pack(ds, as_type(obj.obj.block_id)); - return ds; -} - -template -static datastream& operator<<(datastream& ds, - const history_serial_wrapper& obj) { - fc::raw::pack(ds, fc::unsigned_int(0)); - fc::raw::pack(ds, as_type(obj.obj.id._id)); - fc::raw::pack(ds, as_type(obj.obj.expiration)); - fc::raw::pack(ds, as_type(obj.obj.trx_id)); - return ds; -} - -template -static datastream& operator<<(datastream& ds, - const history_serial_wrapper& obj) { - fc::raw::pack(ds, fc::unsigned_int(0)); - fc::raw::pack(ds, as_type(obj.obj.id._id)); - fc::raw::pack(ds, as_type(obj.obj.trx_id)); - fc::raw::pack(ds, as_type(obj.obj.sender.value)); - fc::raw::pack(ds, as_type<__uint128_t>(obj.obj.sender_id)); - fc::raw::pack(ds, as_type(obj.obj.payer.value)); - fc::raw::pack(ds, as_type(obj.obj.delay_until)); - fc::raw::pack(ds, as_type(obj.obj.expiration)); - fc::raw::pack(ds, as_type(obj.obj.published)); - fc::raw::pack(ds, as_type(obj.obj.packed_trx)); - return ds; -} - -template -static datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { - fc::raw::pack(ds, fc::unsigned_int(0)); - fc::raw::pack(ds, as_type(obj.obj.key)); - fc::raw::pack(ds, as_type(obj.obj.weight)); - return ds; -} - -template -static datastream& operator<<(datastream& ds, - const history_serial_wrapper& obj) { - fc::raw::pack(ds, fc::unsigned_int(0)); - fc::raw::pack(ds, as_type(obj.obj.actor.value)); - fc::raw::pack(ds, as_type(obj.obj.permission.value)); - return ds; -} - -template -static datastream& operator<<(datastream& ds, - const history_serial_wrapper& obj) { - fc::raw::pack(ds, fc::unsigned_int(0)); - fc::raw::pack(ds, make_history_serial_wrapper(as_type(obj.obj.permission))); - fc::raw::pack(ds, as_type(obj.obj.weight)); - return ds; -} - -template -static datastream& operator<<(datastream& ds, const history_serial_wrapper& obj) { - fc::raw::pack(ds, fc::unsigned_int(0)); - fc::raw::pack(ds, as_type(obj.obj.wait_sec)); - fc::raw::pack(ds, as_type(obj.obj.weight)); - return ds; -} - -template -static datastream& operator<<(datastream& ds, - const history_serial_wrapper& obj) { - fc::raw::pack(ds, fc::unsigned_int(0)); - fc::raw::pack(ds, as_type(obj.obj.threshold)); - serialize_shared_vector(ds, obj.obj.keys); - serialize_shared_vector(ds, obj.obj.accounts); - serialize_shared_vector(ds, obj.obj.waits); - return ds; -} - -template -static datastream& operator<<(datastream& ds, - const history_serial_wrapper& obj) { - fc::raw::pack(ds, fc::unsigned_int(0)); - fc::raw::pack(ds, as_type(obj.obj.id._id)); - fc::raw::pack(ds, as_type(obj.obj.usage_id._id)); - fc::raw::pack(ds, as_type(obj.obj.parent._id)); - fc::raw::pack(ds, as_type(obj.obj.owner.value)); - fc::raw::pack(ds, as_type(obj.obj.name.value)); - fc::raw::pack(ds, as_type(obj.obj.last_updated)); - fc::raw::pack(ds, make_history_serial_wrapper(as_type(obj.obj.auth))); - return ds; -} - -template -static datastream& operator<<(datastream& ds, - const history_serial_wrapper& obj) { - fc::raw::pack(ds, fc::unsigned_int(0)); - fc::raw::pack(ds, as_type(obj.obj.id._id)); - fc::raw::pack(ds, as_type(obj.obj.last_used)); - return ds; -} - -template -static datastream& operator<<(datastream& ds, - const history_serial_wrapper& obj) { - fc::raw::pack(ds, fc::unsigned_int(0)); - fc::raw::pack(ds, as_type(obj.obj.id._id)); - fc::raw::pack(ds, as_type(obj.obj.account.value)); - fc::raw::pack(ds, as_type(obj.obj.code.value)); - fc::raw::pack(ds, as_type(obj.obj.message_type.value)); - fc::raw::pack(ds, as_type(obj.obj.required_permission.value)); - return ds; -} - -template -static datastream& -operator<<(datastream& ds, - const history_serial_wrapper& obj) { - fc::raw::pack(ds, fc::unsigned_int(0)); - fc::raw::pack(ds, as_type(obj.obj.id._id)); - fc::raw::pack(ds, as_type(obj.obj.owner.value)); - fc::raw::pack(ds, as_type(obj.obj.pending)); - fc::raw::pack(ds, as_type(obj.obj.net_weight)); - fc::raw::pack(ds, as_type(obj.obj.cpu_weight)); - fc::raw::pack(ds, as_type(obj.obj.ram_bytes)); - return ds; -} - -template -static datastream& operator<<(datastream& ds, - const history_serial_wrapper& obj) { - fc::raw::pack(ds, fc::unsigned_int(0)); - fc::raw::pack(ds, as_type(obj.obj.last_ordinal)); - fc::raw::pack(ds, as_type(obj.obj.value_ex)); - fc::raw::pack(ds, as_type(obj.obj.consumed)); - return ds; -} - -template -static datastream& -operator<<(datastream& ds, - const history_serial_wrapper& obj) { - fc::raw::pack(ds, fc::unsigned_int(0)); - fc::raw::pack(ds, as_type(obj.obj.id._id)); - fc::raw::pack(ds, as_type(obj.obj.owner.value)); - fc::raw::pack( - ds, make_history_serial_wrapper(as_type(obj.obj.net_usage))); - fc::raw::pack( - ds, make_history_serial_wrapper(as_type(obj.obj.cpu_usage))); - fc::raw::pack(ds, as_type(obj.obj.ram_usage)); - return ds; -} - -template -static datastream& -operator<<(datastream& ds, - const history_serial_wrapper& obj) { - fc::raw::pack(ds, fc::unsigned_int(0)); - fc::raw::pack(ds, as_type(obj.obj.id._id)); - fc::raw::pack(ds, make_history_serial_wrapper( - as_type(obj.obj.average_block_net_usage))); - fc::raw::pack(ds, make_history_serial_wrapper( - as_type(obj.obj.average_block_cpu_usage))); - fc::raw::pack(ds, as_type(obj.obj.pending_net_usage)); - fc::raw::pack(ds, as_type(obj.obj.pending_cpu_usage)); - fc::raw::pack(ds, as_type(obj.obj.total_net_weight)); - fc::raw::pack(ds, as_type(obj.obj.total_cpu_weight)); - fc::raw::pack(ds, as_type(obj.obj.total_ram_bytes)); - fc::raw::pack(ds, as_type(obj.obj.virtual_net_limit)); - fc::raw::pack(ds, as_type(obj.obj.virtual_cpu_limit)); - return ds; -} - -template -static datastream& operator<<(datastream& ds, - const history_serial_wrapper& obj) { - fc::raw::pack(ds, fc::unsigned_int(0)); - fc::raw::pack(ds, as_type(obj.obj.numerator)); - fc::raw::pack(ds, as_type(obj.obj.denominator)); - return ds; -} - -template -static datastream& -operator<<(datastream& ds, - const history_serial_wrapper& obj) { - fc::raw::pack(ds, fc::unsigned_int(0)); - fc::raw::pack(ds, as_type(obj.obj.target)); - fc::raw::pack(ds, as_type(obj.obj.max)); - fc::raw::pack(ds, as_type(obj.obj.periods)); - fc::raw::pack(ds, as_type(obj.obj.max_multiplier)); - fc::raw::pack(ds, make_history_serial_wrapper(as_type(obj.obj.contract_rate))); - fc::raw::pack(ds, make_history_serial_wrapper(as_type(obj.obj.expand_rate))); - return ds; -} - -template -static datastream& -operator<<(datastream& ds, - const history_serial_wrapper& obj) { - fc::raw::pack(ds, fc::unsigned_int(0)); - fc::raw::pack(ds, as_type(obj.obj.id._id)); - fc::raw::pack(ds, make_history_serial_wrapper(as_type( - obj.obj.cpu_limit_parameters))); - fc::raw::pack(ds, make_history_serial_wrapper(as_type( - obj.obj.net_limit_parameters))); - fc::raw::pack(ds, as_type(obj.obj.account_cpu_usage_average_window)); - fc::raw::pack(ds, as_type(obj.obj.account_net_usage_average_window)); - return ds; -}; - -} // namespace fc - namespace eosio { using namespace chain; using boost::signals2::scoped_connection; @@ -520,133 +95,6 @@ auto catch_and_log(F f) { } } -/* - * *.log: - * +---------+----------------+-----------+------------------+-----+---------+----------------+ - * | Entry i | Pos of Entry i | Entry i+1 | Pos of Entry i+1 | ... | Entry z | Pos of Entry z | - * +---------+----------------+-----------+------------------+-----+---------+----------------+ - * - * *.index: - * +----------------+------------------+-----+----------------+ - * | Pos of Entry i | Pos of Entry i+1 | ... | Pos of Entry z | - * +----------------+------------------+-----+----------------+ - * - * each entry: - * uint32_t block_num - * uint64_t size of payload - * uint8_t version - * payload - * - * irreversible_state payload: - * uint32_t size of deltas - * char[] deltas - */ - -struct history_log_header { - uint32_t block_num = 0; - uint64_t payload_size = 0; - uint16_t version = 0; -}; - -struct history_log { - const char* const name = ""; - std::fstream log; - std::fstream index; - uint32_t begin_block = 0; - uint32_t end_block = 0; - - void open_log(const std::string& filename) { - log.open(filename, std::ios_base::binary | std::ios_base::in | std::ios_base::out | std::ios_base::app); - uint64_t size = log.tellg(); - if (size >= sizeof(history_log_header)) { - history_log_header header; - log.seekg(0); - log.read((char*)&header, sizeof(header)); - EOS_ASSERT(header.version == 0 && sizeof(header) + header.payload_size + sizeof(uint64_t) <= size, - plugin_exception, "corrupt ${name}.log (1)", ("name", name)); - begin_block = header.block_num; - - uint64_t end_pos; - log.seekg(size - sizeof(end_pos)); - log.read((char*)&end_pos, sizeof(end_pos)); - EOS_ASSERT(end_pos <= size && end_pos + sizeof(header) <= size, plugin_exception, "corrupt ${name}.log (2)", - ("name", name)); - log.seekg(end_pos); - log.read((char*)&header, sizeof(header)); - EOS_ASSERT(end_pos + sizeof(header) + header.payload_size + sizeof(uint64_t) == size, plugin_exception, - "corrupt ${name}.log (3)", ("name", name)); - end_block = header.block_num + 1; - - EOS_ASSERT(begin_block < end_block, plugin_exception, "corrupt ${name}.log (4)", ("name", name)); - ilog("${name}.log has blocks ${b}-${e}", ("name", name)("b", begin_block)("e", end_block - 1)); - } else { - EOS_ASSERT(!size, plugin_exception, "corrupt ${name}.log (5)", ("name", name)); - ilog("${name}.log is empty", ("name", name)); - } - } - - void open_index(const std::string& filename) { - index.open(filename, std::ios_base::binary | std::ios_base::in | std::ios_base::out | std::ios_base::app); - if (index.tellg() == (end_block - begin_block) * sizeof(uint64_t)) - return; - ilog("Regenerate ${name}.index", ("name", name)); - index.close(); - index.open(filename, std::ios_base::binary | std::ios_base::in | std::ios_base::out | std::ios_base::trunc); - - log.seekg(0, std::ios_base::end); - uint64_t size = log.tellg(); - uint64_t pos = 0; - while (pos < size) { - index.write((char*)&pos, sizeof(pos)); - history_log_header header; - EOS_ASSERT(pos + sizeof(header) <= size, plugin_exception, "corrupt ${name}.log (6)", ("name", name)); - log.seekg(pos); - log.read((char*)&header, sizeof(header)); - uint64_t suffix_pos = pos + sizeof(header) + header.payload_size; - uint64_t suffix; - EOS_ASSERT(suffix_pos + sizeof(suffix) <= size, plugin_exception, "corrupt ${name}.log (7)", ("name", name)); - log.seekg(suffix_pos); - log.read((char*)&suffix, sizeof(suffix)); - // ilog("block ${b} at ${pos}-${end} suffix=${suffix} file_size=${fs}", - // ("b", header.block_num)("pos", pos)("end", suffix_pos + sizeof(suffix))("suffix", suffix)("fs", size)); - EOS_ASSERT(suffix == pos, plugin_exception, "corrupt ${name}.log (8)", ("name", name)); - pos = suffix_pos + sizeof(suffix); - } - } - - template - void write_entry(history_log_header header, F write_payload) { - EOS_ASSERT(begin_block == end_block || header.block_num == end_block, plugin_exception, - "writing unexpected block_num to ${name}.log", ("name", name)); - log.seekg(0, std::ios_base::end); - uint64_t pos = log.tellg(); - log.write((char*)&header, sizeof(header)); - write_payload(log); - uint64_t end = log.tellg(); - EOS_ASSERT(end == pos + sizeof(header) + header.payload_size, plugin_exception, - "wrote payload with incorrect size to ${name}.log", ("name", name)); - log.write((char*)&pos, sizeof(pos)); - - index.seekg(0, std::ios_base::end); - index.write((char*)&pos, sizeof(pos)); - if (begin_block == end_block) - begin_block = header.block_num; - end_block = header.block_num + 1; - } - - // returns stream positioned at payload - std::fstream& get_entry(uint32_t block_num, history_log_header& header) { - EOS_ASSERT(block_num >= begin_block && block_num < end_block, plugin_exception, - "read non-existing block in ${name}.log", ("name", name)); - uint64_t pos; - index.seekg((block_num - begin_block) * sizeof(pos)); - index.read((char*)&pos, sizeof(pos)); - log.seekg(pos); - log.read((char*)&header, sizeof(header)); - return log; - } -}; // history_log - struct state_history_plugin_impl : std::enable_shared_from_this { chain_plugin* chain_plug = nullptr; std::unique_ptr db; @@ -1023,7 +471,7 @@ void state_history_plugin::plugin_initialize(const variables_map& options) { // dlog("num: ${s}", ("s", num)); } FC_LOG_AND_RETHROW() -} // namespace eosio +} // state_history_plugin::plugin_initialize void state_history_plugin::plugin_startup() { my->listen(); } -- GitLab