From d2e2a3eee1763769d4479ff38a53b87f7e4e04e0 Mon Sep 17 00:00:00 2001 From: Steven Watanabe Date: Mon, 16 Mar 2020 09:52:32 -0400 Subject: [PATCH 01/15] Make sure that the buffer passed to fpconv_dtoa is large enough. --- include/eosio/to_json.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/eosio/to_json.hpp b/include/eosio/to_json.hpp index 4b1ca6f..45b0a75 100644 --- a/include/eosio/to_json.hpp +++ b/include/eosio/to_json.hpp @@ -135,8 +135,8 @@ result fp_to_json(double value, S& stream) { } else if (std::isnan(value)) { return stream.write("\"NaN\"", 5); } - small_buffer::digits10 + 2> b; - int n = fpconv_dtoa(value, b.pos); + small_buffer<24> b; // fpconv_dtoa generates at most 24 characters + int n = fpconv_dtoa(value, b.pos); if (n <= 0) return stream_error::float_error; b.pos += n; From 23fe5b0ba5d5e46594136f00cd2c627f9951ea6f Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Mon, 16 Mar 2020 17:19:08 -0400 Subject: [PATCH 02/15] ship_protocol --- include/eosio/ship_protocol.hpp | 761 ++++++++++++++++++++++++++++++++ 1 file changed, 761 insertions(+) create mode 100644 include/eosio/ship_protocol.hpp diff --git a/include/eosio/ship_protocol.hpp b/include/eosio/ship_protocol.hpp new file mode 100644 index 0000000..e4dbee4 --- /dev/null +++ b/include/eosio/ship_protocol.hpp @@ -0,0 +1,761 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// todo: move +namespace eosio { +template +result to_json(const input_stream& data, S& stream) { + return to_json_hex(data.pos, data.end - data.pos, stream); +} +} // namespace eosio + +namespace eosio { namespace ship_protocol { + + typedef __uint128_t uint128_t; + +#ifdef __eosio_cdt__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Winvalid-noreturn" + [[noreturn]] inline void report_error(const std::string& s) { eosio::check(false, s); } +# pragma clang diagnostic pop +#else + [[noreturn]] inline void report_error(const std::string& s) { throw std::runtime_error(s); } +#endif + + struct extension { + uint16_t type = {}; + eosio::input_stream data = {}; + }; + + EOSIO_REFLECT(extension, type, data) + + enum class transaction_status : uint8_t { + executed = 0, // succeed, no error handler executed + soft_fail = 1, // objectively failed (not executed), error handler executed + hard_fail = 2, // objectively failed and error handler objectively failed thus no state change + delayed = 3, // transaction delayed/deferred/scheduled for future execution + expired = 4, // transaction expired and storage space refunded to user + }; + + // todo: switch to eosio::result. switch to new serializer string support. + inline std::string to_string(transaction_status status) { + switch (status) { + case transaction_status::executed: return "executed"; + case transaction_status::soft_fail: return "soft_fail"; + case transaction_status::hard_fail: return "hard_fail"; + case transaction_status::delayed: return "delayed"; + case transaction_status::expired: return "expired"; + } + report_error("unknown status: " + std::to_string((uint8_t)status)); + } + + // todo: switch to eosio::result. switch to new serializer string support. + inline transaction_status get_transaction_status(const std::string& s) { + if (s == "executed") + return transaction_status::executed; + if (s == "soft_fail") + return transaction_status::soft_fail; + if (s == "hard_fail") + return transaction_status::hard_fail; + if (s == "delayed") + return transaction_status::delayed; + if (s == "expired") + return transaction_status::expired; + report_error("unknown status: " + s); + } + + template + eosio::result from_bin(transaction_status& obj, S& stream) { + return stream.read_raw(obj); + } + + template + eosio::result to_json(const transaction_status& status, S& stream) { + // todo: switch to new serializer string support. + return eosio::to_json(to_string(status), stream); + } + + struct get_status_request_v0 {}; + + EOSIO_REFLECT(get_status_request_v0) + + struct block_position { + uint32_t block_num = {}; + eosio::checksum256 block_id = {}; + }; + + EOSIO_REFLECT(block_position, block_num, block_id) + + struct get_status_result_v0 { + block_position head = {}; + block_position last_irreversible = {}; + uint32_t trace_begin_block = {}; + uint32_t trace_end_block = {}; + uint32_t chain_state_begin_block = {}; + uint32_t chain_state_end_block = {}; + eosio::checksum256 chain_id = {}; // todo: switch to binary extension + }; + + EOSIO_REFLECT(get_status_result_v0, head, last_irreversible, trace_begin_block, trace_end_block, + chain_state_begin_block, chain_state_end_block, chain_id) + + struct get_blocks_request_v0 { + uint32_t start_block_num = {}; + uint32_t end_block_num = {}; + uint32_t max_messages_in_flight = {}; + std::vector have_positions = {}; + bool irreversible_only = {}; + bool fetch_block = {}; + bool fetch_traces = {}; + bool fetch_deltas = {}; + }; + + EOSIO_REFLECT(get_blocks_request_v0, start_block_num, end_block_num, max_messages_in_flight, have_positions, + irreversible_only, fetch_block, fetch_traces, fetch_deltas) + + struct get_blocks_ack_request_v0 { + uint32_t num_messages = {}; + }; + + EOSIO_REFLECT(get_blocks_ack_request_v0, num_messages) + + using request = std::variant; + + struct get_blocks_result_v0 { + block_position head = {}; + block_position last_irreversible = {}; + std::optional this_block = {}; + std::optional prev_block = {}; + std::optional block = {}; + std::optional traces = {}; + std::optional deltas = {}; + }; + + EOSIO_REFLECT(get_blocks_result_v0, head, last_irreversible, this_block, prev_block, block, traces, deltas) + + using result = std::variant; + + struct row { + bool present = {}; + eosio::input_stream data = {}; + }; + + EOSIO_REFLECT(row, present, data) + + struct table_delta_v0 { + std::string name = {}; + std::vector rows = {}; + }; + + EOSIO_REFLECT(table_delta_v0, name, rows) + + using table_delta = std::variant; + + struct permission_level { + eosio::name actor = {}; + eosio::name permission = {}; + }; + + EOSIO_REFLECT(permission_level, actor, permission) + + struct action { + eosio::name account = {}; + eosio::name name = {}; + std::vector authorization = {}; + eosio::input_stream data = {}; + }; + + EOSIO_REFLECT(action, account, name, authorization, data) + + struct account_auth_sequence { + eosio::name account = {}; + uint64_t sequence = {}; + }; + + EOSIO_REFLECT(account_auth_sequence, account, sequence) + + struct action_receipt_v0 { + eosio::name receiver = {}; + eosio::checksum256 act_digest = {}; + uint64_t global_sequence = {}; + uint64_t recv_sequence = {}; + std::vector auth_sequence = {}; + eosio::varuint32 code_sequence = {}; + eosio::varuint32 abi_sequence = {}; + }; + + EOSIO_REFLECT(action_receipt_v0, receiver, act_digest, global_sequence, recv_sequence, auth_sequence, code_sequence, + abi_sequence) + + using action_receipt = std::variant; + + struct account_delta { + eosio::name account = {}; + int64_t delta = {}; + }; + + EOSIO_REFLECT(account_delta, account, delta) + + struct action_trace_v0 { + eosio::varuint32 action_ordinal = {}; + eosio::varuint32 creator_action_ordinal = {}; + std::optional receipt = {}; + eosio::name receiver = {}; + action act = {}; + bool context_free = {}; + int64_t elapsed = {}; + std::string console = {}; + std::vector account_ram_deltas = {}; + std::optional except = {}; + std::optional error_code = {}; + }; + + EOSIO_REFLECT(action_trace_v0, action_ordinal, creator_action_ordinal, receipt, receiver, act, context_free, elapsed, + console, account_ram_deltas, except, error_code) + + struct action_trace_v1 { + eosio::varuint32 action_ordinal = {}; + eosio::varuint32 creator_action_ordinal = {}; + std::optional receipt = {}; + eosio::name receiver = {}; + action act = {}; + bool context_free = {}; + int64_t elapsed = {}; + std::string console = {}; + std::vector account_ram_deltas = {}; + std::vector account_disk_deltas = {}; + std::optional except = {}; + std::optional error_code = {}; + std::optional return_value = {}; + }; + + EOSIO_REFLECT(action_trace_v1, action_ordinal, creator_action_ordinal, receipt, receiver, act, context_free, elapsed, + console, account_ram_deltas, account_disk_deltas, except, error_code, return_value) + + using action_trace = std::variant; + + struct partial_transaction_v0 { + eosio::time_point_sec expiration = {}; + uint16_t ref_block_num = {}; + uint32_t ref_block_prefix = {}; + eosio::varuint32 max_net_usage_words = {}; + uint8_t max_cpu_usage_ms = {}; + eosio::varuint32 delay_sec = {}; + std::vector transaction_extensions = {}; + std::vector signatures = {}; + std::vector context_free_data = {}; + }; + + EOSIO_REFLECT(partial_transaction_v0, expiration, ref_block_num, ref_block_prefix, max_net_usage_words, + max_cpu_usage_ms, delay_sec, transaction_extensions, signatures, context_free_data) + + using partial_transaction = std::variant; + + struct recurse_transaction_trace; + + struct transaction_trace_v0 { + eosio::checksum256 id = {}; + transaction_status status = {}; + uint32_t cpu_usage_us = {}; + eosio::varuint32 net_usage_words = {}; + int64_t elapsed = {}; + uint64_t net_usage = {}; + bool scheduled = {}; + std::vector action_traces = {}; + std::optional account_ram_delta = {}; + std::optional except = {}; + std::optional error_code = {}; + std::vector failed_dtrx_trace = {}; + std::optional partial = {}; + }; + + EOSIO_REFLECT(transaction_trace_v0, id, status, cpu_usage_us, net_usage_words, elapsed, net_usage, scheduled, + action_traces, account_ram_delta, except, error_code, failed_dtrx_trace, partial) + + using transaction_trace = std::variant; + + struct recurse_transaction_trace { + transaction_trace recurse = {}; + }; + + template + eosio::result from_bin(recurse_transaction_trace& obj, S& stream) { + return from_bin(obj.recurse, stream); + } + + template + eosio::result to_json(const recurse_transaction_trace& obj, S& stream) { + return to_json(obj.recurse, stream); + } + + struct producer_key { + eosio::name producer_name = {}; + eosio::public_key block_signing_key = {}; + }; + + EOSIO_REFLECT(producer_key, producer_name, block_signing_key) + + struct producer_schedule { + uint32_t version = {}; + std::vector producers = {}; + }; + + EOSIO_REFLECT(producer_schedule, version, producers) + + struct transaction_receipt_header { + transaction_status status = {}; + uint32_t cpu_usage_us = {}; + eosio::varuint32 net_usage_words = {}; + }; + + EOSIO_REFLECT(transaction_receipt_header, status, cpu_usage_us, net_usage_words) + + struct packed_transaction { + std::vector signatures = {}; + uint8_t compression = {}; + eosio::input_stream packed_context_free_data = {}; + eosio::input_stream packed_trx = {}; + }; + + EOSIO_REFLECT(packed_transaction, signatures, compression, packed_context_free_data, packed_trx) + + using transaction_variant = std::variant; + + struct transaction_receipt : transaction_receipt_header { + transaction_variant trx = {}; + }; + + EOSIO_REFLECT(transaction_receipt, base transaction_receipt_header, trx) + + struct block_header { + eosio::block_timestamp timestamp{}; + eosio::name producer = {}; + uint16_t confirmed = {}; + eosio::checksum256 previous = {}; + eosio::checksum256 transaction_mroot = {}; + eosio::checksum256 action_mroot = {}; + uint32_t schedule_version = {}; + std::optional new_producers = {}; + std::vector header_extensions = {}; + }; + + EOSIO_REFLECT(block_header, timestamp, producer, confirmed, previous, transaction_mroot, action_mroot, + schedule_version, new_producers, header_extensions) + + struct signed_block_header : block_header { + eosio::signature producer_signature = {}; + }; + + EOSIO_REFLECT(signed_block_header, base block_header, producer_signature) + + struct signed_block : signed_block_header { + std::vector transactions = {}; + std::vector block_extensions = {}; + }; + + EOSIO_REFLECT(signed_block, base signed_block_header, transactions, block_extensions) + + struct transaction_header { + eosio::time_point_sec expiration = {}; + uint16_t ref_block_num = {}; + uint32_t ref_block_prefix = {}; + eosio::varuint32 max_net_usage_words = {}; + uint8_t max_cpu_usage_ms = {}; + eosio::varuint32 delay_sec = {}; + }; + + EOSIO_REFLECT(transaction_header, expiration, ref_block_num, ref_block_prefix, max_net_usage_words, max_cpu_usage_ms, + delay_sec) + + struct transaction : transaction_header { + std::vector context_free_actions = {}; + std::vector actions = {}; + std::vector transaction_extensions = {}; + }; + + EOSIO_REFLECT(transaction, base transaction_header, context_free_actions, actions, transaction_extensions) + + struct code_id { + uint8_t vm_type = {}; + uint8_t vm_version = {}; + eosio::checksum256 code_hash = {}; + }; + + EOSIO_REFLECT(code_id, vm_type, vm_version, code_hash) + + struct account_v0 { + eosio::name name = {}; + eosio::block_timestamp creation_date = {}; + eosio::input_stream abi = {}; + }; + + EOSIO_REFLECT(account_v0, name, creation_date, abi) + + using account = std::variant; + + struct account_metadata_v0 { + eosio::name name = {}; + bool privileged = {}; + eosio::time_point last_code_update = {}; + std::optional code = {}; + }; + + EOSIO_REFLECT(account_metadata_v0, name, privileged, last_code_update, code) + + using account_metadata = std::variant; + + struct code_v0 { + uint8_t vm_type = {}; + uint8_t vm_version = {}; + eosio::checksum256 code_hash = {}; + eosio::input_stream code = {}; + }; + + EOSIO_REFLECT(code_v0, vm_type, vm_version, code_hash, code) + + using code = std::variant; + + struct contract_table_v0 { + eosio::name code = {}; + eosio::name scope = {}; + eosio::name table = {}; + eosio::name payer = {}; + }; + + EOSIO_REFLECT(contract_table_v0, code, scope, table, payer) + + using contract_table = std::variant; + + struct contract_row_v0 { + eosio::name code = {}; + eosio::name scope = {}; + eosio::name table = {}; + uint64_t primary_key = {}; + eosio::name payer = {}; + eosio::input_stream value = {}; + }; + + EOSIO_REFLECT(contract_row_v0, code, scope, table, primary_key, payer, value) + + using contract_row = std::variant; + + struct contract_index64_v0 { + eosio::name code = {}; + eosio::name scope = {}; + eosio::name table = {}; + uint64_t primary_key = {}; + eosio::name payer = {}; + uint64_t secondary_key = {}; + }; + + EOSIO_REFLECT(contract_index64_v0, code, scope, table, primary_key, payer, secondary_key) + + using contract_index64 = std::variant; + + struct contract_index128_v0 { + eosio::name code = {}; + eosio::name scope = {}; + eosio::name table = {}; + uint64_t primary_key = {}; + eosio::name payer = {}; + uint128_t secondary_key = {}; + }; + + EOSIO_REFLECT(contract_index128_v0, code, scope, table, primary_key, payer, secondary_key) + + using contract_index128 = std::variant; + + struct contract_index256_v0 { + eosio::name code = {}; + eosio::name scope = {}; + eosio::name table = {}; + uint64_t primary_key = {}; + eosio::name payer = {}; + eosio::checksum256 secondary_key = {}; + }; + + EOSIO_REFLECT(contract_index256_v0, code, scope, table, primary_key, payer, secondary_key) + + using contract_index256 = std::variant; + + struct contract_index_double_v0 { + eosio::name code = {}; + eosio::name scope = {}; + eosio::name table = {}; + uint64_t primary_key = {}; + eosio::name payer = {}; + double secondary_key = {}; + }; + + EOSIO_REFLECT(contract_index_double_v0, code, scope, table, primary_key, payer, secondary_key) + + using contract_index_double = std::variant; + + struct contract_index_long_double_v0 { + eosio::name code = {}; + eosio::name scope = {}; + eosio::name table = {}; + uint64_t primary_key = {}; + eosio::name payer = {}; + eosio::float128 secondary_key = {}; + }; + + EOSIO_REFLECT(contract_index_long_double_v0, code, scope, table, primary_key, payer, secondary_key) + + using contract_index_long_double = std::variant; + + struct key_value_v0 { + eosio::name database = {}; + eosio::name contract = {}; + eosio::input_stream key = {}; + eosio::input_stream value = {}; + }; + + EOSIO_REFLECT(key_value_v0, database, contract, key, value) + + using key_value = std::variant; + + struct key_weight { + eosio::public_key key = {}; + uint16_t weight = {}; + }; + + EOSIO_REFLECT(key_weight, key, weight) + + struct block_signing_authority_v0 { + uint32_t threshold = {}; + std::vector keys = {}; + }; + + EOSIO_REFLECT(block_signing_authority_v0, threshold, keys) + + using block_signing_authority = std::variant; + + struct producer_authority { + eosio::name producer_name = {}; + block_signing_authority authority = {}; + }; + + EOSIO_REFLECT(producer_authority, producer_name, authority) + + struct producer_authority_schedule { + uint32_t version = {}; + std::vector producers = {}; + }; + + EOSIO_REFLECT(producer_authority_schedule, version, producers) + + struct chain_config_v0 { + uint64_t max_block_net_usage = {}; + uint32_t target_block_net_usage_pct = {}; + uint32_t max_transaction_net_usage = {}; + uint32_t base_per_transaction_net_usage = {}; + uint32_t net_usage_leeway = {}; + uint32_t context_free_discount_net_usage_num = {}; + uint32_t context_free_discount_net_usage_den = {}; + uint32_t max_block_cpu_usage = {}; + uint32_t target_block_cpu_usage_pct = {}; + uint32_t max_transaction_cpu_usage = {}; + uint32_t min_transaction_cpu_usage = {}; + uint32_t max_transaction_lifetime = {}; + uint32_t deferred_trx_expiration_window = {}; + uint32_t max_transaction_delay = {}; + uint32_t max_inline_action_size = {}; + uint16_t max_inline_action_depth = {}; + uint16_t max_authority_depth = {}; + }; + + EOSIO_REFLECT(chain_config_v0, max_block_net_usage, target_block_net_usage_pct, max_transaction_net_usage, + base_per_transaction_net_usage, net_usage_leeway, context_free_discount_net_usage_num, + context_free_discount_net_usage_den, max_block_cpu_usage, target_block_cpu_usage_pct, + max_transaction_cpu_usage, min_transaction_cpu_usage, max_transaction_lifetime, + deferred_trx_expiration_window, max_transaction_delay, max_inline_action_size, max_inline_action_depth, + max_authority_depth) + + using chain_config = std::variant; + + struct global_property_v0 { + std::optional proposed_schedule_block_num = {}; + producer_schedule proposed_schedule = {}; + chain_config configuration = {}; + }; + + EOSIO_REFLECT(global_property_v0, proposed_schedule_block_num, proposed_schedule, configuration) + + struct global_property_v1 { + std::optional proposed_schedule_block_num = {}; + producer_authority_schedule proposed_schedule = {}; + chain_config configuration = {}; + eosio::checksum256 chain_id = {}; + }; + + EOSIO_REFLECT(global_property_v1, proposed_schedule_block_num, proposed_schedule, configuration, chain_id) + + using global_property = std::variant; + + struct generated_transaction_v0 { + eosio::name sender = {}; + uint128_t sender_id = {}; + eosio::name payer = {}; + eosio::checksum256 trx_id = {}; + eosio::input_stream packed_trx = {}; + }; + + EOSIO_REFLECT(generated_transaction_v0, sender, sender_id, payer, trx_id, packed_trx) + + using generated_transaction = std::variant; + + struct activated_protocol_feature_v0 { + eosio::checksum256 feature_digest = {}; + uint32_t activation_block_num = {}; + }; + + EOSIO_REFLECT(activated_protocol_feature_v0, feature_digest, activation_block_num) + + using activated_protocol_feature = std::variant; + + struct protocol_state_v0 { + std::vector activated_protocol_features = {}; + }; + + EOSIO_REFLECT(protocol_state_v0, activated_protocol_features) + + using protocol_state = std::variant; + + struct permission_level_weight { + permission_level permission = {}; + uint16_t weight = {}; + }; + + EOSIO_REFLECT(permission_level_weight, permission, weight) + + struct wait_weight { + uint32_t wait_sec = {}; + uint16_t weight = {}; + }; + + EOSIO_REFLECT(wait_weight, wait_sec, weight) + + struct authority { + uint32_t threshold = {}; + std::vector keys = {}; + std::vector accounts = {}; + std::vector waits = {}; + }; + + EOSIO_REFLECT(authority, threshold, keys, accounts, waits) + + struct permission_v0 { + eosio::name owner = {}; + eosio::name name = {}; + eosio::name parent = {}; + eosio::time_point last_updated = {}; + authority auth = {}; + }; + + EOSIO_REFLECT(permission_v0, owner, name, parent, last_updated, auth) + + using permission = std::variant; + + struct permission_link_v0 { + eosio::name account = {}; + eosio::name code = {}; + eosio::name message_type = {}; + eosio::name required_permission = {}; + }; + + EOSIO_REFLECT(permission_link_v0, account, code, message_type, required_permission) + + using permission_link = std::variant; + + struct resource_limits_v0 { + eosio::name owner = {}; + int64_t net_weight = {}; + int64_t cpu_weight = {}; + int64_t ram_bytes = {}; + }; + + EOSIO_REFLECT(resource_limits_v0, owner, net_weight, cpu_weight, ram_bytes) + + using resource_limits = std::variant; + + struct usage_accumulator_v0 { + uint32_t last_ordinal = {}; + uint64_t value_ex = {}; + uint64_t consumed = {}; + }; + + EOSIO_REFLECT(usage_accumulator_v0, last_ordinal, value_ex, consumed) + + using usage_accumulator = std::variant; + + struct resource_usage_v0 { + eosio::name owner = {}; + usage_accumulator net_usage = {}; + usage_accumulator cpu_usage = {}; + uint64_t ram_usage = {}; + }; + + EOSIO_REFLECT(resource_usage_v0, owner, net_usage, cpu_usage, ram_usage) + + using resource_usage = std::variant; + + struct resource_limits_state_v0 { + usage_accumulator average_block_net_usage = {}; + usage_accumulator average_block_cpu_usage = {}; + uint64_t total_net_weight = {}; + uint64_t total_cpu_weight = {}; + uint64_t total_ram_bytes = {}; + uint64_t virtual_net_limit = {}; + uint64_t virtual_cpu_limit = {}; + }; + + EOSIO_REFLECT(resource_limits_state_v0, average_block_net_usage, average_block_cpu_usage, total_net_weight, + total_cpu_weight, total_ram_bytes, virtual_net_limit, virtual_cpu_limit) + + using resource_limits_state = std::variant; + + struct resource_limits_ratio_v0 { + uint64_t numerator = {}; + uint64_t denominator = {}; + }; + + EOSIO_REFLECT(resource_limits_ratio_v0, numerator, denominator) + + using resource_limits_ratio = std::variant; + + struct elastic_limit_parameters_v0 { + uint64_t target = {}; + uint64_t max = {}; + uint32_t periods = {}; + uint32_t max_multiplier = {}; + resource_limits_ratio contract_rate = {}; + resource_limits_ratio expand_rate = {}; + }; + + EOSIO_REFLECT(elastic_limit_parameters_v0, target, max, periods, max_multiplier, contract_rate, expand_rate) + + using elastic_limit_parameters = std::variant; + + struct resource_limits_config_v0 { + elastic_limit_parameters cpu_limit_parameters = {}; + elastic_limit_parameters net_limit_parameters = {}; + uint32_t account_cpu_usage_average_window = {}; + uint32_t account_net_usage_average_window = {}; + }; + + EOSIO_REFLECT(resource_limits_config_v0, cpu_limit_parameters, net_limit_parameters, + account_cpu_usage_average_window, account_net_usage_average_window) + + using resource_limits_config = std::variant; + +}} // namespace eosio::ship_protocol From b97cd7503bb77937874a4780ec0b3f1dd634b516 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Tue, 17 Mar 2020 14:19:08 -0400 Subject: [PATCH 03/15] Missing includes --- include/eosio/abi.hpp | 1 + include/eosio/from_json.hpp | 1 + 2 files changed, 2 insertions(+) diff --git a/include/eosio/abi.hpp b/include/eosio/abi.hpp index c8b8301..744b2a3 100644 --- a/include/eosio/abi.hpp +++ b/include/eosio/abi.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include diff --git a/include/eosio/from_json.hpp b/include/eosio/from_json.hpp index 842cb3f..83e7e20 100644 --- a/include/eosio/from_json.hpp +++ b/include/eosio/from_json.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include From 273ec0012008fa18d977ae6b8c3f20c1f163b670 Mon Sep 17 00:00:00 2001 From: Steven Watanabe Date: Tue, 17 Mar 2020 18:00:23 -0400 Subject: [PATCH 04/15] Allow non-static member functions to be reflected. --- CMakeLists.txt | 3 +++ include/eosio/fixed_bytes.hpp | 3 ++- include/eosio/for_each_field.hpp | 22 ++++++++++++++++++++-- include/eosio/reflection.hpp | 3 ++- src/reflect_test.cpp | 28 ++++++++++++++++++++++++++++ 5 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 src/reflect_test.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 90c0e89..d768914 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,6 +46,9 @@ target_include_directories(template_test PRIVATE include external/outcome/single add_executable(key_test src/key_test.cpp src/abieos.cpp src/abi.cpp src/crypto.cpp include/eosio/fpconv.c) target_include_directories(key_test PRIVATE include external/outcome/single-header external/rapidjson/include external/date/include) +add_executable(reflect_test src/reflect_test.cpp) +target_include_directories(reflect_test PRIVATE include) + add_executable(test-sanitize src/test.cpp src/abieos.cpp src/abi.cpp src/crypto.cpp include/eosio/fpconv.c) target_include_directories(test-sanitize PRIVATE include external/outcome/single-header external/rapidjson/include external/date/include) target_link_libraries(test-sanitize -fno-omit-frame-pointer -fsanitize=address,undefined) diff --git a/include/eosio/fixed_bytes.hpp b/include/eosio/fixed_bytes.hpp index 97c0c5a..8747e89 100644 --- a/include/eosio/fixed_bytes.hpp +++ b/include/eosio/fixed_bytes.hpp @@ -195,7 +195,8 @@ class fixed_bytes { // Everything else should be using one of the typedefs below. template void eosio_for_each_field(fixed_bytes*, F&& f) { - f("value", [](auto* p) -> decltype((p->value)) { return p->value; }); + f("value", + [](auto* p) -> decltype(&std::decay_t::value) { return &std::decay_t::value; }); } template diff --git a/include/eosio/for_each_field.hpp b/include/eosio/for_each_field.hpp index c44e506..f518a9e 100644 --- a/include/eosio/for_each_field.hpp +++ b/include/eosio/for_each_field.hpp @@ -20,12 +20,30 @@ namespace eosio { template constexpr auto for_each_field(T&& t, F&& f) -> std::enable_if_t>> { - eosio_for_each_field((std::decay_t*)nullptr, [&](const char*, auto member) { f(member(&t)); }); + eosio_for_each_field((std::decay_t*)nullptr, [&](const char*, auto member) { + if constexpr (std::is_member_object_pointer_v) { + f(t.*member(&t)); + } + }); } template constexpr void for_each_field(F&& f) { - eosio_for_each_field((T*)nullptr, f); + eosio_for_each_field((T*)nullptr, [&f](const char* name, auto member) { + if constexpr (std::is_member_object_pointer_v) { + f(name, [member](auto p) -> decltype((p->*member(p))) { return p->*member(p); }); + } + }); +} + +// Calls f(#fn_name, &T::fn_name) for every reflected member function of T. +template +constexpr void for_each_method(F&& f) { + eosio_for_each_field((T*)nullptr, [&f](const char* name, auto member) { + if constexpr (std::is_member_function_pointer_v) { + f(name, member((T*)nullptr)); + } + }); } } // namespace eosio diff --git a/include/eosio/reflection.hpp b/include/eosio/reflection.hpp index 6492bee..20678ba 100644 --- a/include/eosio/reflection.hpp +++ b/include/eosio/reflection.hpp @@ -26,7 +26,8 @@ namespace eosio { namespace reflection { template inline constexpr bool has_for_each_field_v = has_for_each_field::value; -#define EOSIO_REFLECT_MEMBER(STRUCT, FIELD) f(#FIELD, [](auto p) -> decltype((p->FIELD)) { return (p->FIELD); }); +#define EOSIO_REFLECT_MEMBER(STRUCT, FIELD) \ + f(#FIELD, [](auto p) -> decltype(&std::decay_t::FIELD) { return &std::decay_t::FIELD; }); #define EOSIO_REFLECT_STRIP_BASEbase #define EOSIO_REFLECT_BASE(STRUCT, BASE) \ diff --git a/src/reflect_test.cpp b/src/reflect_test.cpp new file mode 100644 index 0000000..d447fc0 --- /dev/null +++ b/src/reflect_test.cpp @@ -0,0 +1,28 @@ +#include +#include +#include + +int error_count; + +void report_error(const char* assertion, const char* file, int line) { + if(error_count <= 20) { + std::printf("%s:%d: failed %s\n", file, line, assertion); + } + ++error_count; +} + +#define CHECK(...) do { if(__VA_ARGS__) {} else { report_error(#__VA_ARGS__, __FILE__, __LINE__); } } while(0) + +struct fn { + int test(int i) { return i * 2; } +}; +EOSIO_REFLECT(fn, test); + +int main() { + int counter = 0; + eosio::for_each_field([&](const char* name, auto method) { ++counter; }); + CHECK(counter == 0); + eosio::for_each_method([&](const char* name, int (fn::*m)(int)) { CHECK(m == &fn::test); ++counter; }); + CHECK(counter == 1); + if(error_count) return 1; +} From 06ad70c350a81af04ccd76e030069a0bee0e30e0 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Wed, 18 Mar 2020 15:02:41 -0400 Subject: [PATCH 05/15] Address review feedback --- include/eosio/ship_protocol.hpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/include/eosio/ship_protocol.hpp b/include/eosio/ship_protocol.hpp index e4dbee4..8b211ab 100644 --- a/include/eosio/ship_protocol.hpp +++ b/include/eosio/ship_protocol.hpp @@ -73,11 +73,6 @@ namespace eosio { namespace ship_protocol { report_error("unknown status: " + s); } - template - eosio::result from_bin(transaction_status& obj, S& stream) { - return stream.read_raw(obj); - } - template eosio::result to_json(const transaction_status& status, S& stream) { // todo: switch to new serializer string support. @@ -235,7 +230,7 @@ namespace eosio { namespace ship_protocol { std::vector account_disk_deltas = {}; std::optional except = {}; std::optional error_code = {}; - std::optional return_value = {}; + eosio::input_stream return_value = {}; }; EOSIO_REFLECT(action_trace_v1, action_ordinal, creator_action_ordinal, receipt, receiver, act, context_free, elapsed, From a0871b439f458c7e896603cb10e1cc97f30ef0a3 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Fri, 20 Mar 2020 07:30:43 -0400 Subject: [PATCH 06/15] fixed bug with implicit conversion to result from T, should use outcome::success(T) --- include/eosio/from_bin.hpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/include/eosio/from_bin.hpp b/include/eosio/from_bin.hpp index 92f9842..e141c8d 100644 --- a/include/eosio/from_bin.hpp +++ b/include/eosio/from_bin.hpp @@ -307,10 +307,8 @@ result from_bin(T& obj, S& stream) { template result from_bin(S& stream) { T obj; - auto r = from_bin(obj, stream); - if (!r) - return r.error(); - return obj; + OUTCOME_TRY( from_bin(obj, stream) ); + return outcome::success(obj); } template @@ -322,10 +320,8 @@ result convert_from_bin(T& obj, const std::vector& bin) { template result convert_from_bin(const std::vector& bin) { T obj; - auto r = convert_from_bin(obj, bin); - if (!r) - return r.error(); - return obj; + OUTCOME_TRY( convert_from_bin(obj, bin) ); + return outcome::success(obj); } } // namespace eosio From a84013ce7e7e5a052eab197836a3ef38852efdd9 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Fri, 20 Mar 2020 07:31:22 -0400 Subject: [PATCH 07/15] when converting an object with optional members to JSON, if the optional is not present the json doesn't include the field --- include/eosio/to_json.hpp | 57 ++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/include/eosio/to_json.hpp b/include/eosio/to_json.hpp index 45b0a75..41b78ce 100644 --- a/include/eosio/to_json.hpp +++ b/include/eosio/to_json.hpp @@ -200,6 +200,14 @@ result to_json(const std::variant& obj, S& stream) { return stream.write(']'); } + template + struct is_std_optional : std::false_type {}; + + template + struct is_std_optional> : std::true_type { + using value_type = T; + }; + template result to_json(const T& t, S& stream) { result ok = outcome::success(); @@ -207,29 +215,40 @@ result to_json(const T& t, S& stream) { OUTCOME_TRY(stream.write('{')); eosio::for_each_field([&](const char* name, auto&& member) { if (ok) { - if (first) { - first = false; - } else { - auto r = stream.write(','); + auto addfield = [&]() { + if (first) { + first = false; + } else { + auto r = stream.write(','); + if (!r) { + ok = r; + return; + } + } + auto r = to_json(name, stream); if (!r) { ok = r; return; } - } - auto r = to_json(name, stream); - if (!r) { - ok = r; - return; - } - r = stream.write(':'); - if (!r) { - ok = r; - return; - } - r = to_json(member(&t), stream); - if (!r) { - ok = r; - return; + r = stream.write(':'); + if (!r) { + ok = r; + return; + } + r = to_json(member(&t), stream); + if (!r) { + ok = r; + return; + } + }; + + auto m = member(&t); + using member_type = std::decay_t; + if constexpr ( not is_std_optional::value ) { + addfield(); + } else { + if( !!m ) + addfield(); } } }); From a6c94be78c806b333ff7aa0158efd9055c731726 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Fri, 20 Mar 2020 17:37:01 -0400 Subject: [PATCH 08/15] recurse_transaction_trace: to_bin --- include/eosio/ship_protocol.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/eosio/ship_protocol.hpp b/include/eosio/ship_protocol.hpp index 8b211ab..b4875b0 100644 --- a/include/eosio/ship_protocol.hpp +++ b/include/eosio/ship_protocol.hpp @@ -282,6 +282,11 @@ namespace eosio { namespace ship_protocol { transaction_trace recurse = {}; }; + template + eosio::result to_bin(const recurse_transaction_trace& obj, S& stream) { + return to_bin(obj.recurse, stream); + } + template eosio::result from_bin(recurse_transaction_trace& obj, S& stream) { return from_bin(obj.recurse, stream); From 84a6172908e4c7056ddcafc4ae379eee891ac6dd Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Thu, 26 Mar 2020 12:28:00 -0400 Subject: [PATCH 09/15] format_json --- include/eosio/stream.hpp | 52 +++++++++++++++++++++++++++++++ include/eosio/to_json.hpp | 65 ++++++++++++++++++++++++++++++--------- 2 files changed, 102 insertions(+), 15 deletions(-) diff --git a/include/eosio/stream.hpp b/include/eosio/stream.hpp index 1a09f73..377ea5a 100644 --- a/include/eosio/stream.hpp +++ b/include/eosio/stream.hpp @@ -166,6 +166,58 @@ struct size_stream { } }; +template +result increase_indent(S&) { + return outcome::success(); +} + +template +result decrease_indent(S&) { + return outcome::success(); +} + +template +result write_colon(S& s) { + return s.write(':'); +} + +template +result write_newline(S&) { + return outcome::success(); +} + +template +struct pretty_stream : Base { + using Base::Base; + int indent_size = 4; + std::vector current_indent; +}; + +template +result increase_indent(pretty_stream& s) { + s.current_indent.resize(s.current_indent.size() + s.indent_size, ' '); + return outcome::success(); +} + +template +result decrease_indent(pretty_stream& s) { + if (s.current_indent.size() < s.indent_size) + return stream_error::overrun; + s.current_indent.resize(s.current_indent.size() - s.indent_size); + return outcome::success(); +} + +template +result write_colon(pretty_stream& s) { + return s.write(": ", 2); +} + +template +result write_newline(pretty_stream& s) { + OUTCOME_TRY(s.write('\n')); + return s.write(s.current_indent.data(), s.current_indent.size()); +} + struct input_stream { const char* pos; const char* end; diff --git a/include/eosio/to_json.hpp b/include/eosio/to_json.hpp index 41b78ce..4b8d88e 100644 --- a/include/eosio/to_json.hpp +++ b/include/eosio/to_json.hpp @@ -160,24 +160,23 @@ template result to_json(float value, S& stream) { return template result to_json(const std::vector& obj, S& stream) { - auto r = stream.write('['); - if (!r) - return r.error(); + OUTCOME_TRY(stream.write('[')); bool first = true; for (auto& v : obj) { - if (!first) { - r = stream.write(','); - if (!r) - return r.error(); + if (first) { + OUTCOME_TRY(increase_indent(stream)); + } else { + OUTCOME_TRY(stream.write(',')); } + OUTCOME_TRY(write_newline(stream)); first = false; - r = to_json(v, stream); - if (!r) - return r.error(); + OUTCOME_TRY(to_json(v, stream)); } - r = stream.write(']'); - if (!r) - return r.error(); + if (!first) { + OUTCOME_TRY(decrease_indent(stream)); + OUTCOME_TRY(write_newline(stream)); + } + OUTCOME_TRY(stream.write(']')); return outcome::success(); } @@ -193,10 +192,15 @@ result to_json(const std::optional& obj, S& stream) { template result to_json(const std::variant& obj, S& stream) { OUTCOME_TRY(stream.write('[')); + OUTCOME_TRY(increase_indent(stream)); + OUTCOME_TRY(write_newline(stream)); OUTCOME_TRY(std::visit( [&](const auto& t) { return to_json(get_type_name((std::decay_t*)nullptr), stream); }, obj)); OUTCOME_TRY(stream.write(',')); + OUTCOME_TRY(write_newline(stream)); OUTCOME_TRY(std::visit([&](auto& x) { return to_json(x, stream); }, obj)); + OUTCOME_TRY(decrease_indent(stream)); + OUTCOME_TRY(write_newline(stream)); return stream.write(']'); } @@ -217,6 +221,11 @@ result to_json(const T& t, S& stream) { if (ok) { auto addfield = [&]() { if (first) { + auto r = increase_indent(stream); + if (!r) { + ok = r; + return; + } first = false; } else { auto r = stream.write(','); @@ -225,12 +234,17 @@ result to_json(const T& t, S& stream) { return; } } - auto r = to_json(name, stream); + auto r = write_newline(stream); if (!r) { ok = r; return; } - r = stream.write(':'); + r = to_json(name, stream); + if (!r) { + ok = r; + return; + } + r = write_colon(stream); if (!r) { ok = r; return; @@ -253,6 +267,10 @@ result to_json(const T& t, S& stream) { } }); OUTCOME_TRY(ok); + if (!first) { + OUTCOME_TRY(decrease_indent(stream)); + OUTCOME_TRY(write_newline(stream)); + } return stream.write('}'); } @@ -293,4 +311,21 @@ result convert_to_json(const T& t) { return stream_error::underrun; } +template +result format_json(const T& t) { + pretty_stream ss; + auto r = to_json(t, ss); + if (!r) + return r.error(); + std::string result(ss.size, 0); + pretty_stream fbs(result.data(), result.size()); + r = to_json(t, fbs); + if (!r) + return r.error(); + if (fbs.pos == fbs.end) + return std::move(result); + else + return stream_error::underrun; +} + } // namespace eosio From c26f69ac96ee05c83a53758c326edc0f450b40d2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 5 Apr 2020 15:17:25 +0000 Subject: [PATCH 10/15] Bump acorn from 5.7.3 to 5.7.4 in /test Bumps [acorn](https://github.com/acornjs/acorn) from 5.7.3 to 5.7.4. - [Release notes](https://github.com/acornjs/acorn/releases) - [Commits](https://github.com/acornjs/acorn/compare/5.7.3...5.7.4) Signed-off-by: dependabot[bot] --- test/yarn.lock | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/test/yarn.lock b/test/yarn.lock index 65aa131..1ac1651 100644 --- a/test/yarn.lock +++ b/test/yarn.lock @@ -154,8 +154,8 @@ acorn-dynamic-import@^3.0.0: acorn "^5.0.0" acorn@^5.0.0, acorn@^5.6.2: - version "5.7.3" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" + version "5.7.4" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e" ajv-keywords@^3.1.0: version "3.2.0" @@ -364,11 +364,11 @@ bluebird@3, bluebird@^3.5.1: bluebird@^2.9.15: version "2.11.0" - resolved "http://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1" + resolved "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1" bluebird@~3.4.1: version "3.4.7" - resolved "http://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3" + resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3" bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: version "4.11.8" @@ -471,7 +471,7 @@ buffer-xor@^1.0.3: buffer@^4.3.0: version "4.9.1" - resolved "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + resolved "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" dependencies: base64-js "^1.0.2" ieee754 "^1.1.4" @@ -673,7 +673,7 @@ combined-stream@1.0.6, combined-stream@~1.0.6: commander@2.9.x: version "2.9.0" - resolved "http://registry.npmjs.org/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" + resolved "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" dependencies: graceful-readlink ">= 1.0.0" @@ -1700,7 +1700,7 @@ lodash@4, lodash@^4.17.10: lodash@^3.6.0: version "3.10.1" - resolved "http://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" + resolved "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" lru-cache@^4.1.1: version "4.1.3" @@ -1818,11 +1818,11 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: minimist@0.0.8: version "0.0.8" - resolved "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + resolved "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" minimist@^1.2.0: version "1.2.0" - resolved "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" minipass@^2.0.2, minipass@^2.2.1, minipass@^2.3.3: version "2.3.4" @@ -1861,7 +1861,7 @@ mixin-deep@^1.2.0: "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: version "0.5.1" - resolved "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: minimist "0.0.8" @@ -2068,7 +2068,7 @@ os-homedir@^1.0.0: os-locale@^1.4.0: version "1.4.0" - resolved "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + resolved "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" dependencies: lcid "^1.0.0" @@ -2310,7 +2310,7 @@ rc@^1.2.7: "readable-stream@1 || 2", readable-stream@^2.0.0, "readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6: version "2.3.6" - resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" dependencies: core-util-is "~1.0.0" inherits "~2.0.3" @@ -2322,7 +2322,7 @@ rc@^1.2.7: readable-stream@~1.0.26-2: version "1.0.34" - resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" dependencies: core-util-is "~1.0.0" inherits "~2.0.1" @@ -2331,7 +2331,7 @@ readable-stream@~1.0.26-2: readable-stream@~2.1.5: version "2.1.5" - resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz#66fa8b720e1438b364681f2ad1a63c618448c9d0" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz#66fa8b720e1438b364681f2ad1a63c618448c9d0" dependencies: buffer-shims "^1.0.0" core-util-is "~1.0.0" @@ -3097,7 +3097,7 @@ worker-farm@^1.5.2: wrap-ansi@^2.0.0: version "2.1.0" - resolved "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" dependencies: string-width "^1.0.1" strip-ansi "^3.0.1" @@ -3155,7 +3155,7 @@ yargs@^12.0.1: yargs@^3.6.0: version "3.32.0" - resolved "http://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz#03088e9ebf9e756b69751611d2a5ef591482c995" + resolved "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz#03088e9ebf9e756b69751611d2a5ef591482c995" dependencies: camelcase "^2.0.1" cliui "^3.0.3" From d0cdf3a3d89e45b1d1fd6020334ff5cf6bdf4dce Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Mon, 6 Apr 2020 10:39:53 -0400 Subject: [PATCH 11/15] gcc fixes --- CMakeLists.txt | 2 +- include/eosio/asset.hpp | 2 +- include/eosio/stream.hpp | 1 + include/eosio/to_key.hpp | 1 + 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d768914..dcb68d9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ endif() set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_CXX_EXTENSIONS ON) if(NOT DEFINED SKIP_SUBMODULE_CHECK) execute_process(COMMAND git submodule status --recursive diff --git a/include/eosio/asset.hpp b/include/eosio/asset.hpp index 52a610e..6c809f7 100644 --- a/include/eosio/asset.hpp +++ b/include/eosio/asset.hpp @@ -32,7 +32,7 @@ struct asset { /** * The symbol name of the asset */ - symbol symbol; + eosio::symbol symbol; /** * Maximum amount possible for this asset. It's capped to 2^62 - 1 diff --git a/include/eosio/stream.hpp b/include/eosio/stream.hpp index 3bd6df4..9031dab 100644 --- a/include/eosio/stream.hpp +++ b/include/eosio/stream.hpp @@ -6,6 +6,7 @@ #include #include #include +#include namespace eosio { enum class stream_error { diff --git a/include/eosio/to_key.hpp b/include/eosio/to_key.hpp index f590c94..0b38348 100644 --- a/include/eosio/to_key.hpp +++ b/include/eosio/to_key.hpp @@ -11,6 +11,7 @@ #include #include #include +#include namespace eosio { From 01c5a3fbc5f7ad077505e484727816d57236db14 Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Mon, 6 Apr 2020 12:40:15 -0400 Subject: [PATCH 12/15] replace abieos_headers target with a new abieos library target --- CMakeLists.txt | 26 ++++++++++++++------------ tools/CMakeLists.txt | 2 +- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dcb68d9..38aed6f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,27 +31,29 @@ Please run the command 'git submodule update --init --recursive'.") endif() endif() -add_library(abieos MODULE src/abieos.cpp src/abi.cpp src/crypto.cpp include/eosio/fpconv.c) -target_include_directories(abieos PRIVATE include external/outcome/single-header external/rapidjson/include external/date/include) +add_library(abieos STATIC src/abi.cpp src/crypto.cpp include/eosio/fpconv.c) +target_include_directories(abieos PUBLIC include external/outcome/single-header external/rapidjson/include external/date/include) +set_target_properties(abieos PROPERTIES POSITION_INDEPENDENT_CODE ON) -add_library(abieos_headers INTERFACE) -target_include_directories(abieos_headers INTERFACE include external/outcome/single-header external/date/include external/rapidjson/include) +add_library(abieos_module MODULE src/abieos.cpp) +target_link_libraries(abieos_module abieos) +set_target_properties(abieos_module PROPERTIES OUTPUT_NAME "abieos") -add_executable(test src/test.cpp src/abieos.cpp src/abi.cpp src/crypto.cpp include/eosio/fpconv.c) -target_include_directories(test PRIVATE include external/outcome/single-header external/rapidjson/include external/date/include) +add_executable(test src/test.cpp src/abieos.cpp) +target_link_libraries(test abieos) -add_executable(template_test src/template_test.cpp src/abieos.cpp src/abi.cpp src/crypto.cpp include/eosio/fpconv.c) -target_include_directories(template_test PRIVATE include external/outcome/single-header external/rapidjson/include external/date/include) +add_executable(template_test src/template_test.cpp src/abieos.cpp) +target_link_libraries(template_test abieos) -add_executable(key_test src/key_test.cpp src/abieos.cpp src/abi.cpp src/crypto.cpp include/eosio/fpconv.c) -target_include_directories(key_test PRIVATE include external/outcome/single-header external/rapidjson/include external/date/include) +add_executable(key_test src/key_test.cpp src/abieos.cpp) +target_link_libraries(key_test abieos) add_executable(reflect_test src/reflect_test.cpp) target_include_directories(reflect_test PRIVATE include) -add_executable(test-sanitize src/test.cpp src/abieos.cpp src/abi.cpp src/crypto.cpp include/eosio/fpconv.c) +add_executable(test-sanitize src/test.cpp src/abieos.cpp) target_include_directories(test-sanitize PRIVATE include external/outcome/single-header external/rapidjson/include external/date/include) -target_link_libraries(test-sanitize -fno-omit-frame-pointer -fsanitize=address,undefined) +target_link_libraries(test-sanitize abieos -fno-omit-frame-pointer -fsanitize=address,undefined) target_compile_options(test-sanitize PUBLIC -fno-omit-frame-pointer -fsanitize=address,undefined) # add_executable(fuzzer src/fuzzer.cpp src/abieos.cpp) diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 4adbe45..63ec466 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -1,7 +1,7 @@ # copyright defined in abieos/LICENSE.txt add_executable(name name.cpp) -target_link_libraries(name abieos_headers) +target_link_libraries(name abieos) add_custom_command( TARGET name POST_BUILD COMMAND ${CMAKE_COMMAND} -E create_symlink $ ${CMAKE_CURRENT_BINARY_DIR}/name2num ) add_custom_command( TARGET name POST_BUILD COMMAND ${CMAKE_COMMAND} -E create_symlink $ ${CMAKE_CURRENT_BINARY_DIR}/num2name ) From b6e397377b87cbd8058c10a6d257ce3767c2b1c9 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Thu, 9 Apr 2020 08:02:31 -0400 Subject: [PATCH 13/15] add time_point::max() --- include/eosio/time.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/eosio/time.hpp b/include/eosio/time.hpp index 35a3aef..e50f2c2 100644 --- a/include/eosio/time.hpp +++ b/include/eosio/time.hpp @@ -63,6 +63,8 @@ class time_point { explicit time_point(microseconds e) : elapsed(e) {} const microseconds& time_since_epoch() const { return elapsed; } uint32_t sec_since_epoch() const { return uint32_t(elapsed.count() / 1000000); } + + static time_point max() { return time_point( microseconds::maximum() ); } /// @cond INTERNAL time_point& operator+=(const microseconds& m) { From 1f6100f496579f6f85d5a9b57f3c8e63c1b5adf5 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Sun, 12 Apr 2020 22:42:57 -0400 Subject: [PATCH 14/15] Expose base58 api, fix checksum160 to use 20 bytes --- include/eosio/crypto.hpp | 3 +++ include/eosio/fixed_bytes.hpp | 2 +- src/crypto.cpp | 7 +++++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/include/eosio/crypto.hpp b/include/eosio/crypto.hpp index 8b143be..a3d471d 100644 --- a/include/eosio/crypto.hpp +++ b/include/eosio/crypto.hpp @@ -152,4 +152,7 @@ result from_json(signature& obj, S& stream) { obj = std::move(result); return outcome::success(); } + + std::string to_base58(const char* d, size_t s ); + } // namespace eosio diff --git a/include/eosio/fixed_bytes.hpp b/include/eosio/fixed_bytes.hpp index 8747e89..59ea6c6 100644 --- a/include/eosio/fixed_bytes.hpp +++ b/include/eosio/fixed_bytes.hpp @@ -202,7 +202,7 @@ void eosio_for_each_field(fixed_bytes*, F&& f) { template EOSIO_COMPARE(fixed_bytes); -using checksum160 = fixed_bytes<20>; +using checksum160 = fixed_bytes<20,uint32_t>; using checksum256 = fixed_bytes<32>; using checksum512 = fixed_bytes<64>; diff --git a/src/crypto.cpp b/src/crypto.cpp index bdb75ef..4ac4fc1 100644 --- a/src/crypto.cpp +++ b/src/crypto.cpp @@ -96,6 +96,7 @@ result> digest_suffix_ripemd160(const Container&.. return digest; } + template result string_to_key(std::string_view s, key_type type, std::string_view suffix) { std::vector whole; @@ -194,3 +195,9 @@ result eosio::signature_from_string(std::string_view s) { else return eosio::from_json_error::expected_signature; } + +namespace eosio { + std::string to_base58(const char* d, size_t s ) { + return binary_to_base58( std::string_view(d,s) ); + } +} From 79f95a1412a53ef82d2c37ad632eb49488226840 Mon Sep 17 00:00:00 2001 From: Steven Watanabe Date: Wed, 15 Apr 2020 17:20:53 -0400 Subject: [PATCH 15/15] Fix incorrect loop condition that caused utf-8 validation to swallow the entire string. --- include/eosio/to_json.hpp | 18 ++++++++---------- src/test.cpp | 1 + 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/include/eosio/to_json.hpp b/include/eosio/to_json.hpp index 45b0a75..fca2484 100644 --- a/include/eosio/to_json.hpp +++ b/include/eosio/to_json.hpp @@ -38,16 +38,14 @@ result to_json(std::string_view sv, S& stream) { while (begin != end) { auto pos = begin; while (pos != end && *pos != '"' && *pos != '\\' && (unsigned char)(*pos) >= 32 && *pos != 127) ++pos; - if (begin != pos) { - while (begin != end) { - stream_adaptor s2(begin, static_cast(pos - begin)); - if (rapidjson::UTF8<>::Validate(s2, s2)) { - OUTCOME_TRY(stream.write(begin, s2.idx)); - begin += s2.idx; - } else { - ++begin; - OUTCOME_TRY(stream.write('?')); - } + while (begin != pos) { + stream_adaptor s2(begin, static_cast(pos - begin)); + if (rapidjson::UTF8<>::Validate(s2, s2)) { + OUTCOME_TRY(stream.write(begin, s2.idx)); + begin += s2.idx; + } else { + ++begin; + OUTCOME_TRY(stream.write('?')); } } if (begin != end) { diff --git a/src/test.cpp b/src/test.cpp index 13b2986..c30e3d5 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -569,6 +569,7 @@ void check_types() { check_type(context, 0, "string", R"("' + '*'.repeat(128) + '")"); check_type(context, 0, "string", R"("\u0000 这是一个测试 Это тест هذا اختبار 👍")"); check(abieos_bin_to_json(context, 0, "string", "\x11invalid utf8: \xff\xfe\xfd", 18) == std::string(R"("invalid utf8: ???")"), "invalid utf8"); + check(abieos_bin_to_json(context, 0, "string", "\4\xe8\xbf\x99\n", 5) == std::string("\"\xe8\xbf\x99\\u000A\""), "escaping"); check_error(context, "Stream overrun", [&] { return abieos_hex_to_json(context, 0, "string", "01"); }); check_type(context, 0, "checksum160", R"("0000000000000000000000000000000000000000")"); check_type(context, 0, "checksum160", R"("123456789ABCDEF01234567890ABCDEF70123456")");