From 17eb804a1d8f1255c874064b8d64fd6798f9ffb6 Mon Sep 17 00:00:00 2001 From: mschoenebeck Date: Sat, 22 Apr 2023 08:39:39 -0500 Subject: [PATCH 01/79] added bls12-381 crypto primitives --- .gitmodules | 3 + libraries/chain/abi_serializer.cpp | 7 + libraries/chain/controller.cpp | 18 +++ .../eosio/chain/protocol_feature_manager.hpp | 1 + libraries/chain/include/eosio/chain/types.hpp | 9 ++ .../eos-vm-oc/intrinsic_mapping.hpp | 12 +- .../eosio/chain/webassembly/interface.hpp | 101 +++++++++++++ libraries/chain/protocol_feature_manager.cpp | 11 ++ libraries/chain/webassembly/crypto.cpp | 102 +++++++++++++ .../chain/webassembly/runtimes/eos-vm.cpp | 12 ++ libraries/libfc/CMakeLists.txt | 4 +- .../libfc/include/fc/crypto/bls_utils.hpp | 35 +++++ libraries/libfc/libraries/bls12_381 | 1 + libraries/libfc/src/crypto/bls_utils.cpp | 77 ++++++++++ libraries/libfc/test/CMakeLists.txt | 5 + libraries/libfc/test/crypto/test_bls.cpp | 138 ++++++++++++++++++ 16 files changed, 534 insertions(+), 2 deletions(-) create mode 100644 libraries/libfc/include/fc/crypto/bls_utils.hpp create mode 160000 libraries/libfc/libraries/bls12_381 create mode 100644 libraries/libfc/src/crypto/bls_utils.cpp create mode 100644 libraries/libfc/test/crypto/test_bls.cpp diff --git a/.gitmodules b/.gitmodules index ab01b3d5c0..b6fa0f19dd 100644 --- a/.gitmodules +++ b/.gitmodules @@ -31,3 +31,6 @@ [submodule "libraries/cli11/cli11"] path = libraries/cli11/cli11 url = https://github.com/AntelopeIO/CLI11.git +[submodule "libraries/libfc/libraries/bls12_381"] + path = libraries/libfc/libraries/bls12_381 + url = https://github.com/mschoenebeck/bls12_381.git diff --git a/libraries/chain/abi_serializer.cpp b/libraries/chain/abi_serializer.cpp index 58e56bcf02..8f39d0049f 100644 --- a/libraries/chain/abi_serializer.cpp +++ b/libraries/chain/abi_serializer.cpp @@ -126,6 +126,13 @@ namespace eosio { namespace chain { built_in_types.emplace("symbol_code", pack_unpack()); built_in_types.emplace("asset", pack_unpack()); built_in_types.emplace("extended_asset", pack_unpack()); + + built_in_types.emplace("bls_scalar", pack_unpack_deadline()); + built_in_types.emplace("bls_g1", pack_unpack_deadline()); + built_in_types.emplace("bls_g2", pack_unpack_deadline()); + built_in_types.emplace("bls_gt", pack_unpack_deadline()); + built_in_types.emplace("bls_fp", pack_unpack_deadline()); + built_in_types.emplace("bls_fp2", pack_unpack_deadline()); } void abi_serializer::set_abi(abi_def abi, const yield_function_t& yield) { diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index 9b38edc753..cd2214634e 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -338,6 +338,8 @@ struct controller_impl { set_activation_handler(); set_activation_handler(); set_activation_handler(); + set_activation_handler(); + bls12_381::init(); self.irreversible_block.connect([this](const block_state_ptr& bsp) { // producer_plugin has already asserted irreversible_block signal is @@ -3838,6 +3840,22 @@ void controller_impl::on_activation +void controller_impl::on_activation() { + db.modify( db.get(), [&]( auto& ps ) { + add_intrinsic_to_whitelist( ps.whitelisted_intrinsics, "bls_g1_add" ); + add_intrinsic_to_whitelist( ps.whitelisted_intrinsics, "bls_g2_add" ); + add_intrinsic_to_whitelist( ps.whitelisted_intrinsics, "bls_g1_mul" ); + add_intrinsic_to_whitelist( ps.whitelisted_intrinsics, "bls_g2_mul" ); + add_intrinsic_to_whitelist( ps.whitelisted_intrinsics, "bls_g1_exp" ); + add_intrinsic_to_whitelist( ps.whitelisted_intrinsics, "bls_g2_exp" ); + add_intrinsic_to_whitelist( ps.whitelisted_intrinsics, "bls_pairing" ); + add_intrinsic_to_whitelist( ps.whitelisted_intrinsics, "bls_g1_map" ); + add_intrinsic_to_whitelist( ps.whitelisted_intrinsics, "bls_g2_map" ); + add_intrinsic_to_whitelist( ps.whitelisted_intrinsics, "bls_fp_mod" ); + } ); +} + /// End of protocol feature activation handlers } } /// eosio::chain diff --git a/libraries/chain/include/eosio/chain/protocol_feature_manager.hpp b/libraries/chain/include/eosio/chain/protocol_feature_manager.hpp index 0370ce3f16..e531273cf5 100644 --- a/libraries/chain/include/eosio/chain/protocol_feature_manager.hpp +++ b/libraries/chain/include/eosio/chain/protocol_feature_manager.hpp @@ -35,6 +35,7 @@ enum class builtin_protocol_feature_t : uint32_t { configurable_wasm_limits = 18, // configurable_wasm_limits2, crypto_primitives = 19, get_block_num = 20, + bls_primitives = 21, reserved_private_fork_protocol_features = 500000, }; diff --git a/libraries/chain/include/eosio/chain/types.hpp b/libraries/chain/include/eosio/chain/types.hpp index b0089f3a15..c55348bb53 100644 --- a/libraries/chain/include/eosio/chain/types.hpp +++ b/libraries/chain/include/eosio/chain/types.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -76,6 +77,14 @@ namespace eosio::chain { using public_key_type = fc::crypto::public_key; using private_key_type = fc::crypto::private_key; using signature_type = fc::crypto::signature; + + using bls_scalar_type = std::array; + using bls_g1_type = bls12_381::g1; + using bls_g2_type = bls12_381::g2; + using bls_gt_type = bls12_381::fp12; + using bls_fp_type = bls12_381::fp; + using bls_fp2_type = bls12_381::fp2; + #if BOOST_VERSION >= 107100 // configurable boost deque performs much better than std::deque in our use cases using block_1024_option_t = boost::container::deque_options< boost::container::block_size<1024u> >::type; diff --git a/libraries/chain/include/eosio/chain/webassembly/eos-vm-oc/intrinsic_mapping.hpp b/libraries/chain/include/eosio/chain/webassembly/eos-vm-oc/intrinsic_mapping.hpp index 464893530e..d9ddce7585 100644 --- a/libraries/chain/include/eosio/chain/webassembly/eos-vm-oc/intrinsic_mapping.hpp +++ b/libraries/chain/include/eosio/chain/webassembly/eos-vm-oc/intrinsic_mapping.hpp @@ -267,7 +267,17 @@ inline constexpr auto get_intrinsic_table() { "env.sha3", "env.blake2_f", "env.k1_recover", - "env.get_block_num" + "env.get_block_num", + "env.bls_g1_add", + "env.bls_g2_add", + "env.bls_g1_mul", + "env.bls_g2_mul", + "env.bls_g1_exp", + "env.bls_g2_exp", + "env.bls_g1_pairing", + "env.bls_g1_map", + "env.bls_g2_map", + "env.bls_fp_mod" ); } inline constexpr std::size_t find_intrinsic_index(std::string_view hf) { diff --git a/libraries/chain/include/eosio/chain/webassembly/interface.hpp b/libraries/chain/include/eosio/chain/webassembly/interface.hpp index 08f0eba6aa..7b8a6d2f6b 100644 --- a/libraries/chain/include/eosio/chain/webassembly/interface.hpp +++ b/libraries/chain/include/eosio/chain/webassembly/interface.hpp @@ -1785,6 +1785,107 @@ namespace webassembly { */ int32_t k1_recover( span signature, span digest, span pub) const; + /** + * Host function for G1 addition on the elliptic curve bls12-381 + * + * @ingroup crypto + * @param op1 - a span containing the first operand G1 point. + * @param op2 - a span containing the second operand G1 point. + * @param[out] result - the result op1 + op2. + */ + void bls_g1_add(span op1, span op2, span result) const; + + /** + * Host function for G2 addition on the elliptic curve bls12-381 + * + * @ingroup crypto + * @param op1 - a span containing the first operand G2 point. + * @param op2 - a span containing the second operand G2 point. + * @param[out] result - the result op1 + op2. + */ + void bls_g2_add(span op1, span op2, span result) const; + + /** + * Host function for G1 scalar multiplication on the elliptic curve bls12-381 + * + * @ingroup crypto + * @param point - a span containing the G1 point operand. + * @param scalar - a span containing the scalar operand. + * @param[out] result - the result: scalar * point. + */ + void bls_g1_mul(span point, span scalar, span result) const; + + /** + * Host function for G2 scalar multiplication on the elliptic curve bls12-381 + * + * @ingroup crypto + * @param point - a span containing the G2 point operand. + * @param scalar - a span containing the scalar operand. + * @param[out] result - the result op1 * op2. + */ + void bls_g2_mul(span point, span scalar, span result) const; + + /** + * Host function for G1 multi-exponentiation on the elliptic curve bls12-381 + * + * @ingroup crypto + * @param points - a span containing a list of G1 points (P0, P1, P2... Pn). + * @param scalars - a span containing a list of scalars (s0, s1, s2... sn). + * @param n - the number of elements in the lists. + * @param[out] result - the result s0 * P0 + s1 * P1 + ... + sn * Pn. + */ + void bls_g1_exp(span points, span scalars, const uint32_t n, span result) const; + + /** + * Host function for G2 multi-exponentiation on the elliptic curve bls12-381 + * + * @ingroup crypto + * @param points - a span containing a list of G2 points (P0, P1, P2... Pn). + * @param scalars - a span containing a list of scalars (s0, s1, s2... sn). + * @param n - the number of elements in the lists. + * @param[out] result - the result s0 * P0 + s1 * P1 + ... + sn * Pn. + */ + void bls_g2_exp(span points, span scalars, const uint32_t n, span result) const; + + /** + * Host function to calculate the pairing of (G1, G2) pairs on the elliptic curve bls12-381 + * + * @ingroup crypto + * @param g1_points - a span containing a list of G1 points (P0, P1, P2... Pn). + * @param g2_points - a span containing a list of G2 points (P0, P1, P2... Pn). + * @param n - the number of elements in the lists. + * @param[out] result - the result e(g1_0, g2_0) * e(g1_1, g2_1) * ... * e(g1_n, g2_n) + */ + void bls_pairing(span g1_points, span g2_points, const uint32_t n, span result) const; + + /** + * Host function for mapping fp to G1 on the elliptic curve bls12-381 + * + * @ingroup crypto + * @param e - a span containing the field element fp to be mapped. + * @param[out] result - the resulting element in G1. + */ + void bls_g1_map(span e, span result) const; + + /** + * Host function for mapping fp2 to G2 on the elliptic curve bls12-381 + * + * @ingroup crypto + * @param e - a span containing the field element fp2 to be mapped. + * @param[out] result - the resulting element in G2. + */ + void bls_g2_map(span e, span result) const; + + /** + * Host function for modular reduction of 64 bit scalar to field element (fp) of the elliptic curve bls12-381 + * Involves Montgomery Reduction on the resulting field element. + * + * @ingroup crypto + * @param s - a span containing the 64 Bit scalar to be reduced. + * @param[out] result - the resulting field element fp in Montogomery form. + */ + void bls_fp_mod(span s, span result) const; + // compiler builtins api void __ashlti3(legacy_ptr, uint64_t, uint64_t, uint32_t) const; void __ashrti3(legacy_ptr, uint64_t, uint64_t, uint32_t) const; diff --git a/libraries/chain/protocol_feature_manager.cpp b/libraries/chain/protocol_feature_manager.cpp index 0f618bc5b4..b58235b799 100644 --- a/libraries/chain/protocol_feature_manager.cpp +++ b/libraries/chain/protocol_feature_manager.cpp @@ -258,6 +258,17 @@ Adds new cryptographic host functions Builtin protocol feature: GET_BLOCK_NUM Enables new `get_block_num` intrinsic which returns the current block number. +*/ + {} + } ) + ( builtin_protocol_feature_t::bls_primitives, builtin_protocol_feature_spec{ + "BLS_PRIMITIVES", + fc::variant("2c302889ce2db124878f7c6092cf27519d450559ed2fdfbad14f532d90fc5139").as(), + // SHA256 hash of the raw message below within the comment delimiters (do not modify message below). +/* +Builtin protocol feature: BLS_PRIMITIVES +Adds new cryptographic host functions +- Add, multiply, multi-exponentiation and pairing functions for the bls12-381 elliptic curve. */ {} } ) diff --git a/libraries/chain/webassembly/crypto.cpp b/libraries/chain/webassembly/crypto.cpp index 43991610f9..a6f18f01e3 100644 --- a/libraries/chain/webassembly/crypto.cpp +++ b/libraries/chain/webassembly/crypto.cpp @@ -7,6 +7,7 @@ #include #include #include +#include namespace { uint32_t ceil_log2(uint32_t n) @@ -246,4 +247,105 @@ namespace eosio { namespace chain { namespace webassembly { return return_code::success; } + void interface::bls_g1_add(span op1, span op2, span result) const + { + bls12_381::g1 a = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(op1.data()), 144}, false, true); + bls12_381::g1 b = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(op2.data()), 144}, false, true); + bls12_381::g1 c = a.add(b); + c.toJacobianBytesLE({reinterpret_cast(result.data()), 144}, true); + } + + void interface::bls_g2_add(span op1, span op2, span result) const + { + bls12_381::g2 a = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(op1.data()), 288}, false, true); + bls12_381::g2 b = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(op2.data()), 288}, false, true); + bls12_381::g2 c = a.add(b); + c.toJacobianBytesLE({reinterpret_cast(result.data()), 288}, true); + } + + void interface::bls_g1_mul(span point, span scalar, span result) const + { + bls12_381::g1 a = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(point.data()), 144}, false, true); + std::array b = bls12_381::scalar::fromBytesLE<4>({reinterpret_cast(scalar.data()), 32}); + bls12_381::g1 c = a.mulScalar(b); + c.toJacobianBytesLE({reinterpret_cast(result.data()), 144}, true); + } + + void interface::bls_g2_mul(span point, span scalar, span result) const + { + bls12_381::g2 a = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(point.data()), 288}, false, true); + std::array b = bls12_381::scalar::fromBytesLE<4>({reinterpret_cast(scalar.data()), 32}); + bls12_381::g2 c = a.mulScalar(b); + c.toJacobianBytesLE({reinterpret_cast(result.data()), 288}, true); + } + + void interface::bls_g1_exp(span points, span scalars, const uint32_t n, span result) const + { + std::vector pv; + std::vector> sv; + pv.reserve(n); + sv.reserve(n); + for(uint32_t i = 0; i < n; i++) + { + bls12_381::g1 p = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(points.data() + i*144), 144}, false, true); + std::array s = bls12_381::scalar::fromBytesLE<4>({reinterpret_cast(scalars.data() + i*32), 32}); + pv.push_back(p); + sv.push_back(s); + } + bls12_381::g1 r = bls12_381::g1::multiExp(pv, sv); + r.toJacobianBytesLE({reinterpret_cast(result.data()), 144}, true); + } + + void interface::bls_g2_exp(span points, span scalars, const uint32_t n, span result) const + { + std::vector pv; + std::vector> sv; + pv.reserve(n); + sv.reserve(n); + for(uint32_t i = 0; i < n; i++) + { + bls12_381::g2 p = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(points.data() + i*288), 288}, false, true); + std::array s = bls12_381::scalar::fromBytesLE<4>({reinterpret_cast(scalars.data() + i*32), 32}); + pv.push_back(p); + sv.push_back(s); + } + bls12_381::g2 r = bls12_381::g2::multiExp(pv, sv); + r.toJacobianBytesLE({reinterpret_cast(result.data()), 288}, true); + } + + void interface::bls_pairing(span g1_points, span g2_points, const uint32_t n, span result) const + { + std::vector> v; + v.reserve(n); + for(uint32_t i = 0; i < n; i++) + { + bls12_381::g1 p_g1 = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(g1_points.data() + i*144), 144}, false, true); + bls12_381::g2 p_g2 = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(g2_points.data() + i*288), 288}, false, true); + bls12_381::pairing::add_pair(v, p_g1, p_g2); + } + bls12_381::fp12 r = bls12_381::pairing::calculate(v); + r.toBytesLE({reinterpret_cast(result.data()), 576}, true); + } + + void interface::bls_g1_map(span e, span result) const + { + bls12_381::fp a = bls12_381::fp::fromBytesLE({reinterpret_cast(e.data()), 48}, false, true); + bls12_381::g1 c = bls12_381::g1::mapToCurve(a); + c.toJacobianBytesLE({reinterpret_cast(result.data()), 144}, true); + } + + void interface::bls_g2_map(span e, span result) const + { + bls12_381::fp2 a = bls12_381::fp2::fromBytesLE({reinterpret_cast(e.data()), 96}, false, true); + bls12_381::g2 c = bls12_381::g2::mapToCurve(a); + c.toJacobianBytesLE({reinterpret_cast(result.data()), 288}, true); + } + + void interface::bls_fp_mod(span s, span result) const + { + std::array k = bls12_381::scalar::fromBytesLE<8>({reinterpret_cast(s.data()), 64}); + bls12_381::fp e = bls12_381::fp::modPrime<8>(k); + e.toBytesLE({reinterpret_cast(result.data()), 48}, true); + } + }}} // ns eosio::chain::webassembly diff --git a/libraries/chain/webassembly/runtimes/eos-vm.cpp b/libraries/chain/webassembly/runtimes/eos-vm.cpp index 522d39e13d..2ff992733e 100644 --- a/libraries/chain/webassembly/runtimes/eos-vm.cpp +++ b/libraries/chain/webassembly/runtimes/eos-vm.cpp @@ -620,6 +620,18 @@ REGISTER_CF_HOST_FUNCTION( blake2_f ); REGISTER_CF_HOST_FUNCTION( sha3 ); REGISTER_CF_HOST_FUNCTION( k1_recover ); +// bls_primitives protocol feature +REGISTER_CF_HOST_FUNCTION( bls_g1_add ); +REGISTER_CF_HOST_FUNCTION( bls_g2_add ); +REGISTER_CF_HOST_FUNCTION( bls_g1_mul ); +REGISTER_CF_HOST_FUNCTION( bls_g2_mul ); +REGISTER_CF_HOST_FUNCTION( bls_g1_exp ); +REGISTER_CF_HOST_FUNCTION( bls_g2_exp ); +REGISTER_CF_HOST_FUNCTION( bls_pairing ); +REGISTER_CF_HOST_FUNCTION( bls_g1_map ); +REGISTER_CF_HOST_FUNCTION( bls_g2_map ); +REGISTER_CF_HOST_FUNCTION( bls_fp_mod ); + } // namespace webassembly } // namespace chain } // namespace eosio diff --git a/libraries/libfc/CMakeLists.txt b/libraries/libfc/CMakeLists.txt index ac86842034..720f26558f 100644 --- a/libraries/libfc/CMakeLists.txt +++ b/libraries/libfc/CMakeLists.txt @@ -1,5 +1,6 @@ add_subdirectory( secp256k1 ) add_subdirectory( libraries/bn256/src ) +add_subdirectory( libraries/bls12_381 ) set(CMAKE_THREAD_PREFER_PTHREAD TRUE) set(THREADS_PREFER_PTHREAD_FLAG TRUE) @@ -55,6 +56,7 @@ set( fc_sources src/crypto/modular_arithmetic.cpp src/crypto/blake2.cpp src/crypto/k1_recover.cpp + src/crypto/bls_utils.cpp src/network/url.cpp src/network/http/http_client.cpp src/compress/zlib.cpp @@ -131,7 +133,7 @@ if(APPLE) find_library(corefoundation_framework CoreFoundation) endif() target_link_libraries( fc PUBLIC Boost::date_time Boost::chrono Boost::iostreams Threads::Threads - OpenSSL::Crypto ZLIB::ZLIB ${PLATFORM_SPECIFIC_LIBS} ${CMAKE_DL_LIBS} secp256k1 ${security_framework} ${corefoundation_framework}) + OpenSSL::Crypto ZLIB::ZLIB ${PLATFORM_SPECIFIC_LIBS} ${CMAKE_DL_LIBS} secp256k1 bls12_381 ${security_framework} ${corefoundation_framework}) # Critically, this ensures that OpenSSL 1.1 & 3.0 both have a variant of BN_zero() with void return value. But it also allows access # to some obsoleted AES functions in 3.0 too, since 3.0's API_COMPAT is effectively 3.0 by default diff --git a/libraries/libfc/include/fc/crypto/bls_utils.hpp b/libraries/libfc/include/fc/crypto/bls_utils.hpp new file mode 100644 index 0000000000..960a8ba00e --- /dev/null +++ b/libraries/libfc/include/fc/crypto/bls_utils.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include "../../../libraries/bls12_381/include/bls12_381.hpp" +#include + +namespace fc { + void to_variant(const bls12_381::g1& var, variant& vo, const fc::yield_function_t& yield = fc::yield_function_t()); + void from_variant(const variant& var, bls12_381::g1& vo); + + void to_variant(const bls12_381::g2& var, variant& vo, const fc::yield_function_t& yield = fc::yield_function_t()); + void from_variant(const variant& var, bls12_381::g2& vo); + + void to_variant(const bls12_381::fp& var, variant& vo, const fc::yield_function_t& yield = fc::yield_function_t()); + void from_variant(const variant& var, bls12_381::fp& vo); + + void to_variant(const bls12_381::fp2& var, variant& vo, const fc::yield_function_t& yield = fc::yield_function_t()); + void from_variant(const variant& var, bls12_381::fp2& vo); + + void to_variant(const bls12_381::fp6& var, variant& vo, const fc::yield_function_t& yield = fc::yield_function_t()); + void from_variant(const variant& var, bls12_381::fp6& vo); + + void to_variant(const bls12_381::fp12& var, variant& vo, const fc::yield_function_t& yield = fc::yield_function_t()); + void from_variant(const variant& var, bls12_381::fp12& vo); + + void to_variant(const std::array& var, variant& vo, const fc::yield_function_t& yield = fc::yield_function_t()); + void from_variant(const variant& var, std::array& vo); +} // namespace fc + +FC_REFLECT(bls12_381::g1, (x)(y)(z) ) +FC_REFLECT(bls12_381::g2, (x)(y)(z) ) +FC_REFLECT(bls12_381::fp, (d) ) +FC_REFLECT(bls12_381::fp2, (c0)(c1) ) +FC_REFLECT(bls12_381::fp6, (c0)(c1)(c2) ) +FC_REFLECT(bls12_381::fp12, (c0)(c1) ) + diff --git a/libraries/libfc/libraries/bls12_381 b/libraries/libfc/libraries/bls12_381 new file mode 160000 index 0000000000..31e042e122 --- /dev/null +++ b/libraries/libfc/libraries/bls12_381 @@ -0,0 +1 @@ +Subproject commit 31e042e1220b6e2a39e4468accff99e035b593c6 diff --git a/libraries/libfc/src/crypto/bls_utils.cpp b/libraries/libfc/src/crypto/bls_utils.cpp new file mode 100644 index 0000000000..ce85dba0b9 --- /dev/null +++ b/libraries/libfc/src/crypto/bls_utils.cpp @@ -0,0 +1,77 @@ +#include + +using namespace bls12_381; + +namespace fc { + + void to_variant(const bls12_381::g1& var, fc::variant& vo, const fc::yield_function_t& yield) + { + vo = bytesToHex<144>(var.toJacobianBytesLE(true)); + } + + void from_variant(const fc::variant& var, bls12_381::g1& vo) + { + vo = g1::fromJacobianBytesLE(hexToBytes(var.as_string()), false, true); + } + + void to_variant(const bls12_381::g2& var, fc::variant& vo, const fc::yield_function_t& yield) + { + vo = bytesToHex<288>(var.toJacobianBytesLE(true)); + } + + void from_variant(const fc::variant& var, bls12_381::g2& vo) + { + vo = g2::fromJacobianBytesLE(hexToBytes(var.as_string()), false, true); + } + + void to_variant(const bls12_381::fp& var, fc::variant& vo, const fc::yield_function_t& yield) + { + vo = bytesToHex<48>(var.toBytesLE(true)); + } + + void from_variant(const fc::variant& var, bls12_381::fp& vo) + { + vo = fp::fromBytesLE(hexToBytes(var.as_string()), false, true); + } + + void to_variant(const bls12_381::fp2& var, fc::variant& vo, const fc::yield_function_t& yield) + { + vo = bytesToHex<96>(var.toBytesLE(true)); + } + + void from_variant(const fc::variant& var, bls12_381::fp2& vo) + { + vo = fp2::fromBytesLE(hexToBytes(var.as_string()), false, true); + } + + void to_variant(const bls12_381::fp6& var, fc::variant& vo, const fc::yield_function_t& yield) + { + vo = bytesToHex<288>(var.toBytesLE(true)); + } + + void from_variant(const fc::variant& var, bls12_381::fp6& vo) + { + vo = fp6::fromBytesLE(hexToBytes(var.as_string()), false, true); + } + + void to_variant(const bls12_381::fp12& var, fc::variant& vo, const fc::yield_function_t& yield) + { + vo = bytesToHex<576>(var.toBytesLE(true)); + } + + void from_variant(const fc::variant& var, bls12_381::fp12& vo) + { + vo = fp12::fromBytesLE(hexToBytes(var.as_string()), false, true); + } + + void to_variant(const std::array& var, fc::variant& vo, const fc::yield_function_t& yield) + { + vo = bytesToHex<32>(scalar::toBytesLE<4>(var)); + } + + void from_variant(const fc::variant& var, std::array& vo) + { + vo = scalar::fromBytesLE<4>(hexToBytes(var.as_string())); + } +} + diff --git a/libraries/libfc/test/CMakeLists.txt b/libraries/libfc/test/CMakeLists.txt index b71efc19df..ac2409d093 100644 --- a/libraries/libfc/test/CMakeLists.txt +++ b/libraries/libfc/test/CMakeLists.txt @@ -10,3 +10,8 @@ add_executable( test_base64 test_base64.cpp ) target_link_libraries( test_base64 fc ) add_test(NAME test_base64 COMMAND test_base64 WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) + +add_executable( test_bls crypto/test_bls.cpp ) +target_link_libraries( test_bls fc ) + +add_test(NAME test_bls COMMAND test_bls WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) diff --git a/libraries/libfc/test/crypto/test_bls.cpp b/libraries/libfc/test/crypto/test_bls.cpp new file mode 100644 index 0000000000..2395f21c7a --- /dev/null +++ b/libraries/libfc/test/crypto/test_bls.cpp @@ -0,0 +1,138 @@ +#define BOOST_TEST_MODULE bls + +#include +#include +#include + +using namespace std; +using namespace bls12_381; + +BOOST_AUTO_TEST_SUITE(bls) + +// sample seeds +vector seed_1 = { 0, 50, 6, 244, 24, 199, 1, 25, 52, 88, 192, 19, 18, 12, 89, 6, 220, 18, 102, 58, 209, 82, 12, 62, 89, 110, 182, 9, 44, 20, 254, 22}; +vector seed_2 = { 6, 51, 22, 89, 11, 15, 4, 61, 127, 241, 79, 26, 88, 52, 1, 6, 18, 79, 10, 8, 36, 182, 154, 35, 75, 156, 215, 41, 29, 90, 125, 233}; +vector seed_3 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12}; +// sample messages +vector message_1 = { 51, 23, 56, 93, 212, 129, 128, 27, 251, 12, 42, 129, 210, 9, 34, 98}; +vector message_2 = { 16, 38, 54, 125, 71, 214, 217, 78, 73, 23, 127, 235, 8, 94, 41, 53}; +vector message_3 = { 12, 4, 1, 64, 127, 86, 2, 8, 145, 25, 27, 5, 88, 4, 42, 58}; + +// test a single key signature + verification +BOOST_AUTO_TEST_CASE(bls_sig_verify) try { + array sk = secret_key(seed_1); + g1 pk = public_key(sk); + g2 signature = sign(sk, message_1); + + bool ok = verify(pk, message_1, signature); + BOOST_CHECK_EQUAL(ok, true); +} FC_LOG_AND_RETHROW(); + +// test serialization / deserialization of private key, public key and signature +BOOST_AUTO_TEST_CASE(bls_serialization_test) try { + array sk = secret_key(seed_1); + g1 pk = public_key(sk); + g2 signature = sign(sk, message_1); + + string pk_string = bytesToHex<144>(pk.toJacobianBytesBE()); + string signature_string = bytesToHex<288>(signature.toJacobianBytesBE()); + cout << pk_string << std::endl; + cout << signature_string << std::endl; + + g1 pk2 = g1::fromJacobianBytesBE(hexToBytes(pk_string)); + g2 signature2 = g2::fromJacobianBytesBE(hexToBytes(signature_string)); + bool ok = verify(pk2, message_1, signature2); + BOOST_CHECK_EQUAL(ok, true); +} FC_LOG_AND_RETHROW(); + +// test public keys + signatures aggregation + verification +BOOST_AUTO_TEST_CASE(bls_agg_sig_verify) try { + array sk1 = secret_key(seed_1); + g1 pk1 = public_key(sk1); + g2 sig1 = sign(sk1, message_1); + + array sk2 = secret_key(seed_2); + g1 pk2 = public_key(sk2); + g2 sig2 = sign(sk2, message_2); + + g2 aggSig = aggregate_signatures({sig1, sig2}); + + bool ok = aggregate_verify({pk1, pk2}, {message_1, message_2}, aggSig); + BOOST_CHECK_EQUAL(ok, true); +} FC_LOG_AND_RETHROW(); + +// test signature aggregation + aggregate tree verification +BOOST_AUTO_TEST_CASE(bls_agg_tree_verify) try { + array sk1 = secret_key(seed_1); + g1 pk1 = public_key(sk1); + g2 sig1 = sign(sk1, message_1); + + array sk2 = secret_key(seed_2); + g1 pk2 = public_key(sk2); + g2 sig2 = sign(sk2, message_2); + + g2 aggSig = aggregate_signatures({sig1, sig2}); + + array sk3 = secret_key(seed_3); + g1 pk3 = public_key(sk3); + g2 sig3 = sign(sk3, message_3); + + g2 aggSigFinal = aggregate_signatures({aggSig, sig3}); + + bool ok = aggregate_verify({pk1, pk2, pk3}, {message_1, message_2, message_3}, aggSigFinal); + BOOST_CHECK_EQUAL(ok, true); +} FC_LOG_AND_RETHROW(); + +// test public key aggregation +BOOST_AUTO_TEST_CASE(bls_agg_pk_verify) try { + array sk1 = secret_key(seed_1); + g1 pk1 = public_key(sk1); + g2 sig1 = sign(sk1, message_1); + + array sk2 = secret_key(seed_2); + g1 pk2 = public_key(sk2); + g2 sig2 = sign(sk2, message_1); + + array sk3 = secret_key(seed_3); + g1 pk3 = public_key(sk3); + g2 sig3 = sign(sk3, message_1); + + g2 sigAgg = aggregate_signatures({sig1, sig2, sig3}); + g1 pkAgg = aggregate_public_keys({pk1, pk2, pk3}); + + bool ok = verify(pkAgg, message_1, sigAgg); + BOOST_CHECK_EQUAL(ok, true); +} FC_LOG_AND_RETHROW(); + +// test wrong key and wrong signature +BOOST_AUTO_TEST_CASE(bls_bad_sig_verify) try { + array sk1 = secret_key(seed_1); + g1 pk1 = public_key(sk1); + g2 sig1 = sign(sk1, message_1); + + array sk2 = secret_key(seed_2); + g1 pk2 = public_key(sk2); + g2 sig2 = sign(sk2, message_1); + + bool ok1 = verify(pk1, message_1, sig2); // wrong signature + bool ok2 = verify(pk2, message_1, sig1); // wrong key + BOOST_CHECK_EQUAL(ok1, false); + BOOST_CHECK_EQUAL(ok2, false); +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_CASE(bls_pop_verify) try { + array sk1 = secret_key(seed_1); + g1 pk1 = public_key(sk1); + g2 sig1 = sign(sk1, message_1); + + array sk2 = secret_key(seed_2); + g1 pk2 = public_key(sk2); + g2 sig2 = sign(sk2, message_1); + + g2 aggsig = aggregate_signatures({sig1, sig2}); + bool ok = pop_fast_aggregate_verify({pk1, pk2}, message_1, aggsig); + BOOST_CHECK_EQUAL(ok, true); +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_SUITE_END() + From ece632eed7dc9e32d7fecc2d5a2ab375df65f8d6 Mon Sep 17 00:00:00 2001 From: mschoenebeck Date: Sat, 22 Apr 2023 09:25:51 -0500 Subject: [PATCH 02/79] correct bit/byte mistake in comment --- .../chain/include/eosio/chain/webassembly/interface.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/chain/include/eosio/chain/webassembly/interface.hpp b/libraries/chain/include/eosio/chain/webassembly/interface.hpp index 7b8a6d2f6b..10e271d73e 100644 --- a/libraries/chain/include/eosio/chain/webassembly/interface.hpp +++ b/libraries/chain/include/eosio/chain/webassembly/interface.hpp @@ -1877,11 +1877,11 @@ namespace webassembly { void bls_g2_map(span e, span result) const; /** - * Host function for modular reduction of 64 bit scalar to field element (fp) of the elliptic curve bls12-381 - * Involves Montgomery Reduction on the resulting field element. + * Host function for modular reduction of 64 bytes wide scalar to a field element (fp, 48 bytes) of the elliptic curve bls12-381 + * Involves Montgomery conversion on the resulting field element. * * @ingroup crypto - * @param s - a span containing the 64 Bit scalar to be reduced. + * @param s - a span containing the 64 bytes wide scalar to be reduced. * @param[out] result - the resulting field element fp in Montogomery form. */ void bls_fp_mod(span s, span result) const; From 10776fcac99f58bae8ec2c32183558499b6efa27 Mon Sep 17 00:00:00 2001 From: mschoenebeck Date: Mon, 24 Apr 2023 18:57:07 -0500 Subject: [PATCH 03/79] corrected SHA256 hash of BLS_PRIMITIVES protocol feature --- libraries/chain/protocol_feature_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/chain/protocol_feature_manager.cpp b/libraries/chain/protocol_feature_manager.cpp index b58235b799..0a4ead0573 100644 --- a/libraries/chain/protocol_feature_manager.cpp +++ b/libraries/chain/protocol_feature_manager.cpp @@ -263,7 +263,7 @@ Enables new `get_block_num` intrinsic which returns the current block number. } ) ( builtin_protocol_feature_t::bls_primitives, builtin_protocol_feature_spec{ "BLS_PRIMITIVES", - fc::variant("2c302889ce2db124878f7c6092cf27519d450559ed2fdfbad14f532d90fc5139").as(), + fc::variant("01969c44de35999b924095ae7f50081a7f274409fdbccb9fc54fa7836c76089c").as(), // SHA256 hash of the raw message below within the comment delimiters (do not modify message below). /* Builtin protocol feature: BLS_PRIMITIVES From 9b42070807ab32155cd859b460acd54079d83a4f Mon Sep 17 00:00:00 2001 From: mschoenebeck Date: Mon, 1 May 2023 07:35:55 -0500 Subject: [PATCH 04/79] updated submodule --- libraries/libfc/libraries/bls12_381 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/libfc/libraries/bls12_381 b/libraries/libfc/libraries/bls12_381 index 31e042e122..0a7d5f21f1 160000 --- a/libraries/libfc/libraries/bls12_381 +++ b/libraries/libfc/libraries/bls12_381 @@ -1 +1 @@ -Subproject commit 31e042e1220b6e2a39e4468accff99e035b593c6 +Subproject commit 0a7d5f21f1c41ca1ed98f349639ceb98edcd5494 From 53e267d5c8d7e718d2d3cebe84196c9ce73b34ee Mon Sep 17 00:00:00 2001 From: mschoenebeck Date: Mon, 8 May 2023 10:05:11 -0500 Subject: [PATCH 05/79] updated submodule bls12_381 (clang fixes) --- libraries/libfc/libraries/bls12_381 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/libfc/libraries/bls12_381 b/libraries/libfc/libraries/bls12_381 index 0a7d5f21f1..5b7ce8e068 160000 --- a/libraries/libfc/libraries/bls12_381 +++ b/libraries/libfc/libraries/bls12_381 @@ -1 +1 @@ -Subproject commit 0a7d5f21f1c41ca1ed98f349639ceb98edcd5494 +Subproject commit 5b7ce8e068fb9b404308f8fc192cc5660dc3821e From 201a0f78225c9662d50e56189247da35caa4aaf9 Mon Sep 17 00:00:00 2001 From: mschoenebeck Date: Mon, 8 May 2023 18:21:09 -0500 Subject: [PATCH 06/79] updated bls lib --- libraries/libfc/libraries/bls12_381 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/libfc/libraries/bls12_381 b/libraries/libfc/libraries/bls12_381 index 5b7ce8e068..f9b18366d6 160000 --- a/libraries/libfc/libraries/bls12_381 +++ b/libraries/libfc/libraries/bls12_381 @@ -1 +1 @@ -Subproject commit 5b7ce8e068fb9b404308f8fc192cc5660dc3821e +Subproject commit f9b18366d6f18b64bdf99a1b41166e20a1e63ed5 From 22656adfac795a307759b3bec8d0c7fd604bf0a9 Mon Sep 17 00:00:00 2001 From: mschoenebeck Date: Mon, 8 May 2023 19:05:32 -0500 Subject: [PATCH 07/79] synced submodules --- libraries/chainbase | 2 +- libraries/cli11/cli11 | 2 +- libraries/eos-vm | 2 +- libraries/libfc/libraries/bn256 | 2 +- tests/abieos | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libraries/chainbase b/libraries/chainbase index 2b5b800a31..c1d30da95c 160000 --- a/libraries/chainbase +++ b/libraries/chainbase @@ -1 +1 @@ -Subproject commit 2b5b800a317a4e3edab14115788cff0907bb5f3d +Subproject commit c1d30da95c9f5e2e80d32732d3063671ff23b123 diff --git a/libraries/cli11/cli11 b/libraries/cli11/cli11 index 90b0d6720d..f325cc66b4 160000 --- a/libraries/cli11/cli11 +++ b/libraries/cli11/cli11 @@ -1 +1 @@ -Subproject commit 90b0d6720d199be4503c7f8fdbbc31ffb7d58c1a +Subproject commit f325cc66b40cf05e35b457561e0fa1adfedfc973 diff --git a/libraries/eos-vm b/libraries/eos-vm index 1592261e96..329db27d88 160000 --- a/libraries/eos-vm +++ b/libraries/eos-vm @@ -1 +1 @@ -Subproject commit 1592261e96a5ebb4a5f261d7167c0723ca941b9b +Subproject commit 329db27d888dce32c96b4f209cdea45f1d07e5e7 diff --git a/libraries/libfc/libraries/bn256 b/libraries/libfc/libraries/bn256 index 4fe51c043d..63c6c9919c 160000 --- a/libraries/libfc/libraries/bn256 +++ b/libraries/libfc/libraries/bn256 @@ -1 +1 @@ -Subproject commit 4fe51c043d86798fa9bab7015e4d48d1722a9fa5 +Subproject commit 63c6c9919c98a76c23209a321a7d006c4f44ce53 diff --git a/tests/abieos b/tests/abieos index 06fac05851..08145090b6 160000 --- a/tests/abieos +++ b/tests/abieos @@ -1 +1 @@ -Subproject commit 06fac058514378aa491056f8613d4c739ff89fdb +Subproject commit 08145090b6407b91fbab5721b624d2b3001ef84f From bcbd4a4850cb0640014b0181fa4844574972b214 Mon Sep 17 00:00:00 2001 From: mschoenebeck Date: Wed, 24 May 2023 02:39:23 -0500 Subject: [PATCH 08/79] sync with antelope/main --- libraries/appbase | 2 +- libraries/chainbase | 2 +- libraries/libfc/libraries/bn256 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/appbase b/libraries/appbase index 54cc7fb4f9..9c57bbbee4 160000 --- a/libraries/appbase +++ b/libraries/appbase @@ -1 +1 @@ -Subproject commit 54cc7fb4f9a3dbbe2c71bdf23f9342c9c01b9673 +Subproject commit 9c57bbbee43dbc7f46a558760086b6e8bf8f2940 diff --git a/libraries/chainbase b/libraries/chainbase index c1d30da95c..0cc3c62aa6 160000 --- a/libraries/chainbase +++ b/libraries/chainbase @@ -1 +1 @@ -Subproject commit c1d30da95c9f5e2e80d32732d3063671ff23b123 +Subproject commit 0cc3c62aa641ea89e4f89e61eb2662fd4da92684 diff --git a/libraries/libfc/libraries/bn256 b/libraries/libfc/libraries/bn256 index da781dbd15..63c6c9919c 160000 --- a/libraries/libfc/libraries/bn256 +++ b/libraries/libfc/libraries/bn256 @@ -1 +1 @@ -Subproject commit da781dbd15c23b53339240f21458c7ae2ad061c4 +Subproject commit 63c6c9919c98a76c23209a321a7d006c4f44ce53 From 362c3eaefc35e96f4192362cc65162772e6c59b6 Mon Sep 17 00:00:00 2001 From: mschoenebeck Date: Wed, 24 May 2023 02:42:30 -0500 Subject: [PATCH 09/79] updated submodules --- libraries/appbase | 2 +- libraries/libfc/libraries/bn256 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/appbase b/libraries/appbase index 9c57bbbee4..54cc7fb4f9 160000 --- a/libraries/appbase +++ b/libraries/appbase @@ -1 +1 @@ -Subproject commit 9c57bbbee43dbc7f46a558760086b6e8bf8f2940 +Subproject commit 54cc7fb4f9a3dbbe2c71bdf23f9342c9c01b9673 diff --git a/libraries/libfc/libraries/bn256 b/libraries/libfc/libraries/bn256 index 63c6c9919c..da781dbd15 160000 --- a/libraries/libfc/libraries/bn256 +++ b/libraries/libfc/libraries/bn256 @@ -1 +1 @@ -Subproject commit 63c6c9919c98a76c23209a321a7d006c4f44ce53 +Subproject commit da781dbd15c23b53339240f21458c7ae2ad061c4 From c931460b542aceb95f4905224145b01d8d4088d4 Mon Sep 17 00:00:00 2001 From: mschoenebeck Date: Wed, 24 May 2023 05:18:54 -0500 Subject: [PATCH 10/79] removed bls types from abi_serializer --- libraries/chain/abi_serializer.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/libraries/chain/abi_serializer.cpp b/libraries/chain/abi_serializer.cpp index 246e447a59..c06c6a4fb4 100644 --- a/libraries/chain/abi_serializer.cpp +++ b/libraries/chain/abi_serializer.cpp @@ -127,13 +127,6 @@ namespace eosio { namespace chain { built_in_types.emplace("symbol_code", pack_unpack()); built_in_types.emplace("asset", pack_unpack()); built_in_types.emplace("extended_asset", pack_unpack()); - - built_in_types.emplace("bls_scalar", pack_unpack_deadline()); - built_in_types.emplace("bls_g1", pack_unpack_deadline()); - built_in_types.emplace("bls_g2", pack_unpack_deadline()); - built_in_types.emplace("bls_gt", pack_unpack_deadline()); - built_in_types.emplace("bls_fp", pack_unpack_deadline()); - built_in_types.emplace("bls_fp2", pack_unpack_deadline()); } void abi_serializer::set_abi(abi_def abi, const yield_function_t& yield) { From 1a350398899c380b5d1ae95fe8c684de91c6e179 Mon Sep 17 00:00:00 2001 From: mschoenebeck Date: Wed, 24 May 2023 05:57:47 -0500 Subject: [PATCH 11/79] removed bls typedefs from types.hpp and deleted bls_utils.hpp/cpp --- libraries/chain/controller.cpp | 1 + libraries/chain/include/eosio/chain/types.hpp | 8 -- libraries/chain/webassembly/crypto.cpp | 2 +- libraries/libfc/CMakeLists.txt | 1 - .../libfc/include/fc/crypto/bls_utils.hpp | 35 --------- libraries/libfc/src/crypto/bls_utils.cpp | 77 ------------------- libraries/libfc/test/crypto/test_bls.cpp | 2 +- 7 files changed, 3 insertions(+), 123 deletions(-) delete mode 100644 libraries/libfc/include/fc/crypto/bls_utils.hpp delete mode 100644 libraries/libfc/src/crypto/bls_utils.cpp diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index 36c271e2d0..a36629e793 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include diff --git a/libraries/chain/include/eosio/chain/types.hpp b/libraries/chain/include/eosio/chain/types.hpp index 20ac20ee41..0d12de8158 100644 --- a/libraries/chain/include/eosio/chain/types.hpp +++ b/libraries/chain/include/eosio/chain/types.hpp @@ -15,7 +15,6 @@ #include #include #include -#include #include #include @@ -78,13 +77,6 @@ namespace eosio::chain { using private_key_type = fc::crypto::private_key; using signature_type = fc::crypto::signature; - using bls_scalar_type = std::array; - using bls_g1_type = bls12_381::g1; - using bls_g2_type = bls12_381::g2; - using bls_gt_type = bls12_381::fp12; - using bls_fp_type = bls12_381::fp; - using bls_fp2_type = bls12_381::fp2; - // configurable boost deque (for boost >= 1.71) performs much better than std::deque in our use cases using block_1024_option_t = boost::container::deque_options< boost::container::block_size<1024u> >::type; template diff --git a/libraries/chain/webassembly/crypto.cpp b/libraries/chain/webassembly/crypto.cpp index db1bedf972..86adf504bb 100644 --- a/libraries/chain/webassembly/crypto.cpp +++ b/libraries/chain/webassembly/crypto.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include namespace { uint32_t ceil_log2(uint32_t n) diff --git a/libraries/libfc/CMakeLists.txt b/libraries/libfc/CMakeLists.txt index 720f26558f..510fa14a7e 100644 --- a/libraries/libfc/CMakeLists.txt +++ b/libraries/libfc/CMakeLists.txt @@ -56,7 +56,6 @@ set( fc_sources src/crypto/modular_arithmetic.cpp src/crypto/blake2.cpp src/crypto/k1_recover.cpp - src/crypto/bls_utils.cpp src/network/url.cpp src/network/http/http_client.cpp src/compress/zlib.cpp diff --git a/libraries/libfc/include/fc/crypto/bls_utils.hpp b/libraries/libfc/include/fc/crypto/bls_utils.hpp deleted file mode 100644 index 960a8ba00e..0000000000 --- a/libraries/libfc/include/fc/crypto/bls_utils.hpp +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include "../../../libraries/bls12_381/include/bls12_381.hpp" -#include - -namespace fc { - void to_variant(const bls12_381::g1& var, variant& vo, const fc::yield_function_t& yield = fc::yield_function_t()); - void from_variant(const variant& var, bls12_381::g1& vo); - - void to_variant(const bls12_381::g2& var, variant& vo, const fc::yield_function_t& yield = fc::yield_function_t()); - void from_variant(const variant& var, bls12_381::g2& vo); - - void to_variant(const bls12_381::fp& var, variant& vo, const fc::yield_function_t& yield = fc::yield_function_t()); - void from_variant(const variant& var, bls12_381::fp& vo); - - void to_variant(const bls12_381::fp2& var, variant& vo, const fc::yield_function_t& yield = fc::yield_function_t()); - void from_variant(const variant& var, bls12_381::fp2& vo); - - void to_variant(const bls12_381::fp6& var, variant& vo, const fc::yield_function_t& yield = fc::yield_function_t()); - void from_variant(const variant& var, bls12_381::fp6& vo); - - void to_variant(const bls12_381::fp12& var, variant& vo, const fc::yield_function_t& yield = fc::yield_function_t()); - void from_variant(const variant& var, bls12_381::fp12& vo); - - void to_variant(const std::array& var, variant& vo, const fc::yield_function_t& yield = fc::yield_function_t()); - void from_variant(const variant& var, std::array& vo); -} // namespace fc - -FC_REFLECT(bls12_381::g1, (x)(y)(z) ) -FC_REFLECT(bls12_381::g2, (x)(y)(z) ) -FC_REFLECT(bls12_381::fp, (d) ) -FC_REFLECT(bls12_381::fp2, (c0)(c1) ) -FC_REFLECT(bls12_381::fp6, (c0)(c1)(c2) ) -FC_REFLECT(bls12_381::fp12, (c0)(c1) ) - diff --git a/libraries/libfc/src/crypto/bls_utils.cpp b/libraries/libfc/src/crypto/bls_utils.cpp deleted file mode 100644 index ce85dba0b9..0000000000 --- a/libraries/libfc/src/crypto/bls_utils.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include - -using namespace bls12_381; - -namespace fc { - - void to_variant(const bls12_381::g1& var, fc::variant& vo, const fc::yield_function_t& yield) - { - vo = bytesToHex<144>(var.toJacobianBytesLE(true)); - } - - void from_variant(const fc::variant& var, bls12_381::g1& vo) - { - vo = g1::fromJacobianBytesLE(hexToBytes(var.as_string()), false, true); - } - - void to_variant(const bls12_381::g2& var, fc::variant& vo, const fc::yield_function_t& yield) - { - vo = bytesToHex<288>(var.toJacobianBytesLE(true)); - } - - void from_variant(const fc::variant& var, bls12_381::g2& vo) - { - vo = g2::fromJacobianBytesLE(hexToBytes(var.as_string()), false, true); - } - - void to_variant(const bls12_381::fp& var, fc::variant& vo, const fc::yield_function_t& yield) - { - vo = bytesToHex<48>(var.toBytesLE(true)); - } - - void from_variant(const fc::variant& var, bls12_381::fp& vo) - { - vo = fp::fromBytesLE(hexToBytes(var.as_string()), false, true); - } - - void to_variant(const bls12_381::fp2& var, fc::variant& vo, const fc::yield_function_t& yield) - { - vo = bytesToHex<96>(var.toBytesLE(true)); - } - - void from_variant(const fc::variant& var, bls12_381::fp2& vo) - { - vo = fp2::fromBytesLE(hexToBytes(var.as_string()), false, true); - } - - void to_variant(const bls12_381::fp6& var, fc::variant& vo, const fc::yield_function_t& yield) - { - vo = bytesToHex<288>(var.toBytesLE(true)); - } - - void from_variant(const fc::variant& var, bls12_381::fp6& vo) - { - vo = fp6::fromBytesLE(hexToBytes(var.as_string()), false, true); - } - - void to_variant(const bls12_381::fp12& var, fc::variant& vo, const fc::yield_function_t& yield) - { - vo = bytesToHex<576>(var.toBytesLE(true)); - } - - void from_variant(const fc::variant& var, bls12_381::fp12& vo) - { - vo = fp12::fromBytesLE(hexToBytes(var.as_string()), false, true); - } - - void to_variant(const std::array& var, fc::variant& vo, const fc::yield_function_t& yield) - { - vo = bytesToHex<32>(scalar::toBytesLE<4>(var)); - } - - void from_variant(const fc::variant& var, std::array& vo) - { - vo = scalar::fromBytesLE<4>(hexToBytes(var.as_string())); - } -} - diff --git a/libraries/libfc/test/crypto/test_bls.cpp b/libraries/libfc/test/crypto/test_bls.cpp index bac774fb91..41ab3d95b5 100644 --- a/libraries/libfc/test/crypto/test_bls.cpp +++ b/libraries/libfc/test/crypto/test_bls.cpp @@ -1,6 +1,6 @@ #include -#include +#include #include using namespace std; From 8f7d439f6253fb42a2acf126661f4d41aa63b335 Mon Sep 17 00:00:00 2001 From: mschoenebeck Date: Wed, 7 Jun 2023 18:13:38 -0500 Subject: [PATCH 12/79] update according to Github comments --- .../eosio/chain/webassembly/interface.hpp | 30 ++- libraries/chain/webassembly/crypto.cpp | 178 +++++++++++------- libraries/libfc/libraries/bls12_381 | 2 +- 3 files changed, 128 insertions(+), 82 deletions(-) diff --git a/libraries/chain/include/eosio/chain/webassembly/interface.hpp b/libraries/chain/include/eosio/chain/webassembly/interface.hpp index 10e271d73e..59fac5078a 100644 --- a/libraries/chain/include/eosio/chain/webassembly/interface.hpp +++ b/libraries/chain/include/eosio/chain/webassembly/interface.hpp @@ -1792,8 +1792,9 @@ namespace webassembly { * @param op1 - a span containing the first operand G1 point. * @param op2 - a span containing the second operand G1 point. * @param[out] result - the result op1 + op2. + * @return -1 if there was an error 0 otherwise */ - void bls_g1_add(span op1, span op2, span result) const; + int32_t bls_g1_add(span op1, span op2, span result) const; /** * Host function for G2 addition on the elliptic curve bls12-381 @@ -1802,8 +1803,9 @@ namespace webassembly { * @param op1 - a span containing the first operand G2 point. * @param op2 - a span containing the second operand G2 point. * @param[out] result - the result op1 + op2. + * @return -1 if there was an error 0 otherwise */ - void bls_g2_add(span op1, span op2, span result) const; + int32_t bls_g2_add(span op1, span op2, span result) const; /** * Host function for G1 scalar multiplication on the elliptic curve bls12-381 @@ -1812,8 +1814,9 @@ namespace webassembly { * @param point - a span containing the G1 point operand. * @param scalar - a span containing the scalar operand. * @param[out] result - the result: scalar * point. + * @return -1 if there was an error 0 otherwise */ - void bls_g1_mul(span point, span scalar, span result) const; + int32_t bls_g1_mul(span point, span scalar, span result) const; /** * Host function for G2 scalar multiplication on the elliptic curve bls12-381 @@ -1822,8 +1825,9 @@ namespace webassembly { * @param point - a span containing the G2 point operand. * @param scalar - a span containing the scalar operand. * @param[out] result - the result op1 * op2. + * @return -1 if there was an error 0 otherwise */ - void bls_g2_mul(span point, span scalar, span result) const; + int32_t bls_g2_mul(span point, span scalar, span result) const; /** * Host function for G1 multi-exponentiation on the elliptic curve bls12-381 @@ -1833,8 +1837,9 @@ namespace webassembly { * @param scalars - a span containing a list of scalars (s0, s1, s2... sn). * @param n - the number of elements in the lists. * @param[out] result - the result s0 * P0 + s1 * P1 + ... + sn * Pn. + * @return -1 if there was an error 0 otherwise */ - void bls_g1_exp(span points, span scalars, const uint32_t n, span result) const; + int32_t bls_g1_exp(span points, span scalars, const uint32_t n, span result) const; /** * Host function for G2 multi-exponentiation on the elliptic curve bls12-381 @@ -1844,8 +1849,9 @@ namespace webassembly { * @param scalars - a span containing a list of scalars (s0, s1, s2... sn). * @param n - the number of elements in the lists. * @param[out] result - the result s0 * P0 + s1 * P1 + ... + sn * Pn. + * @return -1 if there was an error 0 otherwise */ - void bls_g2_exp(span points, span scalars, const uint32_t n, span result) const; + int32_t bls_g2_exp(span points, span scalars, const uint32_t n, span result) const; /** * Host function to calculate the pairing of (G1, G2) pairs on the elliptic curve bls12-381 @@ -1855,8 +1861,9 @@ namespace webassembly { * @param g2_points - a span containing a list of G2 points (P0, P1, P2... Pn). * @param n - the number of elements in the lists. * @param[out] result - the result e(g1_0, g2_0) * e(g1_1, g2_1) * ... * e(g1_n, g2_n) + * @return -1 if there was an error 0 otherwise */ - void bls_pairing(span g1_points, span g2_points, const uint32_t n, span result) const; + int32_t bls_pairing(span g1_points, span g2_points, const uint32_t n, span result) const; /** * Host function for mapping fp to G1 on the elliptic curve bls12-381 @@ -1864,8 +1871,9 @@ namespace webassembly { * @ingroup crypto * @param e - a span containing the field element fp to be mapped. * @param[out] result - the resulting element in G1. + * @return -1 if there was an error 0 otherwise */ - void bls_g1_map(span e, span result) const; + int32_t bls_g1_map(span e, span result) const; /** * Host function for mapping fp2 to G2 on the elliptic curve bls12-381 @@ -1873,8 +1881,9 @@ namespace webassembly { * @ingroup crypto * @param e - a span containing the field element fp2 to be mapped. * @param[out] result - the resulting element in G2. + * @return -1 if there was an error 0 otherwise */ - void bls_g2_map(span e, span result) const; + int32_t bls_g2_map(span e, span result) const; /** * Host function for modular reduction of 64 bytes wide scalar to a field element (fp, 48 bytes) of the elliptic curve bls12-381 @@ -1883,8 +1892,9 @@ namespace webassembly { * @ingroup crypto * @param s - a span containing the 64 bytes wide scalar to be reduced. * @param[out] result - the resulting field element fp in Montogomery form. + * @return -1 if there was an error 0 otherwise */ - void bls_fp_mod(span s, span result) const; + int32_t bls_fp_mod(span s, span result) const; // compiler builtins api void __ashlti3(legacy_ptr, uint64_t, uint64_t, uint32_t) const; diff --git a/libraries/chain/webassembly/crypto.cpp b/libraries/chain/webassembly/crypto.cpp index 86adf504bb..cadb9fbeb7 100644 --- a/libraries/chain/webassembly/crypto.cpp +++ b/libraries/chain/webassembly/crypto.cpp @@ -251,105 +251,141 @@ namespace eosio { namespace chain { namespace webassembly { return return_code::success; } - void interface::bls_g1_add(span op1, span op2, span result) const + int32_t interface::bls_g1_add(span op1, span op2, span result) const { - bls12_381::g1 a = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(op1.data()), 144}, false, true); - bls12_381::g1 b = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(op2.data()), 144}, false, true); - bls12_381::g1 c = a.add(b); - c.toJacobianBytesLE({reinterpret_cast(result.data()), 144}, true); + if(op1.size() != 144 || op2.size() != 144 || result.size() != 144) + return return_code::failure; + bls12_381::g1 a = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(op1.data()), 144}, false, true); + bls12_381::g1 b = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(op2.data()), 144}, false, true); + bls12_381::g1 c = a.add(b); + c.toJacobianBytesLE({reinterpret_cast(result.data()), 144}, true); + return return_code::success; } - void interface::bls_g2_add(span op1, span op2, span result) const + int32_t interface::bls_g2_add(span op1, span op2, span result) const { - bls12_381::g2 a = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(op1.data()), 288}, false, true); - bls12_381::g2 b = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(op2.data()), 288}, false, true); - bls12_381::g2 c = a.add(b); - c.toJacobianBytesLE({reinterpret_cast(result.data()), 288}, true); + if(op1.size() != 288 || op2.size() != 288 || result.size() != 288) + return return_code::failure; + bls12_381::g2 a = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(op1.data()), 288}, false, true); + bls12_381::g2 b = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(op2.data()), 288}, false, true); + bls12_381::g2 c = a.add(b); + c.toJacobianBytesLE({reinterpret_cast(result.data()), 288}, true); + return return_code::success; } - void interface::bls_g1_mul(span point, span scalar, span result) const + int32_t interface::bls_g1_mul(span point, span scalar, span result) const { - bls12_381::g1 a = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(point.data()), 144}, false, true); - std::array b = bls12_381::scalar::fromBytesLE<4>({reinterpret_cast(scalar.data()), 32}); - bls12_381::g1 c = a.mulScalar(b); - c.toJacobianBytesLE({reinterpret_cast(result.data()), 144}, true); + if(point.size() != 144 || scalar.size() != 32 || result.size() != 144) + return return_code::failure; + bls12_381::g1 a = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(point.data()), 144}, false, true); + std::array b = bls12_381::scalar::fromBytesLE<4>({reinterpret_cast(scalar.data()), 32}); + bls12_381::g1 c = a.mulScalar(b); + c.toJacobianBytesLE({reinterpret_cast(result.data()), 144}, true); + return return_code::success; } - void interface::bls_g2_mul(span point, span scalar, span result) const + int32_t interface::bls_g2_mul(span point, span scalar, span result) const { - bls12_381::g2 a = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(point.data()), 288}, false, true); - std::array b = bls12_381::scalar::fromBytesLE<4>({reinterpret_cast(scalar.data()), 32}); - bls12_381::g2 c = a.mulScalar(b); - c.toJacobianBytesLE({reinterpret_cast(result.data()), 288}, true); + if(point.size() != 288 || scalar.size() != 32 || result.size() != 288) + return return_code::failure; + bls12_381::g2 a = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(point.data()), 288}, false, true); + std::array b = bls12_381::scalar::fromBytesLE<4>({reinterpret_cast(scalar.data()), 32}); + bls12_381::g2 c = a.mulScalar(b); + c.toJacobianBytesLE({reinterpret_cast(result.data()), 288}, true); + return return_code::success; } - void interface::bls_g1_exp(span points, span scalars, const uint32_t n, span result) const + int32_t interface::bls_g1_exp(span points, span scalars, const uint32_t n, span result) const { - std::vector pv; - std::vector> sv; - pv.reserve(n); - sv.reserve(n); - for(uint32_t i = 0; i < n; i++) - { - bls12_381::g1 p = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(points.data() + i*144), 144}, false, true); - std::array s = bls12_381::scalar::fromBytesLE<4>({reinterpret_cast(scalars.data() + i*32), 32}); - pv.push_back(p); - sv.push_back(s); - } - bls12_381::g1 r = bls12_381::g1::multiExp(pv, sv); - r.toJacobianBytesLE({reinterpret_cast(result.data()), 144}, true); + if(points.size() != n*144 || scalars.size() != n*32 || result.size() != 144) + return return_code::failure; + std::vector pv; + std::vector> sv; + pv.reserve(n); + sv.reserve(n); + for(uint32_t i = 0; i < n; i++) + { + bls12_381::g1 p = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(points.data() + i*144), 144}, false, true); + std::array s = bls12_381::scalar::fromBytesLE<4>({reinterpret_cast(scalars.data() + i*32), 32}); + pv.push_back(p); + sv.push_back(s); + if(i%10 == 0) + context.trx_context.checktime(); + } + bls12_381::g1 r = bls12_381::g1::multiExp(pv, sv); + r.toJacobianBytesLE({reinterpret_cast(result.data()), 144}, true); + return return_code::success; } - void interface::bls_g2_exp(span points, span scalars, const uint32_t n, span result) const + int32_t interface::bls_g2_exp(span points, span scalars, const uint32_t n, span result) const { - std::vector pv; - std::vector> sv; - pv.reserve(n); - sv.reserve(n); - for(uint32_t i = 0; i < n; i++) - { - bls12_381::g2 p = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(points.data() + i*288), 288}, false, true); - std::array s = bls12_381::scalar::fromBytesLE<4>({reinterpret_cast(scalars.data() + i*32), 32}); - pv.push_back(p); - sv.push_back(s); - } - bls12_381::g2 r = bls12_381::g2::multiExp(pv, sv); - r.toJacobianBytesLE({reinterpret_cast(result.data()), 288}, true); + if(points.size() != n*288 || scalars.size() != n*32 || result.size() != 288) + return return_code::failure; + std::vector pv; + std::vector> sv; + pv.reserve(n); + sv.reserve(n); + for(uint32_t i = 0; i < n; i++) + { + bls12_381::g2 p = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(points.data() + i*288), 288}, false, true); + std::array s = bls12_381::scalar::fromBytesLE<4>({reinterpret_cast(scalars.data() + i*32), 32}); + pv.push_back(p); + sv.push_back(s); + if(i%6 == 0) + context.trx_context.checktime(); + } + bls12_381::g2 r = bls12_381::g2::multiExp(pv, sv); + r.toJacobianBytesLE({reinterpret_cast(result.data()), 288}, true); + return return_code::success; } - void interface::bls_pairing(span g1_points, span g2_points, const uint32_t n, span result) const + int32_t interface::bls_pairing(span g1_points, span g2_points, const uint32_t n, span result) const { - std::vector> v; - v.reserve(n); - for(uint32_t i = 0; i < n; i++) - { - bls12_381::g1 p_g1 = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(g1_points.data() + i*144), 144}, false, true); - bls12_381::g2 p_g2 = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(g2_points.data() + i*288), 288}, false, true); - bls12_381::pairing::add_pair(v, p_g1, p_g2); - } - bls12_381::fp12 r = bls12_381::pairing::calculate(v); - r.toBytesLE({reinterpret_cast(result.data()), 576}, true); + if(g1_points.size() != n*144 || g2_points.size() != n*288 || result.size() != 576) + return return_code::failure; + std::vector> v; + v.reserve(n); + for(uint32_t i = 0; i < n; i++) + { + bls12_381::g1 p_g1 = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(g1_points.data() + i*144), 144}, false, true); + bls12_381::g2 p_g2 = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(g2_points.data() + i*288), 288}, false, true); + bls12_381::pairing::add_pair(v, p_g1, p_g2); + if(i%4 == 0) + context.trx_context.checktime(); + } + bls12_381::fp12 r = bls12_381::pairing::calculate(v); + r.toBytesLE({reinterpret_cast(result.data()), 576}, true); + return return_code::success; } - void interface::bls_g1_map(span e, span result) const + int32_t interface::bls_g1_map(span e, span result) const { - bls12_381::fp a = bls12_381::fp::fromBytesLE({reinterpret_cast(e.data()), 48}, false, true); - bls12_381::g1 c = bls12_381::g1::mapToCurve(a); - c.toJacobianBytesLE({reinterpret_cast(result.data()), 144}, true); + if(e.size() != 48 || result.size() != 144) + return return_code::failure; + bls12_381::fp a = bls12_381::fp::fromBytesLE({reinterpret_cast(e.data()), 48}, false, true); + bls12_381::g1 c = bls12_381::g1::mapToCurve(a); + c.toJacobianBytesLE({reinterpret_cast(result.data()), 144}, true); + return return_code::success; } - void interface::bls_g2_map(span e, span result) const + int32_t interface::bls_g2_map(span e, span result) const { - bls12_381::fp2 a = bls12_381::fp2::fromBytesLE({reinterpret_cast(e.data()), 96}, false, true); - bls12_381::g2 c = bls12_381::g2::mapToCurve(a); - c.toJacobianBytesLE({reinterpret_cast(result.data()), 288}, true); + if(e.size() != 96 || result.size() != 288) + return return_code::failure; + bls12_381::fp2 a = bls12_381::fp2::fromBytesLE({reinterpret_cast(e.data()), 96}, false, true); + bls12_381::g2 c = bls12_381::g2::mapToCurve(a); + c.toJacobianBytesLE({reinterpret_cast(result.data()), 288}, true); + return return_code::success; } - void interface::bls_fp_mod(span s, span result) const + int32_t interface::bls_fp_mod(span s, span result) const { - std::array k = bls12_381::scalar::fromBytesLE<8>({reinterpret_cast(s.data()), 64}); - bls12_381::fp e = bls12_381::fp::modPrime<8>(k); - e.toBytesLE({reinterpret_cast(result.data()), 48}, true); + if(s.size() != 64 || result.size() != 48) + return return_code::failure; + std::array k = bls12_381::scalar::fromBytesLE<8>({reinterpret_cast(s.data()), 64}); + bls12_381::fp e = bls12_381::fp::modPrime<8>(k); + e.toBytesLE({reinterpret_cast(result.data()), 48}, true); + return return_code::success; } }}} // ns eosio::chain::webassembly diff --git a/libraries/libfc/libraries/bls12_381 b/libraries/libfc/libraries/bls12_381 index f9b18366d6..a6174ec151 160000 --- a/libraries/libfc/libraries/bls12_381 +++ b/libraries/libfc/libraries/bls12_381 @@ -1 +1 @@ -Subproject commit f9b18366d6f18b64bdf99a1b41166e20a1e63ed5 +Subproject commit a6174ec15175bc4076feb7b7b9cdedc5c80fa7e7 From 76c82ae5fba0a4bc1bced7d1528f4300ec3e8b81 Mon Sep 17 00:00:00 2001 From: mschoenebeck Date: Thu, 8 Jun 2023 03:13:43 -0500 Subject: [PATCH 13/79] updated bls12_381::init() --- libraries/libfc/libraries/bls12_381 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/libfc/libraries/bls12_381 b/libraries/libfc/libraries/bls12_381 index a6174ec151..913efe61e5 160000 --- a/libraries/libfc/libraries/bls12_381 +++ b/libraries/libfc/libraries/bls12_381 @@ -1 +1 @@ -Subproject commit a6174ec15175bc4076feb7b7b9cdedc5c80fa7e7 +Subproject commit 913efe61e5055901e877b640bda369bf83825277 From 06411fa037523aadc780b855a7f04951635cb40d Mon Sep 17 00:00:00 2001 From: mschoenebeck Date: Sat, 10 Jun 2023 04:35:09 -0500 Subject: [PATCH 14/79] added yield() to pairing::calculate and g2::multiExp --- libraries/chain/include/eosio/chain/types.hpp | 2 +- libraries/chain/webassembly/crypto.cpp | 4 ++-- libraries/libfc/libraries/bls12_381 | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/chain/include/eosio/chain/types.hpp b/libraries/chain/include/eosio/chain/types.hpp index 0d12de8158..99466395d7 100644 --- a/libraries/chain/include/eosio/chain/types.hpp +++ b/libraries/chain/include/eosio/chain/types.hpp @@ -76,7 +76,7 @@ namespace eosio::chain { using public_key_type = fc::crypto::public_key; using private_key_type = fc::crypto::private_key; using signature_type = fc::crypto::signature; - + // configurable boost deque (for boost >= 1.71) performs much better than std::deque in our use cases using block_1024_option_t = boost::container::deque_options< boost::container::block_size<1024u> >::type; template diff --git a/libraries/chain/webassembly/crypto.cpp b/libraries/chain/webassembly/crypto.cpp index cadb9fbeb7..15fcfdc8f6 100644 --- a/libraries/chain/webassembly/crypto.cpp +++ b/libraries/chain/webassembly/crypto.cpp @@ -334,7 +334,7 @@ namespace eosio { namespace chain { namespace webassembly { if(i%6 == 0) context.trx_context.checktime(); } - bls12_381::g2 r = bls12_381::g2::multiExp(pv, sv); + bls12_381::g2 r = bls12_381::g2::multiExp(pv, sv, [this](){ context.trx_context.checktime(); }); r.toJacobianBytesLE({reinterpret_cast(result.data()), 288}, true); return return_code::success; } @@ -353,7 +353,7 @@ namespace eosio { namespace chain { namespace webassembly { if(i%4 == 0) context.trx_context.checktime(); } - bls12_381::fp12 r = bls12_381::pairing::calculate(v); + bls12_381::fp12 r = bls12_381::pairing::calculate(v, [this](){ context.trx_context.checktime(); }); r.toBytesLE({reinterpret_cast(result.data()), 576}, true); return return_code::success; } diff --git a/libraries/libfc/libraries/bls12_381 b/libraries/libfc/libraries/bls12_381 index 913efe61e5..59317bddde 160000 --- a/libraries/libfc/libraries/bls12_381 +++ b/libraries/libfc/libraries/bls12_381 @@ -1 +1 @@ -Subproject commit 913efe61e5055901e877b640bda369bf83825277 +Subproject commit 59317bddde415888d8fc8d81a5018fb5206a8c11 From 8a0e21f83798387308006de04c018578feaa547b Mon Sep 17 00:00:00 2001 From: mschoenebeck Date: Wed, 14 Jun 2023 09:16:51 -0500 Subject: [PATCH 15/79] renamed bls lib --- .gitmodules | 6 +++--- libraries/chain/controller.cpp | 2 +- libraries/chain/webassembly/crypto.cpp | 2 +- libraries/libfc/CMakeLists.txt | 4 ++-- libraries/libfc/libraries/bls12-381 | 1 + libraries/libfc/libraries/bls12_381 | 1 - libraries/libfc/test/crypto/test_bls.cpp | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) create mode 160000 libraries/libfc/libraries/bls12-381 delete mode 160000 libraries/libfc/libraries/bls12_381 diff --git a/.gitmodules b/.gitmodules index b6fa0f19dd..92187b7715 100644 --- a/.gitmodules +++ b/.gitmodules @@ -31,6 +31,6 @@ [submodule "libraries/cli11/cli11"] path = libraries/cli11/cli11 url = https://github.com/AntelopeIO/CLI11.git -[submodule "libraries/libfc/libraries/bls12_381"] - path = libraries/libfc/libraries/bls12_381 - url = https://github.com/mschoenebeck/bls12_381.git +[submodule "libraries/libfc/libraries/bls12-381"] + path = libraries/libfc/libraries/bls12-381 + url = https://github.com/mschoenebeck/bls12-381.git diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index a36629e793..de1e5c9d33 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include diff --git a/libraries/chain/webassembly/crypto.cpp b/libraries/chain/webassembly/crypto.cpp index 15fcfdc8f6..937e2fe298 100644 --- a/libraries/chain/webassembly/crypto.cpp +++ b/libraries/chain/webassembly/crypto.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include namespace { uint32_t ceil_log2(uint32_t n) diff --git a/libraries/libfc/CMakeLists.txt b/libraries/libfc/CMakeLists.txt index 510fa14a7e..25d91827e3 100644 --- a/libraries/libfc/CMakeLists.txt +++ b/libraries/libfc/CMakeLists.txt @@ -1,6 +1,6 @@ add_subdirectory( secp256k1 ) add_subdirectory( libraries/bn256/src ) -add_subdirectory( libraries/bls12_381 ) +add_subdirectory( libraries/bls12-381 ) set(CMAKE_THREAD_PREFER_PTHREAD TRUE) set(THREADS_PREFER_PTHREAD_FLAG TRUE) @@ -132,7 +132,7 @@ if(APPLE) find_library(corefoundation_framework CoreFoundation) endif() target_link_libraries( fc PUBLIC Boost::date_time Boost::chrono Boost::iostreams Threads::Threads - OpenSSL::Crypto ZLIB::ZLIB ${PLATFORM_SPECIFIC_LIBS} ${CMAKE_DL_LIBS} secp256k1 bls12_381 ${security_framework} ${corefoundation_framework}) + OpenSSL::Crypto ZLIB::ZLIB ${PLATFORM_SPECIFIC_LIBS} ${CMAKE_DL_LIBS} secp256k1 bls12-381 ${security_framework} ${corefoundation_framework}) # Critically, this ensures that OpenSSL 1.1 & 3.0 both have a variant of BN_zero() with void return value. But it also allows access # to some obsoleted AES functions in 3.0 too, since 3.0's API_COMPAT is effectively 3.0 by default diff --git a/libraries/libfc/libraries/bls12-381 b/libraries/libfc/libraries/bls12-381 new file mode 160000 index 0000000000..d8c21132eb --- /dev/null +++ b/libraries/libfc/libraries/bls12-381 @@ -0,0 +1 @@ +Subproject commit d8c21132ebb6f0f13aa36286f794f344ea33992c diff --git a/libraries/libfc/libraries/bls12_381 b/libraries/libfc/libraries/bls12_381 deleted file mode 160000 index 59317bddde..0000000000 --- a/libraries/libfc/libraries/bls12_381 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 59317bddde415888d8fc8d81a5018fb5206a8c11 diff --git a/libraries/libfc/test/crypto/test_bls.cpp b/libraries/libfc/test/crypto/test_bls.cpp index 41ab3d95b5..3e8853a171 100644 --- a/libraries/libfc/test/crypto/test_bls.cpp +++ b/libraries/libfc/test/crypto/test_bls.cpp @@ -1,6 +1,6 @@ #include -#include +#include #include using namespace std; From 81020c3ed74e931edbeb38b141096765c59e2772 Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Wed, 14 Jun 2023 16:42:31 -0400 Subject: [PATCH 16/79] regenerate deepmind log for new BLS_PRIMITIVES --- unittests/deep-mind/deep-mind.log | 91 ++++++++++++++++--------------- 1 file changed, 48 insertions(+), 43 deletions(-) diff --git a/unittests/deep-mind/deep-mind.log b/unittests/deep-mind/deep-mind.log index 27f01404ec..957f5e2867 100644 --- a/unittests/deep-mind/deep-mind.log +++ b/unittests/deep-mind/deep-mind.log @@ -34,11 +34,11 @@ DMLOG START_BLOCK 3 DMLOG CREATION_OP ROOT 0 DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304002,"value_ex":0,"consumed":0},"cpu_usage":{"last_ordinal":1262304002,"value_ex":1157,"consumed":101},"ram_usage":2724} DMLOG TRX_OP CREATE onblock da9fbe9042e1bc9bd64d7a4506534d492107a29f79ad671c1fea19ae3fb70eb4 01e10b5e02005132b41600000000010000000000ea305500000000221acfa4010000000000ea305500000000a8ed32329801013b3d4b0000000000ea30550000000000015ab65a885a31e441ac485ebd2aeba87bf7ee6e7bcc40bf3a24506ba1000000000000000000000000000000000000000000000000000000000000000062267e8b11d7d8f28e1f991a4de2b08cf92500861af2795765bdc9263cd6f4cd000000000001000021010ec7e080177b2c02b278d5088611686b49d739925a92d9bfcacd7fc6b74053bd000000 -DMLOG APPLIED_TRANSACTION 3 da9fbe9042e1bc9bd64d7a4506534d492107a29f79ad671c1fea19ae3fb70eb403000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd01006400000000000000000000000000000000000000000001010000010000000000ea3055ccfe3b56076237b0b6da2f580652ee1420231b96d3d96b28183769ac932c9e5902000000000000000200000000000000010000000000ea3055020000000000000000000000000000ea30550000000000ea305500000000221acfa4010000000000ea305500000000a8ed32329801013b3d4b0000000000ea30550000000000015ab65a885a31e441ac485ebd2aeba87bf7ee6e7bcc40bf3a24506ba1000000000000000000000000000000000000000000000000000000000000000062267e8b11d7d8f28e1f991a4de2b08cf92500861af2795765bdc9263cd6f4cd000000000001000021010ec7e080177b2c02b278d5088611686b49d739925a92d9bfcacd7fc6b74053bd00000000000000000000da9fbe9042e1bc9bd64d7a4506534d492107a29f79ad671c1fea19ae3fb70eb403000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0000000000000000 +DMLOG APPLIED_TRANSACTION 3 da9fbe9042e1bc9bd64d7a4506534d492107a29f79ad671c1fea19ae3fb70eb403000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b501006400000000000000000000000000000000000000000001010000010000000000ea3055ccfe3b56076237b0b6da2f580652ee1420231b96d3d96b28183769ac932c9e5902000000000000000200000000000000010000000000ea3055020000000000000000000000000000ea30550000000000ea305500000000221acfa4010000000000ea305500000000a8ed32329801013b3d4b0000000000ea30550000000000015ab65a885a31e441ac485ebd2aeba87bf7ee6e7bcc40bf3a24506ba1000000000000000000000000000000000000000000000000000000000000000062267e8b11d7d8f28e1f991a4de2b08cf92500861af2795765bdc9263cd6f4cd000000000001000021010ec7e080177b2c02b278d5088611686b49d739925a92d9bfcacd7fc6b74053bd00000000000000000000da9fbe9042e1bc9bd64d7a4506534d492107a29f79ad671c1fea19ae3fb70eb403000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50000000000000000 DMLOG CREATION_OP ROOT 0 DMLOG RAM_OP 0 eosio code add setcode eosio 180494 177770 DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304002,"value_ex":35325,"consumed":6104},"cpu_usage":{"last_ordinal":1262304002,"value_ex":12732,"consumed":2101},"ram_usage":180494} -DMLOG APPLIED_TRANSACTION 3 03917c562680b415b93db73416ff29230dfbe7ab1ba4d208b46029d01333cd3a03000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0100d0070000fb050000000000000000d8170000000000000001010000010000000000ea30559a90c525172f87bbac0a6378610727f0fe1d7ebe908df973923d29a1606f9a5703000000000000000300000000000000010000000000ea3055030000000000000001000000000000ea30550000000000ea305500000040258ab2c2010000000000ea305500000000a8ed3232fe8a010000000000ea30550000f18a010061736d01000000019d011a60000060037f7e7f0060027f7e0060027f7f0060057f7e7e7e7e0060047f7e7e7e0060017f017f60017f0060037f7f7f017f6000017f60027f7f017f60017e0060027e7f0060047e7e7e7e0060027f7f017e6000017e60047e7e7e7e017f60047f7e7e7f0060037f7f7f0060067e7e7e7e7f7f017f60047f7e7f7f0060037e7e7e0060037e7e7f017f60047f7f7e7f0060027e7e0060047f7f7f7f00028e041803656e761469735f666561747572655f616374697661746564000603656e761370726561637469766174655f66656174757265000703656e760c656f73696f5f617373657274000303656e76066d656d736574000803656e7610616374696f6e5f646174615f73697a65000903656e7610726561645f616374696f6e5f64617461000a03656e76066d656d637079000803656e760c726571756972655f61757468000b03656e760e7365745f70726976696c65676564000c03656e76137365745f7265736f757263655f6c696d697473000d03656e760561626f7274000003656e76167365745f70726f706f7365645f70726f647563657273000e03656e76207365745f626c6f636b636861696e5f706172616d65746572735f7061636b6564000303656e76206765745f626c6f636b636861696e5f706172616d65746572735f7061636b6564000a03656e760c63757272656e745f74696d65000f03656e76146765745f6163746976655f70726f647563657273000a03656e760b64625f66696e645f693634001003656e76095f5f6173686c746933001103656e7611656f73696f5f6173736572745f636f6465000203656e761063757272656e745f7265636569766572000f03656e760a64625f6765745f693634000803656e7606736861323536001203656e760c64625f73746f72655f693634001303656e760d64625f7570646174655f69363400140347460006070007090a08060607070a0a030307070a060715011602160316041603160316030516011603030a0a0a030a17170318181818181818180318181818031818181818081904050170010a0a05030100010616037f014180c0000b7f0041abc3000b7f0041abc3000b070901056170706c79002d090f010041010b092e30323436383a3b3d0ac98001460400101b0b800101037f02400240024002402000450d004100410028028c40200041107622016a220236028c404100410028028440220320006a41076a417871220036028440200241107420004d0d0120014000417f460d020c030b41000f0b4100200241016a36028c40200141016a4000417f470d010b4100419cc000100220030f0b20030b02000b3601017f230041106b2200410036020c4100200028020c28020041076a417871220036028440410020003602804041003f0036028c400b02000b06004190c0000bf50101067f4100210202400240410020006b22032000712000470d00200041104b0d01200110190f0b101d411636020041000f0b0240024002402000417f6a220420016a10192200450d002000200420006a2003712202460d012000417c6a220328020022044107712201450d02200020044178716a220441786a2205280200210620032001200220006b2207723602002002417c6a200420026b2203200172360200200241786a20064107712201200772360200200520012003723602002000101a0b20020f0b20000f0b200241786a200041786a280200200220006b22006a3602002002417c6a200328020020006b36020020020b3301017f411621030240024020014104490d0020012002101e2201450d0120002001360200410021030b20030f0b101d2802000b3801027f02402000410120001b2201101922000d000340410021004100280298402202450d012002110000200110192200450d000b0b20000b0600200010200b0e0002402000450d002000101a0b0b0600200010220b6b01027f230041106b2202240002402002410c6a20014104200141044b1b22012000410120001b2203101f450d00024003404100280298402200450d0120001100002002410c6a20012003101f0d000c020b0b2002410036020c0b200228020c2100200241106a240020000b08002000200110240b0e0002402000450d002000101a0b0b08002000200110260b0500100a000b4e01017f230041e0006b220124002001200141d8006a3602082001200141106a3602042001200141106a36020020012000102a1a200141106a200128020420012802006b100c200141e0006a24000b920901047f02402000280208200028020422026b41074a0d00410041e8c0001002200041046a28020021020b20022001410810061a200041046a2202200228020041086a2203360200200141086a21040240200041086a220528020020036b41034a0d00410041e8c0001002200228020021030b20032004410410061a2002200228020041046a22033602002001410c6a21020240200528020020036b41034a0d00410041e8c0001002200041046a28020021030b20032002410410061a200041046a2202200228020041046a2203360200200141106a21040240200041086a220528020020036b41034a0d00410041e8c0001002200228020021030b20032004410410061a2002200228020041046a2203360200200141146a21020240200528020020036b41034a0d00410041e8c0001002200041046a28020021030b20032002410410061a200041046a2202200228020041046a2203360200200141186a21040240200041086a220528020020036b41034a0d00410041e8c0001002200228020021030b20032004410410061a2002200228020041046a22033602002001411c6a21020240200528020020036b41034a0d00410041e8c0001002200041046a28020021030b20032002410410061a200041046a2202200228020041046a2203360200200141206a21040240200041086a220528020020036b41034a0d00410041e8c0001002200228020021030b20032004410410061a2002200228020041046a2203360200200141246a21020240200528020020036b41034a0d00410041e8c0001002200041046a28020021030b20032002410410061a200041046a2202200228020041046a2203360200200141286a21040240200041086a220528020020036b41034a0d00410041e8c0001002200228020021030b20032004410410061a2002200228020041046a22033602002001412c6a21020240200528020020036b41034a0d00410041e8c0001002200041046a28020021030b20032002410410061a200041046a2202200228020041046a2203360200200141306a21040240200041086a220528020020036b41034a0d00410041e8c0001002200228020021030b20032004410410061a2002200228020041046a2203360200200141346a21020240200528020020036b41034a0d00410041e8c0001002200041046a28020021030b20032002410410061a200041046a2202200228020041046a2203360200200141386a21040240200041086a220528020020036b41034a0d00410041e8c0001002200228020021030b20032004410410061a2002200228020041046a22033602002001413c6a21020240200528020020036b41034a0d00410041e8c0001002200041046a28020021030b20032002410410061a200041046a2202200228020041046a2203360200200141c0006a21040240200041086a220528020020036b41014a0d00410041e8c0001002200228020021030b20032004410210061a2002200228020041026a2203360200200141c2006a21010240200528020020036b41014a0d00410041e8c0001002200041046a28020021030b20032001410210061a200041046a2201200128020041026a36020020000bfa0203017f027e017f230041206b220124002001200029030022024220883c000b200120024228883c000a200120024230883c0009200120024238883c00082001200041086a29030022034220883c0003200120034228883c0002200120034230883c0001200120034238883c000020012002a722043a000f200120044108763a000e200120044110763a000d200120044118763a000c20012003a722043a0007200120044108763a0006200120044110763a0005200120044118763a00042001200041186a29030022023c00172001200029031022034220883c001b200120034228883c001a200120034230883c0019200120034238883c0018200120024220883c0013200120024228883c0012200120024230883c0011200120024238883c001020012002a722004108763a0016200120004110763a0015200120004118763a001420012003a722003a001f200120004108763a001e200120004110763a001d200120004118763a001c200110002100200141206a240020000bf60203017f027e017f230041206b220124002001200029030022024220883c000b200120024228883c000a200120024230883c0009200120024238883c00082001200041086a29030022034220883c0003200120034228883c0002200120034230883c0001200120034238883c000020012002a722043a000f200120044108763a000e200120044110763a000d200120044118763a000c20012003a722043a0007200120044108763a0006200120044110763a0005200120044118763a00042001200041186a29030022023c00172001200029031022034220883c001b200120034228883c001a200120034230883c0019200120034238883c0018200120024220883c0013200120024228883c0012200120024230883c0011200120024238883c001020012002a722004108763a0016200120004110763a0015200120004118763a001420012003a722003a001f200120004108763a001e200120004110763a001d200120004118763a001c20011001200141206a24000bcc0401017f23004190016b220324001018024020012000520d0002400240024002400240024002400240200242ffffb7f6a497b2d942570d00200242ffffffffb5f7d6d942570d01200242808080d0b2b3bb9932510d03200242808080c093fad6d942510d0420024280808080b6f7d6d942520d082003410036028c0120034101360288012003200329038801370300200120012003102f1a0c080b200242fffffffffff698d942550d0120024290a9d9d9dd8c99d6ba7f510d0420024280808080daac9bd6ba7f520d0720034100360264200341023602602003200329036037032820012001200341286a10311a0c070b2002428080b8f6a497b2d942510d0420024280808096cdebd4d942520d062003410036026c200341033602682003200329036837032020012001200341206a10331a0c060b2002428080808080f798d942510d042002428080b8f6a4979ad942520d0520034100360284012003410436028001200320032903800137030820012001200341086a10351a0c050b20034100360254200341053602502003200329035037033820012001200341386a10371a0c040b20034100360274200341063602702003200329037037031820012001200341186a10391a0c030b2003410036024c200341073602482003200329034837034020012001200341c0006a10371a0c020b2003410036027c200341083602782003200329037837031020012001200341106a103c1a0c010b2003410036025c200341093602582003200329035837033020012001200341306a103e1a0b4100101c20034190016a24000b1200200029030010072001200241004710080bd30201077f230041306b2203210420032400200228020421052002280200210641002102024010042207450d00024002402007418104490d002007101921020c010b20032007410f6a4170716b220224000b2002200710051a0b200441003a002820044200370320200220076a2103200441206a41086a210802400240200741074b0d0041004185c1001002200441206a2002410810061a200241086a21090c010b200441206a2002410810061a200241086a210920074108470d0041004185c10010020b20082009410110061a200441186a200336020020042002360210200441146a200241096a3602002004200137030820042000370300200420054101756a2103200441286a2d000021082004290320210002402005410171450d00200328020020066a28020021060b20032000200841ff0171200611010002402007418104490d002002101a0b200441306a240041010b0600200110070b830201057f230041306b22032104200324002002280204210520022802002106024002400240024010042207450d002007418104490d012007101921020c020b410021020c020b20032007410f6a4170716b220224000b2002200710051a0b20044200370328200220076a21030240200741074b0d0041004185c10010020b200441286a2002410810061a2004411c6a200241086a360200200441206a2003360200200420013703102004200037030820042002360218200441086a20054101756a21032004290328210002402005410171450d00200328020020066a28020021060b20032000200611020002402007418104490d002002101a0b200441306a240041010b0d0020002903001007200110290bf70201067f230041a0026b2203210420032400200228020421052002280200210641002102024010042207450d00024002402007418104490d002007101921020c010b20032007410f6a4170716b220224000b2002200710051a0b200441c8006a410041c80010031a2004200236023c200420023602382004200220076a360240200441386a200441c8006a10421a200441086a41086a220320042802403602002004200429033837030820044190016a41086a220820032802003602002004200429030837039001200441d8016a41086a20082802002203360200200441306a2003360200200420003703182004200137032020042004290390012200370328200420003703d80120044190016a200441c8006a41c80010061a200441d8016a20044190016a41c80010061a200441186a20054101756a210302402005410171450d00200328020020066a28020021060b2003200441d8016a200611030002402007418104490d002002101a0b200441a0026a240041010b130020002903001007200120022003200410090b940302067f027e23004180016b22032104200324002002280204210520022802002106024002400240024010042207450d002007418104490d012007101921020c020b410021020c020b20032007410f6a4170716b220224000b2002200710051a0b2004420037034820044200370340200442003703502004420037035820042002360234200420023602302004200220076a3602382004200441306a3602702004200441c0006a360210200441106a200441f0006a103f200441086a2203200428023836020020042004290330370300200441e0006a41086a2208200328020036020020042004290300370360200441f0006a41086a20082802002203360200200441286a2003360200200420003703102004200137031820042004290360220037032020042000370370200441106a20054101756a21032004290358210020042903502101200429034821092004290340210a02402005410171450d00200328020020066a28020021060b2003200a200920012000200611040002402007418104490d002002101a0b20044180016a240041010b0d00200029030010072001102c0bfe0301087f230041a0016b22032104200324002002280204210520022802002106024002400240024010042207450d002007418104490d012007101921020c020b410021020c020b20032007410f6a4170716b220224000b2002200710051a0b200441c0006a41186a22034200370300200441c0006a41106a22084200370300200442003703482004420037034020042002360234200420023602302004200220076a3602382004200441306a3602602004200441c0006a3602800120044180016a200441e0006a1048200441086a2209200428023836020020042004290330370300200441e0006a41086a220a20092802003602002004200429030037036020044180016a41086a200a2802002209360200200441106a41186a200936020020042000370310200420013703182004200429036022003703202004200037038001200441e0006a41186a22092003290300370300200441e0006a41106a22032008290300370300200420042903483703682004200429034037036020044180016a41186a200929030037030020044180016a41106a200329030037030020042004290368370388012004200429036037038001200441106a20054101756a210302402005410171450d00200328020020066a28020021060b200320044180016a200611030002402007418104490d002002101a0b200441a0016a240041010b5601027f23002202210320002903001007024010042200418104490d00200010192202200010051a20022000100b1a200324000f0b20022000410f6a4170716b220224002002200010051a20022000100b1a200324000bb80501077f230041f0006b220321042003240020022802042105200228020021064100210741002102024010042208450d00024002402008418104490d002008101921020c010b20032008410f6a4170716b220224000b2002200810051a0b200441003602482004420037034020042002360234200420023602302004200220086a360238200441306a200441c0006a10411a200441086a2203200428023836020020042004290330370300200441d0006a41086a2209200328020036020020042004290300370350200441e0006a41086a20092802002203360200200441286a20033602002004200037031020042001370318200420042903502200370320200420003703602004410036025820044200370350200428024420042802406b220341306d21090240024002402003450d00200941d6aad52a4f0d01200441d8006a200310202207200941306c6a36020020042007360250200420073602542004280244200428024022096b22034101480d0020072009200310061a20042004280254200341306e41306c6a22073602540b200441106a20054101756a210302402005410171450d00200328020020066a28020021060b2004410036026820044200370360200720042802506b220741306d210502402007450d00200541d6aad52a4f0d02200441e8006a200710202207200541306c6a36020020042007360260200420073602642004280254200428025022096b22054101480d0020072009200510061a20042007200541306e41306c6a3602640b2003200441e0006a2006110300024020042802602207450d0020042007360264200710220b024020042802502207450d0020042007360254200710220b02402008418104490d002002101a0b024020042802402202450d0020042002360244200210220b200441f0006a240041010f0b200441d0006a1028000b200441e0006a1028000b130002402001102b0d00410041d9c20010020b0b0900200029030010070b870302067f017e23004180016b22032104200324002002280204210520022802002106024002400240024010042207450d002007418104490d012007101921020c020b410021020c020b20032007410f6a4170716b220224000b2002200710051a0b2004420037035020044200370348200442003703582004200236023c200420023602382004200220076a3602402004200441386a3602702004200441c8006a360218200441186a200441f0006a1040200441086a41086a2203200428024036020020042004290338370308200441e0006a41086a2208200328020036020020042004290308370360200441f0006a41086a20082802002203360200200441306a2003360200200420003703182004200137032020042004290360220037032820042000370370200441186a20054101756a210320042903582100200429035021012004290348210902402005410171450d00200328020020066a28020021060b2003200920012000200611050002402007418104490d002002101a0b20044180016a240041010bc00203017f017e027f230041c0006b2203240020032001370338200341306a41003602002003427f37032020034200370328200320002903002204370310200320043703180240024002402004200442808080809aecb4ee312001101022004100480d000240200341106a200010452200280230200341106a460d00410041b5c00010020b20032002360208200341106a20004200200341086a1046200328022822050d010c020b2003200236020c2003200341386a3602082003200341106a2001200341086a104720032802282205450d010b024002402003412c6a220628020022002005460d000340200041686a220028020021022000410036020002402002450d00200210220b20052000470d000b200341286a28020021000c010b200521000b2006200536020020001022200341c0006a24000f0b200341c0006a24000b9e0301057f23004180016b2203240020032204200229020037035841002102024010042205450d00024002402005418104490d002005101921020c010b20032005410f6a4170716b220224000b2002200510051a0b200441d0006a4100360200200442003703402004420037034820042002360234200420023602302004200220056a360238200221030240200541074b0d0041004185c1001002200428023421030b200441c0006a2003410810061a2004200341086a360234200441306a200441c0006a41086a220310431a200441086a2206200441306a41086a28020036020020042004290330370300200441e0006a41086a2207200628020036020020042004290300370360200441f0006a41086a20072802002206360200200441286a20063602002004200037031020042001370318200420042903602200370320200420003703702004200441d8006a3602742004200441106a360270200441f0006a200441c0006a104402402005418104490d002002101a0b024020032802002202450d00200441cc006a2002360200200210220b20044180016a240041010bc10201037f20002802002102024020012802002203280208200328020422046b41074b0d0041004185c1001002200341046a28020021040b20022004410810061a200341046a2203200328020041086a3602002000280200220041086a2102024020012802002203280208200328020422046b41074b0d0041004185c1001002200341046a28020021040b20022004410810061a200341046a2203200328020041086a360200200041106a2102024020012802002203280208200328020422046b41074b0d0041004185c1001002200341046a28020021040b20022004410810061a200341046a2203200328020041086a360200200041186a2100024020012802002201280208200128020422036b41074b0d0041004185c1001002200141046a28020021030b20002003410810061a200141046a2201200128020041086a3602000bf30101037f20002802002102024020012802002203280208200328020422046b41074b0d0041004185c1001002200341046a28020021040b20022004410810061a200341046a2203200328020041086a3602002000280200220441086a2102024020012802002203280208200328020422006b41074b0d0041004185c1001002200341046a28020021000b20022000410810061a200341046a2203200328020041086a360200200441106a2100024020012802002201280208200128020422036b41074b0d0041004185c1001002200141046a28020021030b20002003410810061a200141046a2201200128020041086a3602000be80303017f017e067f2000280204210242002103200041086a2104200041046a2105410021060340024020022004280200490d00410041fbc2001002200528020021020b20022d000021072005200241016a22023602002003200741ff0071200641ff0171220674ad842103200641076a2106200221022007418001710d000b02400240024020012802042208200128020022096b41306d22072003a722024f0d002001200220076b105620012802002209200141046a2802002208470d010c020b0240200720024d0d00200141046a2009200241306c6a22083602000b20092008460d010b200041046a22042802002102200041086a210103400240200128020020026b41074b0d0041004185c1001002200428020021020b20092002410810061a2004200428020041086a220236020041002105420021030340024020022001280200490d00410041fbc2001002200428020021020b20022d000021072004200241016a22063602002003200741ff0071200541ff0171220274ad842103200241076a2105200621022007418001710d000b200920033e02082009410c6a21020240200128020020066b41204b0d0041004185c1001002200428020021060b20022006412110061a2004200428020041216a2202360200200941306a22092008470d000b0b20000b920901047f02402000280208200028020422026b41074b0d0041004185c1001002200041046a28020021020b20012002410810061a200041046a2202200228020041086a2203360200200141086a21040240200041086a220528020020036b41034b0d0041004185c1001002200228020021030b20042003410410061a2002200228020041046a22033602002001410c6a21020240200528020020036b41034b0d0041004185c1001002200041046a28020021030b20022003410410061a200041046a2202200228020041046a2203360200200141106a21040240200041086a220528020020036b41034b0d0041004185c1001002200228020021030b20042003410410061a2002200228020041046a2203360200200141146a21020240200528020020036b41034b0d0041004185c1001002200041046a28020021030b20022003410410061a200041046a2202200228020041046a2203360200200141186a21040240200041086a220528020020036b41034b0d0041004185c1001002200228020021030b20042003410410061a2002200228020041046a22033602002001411c6a21020240200528020020036b41034b0d0041004185c1001002200041046a28020021030b20022003410410061a200041046a2202200228020041046a2203360200200141206a21040240200041086a220528020020036b41034b0d0041004185c1001002200228020021030b20042003410410061a2002200228020041046a2203360200200141246a21020240200528020020036b41034b0d0041004185c1001002200041046a28020021030b20022003410410061a200041046a2202200228020041046a2203360200200141286a21040240200041086a220528020020036b41034b0d0041004185c1001002200228020021030b20042003410410061a2002200228020041046a22033602002001412c6a21020240200528020020036b41034b0d0041004185c1001002200041046a28020021030b20022003410410061a200041046a2202200228020041046a2203360200200141306a21040240200041086a220528020020036b41034b0d0041004185c1001002200228020021030b20042003410410061a2002200228020041046a2203360200200141346a21020240200528020020036b41034b0d0041004185c1001002200041046a28020021030b20022003410410061a200041046a2202200228020041046a2203360200200141386a21040240200041086a220528020020036b41034b0d0041004185c1001002200228020021030b20042003410410061a2002200228020041046a22033602002001413c6a21020240200528020020036b41034b0d0041004185c1001002200041046a28020021030b20022003410410061a200041046a2202200228020041046a2203360200200141c0006a21040240200041086a220528020020036b41014b0d0041004185c1001002200228020021030b20042003410210061a2002200228020041026a2203360200200141c2006a21010240200528020020036b41014b0d0041004185c1001002200041046a28020021030b20012003410210061a200041046a2201200128020041026a36020020000ba10203017f017e057f2000280204210242002103200041086a2104200041046a2105410021060340024020022004280200490d00410041fbc2001002200528020021020b20022d000021072005200241016a22083602002003200741ff0071200641ff0171220274ad842103200241076a2106200821022007418001710d000b0240024020012802042207200128020022026b22052003a722064f0d002001200620056b1051200041046a2802002108200141046a2802002107200128020021020c010b200520064d0d00200141046a200220066a22073602000b0240200041086a28020020086b200720026b22074f0d0041004185c1001002200041046a28020021080b20022008200710061a200041046a2202200228020020076a36020020000bf80103017f017e027f230041106b22022400200242003703002002410036020820012903002103024002402001410c6a28020020012802086b2204450d002004417f4c0d01200241086a20041020220520046a36020020022005360200200220053602042001410c6a280200200141086a28020022046b22014101480d0020052004200110061a2002200520016a3602040b20002802002000280204220128020422044101756a21002001280200210102402004410171450d00200028020020016a28020021010b2000200320022001110100024020022802002201450d0020022001360204200110220b200241106a24000f0b20021028000bbf0302077f017e230041206b22022103200224000240200028021822042000411c6a2802002205460d0002400340200541786a2802002001460d012004200541686a2205470d000c020b0b20042005460d00200541686a2802002105200341206a240020050f0b02400240024020014100410010142204417f4c0d0020044181044f0d0120022004410f6a4170716b22022400410021060c020b410041eec00010020b200410192102410121060b20012002200410141a41c000102022052000360230200542003703000240200441074b0d0041004185c10010020b20052002410810061a200541106a2107200241086a21080240200441786a411f4b0d0041004185c10010020b20072008412010061a20052001360234200320053602182003200529030022093703102003200136020c0240024002402000411c6a22072802002204200041206a2802004f0d00200420093703082004200136021020034100360218200420053602002007200441186a36020020060d010c020b200041186a200341186a200341106a2003410c6a105d2006450d010b2002101a0b200328021821012003410036021802402001450d00200110220b200341206a240020050bc40103027f017e017f230022042105024020012802302000460d00410041bdc10010020b024020002903001013510d00410041ebc10010020b20012903002106200328020022032802002207200328020420076b200141106a22071015024020062001290300510d004100419ec20010020b2004220441506a2203240020032001410810061a200441586a2007412010061a20012802342002200341281017024020062000290310540d00200041106a427e200642017c2006427d561b3703000b200524000bfb0101047f230041306b2204240020042002370328024020012903001013510d004100418ac10010020b20042003360214200420013602102004200441286a36021841c000102022032001200441106a105c1a2004200336022020042003290300220237031020042003280234220536020c024002402001411c6a22062802002207200141206a2802004f0d00200720023703082007200536021020044100360220200720033602002006200741186a3602000c010b200141186a200441206a200441106a2004410c6a105d0b2000200336020420002001360200200428022021012004410036022002402001450d00200110220b200441306a24000b960305027f017e017f017e017f230041d0006b2202240020002802002103024020012802002201280208200128020422006b411f4b0d0041004185c1001002200141046a28020021000b200241306a2000412010061a200141046a2201200128020041206a3602004200210441102101200241106a2105410021004200210602400340200241306a20006a2107024020014102490d002006420886200420073100008422044238888421062001417f6a210120044208862104200041016a22004120470d010c020b024020014101460d00410041ffc20010020b200520063703082005200420073100008437030041102101200541106a21054200210442002106200041016a22004120470d000b0b024020014110460d00024020014102490d00200220042006200141037441786a1011200241086a2903002106200229030021040b20052004370300200520063703080b20032002290310370300200341086a2002290318370300200341186a200241106a41186a290300370300200341106a200241106a41106a290300370300200241d0006a24000bba0101047f230041106b22022103200224000240024002400240024010042204450d002004418004490d012004101921020c020b2003420037030841002102200341086a21050c020b20022004410f6a4170716b220224000b2002200410051a20034200370308200341086a2105200441074b0d010b41004185c10010020b20052002410810061a20034200370300200241086a2102024020044178714108470d0041004185c10010020b20032002410810061a200341106a24000b4401037f230022022103024010042204450d00024002402004418004490d002004101921020c010b20022004410f6a4170716b220224000b2002200410051a0b200324000b4401037f230022022103024010042204450d00024002402004418004490d002004101921020c010b20022004410f6a4170716b220224000b2002200410051a0b200324000b4401037f230022022103024010042204450d00024002402004418004490d002004101921020c010b20022004410f6a4170716b220224000b2002200410051a0b200324000b4401037f230022022103024010042204450d00024002402004418004490d002004101921020c010b20022004410f6a4170716b220224000b2002200410051a0b200324000b4401037f230022022103024010042204450d00024002402004418004490d002004101921020c010b20022004410f6a4170716b220224000b2002200410051a0b200324000b4401037f230022022103024010042204450d00024002402004418004490d002004101921020c010b20022004410f6a4170716b220224000b2002200410051a0b200324000bd30201047f230041306b2202210320022400024002400240024010042204450d002004418004490d012004101921020c020b410021020c020b20022004410f6a4170716b220224000b2002200410051a0b20032002360224200320023602202003200220046a2205360228200342003703180240200441074b0d0041004185c1001002200341286a2802002105200328022421020b200341186a2002410810061a2003200241086a2202360224024020052002470d0041004185c1001002200341206a41086a2802002105200328022421020b200341176a2002410110061a2003200241016a2202360224024020052002470d0041004185c1001002200328022421020b200341166a2002410110061a2003200241016a3602242003410036021020034200370308200341206a200341086a10431a024020032802082202450d002003200236020c200210220b200341306a24000bbe0201067f0240024002400240024020002802082202200028020422036b20014f0d002003200028020022046b220520016a2206417f4c0d0241ffffffff0721070240200220046b220241feffffff034b0d0020062002410174220220022006491b2207450d020b2007102021020c030b200041046a21000340200341003a00002000200028020041016a22033602002001417f6a22010d000c040b0b41002107410021020c010b20001028000b200220076a2107200320016a20046b2104200220056a220521030340200341003a0000200341016a21032001417f6a22010d000b200220046a21042005200041046a2206280200200028020022016b22036b2102024020034101480d0020022001200310061a200028020021010b2000200236020020062004360200200041086a20073602002001450d00200110220f0b0bd00102047f017e230041106b22022103200224000240024002400240024010042204450d002004418004490d012004101921020c020b2003420037030841002102200341086a21050c020b20022004410f6a4170716b220224000b2002200410051a20034200370308200341086a2105200441074b0d010b41004185c10010020b20052002410810061a200241086a2102024020044108470d0041004185c10010020b200341076a2002410110061a2003290308210620032d0007210420001007200620044100471008200341106a24000bab0202047f047e230041206b22022103200224000240024002400240024010042204450d002004418004490d012004101921020c020b2003420037031841002102200341186a21050c020b20022004410f6a4170716b220224000b2002200410051a20034200370318200341186a2105200441074b0d010b41004185c10010020b20052002410810061a200241086a21050240200441787122044108470d0041004185c10010020b200341106a2005410810061a200241106a2105024020044110470d0041004185c10010020b200341086a2005410810061a200241186a2102024020044118470d0041004185c10010020b20032002410810061a200329030021062003290308210720032903102108200329031821092000100720092008200720061009200341206a24000bd30101047f230041206b22022103200224000240024002400240024010042204450d002004418004490d012004101921020c020b41002102200341186a21050c020b20022004410f6a4170716b220224000b2002200410051a200341186a2105200441074b0d010b41004185c10010020b20052002410810061a200241086a21050240200441787122044108470d0041004185c10010020b200341106a2005410810061a200241106a2102024020044110470d0041004185c10010020b200341086a2002410810061a20001007200341206a24000bc60301047f23004180016b220221032002240041002104024010042205450d00024002402005418004490d002005101921040c010b20022005410f6a4170716b220424000b2004200510051a0b20032004360254200320043602502003200420056a3602582003410036024820034200370340200341d0006a200341c0006a10411a200341106a41086a2204200328025836020020032003290350370310200341e0006a41086a2205200428020036020020032003290310370360200341f0006a41086a20052802002204360200200341386a20043602002003200037032020032001370328200320032903602200370330200320003703702003410036020820034200370300200328024420032802406b220441306d2105024002402004450d00200541d6aad52a4f0d01200341086a200410202204200541306c6a36020020032004360200200320043602042003280244200328024022026b22054101480d0020042002200510061a20032003280204200541306e41306c6a3602040b200341206a20031038024020032802002204450d0020032004360204200410220b024020032802402204450d0020032004360244200410220b20034180016a24000f0b20031028000bc60301067f0240024002400240024020002802082202200028020422036b41306d20014f0d002003200028020022046b41306d220520016a220641d6aad52a4f0d0241d5aad52a21030240200220046b41306d220241a9d5aa154b0d0020062002410174220320032006491b2203450d020b200341306c102021040c030b200041046a21020340200341086a2200420037030020034200370300200341286a4200370300200341206a4200370300200341186a4200370300200341106a4200370300200041003602002002200228020041306a22033602002001417f6a22010d000c040b0b41002103410021040c010b20001028000b2004200341306c6a21072004200541306c6a220521030340200341086a2202420037030020034200370300200341286a4200370300200341206a4200370300200341186a4200370300200341106a420037030020024100360200200341306a21032001417f6a22010d000b2004200641306c6a21042005200041046a2206280200200028020022036b220141506d41306c6a2102024020014101480d0020022003200110061a200028020021030b2000200236020020062004360200200041086a20073602002003450d00200310220f0b0b8a0101037f230041e0006b2202210320022400024002400240024010042204450d002004418004490d012004101921020c020b410021020c020b20022004410f6a4170716b220224000b2002200410051a0b20032002360254200320023602502003200220046a360258200341d0006a200341086a10421a20001007200341086a1029200341e0006a24000b950101047f230041106b22022103200224000240024002400240024010042204450d002004418004490d012004101921020c020b2003420037030841002102200341086a21050c020b20022004410f6a4170716b220224000b2002200410051a20034200370308200341086a2105200441074b0d010b41004185c10010020b20052002410810061a20032903081007200341106a24000bd70303047f027e017f230041f0006b2202210320022400024002400240024010042204450d002004418004490d012004101921050c020b410021050c020b20022004410f6a4170716b220524000b2005200410051a0b42002106200341286a420037030041102102200341106a41106a4200370300200342003703182003420037031002402004411f4b0d0041004185c10010020b200341d0006a2005412010061a200341306a2105410021044200210702400340200341d0006a20046a2108024020024102490d002007420886200620083100008422064238888421072002417f6a210220064208862106200441016a22044120470d010c020b024020024101460d00410041ffc20010020b200520073703082005200620083100008437030041102102200541106a21054200210642002107200441016a22044120470d000b0b024020024110460d00024020024102490d00200320062007200241037441786a1011200341086a2903002107200329030021060b20052006370300200520073703080b200341106a41186a200341306a41186a290300370300200341106a41106a200341306a41106a290300370300200320032903383703182003200329033037031020001007200341106a102c200341f0006a24000be00303047f027e017f230041f0006b2202210320022400024002400240024010042204450d002004418004490d012004101921050c020b410021050c020b20022004410f6a4170716b220524000b2005200410051a0b42002106200341286a420037030041102102200341106a41106a4200370300200342003703182003420037031002402004411f4b0d0041004185c10010020b200341d0006a2005412010061a200341306a2105410021044200210702400340200341d0006a20046a2108024020024102490d002007420886200620083100008422064238888421072002417f6a210220064208862106200441016a22044120470d010c020b024020024101460d00410041ffc20010020b200520073703082005200620083100008437030041102102200541106a21054200210642002107200441016a22044120470d000b0b024020024110460d00024020024102490d00200320062007200241037441786a1011200341086a2903002107200329030021060b20052006370300200520073703080b200341106a41186a200341306a41186a290300370300200341106a41106a200341306a41106a29030037030020032003290338370318200320032903303703100240200341106a102b0d00410041d9c20010020b200341f0006a24000beb0201037f23004180016b2202210320022400024002400240024010042204450d002004418004490d012004101921020c020b410021020c020b20022004410f6a4170716b220224000b2002200410051a0b20032002360254200320023602502003200220046a360258200342003703480240200441074b0d0041004185c1001002200328025421020b200341c8006a2002410810061a2003200241086a3602542003410036024020034200370338200341d0006a200341386a10431a200341086a41086a2202200341d0006a41086a28020036020020032003290350370308200341e0006a41086a2204200228020036020020032003290308370360200341f0006a41086a20042802002202360200200341306a2002360200200320003703182003200137032020032003290360220037032820032000370370200341186a2003290348200341386a103d024020032802382202450d002003200236023c200210220b20034180016a24000bbc0102037f017e230041306b22032400200020013602302000420037030020002002280204220428020029030037030020022802002101200428020422042802002205200428020420056b200041106a2204101520032000410810061a20034108722004412010061a2000200129030842808080809aecb4ee31200228020829030020002903002206200341281016360234024020062001290310540d00200141106a427e200642017c2006427d561b3703000b200341306a240020000baa0301057f024002402000280204200028020022046b41186d220541016a220641abd5aad5004f0d0041aad5aad500210702400240200028020820046b41186d220441d4aad52a4b0d0020062004410174220720072006491b2207450d010b200741186c102021040c020b41002107410021040c010b20001028000b20012802002106200141003602002004200541186c22086a2201200636020020012002290300370308200120032802003602102004200741186c6a2105200141186a210602400240200041046a280200220220002802002207460d00200420086a41686a21010340200241686a220428020021032004410036020020012003360200200141106a200241786a280200360200200141086a200241706a290300370300200141686a21012004210220072004470d000b200141186a2101200041046a2802002107200028020021020c010b200721020b20002001360200200041046a2006360200200041086a2005360200024020072002460d000340200741686a220728020021012007410036020002402001450d00200110220b20022007470d000b0b02402002450d00200210220b0b0bdf030b00419cc0000b4c6661696c656420746f20616c6c6f63617465207061676573006f626a6563742070617373656420746f206974657261746f725f746f206973206e6f7420696e206d756c74695f696e646578000041e8c0000b1d7772697465006572726f722072656164696e67206974657261746f7200004185c1000b05726561640000418ac1000b3363616e6e6f7420637265617465206f626a6563747320696e207461626c65206f6620616e6f7468657220636f6e7472616374000041bdc1000b2e6f626a6563742070617373656420746f206d6f64696679206973206e6f7420696e206d756c74695f696e646578000041ebc1000b3363616e6e6f74206d6f64696679206f626a6563747320696e207461626c65206f6620616e6f7468657220636f6e74726163740000419ec2000b3b757064617465722063616e6e6f74206368616e6765207072696d617279206b6579207768656e206d6f64696679696e6720616e206f626a656374000041d9c2000b2270726f746f636f6c2066656174757265206973206e6f7420616374697661746564000041fbc2000b04676574000041ffc2000b2c756e6578706563746564206572726f7220696e2066697865645f627974657320636f6e7374727563746f72000041000b04b02100000000000000000000000003917c562680b415b93db73416ff29230dfbe7ab1ba4d208b46029d01333cd3a03000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd010000000000ea30556ab602000000000000000000000000 +DMLOG APPLIED_TRANSACTION 3 03917c562680b415b93db73416ff29230dfbe7ab1ba4d208b46029d01333cd3a03000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50100d0070000fb050000000000000000d8170000000000000001010000010000000000ea30559a90c525172f87bbac0a6378610727f0fe1d7ebe908df973923d29a1606f9a5703000000000000000300000000000000010000000000ea3055030000000000000001000000000000ea30550000000000ea305500000040258ab2c2010000000000ea305500000000a8ed3232fe8a010000000000ea30550000f18a010061736d01000000019d011a60000060037f7e7f0060027f7e0060027f7f0060057f7e7e7e7e0060047f7e7e7e0060017f017f60017f0060037f7f7f017f6000017f60027f7f017f60017e0060027e7f0060047e7e7e7e0060027f7f017e6000017e60047e7e7e7e017f60047f7e7e7f0060037f7f7f0060067e7e7e7e7f7f017f60047f7e7f7f0060037e7e7e0060037e7e7f017f60047f7f7e7f0060027e7e0060047f7f7f7f00028e041803656e761469735f666561747572655f616374697661746564000603656e761370726561637469766174655f66656174757265000703656e760c656f73696f5f617373657274000303656e76066d656d736574000803656e7610616374696f6e5f646174615f73697a65000903656e7610726561645f616374696f6e5f64617461000a03656e76066d656d637079000803656e760c726571756972655f61757468000b03656e760e7365745f70726976696c65676564000c03656e76137365745f7265736f757263655f6c696d697473000d03656e760561626f7274000003656e76167365745f70726f706f7365645f70726f647563657273000e03656e76207365745f626c6f636b636861696e5f706172616d65746572735f7061636b6564000303656e76206765745f626c6f636b636861696e5f706172616d65746572735f7061636b6564000a03656e760c63757272656e745f74696d65000f03656e76146765745f6163746976655f70726f647563657273000a03656e760b64625f66696e645f693634001003656e76095f5f6173686c746933001103656e7611656f73696f5f6173736572745f636f6465000203656e761063757272656e745f7265636569766572000f03656e760a64625f6765745f693634000803656e7606736861323536001203656e760c64625f73746f72655f693634001303656e760d64625f7570646174655f69363400140347460006070007090a08060607070a0a030307070a060715011602160316041603160316030516011603030a0a0a030a17170318181818181818180318181818031818181818081904050170010a0a05030100010616037f014180c0000b7f0041abc3000b7f0041abc3000b070901056170706c79002d090f010041010b092e30323436383a3b3d0ac98001460400101b0b800101037f02400240024002402000450d004100410028028c40200041107622016a220236028c404100410028028440220320006a41076a417871220036028440200241107420004d0d0120014000417f460d020c030b41000f0b4100200241016a36028c40200141016a4000417f470d010b4100419cc000100220030f0b20030b02000b3601017f230041106b2200410036020c4100200028020c28020041076a417871220036028440410020003602804041003f0036028c400b02000b06004190c0000bf50101067f4100210202400240410020006b22032000712000470d00200041104b0d01200110190f0b101d411636020041000f0b0240024002402000417f6a220420016a10192200450d002000200420006a2003712202460d012000417c6a220328020022044107712201450d02200020044178716a220441786a2205280200210620032001200220006b2207723602002002417c6a200420026b2203200172360200200241786a20064107712201200772360200200520012003723602002000101a0b20020f0b20000f0b200241786a200041786a280200200220006b22006a3602002002417c6a200328020020006b36020020020b3301017f411621030240024020014104490d0020012002101e2201450d0120002001360200410021030b20030f0b101d2802000b3801027f02402000410120001b2201101922000d000340410021004100280298402202450d012002110000200110192200450d000b0b20000b0600200010200b0e0002402000450d002000101a0b0b0600200010220b6b01027f230041106b2202240002402002410c6a20014104200141044b1b22012000410120001b2203101f450d00024003404100280298402200450d0120001100002002410c6a20012003101f0d000c020b0b2002410036020c0b200228020c2100200241106a240020000b08002000200110240b0e0002402000450d002000101a0b0b08002000200110260b0500100a000b4e01017f230041e0006b220124002001200141d8006a3602082001200141106a3602042001200141106a36020020012000102a1a200141106a200128020420012802006b100c200141e0006a24000b920901047f02402000280208200028020422026b41074a0d00410041e8c0001002200041046a28020021020b20022001410810061a200041046a2202200228020041086a2203360200200141086a21040240200041086a220528020020036b41034a0d00410041e8c0001002200228020021030b20032004410410061a2002200228020041046a22033602002001410c6a21020240200528020020036b41034a0d00410041e8c0001002200041046a28020021030b20032002410410061a200041046a2202200228020041046a2203360200200141106a21040240200041086a220528020020036b41034a0d00410041e8c0001002200228020021030b20032004410410061a2002200228020041046a2203360200200141146a21020240200528020020036b41034a0d00410041e8c0001002200041046a28020021030b20032002410410061a200041046a2202200228020041046a2203360200200141186a21040240200041086a220528020020036b41034a0d00410041e8c0001002200228020021030b20032004410410061a2002200228020041046a22033602002001411c6a21020240200528020020036b41034a0d00410041e8c0001002200041046a28020021030b20032002410410061a200041046a2202200228020041046a2203360200200141206a21040240200041086a220528020020036b41034a0d00410041e8c0001002200228020021030b20032004410410061a2002200228020041046a2203360200200141246a21020240200528020020036b41034a0d00410041e8c0001002200041046a28020021030b20032002410410061a200041046a2202200228020041046a2203360200200141286a21040240200041086a220528020020036b41034a0d00410041e8c0001002200228020021030b20032004410410061a2002200228020041046a22033602002001412c6a21020240200528020020036b41034a0d00410041e8c0001002200041046a28020021030b20032002410410061a200041046a2202200228020041046a2203360200200141306a21040240200041086a220528020020036b41034a0d00410041e8c0001002200228020021030b20032004410410061a2002200228020041046a2203360200200141346a21020240200528020020036b41034a0d00410041e8c0001002200041046a28020021030b20032002410410061a200041046a2202200228020041046a2203360200200141386a21040240200041086a220528020020036b41034a0d00410041e8c0001002200228020021030b20032004410410061a2002200228020041046a22033602002001413c6a21020240200528020020036b41034a0d00410041e8c0001002200041046a28020021030b20032002410410061a200041046a2202200228020041046a2203360200200141c0006a21040240200041086a220528020020036b41014a0d00410041e8c0001002200228020021030b20032004410210061a2002200228020041026a2203360200200141c2006a21010240200528020020036b41014a0d00410041e8c0001002200041046a28020021030b20032001410210061a200041046a2201200128020041026a36020020000bfa0203017f027e017f230041206b220124002001200029030022024220883c000b200120024228883c000a200120024230883c0009200120024238883c00082001200041086a29030022034220883c0003200120034228883c0002200120034230883c0001200120034238883c000020012002a722043a000f200120044108763a000e200120044110763a000d200120044118763a000c20012003a722043a0007200120044108763a0006200120044110763a0005200120044118763a00042001200041186a29030022023c00172001200029031022034220883c001b200120034228883c001a200120034230883c0019200120034238883c0018200120024220883c0013200120024228883c0012200120024230883c0011200120024238883c001020012002a722004108763a0016200120004110763a0015200120004118763a001420012003a722003a001f200120004108763a001e200120004110763a001d200120004118763a001c200110002100200141206a240020000bf60203017f027e017f230041206b220124002001200029030022024220883c000b200120024228883c000a200120024230883c0009200120024238883c00082001200041086a29030022034220883c0003200120034228883c0002200120034230883c0001200120034238883c000020012002a722043a000f200120044108763a000e200120044110763a000d200120044118763a000c20012003a722043a0007200120044108763a0006200120044110763a0005200120044118763a00042001200041186a29030022023c00172001200029031022034220883c001b200120034228883c001a200120034230883c0019200120034238883c0018200120024220883c0013200120024228883c0012200120024230883c0011200120024238883c001020012002a722004108763a0016200120004110763a0015200120004118763a001420012003a722003a001f200120004108763a001e200120004110763a001d200120004118763a001c20011001200141206a24000bcc0401017f23004190016b220324001018024020012000520d0002400240024002400240024002400240200242ffffb7f6a497b2d942570d00200242ffffffffb5f7d6d942570d01200242808080d0b2b3bb9932510d03200242808080c093fad6d942510d0420024280808080b6f7d6d942520d082003410036028c0120034101360288012003200329038801370300200120012003102f1a0c080b200242fffffffffff698d942550d0120024290a9d9d9dd8c99d6ba7f510d0420024280808080daac9bd6ba7f520d0720034100360264200341023602602003200329036037032820012001200341286a10311a0c070b2002428080b8f6a497b2d942510d0420024280808096cdebd4d942520d062003410036026c200341033602682003200329036837032020012001200341206a10331a0c060b2002428080808080f798d942510d042002428080b8f6a4979ad942520d0520034100360284012003410436028001200320032903800137030820012001200341086a10351a0c050b20034100360254200341053602502003200329035037033820012001200341386a10371a0c040b20034100360274200341063602702003200329037037031820012001200341186a10391a0c030b2003410036024c200341073602482003200329034837034020012001200341c0006a10371a0c020b2003410036027c200341083602782003200329037837031020012001200341106a103c1a0c010b2003410036025c200341093602582003200329035837033020012001200341306a103e1a0b4100101c20034190016a24000b1200200029030010072001200241004710080bd30201077f230041306b2203210420032400200228020421052002280200210641002102024010042207450d00024002402007418104490d002007101921020c010b20032007410f6a4170716b220224000b2002200710051a0b200441003a002820044200370320200220076a2103200441206a41086a210802400240200741074b0d0041004185c1001002200441206a2002410810061a200241086a21090c010b200441206a2002410810061a200241086a210920074108470d0041004185c10010020b20082009410110061a200441186a200336020020042002360210200441146a200241096a3602002004200137030820042000370300200420054101756a2103200441286a2d000021082004290320210002402005410171450d00200328020020066a28020021060b20032000200841ff0171200611010002402007418104490d002002101a0b200441306a240041010b0600200110070b830201057f230041306b22032104200324002002280204210520022802002106024002400240024010042207450d002007418104490d012007101921020c020b410021020c020b20032007410f6a4170716b220224000b2002200710051a0b20044200370328200220076a21030240200741074b0d0041004185c10010020b200441286a2002410810061a2004411c6a200241086a360200200441206a2003360200200420013703102004200037030820042002360218200441086a20054101756a21032004290328210002402005410171450d00200328020020066a28020021060b20032000200611020002402007418104490d002002101a0b200441306a240041010b0d0020002903001007200110290bf70201067f230041a0026b2203210420032400200228020421052002280200210641002102024010042207450d00024002402007418104490d002007101921020c010b20032007410f6a4170716b220224000b2002200710051a0b200441c8006a410041c80010031a2004200236023c200420023602382004200220076a360240200441386a200441c8006a10421a200441086a41086a220320042802403602002004200429033837030820044190016a41086a220820032802003602002004200429030837039001200441d8016a41086a20082802002203360200200441306a2003360200200420003703182004200137032020042004290390012200370328200420003703d80120044190016a200441c8006a41c80010061a200441d8016a20044190016a41c80010061a200441186a20054101756a210302402005410171450d00200328020020066a28020021060b2003200441d8016a200611030002402007418104490d002002101a0b200441a0026a240041010b130020002903001007200120022003200410090b940302067f027e23004180016b22032104200324002002280204210520022802002106024002400240024010042207450d002007418104490d012007101921020c020b410021020c020b20032007410f6a4170716b220224000b2002200710051a0b2004420037034820044200370340200442003703502004420037035820042002360234200420023602302004200220076a3602382004200441306a3602702004200441c0006a360210200441106a200441f0006a103f200441086a2203200428023836020020042004290330370300200441e0006a41086a2208200328020036020020042004290300370360200441f0006a41086a20082802002203360200200441286a2003360200200420003703102004200137031820042004290360220037032020042000370370200441106a20054101756a21032004290358210020042903502101200429034821092004290340210a02402005410171450d00200328020020066a28020021060b2003200a200920012000200611040002402007418104490d002002101a0b20044180016a240041010b0d00200029030010072001102c0bfe0301087f230041a0016b22032104200324002002280204210520022802002106024002400240024010042207450d002007418104490d012007101921020c020b410021020c020b20032007410f6a4170716b220224000b2002200710051a0b200441c0006a41186a22034200370300200441c0006a41106a22084200370300200442003703482004420037034020042002360234200420023602302004200220076a3602382004200441306a3602602004200441c0006a3602800120044180016a200441e0006a1048200441086a2209200428023836020020042004290330370300200441e0006a41086a220a20092802003602002004200429030037036020044180016a41086a200a2802002209360200200441106a41186a200936020020042000370310200420013703182004200429036022003703202004200037038001200441e0006a41186a22092003290300370300200441e0006a41106a22032008290300370300200420042903483703682004200429034037036020044180016a41186a200929030037030020044180016a41106a200329030037030020042004290368370388012004200429036037038001200441106a20054101756a210302402005410171450d00200328020020066a28020021060b200320044180016a200611030002402007418104490d002002101a0b200441a0016a240041010b5601027f23002202210320002903001007024010042200418104490d00200010192202200010051a20022000100b1a200324000f0b20022000410f6a4170716b220224002002200010051a20022000100b1a200324000bb80501077f230041f0006b220321042003240020022802042105200228020021064100210741002102024010042208450d00024002402008418104490d002008101921020c010b20032008410f6a4170716b220224000b2002200810051a0b200441003602482004420037034020042002360234200420023602302004200220086a360238200441306a200441c0006a10411a200441086a2203200428023836020020042004290330370300200441d0006a41086a2209200328020036020020042004290300370350200441e0006a41086a20092802002203360200200441286a20033602002004200037031020042001370318200420042903502200370320200420003703602004410036025820044200370350200428024420042802406b220341306d21090240024002402003450d00200941d6aad52a4f0d01200441d8006a200310202207200941306c6a36020020042007360250200420073602542004280244200428024022096b22034101480d0020072009200310061a20042004280254200341306e41306c6a22073602540b200441106a20054101756a210302402005410171450d00200328020020066a28020021060b2004410036026820044200370360200720042802506b220741306d210502402007450d00200541d6aad52a4f0d02200441e8006a200710202207200541306c6a36020020042007360260200420073602642004280254200428025022096b22054101480d0020072009200510061a20042007200541306e41306c6a3602640b2003200441e0006a2006110300024020042802602207450d0020042007360264200710220b024020042802502207450d0020042007360254200710220b02402008418104490d002002101a0b024020042802402202450d0020042002360244200210220b200441f0006a240041010f0b200441d0006a1028000b200441e0006a1028000b130002402001102b0d00410041d9c20010020b0b0900200029030010070b870302067f017e23004180016b22032104200324002002280204210520022802002106024002400240024010042207450d002007418104490d012007101921020c020b410021020c020b20032007410f6a4170716b220224000b2002200710051a0b2004420037035020044200370348200442003703582004200236023c200420023602382004200220076a3602402004200441386a3602702004200441c8006a360218200441186a200441f0006a1040200441086a41086a2203200428024036020020042004290338370308200441e0006a41086a2208200328020036020020042004290308370360200441f0006a41086a20082802002203360200200441306a2003360200200420003703182004200137032020042004290360220037032820042000370370200441186a20054101756a210320042903582100200429035021012004290348210902402005410171450d00200328020020066a28020021060b2003200920012000200611050002402007418104490d002002101a0b20044180016a240041010bc00203017f017e027f230041c0006b2203240020032001370338200341306a41003602002003427f37032020034200370328200320002903002204370310200320043703180240024002402004200442808080809aecb4ee312001101022004100480d000240200341106a200010452200280230200341106a460d00410041b5c00010020b20032002360208200341106a20004200200341086a1046200328022822050d010c020b2003200236020c2003200341386a3602082003200341106a2001200341086a104720032802282205450d010b024002402003412c6a220628020022002005460d000340200041686a220028020021022000410036020002402002450d00200210220b20052000470d000b200341286a28020021000c010b200521000b2006200536020020001022200341c0006a24000f0b200341c0006a24000b9e0301057f23004180016b2203240020032204200229020037035841002102024010042205450d00024002402005418104490d002005101921020c010b20032005410f6a4170716b220224000b2002200510051a0b200441d0006a4100360200200442003703402004420037034820042002360234200420023602302004200220056a360238200221030240200541074b0d0041004185c1001002200428023421030b200441c0006a2003410810061a2004200341086a360234200441306a200441c0006a41086a220310431a200441086a2206200441306a41086a28020036020020042004290330370300200441e0006a41086a2207200628020036020020042004290300370360200441f0006a41086a20072802002206360200200441286a20063602002004200037031020042001370318200420042903602200370320200420003703702004200441d8006a3602742004200441106a360270200441f0006a200441c0006a104402402005418104490d002002101a0b024020032802002202450d00200441cc006a2002360200200210220b20044180016a240041010bc10201037f20002802002102024020012802002203280208200328020422046b41074b0d0041004185c1001002200341046a28020021040b20022004410810061a200341046a2203200328020041086a3602002000280200220041086a2102024020012802002203280208200328020422046b41074b0d0041004185c1001002200341046a28020021040b20022004410810061a200341046a2203200328020041086a360200200041106a2102024020012802002203280208200328020422046b41074b0d0041004185c1001002200341046a28020021040b20022004410810061a200341046a2203200328020041086a360200200041186a2100024020012802002201280208200128020422036b41074b0d0041004185c1001002200141046a28020021030b20002003410810061a200141046a2201200128020041086a3602000bf30101037f20002802002102024020012802002203280208200328020422046b41074b0d0041004185c1001002200341046a28020021040b20022004410810061a200341046a2203200328020041086a3602002000280200220441086a2102024020012802002203280208200328020422006b41074b0d0041004185c1001002200341046a28020021000b20022000410810061a200341046a2203200328020041086a360200200441106a2100024020012802002201280208200128020422036b41074b0d0041004185c1001002200141046a28020021030b20002003410810061a200141046a2201200128020041086a3602000be80303017f017e067f2000280204210242002103200041086a2104200041046a2105410021060340024020022004280200490d00410041fbc2001002200528020021020b20022d000021072005200241016a22023602002003200741ff0071200641ff0171220674ad842103200641076a2106200221022007418001710d000b02400240024020012802042208200128020022096b41306d22072003a722024f0d002001200220076b105620012802002209200141046a2802002208470d010c020b0240200720024d0d00200141046a2009200241306c6a22083602000b20092008460d010b200041046a22042802002102200041086a210103400240200128020020026b41074b0d0041004185c1001002200428020021020b20092002410810061a2004200428020041086a220236020041002105420021030340024020022001280200490d00410041fbc2001002200428020021020b20022d000021072004200241016a22063602002003200741ff0071200541ff0171220274ad842103200241076a2105200621022007418001710d000b200920033e02082009410c6a21020240200128020020066b41204b0d0041004185c1001002200428020021060b20022006412110061a2004200428020041216a2202360200200941306a22092008470d000b0b20000b920901047f02402000280208200028020422026b41074b0d0041004185c1001002200041046a28020021020b20012002410810061a200041046a2202200228020041086a2203360200200141086a21040240200041086a220528020020036b41034b0d0041004185c1001002200228020021030b20042003410410061a2002200228020041046a22033602002001410c6a21020240200528020020036b41034b0d0041004185c1001002200041046a28020021030b20022003410410061a200041046a2202200228020041046a2203360200200141106a21040240200041086a220528020020036b41034b0d0041004185c1001002200228020021030b20042003410410061a2002200228020041046a2203360200200141146a21020240200528020020036b41034b0d0041004185c1001002200041046a28020021030b20022003410410061a200041046a2202200228020041046a2203360200200141186a21040240200041086a220528020020036b41034b0d0041004185c1001002200228020021030b20042003410410061a2002200228020041046a22033602002001411c6a21020240200528020020036b41034b0d0041004185c1001002200041046a28020021030b20022003410410061a200041046a2202200228020041046a2203360200200141206a21040240200041086a220528020020036b41034b0d0041004185c1001002200228020021030b20042003410410061a2002200228020041046a2203360200200141246a21020240200528020020036b41034b0d0041004185c1001002200041046a28020021030b20022003410410061a200041046a2202200228020041046a2203360200200141286a21040240200041086a220528020020036b41034b0d0041004185c1001002200228020021030b20042003410410061a2002200228020041046a22033602002001412c6a21020240200528020020036b41034b0d0041004185c1001002200041046a28020021030b20022003410410061a200041046a2202200228020041046a2203360200200141306a21040240200041086a220528020020036b41034b0d0041004185c1001002200228020021030b20042003410410061a2002200228020041046a2203360200200141346a21020240200528020020036b41034b0d0041004185c1001002200041046a28020021030b20022003410410061a200041046a2202200228020041046a2203360200200141386a21040240200041086a220528020020036b41034b0d0041004185c1001002200228020021030b20042003410410061a2002200228020041046a22033602002001413c6a21020240200528020020036b41034b0d0041004185c1001002200041046a28020021030b20022003410410061a200041046a2202200228020041046a2203360200200141c0006a21040240200041086a220528020020036b41014b0d0041004185c1001002200228020021030b20042003410210061a2002200228020041026a2203360200200141c2006a21010240200528020020036b41014b0d0041004185c1001002200041046a28020021030b20012003410210061a200041046a2201200128020041026a36020020000ba10203017f017e057f2000280204210242002103200041086a2104200041046a2105410021060340024020022004280200490d00410041fbc2001002200528020021020b20022d000021072005200241016a22083602002003200741ff0071200641ff0171220274ad842103200241076a2106200821022007418001710d000b0240024020012802042207200128020022026b22052003a722064f0d002001200620056b1051200041046a2802002108200141046a2802002107200128020021020c010b200520064d0d00200141046a200220066a22073602000b0240200041086a28020020086b200720026b22074f0d0041004185c1001002200041046a28020021080b20022008200710061a200041046a2202200228020020076a36020020000bf80103017f017e027f230041106b22022400200242003703002002410036020820012903002103024002402001410c6a28020020012802086b2204450d002004417f4c0d01200241086a20041020220520046a36020020022005360200200220053602042001410c6a280200200141086a28020022046b22014101480d0020052004200110061a2002200520016a3602040b20002802002000280204220128020422044101756a21002001280200210102402004410171450d00200028020020016a28020021010b2000200320022001110100024020022802002201450d0020022001360204200110220b200241106a24000f0b20021028000bbf0302077f017e230041206b22022103200224000240200028021822042000411c6a2802002205460d0002400340200541786a2802002001460d012004200541686a2205470d000c020b0b20042005460d00200541686a2802002105200341206a240020050f0b02400240024020014100410010142204417f4c0d0020044181044f0d0120022004410f6a4170716b22022400410021060c020b410041eec00010020b200410192102410121060b20012002200410141a41c000102022052000360230200542003703000240200441074b0d0041004185c10010020b20052002410810061a200541106a2107200241086a21080240200441786a411f4b0d0041004185c10010020b20072008412010061a20052001360234200320053602182003200529030022093703102003200136020c0240024002402000411c6a22072802002204200041206a2802004f0d00200420093703082004200136021020034100360218200420053602002007200441186a36020020060d010c020b200041186a200341186a200341106a2003410c6a105d2006450d010b2002101a0b200328021821012003410036021802402001450d00200110220b200341206a240020050bc40103027f017e017f230022042105024020012802302000460d00410041bdc10010020b024020002903001013510d00410041ebc10010020b20012903002106200328020022032802002207200328020420076b200141106a22071015024020062001290300510d004100419ec20010020b2004220441506a2203240020032001410810061a200441586a2007412010061a20012802342002200341281017024020062000290310540d00200041106a427e200642017c2006427d561b3703000b200524000bfb0101047f230041306b2204240020042002370328024020012903001013510d004100418ac10010020b20042003360214200420013602102004200441286a36021841c000102022032001200441106a105c1a2004200336022020042003290300220237031020042003280234220536020c024002402001411c6a22062802002207200141206a2802004f0d00200720023703082007200536021020044100360220200720033602002006200741186a3602000c010b200141186a200441206a200441106a2004410c6a105d0b2000200336020420002001360200200428022021012004410036022002402001450d00200110220b200441306a24000b960305027f017e017f017e017f230041d0006b2202240020002802002103024020012802002201280208200128020422006b411f4b0d0041004185c1001002200141046a28020021000b200241306a2000412010061a200141046a2201200128020041206a3602004200210441102101200241106a2105410021004200210602400340200241306a20006a2107024020014102490d002006420886200420073100008422044238888421062001417f6a210120044208862104200041016a22004120470d010c020b024020014101460d00410041ffc20010020b200520063703082005200420073100008437030041102101200541106a21054200210442002106200041016a22004120470d000b0b024020014110460d00024020014102490d00200220042006200141037441786a1011200241086a2903002106200229030021040b20052004370300200520063703080b20032002290310370300200341086a2002290318370300200341186a200241106a41186a290300370300200341106a200241106a41106a290300370300200241d0006a24000bba0101047f230041106b22022103200224000240024002400240024010042204450d002004418004490d012004101921020c020b2003420037030841002102200341086a21050c020b20022004410f6a4170716b220224000b2002200410051a20034200370308200341086a2105200441074b0d010b41004185c10010020b20052002410810061a20034200370300200241086a2102024020044178714108470d0041004185c10010020b20032002410810061a200341106a24000b4401037f230022022103024010042204450d00024002402004418004490d002004101921020c010b20022004410f6a4170716b220224000b2002200410051a0b200324000b4401037f230022022103024010042204450d00024002402004418004490d002004101921020c010b20022004410f6a4170716b220224000b2002200410051a0b200324000b4401037f230022022103024010042204450d00024002402004418004490d002004101921020c010b20022004410f6a4170716b220224000b2002200410051a0b200324000b4401037f230022022103024010042204450d00024002402004418004490d002004101921020c010b20022004410f6a4170716b220224000b2002200410051a0b200324000b4401037f230022022103024010042204450d00024002402004418004490d002004101921020c010b20022004410f6a4170716b220224000b2002200410051a0b200324000b4401037f230022022103024010042204450d00024002402004418004490d002004101921020c010b20022004410f6a4170716b220224000b2002200410051a0b200324000bd30201047f230041306b2202210320022400024002400240024010042204450d002004418004490d012004101921020c020b410021020c020b20022004410f6a4170716b220224000b2002200410051a0b20032002360224200320023602202003200220046a2205360228200342003703180240200441074b0d0041004185c1001002200341286a2802002105200328022421020b200341186a2002410810061a2003200241086a2202360224024020052002470d0041004185c1001002200341206a41086a2802002105200328022421020b200341176a2002410110061a2003200241016a2202360224024020052002470d0041004185c1001002200328022421020b200341166a2002410110061a2003200241016a3602242003410036021020034200370308200341206a200341086a10431a024020032802082202450d002003200236020c200210220b200341306a24000bbe0201067f0240024002400240024020002802082202200028020422036b20014f0d002003200028020022046b220520016a2206417f4c0d0241ffffffff0721070240200220046b220241feffffff034b0d0020062002410174220220022006491b2207450d020b2007102021020c030b200041046a21000340200341003a00002000200028020041016a22033602002001417f6a22010d000c040b0b41002107410021020c010b20001028000b200220076a2107200320016a20046b2104200220056a220521030340200341003a0000200341016a21032001417f6a22010d000b200220046a21042005200041046a2206280200200028020022016b22036b2102024020034101480d0020022001200310061a200028020021010b2000200236020020062004360200200041086a20073602002001450d00200110220f0b0bd00102047f017e230041106b22022103200224000240024002400240024010042204450d002004418004490d012004101921020c020b2003420037030841002102200341086a21050c020b20022004410f6a4170716b220224000b2002200410051a20034200370308200341086a2105200441074b0d010b41004185c10010020b20052002410810061a200241086a2102024020044108470d0041004185c10010020b200341076a2002410110061a2003290308210620032d0007210420001007200620044100471008200341106a24000bab0202047f047e230041206b22022103200224000240024002400240024010042204450d002004418004490d012004101921020c020b2003420037031841002102200341186a21050c020b20022004410f6a4170716b220224000b2002200410051a20034200370318200341186a2105200441074b0d010b41004185c10010020b20052002410810061a200241086a21050240200441787122044108470d0041004185c10010020b200341106a2005410810061a200241106a2105024020044110470d0041004185c10010020b200341086a2005410810061a200241186a2102024020044118470d0041004185c10010020b20032002410810061a200329030021062003290308210720032903102108200329031821092000100720092008200720061009200341206a24000bd30101047f230041206b22022103200224000240024002400240024010042204450d002004418004490d012004101921020c020b41002102200341186a21050c020b20022004410f6a4170716b220224000b2002200410051a200341186a2105200441074b0d010b41004185c10010020b20052002410810061a200241086a21050240200441787122044108470d0041004185c10010020b200341106a2005410810061a200241106a2102024020044110470d0041004185c10010020b200341086a2002410810061a20001007200341206a24000bc60301047f23004180016b220221032002240041002104024010042205450d00024002402005418004490d002005101921040c010b20022005410f6a4170716b220424000b2004200510051a0b20032004360254200320043602502003200420056a3602582003410036024820034200370340200341d0006a200341c0006a10411a200341106a41086a2204200328025836020020032003290350370310200341e0006a41086a2205200428020036020020032003290310370360200341f0006a41086a20052802002204360200200341386a20043602002003200037032020032001370328200320032903602200370330200320003703702003410036020820034200370300200328024420032802406b220441306d2105024002402004450d00200541d6aad52a4f0d01200341086a200410202204200541306c6a36020020032004360200200320043602042003280244200328024022026b22054101480d0020042002200510061a20032003280204200541306e41306c6a3602040b200341206a20031038024020032802002204450d0020032004360204200410220b024020032802402204450d0020032004360244200410220b20034180016a24000f0b20031028000bc60301067f0240024002400240024020002802082202200028020422036b41306d20014f0d002003200028020022046b41306d220520016a220641d6aad52a4f0d0241d5aad52a21030240200220046b41306d220241a9d5aa154b0d0020062002410174220320032006491b2203450d020b200341306c102021040c030b200041046a21020340200341086a2200420037030020034200370300200341286a4200370300200341206a4200370300200341186a4200370300200341106a4200370300200041003602002002200228020041306a22033602002001417f6a22010d000c040b0b41002103410021040c010b20001028000b2004200341306c6a21072004200541306c6a220521030340200341086a2202420037030020034200370300200341286a4200370300200341206a4200370300200341186a4200370300200341106a420037030020024100360200200341306a21032001417f6a22010d000b2004200641306c6a21042005200041046a2206280200200028020022036b220141506d41306c6a2102024020014101480d0020022003200110061a200028020021030b2000200236020020062004360200200041086a20073602002003450d00200310220f0b0b8a0101037f230041e0006b2202210320022400024002400240024010042204450d002004418004490d012004101921020c020b410021020c020b20022004410f6a4170716b220224000b2002200410051a0b20032002360254200320023602502003200220046a360258200341d0006a200341086a10421a20001007200341086a1029200341e0006a24000b950101047f230041106b22022103200224000240024002400240024010042204450d002004418004490d012004101921020c020b2003420037030841002102200341086a21050c020b20022004410f6a4170716b220224000b2002200410051a20034200370308200341086a2105200441074b0d010b41004185c10010020b20052002410810061a20032903081007200341106a24000bd70303047f027e017f230041f0006b2202210320022400024002400240024010042204450d002004418004490d012004101921050c020b410021050c020b20022004410f6a4170716b220524000b2005200410051a0b42002106200341286a420037030041102102200341106a41106a4200370300200342003703182003420037031002402004411f4b0d0041004185c10010020b200341d0006a2005412010061a200341306a2105410021044200210702400340200341d0006a20046a2108024020024102490d002007420886200620083100008422064238888421072002417f6a210220064208862106200441016a22044120470d010c020b024020024101460d00410041ffc20010020b200520073703082005200620083100008437030041102102200541106a21054200210642002107200441016a22044120470d000b0b024020024110460d00024020024102490d00200320062007200241037441786a1011200341086a2903002107200329030021060b20052006370300200520073703080b200341106a41186a200341306a41186a290300370300200341106a41106a200341306a41106a290300370300200320032903383703182003200329033037031020001007200341106a102c200341f0006a24000be00303047f027e017f230041f0006b2202210320022400024002400240024010042204450d002004418004490d012004101921050c020b410021050c020b20022004410f6a4170716b220524000b2005200410051a0b42002106200341286a420037030041102102200341106a41106a4200370300200342003703182003420037031002402004411f4b0d0041004185c10010020b200341d0006a2005412010061a200341306a2105410021044200210702400340200341d0006a20046a2108024020024102490d002007420886200620083100008422064238888421072002417f6a210220064208862106200441016a22044120470d010c020b024020024101460d00410041ffc20010020b200520073703082005200620083100008437030041102102200541106a21054200210642002107200441016a22044120470d000b0b024020024110460d00024020024102490d00200320062007200241037441786a1011200341086a2903002107200329030021060b20052006370300200520073703080b200341106a41186a200341306a41186a290300370300200341106a41106a200341306a41106a29030037030020032003290338370318200320032903303703100240200341106a102b0d00410041d9c20010020b200341f0006a24000beb0201037f23004180016b2202210320022400024002400240024010042204450d002004418004490d012004101921020c020b410021020c020b20022004410f6a4170716b220224000b2002200410051a0b20032002360254200320023602502003200220046a360258200342003703480240200441074b0d0041004185c1001002200328025421020b200341c8006a2002410810061a2003200241086a3602542003410036024020034200370338200341d0006a200341386a10431a200341086a41086a2202200341d0006a41086a28020036020020032003290350370308200341e0006a41086a2204200228020036020020032003290308370360200341f0006a41086a20042802002202360200200341306a2002360200200320003703182003200137032020032003290360220037032820032000370370200341186a2003290348200341386a103d024020032802382202450d002003200236023c200210220b20034180016a24000bbc0102037f017e230041306b22032400200020013602302000420037030020002002280204220428020029030037030020022802002101200428020422042802002205200428020420056b200041106a2204101520032000410810061a20034108722004412010061a2000200129030842808080809aecb4ee31200228020829030020002903002206200341281016360234024020062001290310540d00200141106a427e200642017c2006427d561b3703000b200341306a240020000baa0301057f024002402000280204200028020022046b41186d220541016a220641abd5aad5004f0d0041aad5aad500210702400240200028020820046b41186d220441d4aad52a4b0d0020062004410174220720072006491b2207450d010b200741186c102021040c020b41002107410021040c010b20001028000b20012802002106200141003602002004200541186c22086a2201200636020020012002290300370308200120032802003602102004200741186c6a2105200141186a210602400240200041046a280200220220002802002207460d00200420086a41686a21010340200241686a220428020021032004410036020020012003360200200141106a200241786a280200360200200141086a200241706a290300370300200141686a21012004210220072004470d000b200141186a2101200041046a2802002107200028020021020c010b200721020b20002001360200200041046a2006360200200041086a2005360200024020072002460d000340200741686a220728020021012007410036020002402001450d00200110220b20022007470d000b0b02402002450d00200210220b0b0bdf030b00419cc0000b4c6661696c656420746f20616c6c6f63617465207061676573006f626a6563742070617373656420746f206974657261746f725f746f206973206e6f7420696e206d756c74695f696e646578000041e8c0000b1d7772697465006572726f722072656164696e67206974657261746f7200004185c1000b05726561640000418ac1000b3363616e6e6f7420637265617465206f626a6563747320696e207461626c65206f6620616e6f7468657220636f6e7472616374000041bdc1000b2e6f626a6563742070617373656420746f206d6f64696679206973206e6f7420696e206d756c74695f696e646578000041ebc1000b3363616e6e6f74206d6f64696679206f626a6563747320696e207461626c65206f6620616e6f7468657220636f6e74726163740000419ec2000b3b757064617465722063616e6e6f74206368616e6765207072696d617279206b6579207768656e206d6f64696679696e6720616e206f626a656374000041d9c2000b2270726f746f636f6c2066656174757265206973206e6f7420616374697661746564000041fbc2000b04676574000041ffc2000b2c756e6578706563746564206572726f7220696e2066697865645f627974657320636f6e7374727563746f72000041000b04b02100000000000000000000000003917c562680b415b93db73416ff29230dfbe7ab1ba4d208b46029d01333cd3a03000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b5010000000000ea30556ab602000000000000000000000000 DMLOG CREATION_OP ROOT 0 DMLOG RAM_OP 0 eosio abi update setabi eosio 180538 44 DMLOG RAM_OP 0 eosio:eosio:abihash table add create_table eosio 180650 112 @@ -46,82 +46,86 @@ DMLOG TBL_OP INS 0 eosio eosio abihash eosio DMLOG RAM_OP 0 eosio:eosio:abihash:eosio table_row add primary_index_add eosio 180802 152 DMLOG DB_OP INS 0 eosio eosio eosio abihash eosio 0000000000ea3055d7abd75d188060de8a01ab2672d1cc2cd768fddc56203181b43685cc11f5ce46 DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304002,"value_ex":41298,"consumed":7136},"cpu_usage":{"last_ordinal":1262304002,"value_ex":24307,"consumed":4101},"ram_usage":180802} -DMLOG APPLIED_TRANSACTION 3 78216184577675cf681592f18c754116fdf63576c1fa05b7566dd6ae6fe2ed8003000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0100d00700008101000000000000000008040000000000000001010000010000000000ea3055e7de58a9939c6e694d3235202685f51b7fab8e82b1f9f96a637dafd9be0998a204000000000000000400000000000000010000000000ea3055040000000000000001010000000000ea30550000000000ea305500000000b863b2c2010000000000ea305500000000a8ed32328a110000000000ea305580110e656f73696f3a3a6162692f312e310019086162695f686173680002056f776e6572046e616d6504686173680b636865636b73756d32353608616374697661746500010e666561747572655f6469676573740b636865636b73756d32353609617574686f726974790004097468726573686f6c640675696e743332046b6579730c6b65795f7765696768745b5d086163636f756e7473197065726d697373696f6e5f6c6576656c5f7765696768745b5d0577616974730d776169745f7765696768745b5d15626c6f636b636861696e5f706172616d65746572730011136d61785f626c6f636b5f6e65745f75736167650675696e7436341a7461726765745f626c6f636b5f6e65745f75736167655f7063740675696e743332196d61785f7472616e73616374696f6e5f6e65745f75736167650675696e7433321e626173655f7065725f7472616e73616374696f6e5f6e65745f75736167650675696e743332106e65745f75736167655f6c65657761790675696e74333223636f6e746578745f667265655f646973636f756e745f6e65745f75736167655f6e756d0675696e74333223636f6e746578745f667265655f646973636f756e745f6e65745f75736167655f64656e0675696e743332136d61785f626c6f636b5f6370755f75736167650675696e7433321a7461726765745f626c6f636b5f6370755f75736167655f7063740675696e743332196d61785f7472616e73616374696f6e5f6370755f75736167650675696e743332196d696e5f7472616e73616374696f6e5f6370755f75736167650675696e743332186d61785f7472616e73616374696f6e5f6c69666574696d650675696e7433321e64656665727265645f7472785f65787069726174696f6e5f77696e646f770675696e743332156d61785f7472616e73616374696f6e5f64656c61790675696e743332166d61785f696e6c696e655f616374696f6e5f73697a650675696e743332176d61785f696e6c696e655f616374696f6e5f64657074680675696e743136136d61785f617574686f726974795f64657074680675696e7431360b63616e63656c64656c617900020e63616e63656c696e675f61757468107065726d697373696f6e5f6c6576656c067472785f69640b636865636b73756d3235360a64656c657465617574680002076163636f756e74046e616d650a7065726d697373696f6e046e616d650a6b65795f7765696768740002036b65790a7075626c69635f6b6579067765696768740675696e743136086c696e6b617574680004076163636f756e74046e616d6504636f6465046e616d650474797065046e616d650b726571756972656d656e74046e616d650a6e65776163636f756e7400040763726561746f72046e616d65046e616d65046e616d65056f776e657209617574686f726974790661637469766509617574686f72697479076f6e6572726f7200020973656e6465725f69640775696e743132380873656e745f747278056279746573107065726d697373696f6e5f6c6576656c0002056163746f72046e616d650a7065726d697373696f6e046e616d65177065726d697373696f6e5f6c6576656c5f77656967687400020a7065726d697373696f6e107065726d697373696f6e5f6c6576656c067765696768740675696e7431360c70726f64756365725f6b657900020d70726f64756365725f6e616d65046e616d6511626c6f636b5f7369676e696e675f6b65790a7075626c69635f6b65790c72657161637469766174656400010e666561747572655f6469676573740b636865636b73756d323536077265716175746800010466726f6d046e616d65067365746162690002076163636f756e74046e616d65036162690562797465730a736574616c696d6974730004076163636f756e74046e616d650972616d5f627974657305696e7436340a6e65745f77656967687405696e7436340a6370755f77656967687405696e74363407736574636f64650004076163636f756e74046e616d6506766d747970650575696e743809766d76657273696f6e0575696e743804636f64650562797465730a736574676c696d69747300030372616d0675696e743634036e65740675696e743634036370750675696e74363409736574706172616d73000106706172616d7315626c6f636b636861696e5f706172616d657465727307736574707269760002076163636f756e74046e616d650769735f707269760575696e74380873657470726f64730001087363686564756c650e70726f64756365725f6b65795b5d0a756e6c696e6b617574680003076163636f756e74046e616d6504636f6465046e616d650474797065046e616d650a757064617465617574680004076163636f756e74046e616d650a7065726d697373696f6e046e616d6506706172656e74046e616d65046175746809617574686f726974790b776169745f776569676874000208776169745f7365630675696e743332067765696768740675696e743136110000002a9bed32320861637469766174650000bc892a4585a6410b63616e63656c64656c6179000040cbdaa8aca24a0a64656c65746561757468000000002d6b03a78b086c696e6b617574680000409e9a2264b89a0a6e65776163636f756e7400000000e0d27bd5a4076f6e6572726f7200905436db6564acba0c72657161637469766174656400000000a0656dacba07726571617574680000000000b863b2c206736574616269000000ce4eba68b2c20a736574616c696d6974730000000040258ab2c207736574636f6465000000ce4ebac8b2c20a736574676c696d697473000000c0d25c53b3c209736574706172616d730000000060bb5bb3c207736574707269760000000038d15bb3c20873657470726f6473000040cbdac0e9e2d40a756e6c696e6b61757468000040cbdaa86c52d50a757064617465617574680001000000a061d3dc31036936340000086162695f6861736800000000000000000000000000000078216184577675cf681592f18c754116fdf63576c1fa05b7566dd6ae6fe2ed8003000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd010000000000ea3055340100000000000000000000000000 +DMLOG APPLIED_TRANSACTION 3 78216184577675cf681592f18c754116fdf63576c1fa05b7566dd6ae6fe2ed8003000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50100d00700008101000000000000000008040000000000000001010000010000000000ea3055e7de58a9939c6e694d3235202685f51b7fab8e82b1f9f96a637dafd9be0998a204000000000000000400000000000000010000000000ea3055040000000000000001010000000000ea30550000000000ea305500000000b863b2c2010000000000ea305500000000a8ed32328a110000000000ea305580110e656f73696f3a3a6162692f312e310019086162695f686173680002056f776e6572046e616d6504686173680b636865636b73756d32353608616374697661746500010e666561747572655f6469676573740b636865636b73756d32353609617574686f726974790004097468726573686f6c640675696e743332046b6579730c6b65795f7765696768745b5d086163636f756e7473197065726d697373696f6e5f6c6576656c5f7765696768745b5d0577616974730d776169745f7765696768745b5d15626c6f636b636861696e5f706172616d65746572730011136d61785f626c6f636b5f6e65745f75736167650675696e7436341a7461726765745f626c6f636b5f6e65745f75736167655f7063740675696e743332196d61785f7472616e73616374696f6e5f6e65745f75736167650675696e7433321e626173655f7065725f7472616e73616374696f6e5f6e65745f75736167650675696e743332106e65745f75736167655f6c65657761790675696e74333223636f6e746578745f667265655f646973636f756e745f6e65745f75736167655f6e756d0675696e74333223636f6e746578745f667265655f646973636f756e745f6e65745f75736167655f64656e0675696e743332136d61785f626c6f636b5f6370755f75736167650675696e7433321a7461726765745f626c6f636b5f6370755f75736167655f7063740675696e743332196d61785f7472616e73616374696f6e5f6370755f75736167650675696e743332196d696e5f7472616e73616374696f6e5f6370755f75736167650675696e743332186d61785f7472616e73616374696f6e5f6c69666574696d650675696e7433321e64656665727265645f7472785f65787069726174696f6e5f77696e646f770675696e743332156d61785f7472616e73616374696f6e5f64656c61790675696e743332166d61785f696e6c696e655f616374696f6e5f73697a650675696e743332176d61785f696e6c696e655f616374696f6e5f64657074680675696e743136136d61785f617574686f726974795f64657074680675696e7431360b63616e63656c64656c617900020e63616e63656c696e675f61757468107065726d697373696f6e5f6c6576656c067472785f69640b636865636b73756d3235360a64656c657465617574680002076163636f756e74046e616d650a7065726d697373696f6e046e616d650a6b65795f7765696768740002036b65790a7075626c69635f6b6579067765696768740675696e743136086c696e6b617574680004076163636f756e74046e616d6504636f6465046e616d650474797065046e616d650b726571756972656d656e74046e616d650a6e65776163636f756e7400040763726561746f72046e616d65046e616d65046e616d65056f776e657209617574686f726974790661637469766509617574686f72697479076f6e6572726f7200020973656e6465725f69640775696e743132380873656e745f747278056279746573107065726d697373696f6e5f6c6576656c0002056163746f72046e616d650a7065726d697373696f6e046e616d65177065726d697373696f6e5f6c6576656c5f77656967687400020a7065726d697373696f6e107065726d697373696f6e5f6c6576656c067765696768740675696e7431360c70726f64756365725f6b657900020d70726f64756365725f6e616d65046e616d6511626c6f636b5f7369676e696e675f6b65790a7075626c69635f6b65790c72657161637469766174656400010e666561747572655f6469676573740b636865636b73756d323536077265716175746800010466726f6d046e616d65067365746162690002076163636f756e74046e616d65036162690562797465730a736574616c696d6974730004076163636f756e74046e616d650972616d5f627974657305696e7436340a6e65745f77656967687405696e7436340a6370755f77656967687405696e74363407736574636f64650004076163636f756e74046e616d6506766d747970650575696e743809766d76657273696f6e0575696e743804636f64650562797465730a736574676c696d69747300030372616d0675696e743634036e65740675696e743634036370750675696e74363409736574706172616d73000106706172616d7315626c6f636b636861696e5f706172616d657465727307736574707269760002076163636f756e74046e616d650769735f707269760575696e74380873657470726f64730001087363686564756c650e70726f64756365725f6b65795b5d0a756e6c696e6b617574680003076163636f756e74046e616d6504636f6465046e616d650474797065046e616d650a757064617465617574680004076163636f756e74046e616d650a7065726d697373696f6e046e616d6506706172656e74046e616d65046175746809617574686f726974790b776169745f776569676874000208776169745f7365630675696e743332067765696768740675696e743136110000002a9bed32320861637469766174650000bc892a4585a6410b63616e63656c64656c6179000040cbdaa8aca24a0a64656c65746561757468000000002d6b03a78b086c696e6b617574680000409e9a2264b89a0a6e65776163636f756e7400000000e0d27bd5a4076f6e6572726f7200905436db6564acba0c72657161637469766174656400000000a0656dacba07726571617574680000000000b863b2c206736574616269000000ce4eba68b2c20a736574616c696d6974730000000040258ab2c207736574636f6465000000ce4ebac8b2c20a736574676c696d697473000000c0d25c53b3c209736574706172616d730000000060bb5bb3c207736574707269760000000038d15bb3c20873657470726f6473000040cbdac0e9e2d40a756e6c696e6b61757468000040cbdaa86c52d50a757064617465617574680001000000a061d3dc31036936340000086162695f6861736800000000000000000000000000000078216184577675cf681592f18c754116fdf63576c1fa05b7566dd6ae6fe2ed8003000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b5010000000000ea3055340100000000000000000000000000 DMLOG CREATION_OP ROOT 0 DMLOG FEATURE_OP PRE_ACTIVATE 0 1a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b7241 {"feature_digest":"1a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b7241","subjective_restrictions":{"enabled":true,"preactivation_required":true,"earliest_allowed_activation_time":"1970-01-01T00:00:00.000"},"description_digest":"f3c3d91c4603cde2397268bfed4e662465293aab10cd9416db0d442b8cec2949","dependencies":[],"protocol_feature_type":"builtin","specification":[{"name":"builtin_feature_codename","value":"ONLY_LINK_TO_EXISTING_PERMISSION"}]} DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304002,"value_ex":42039,"consumed":7264},"cpu_usage":{"last_ordinal":1262304002,"value_ex":35882,"consumed":6101},"ram_usage":180802} -DMLOG APPLIED_TRANSACTION 3 aa30bc93a59737ce708fd4d691b61d7858bfb309c4cf883e77a6a161b5a4abe503000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0100d007000010000000000000000080000000000000000001010000010000000000ea3055218268a92acd1b24eeaeff3b51b569de14ee151eea2132d748be984aa9535d1405000000000000000500000000000000010000000000ea3055050000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232201a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b724100000000000000000000aa30bc93a59737ce708fd4d691b61d7858bfb309c4cf883e77a6a161b5a4abe503000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0000000000000000 +DMLOG APPLIED_TRANSACTION 3 aa30bc93a59737ce708fd4d691b61d7858bfb309c4cf883e77a6a161b5a4abe503000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50100d007000010000000000000000080000000000000000001010000010000000000ea3055218268a92acd1b24eeaeff3b51b569de14ee151eea2132d748be984aa9535d1405000000000000000500000000000000010000000000ea3055050000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232201a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b724100000000000000000000aa30bc93a59737ce708fd4d691b61d7858bfb309c4cf883e77a6a161b5a4abe503000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50000000000000000 DMLOG CREATION_OP ROOT 0 DMLOG FEATURE_OP PRE_ACTIVATE 0 ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea99 {"feature_digest":"ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea99","subjective_restrictions":{"enabled":true,"preactivation_required":true,"earliest_allowed_activation_time":"1970-01-01T00:00:00.000"},"description_digest":"9908b3f8413c8474ab2a6be149d3f4f6d0421d37886033f27d4759c47a26d944","dependencies":[],"protocol_feature_type":"builtin","specification":[{"name":"builtin_feature_codename","value":"REPLACE_DEFERRED"}]} DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304002,"value_ex":42780,"consumed":7392},"cpu_usage":{"last_ordinal":1262304002,"value_ex":47457,"consumed":8101},"ram_usage":180802} -DMLOG APPLIED_TRANSACTION 3 3f12eecaafb41ec5142c6c6d69df767fb8f5183e1e5468aa418bef38a2bdf2bb03000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0100d007000010000000000000000080000000000000000001010000010000000000ea305513ab6d113ba5b180d6f68e1b67bdea99847550d673a1785e40dfe4faee8ec7c706000000000000000600000000000000010000000000ea3055060000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea99000000000000000000003f12eecaafb41ec5142c6c6d69df767fb8f5183e1e5468aa418bef38a2bdf2bb03000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0000000000000000 +DMLOG APPLIED_TRANSACTION 3 3f12eecaafb41ec5142c6c6d69df767fb8f5183e1e5468aa418bef38a2bdf2bb03000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50100d007000010000000000000000080000000000000000001010000010000000000ea305513ab6d113ba5b180d6f68e1b67bdea99847550d673a1785e40dfe4faee8ec7c706000000000000000600000000000000010000000000ea3055060000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea99000000000000000000003f12eecaafb41ec5142c6c6d69df767fb8f5183e1e5468aa418bef38a2bdf2bb03000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50000000000000000 DMLOG CREATION_OP ROOT 0 DMLOG FEATURE_OP PRE_ACTIVATE 0 4a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0f {"feature_digest":"4a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0f","subjective_restrictions":{"enabled":true,"preactivation_required":true,"earliest_allowed_activation_time":"1970-01-01T00:00:00.000"},"description_digest":"45967387ee92da70171efd9fefd1ca8061b5efe6f124d269cd2468b47f1575a0","dependencies":["ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea99"],"protocol_feature_type":"builtin","specification":[{"name":"builtin_feature_codename","value":"NO_DUPLICATE_DEFERRED_ID"}]} DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304002,"value_ex":43521,"consumed":7520},"cpu_usage":{"last_ordinal":1262304002,"value_ex":59032,"consumed":10101},"ram_usage":180802} -DMLOG APPLIED_TRANSACTION 3 39ec55367e4e4d0d6063a5e5aa2aa15d4a1aa1fbe0abe42c9081713ee04e55b103000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0100d007000010000000000000000080000000000000000001010000010000000000ea30552267bc3ee69f217c4f0bdbff84c23074f1780839b8adfb17537db55da4a0dc7607000000000000000700000000000000010000000000ea3055070000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232204a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0f0000000000000000000039ec55367e4e4d0d6063a5e5aa2aa15d4a1aa1fbe0abe42c9081713ee04e55b103000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0000000000000000 +DMLOG APPLIED_TRANSACTION 3 39ec55367e4e4d0d6063a5e5aa2aa15d4a1aa1fbe0abe42c9081713ee04e55b103000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50100d007000010000000000000000080000000000000000001010000010000000000ea30552267bc3ee69f217c4f0bdbff84c23074f1780839b8adfb17537db55da4a0dc7607000000000000000700000000000000010000000000ea3055070000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232204a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0f0000000000000000000039ec55367e4e4d0d6063a5e5aa2aa15d4a1aa1fbe0abe42c9081713ee04e55b103000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50000000000000000 DMLOG CREATION_OP ROOT 0 DMLOG FEATURE_OP PRE_ACTIVATE 0 e0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff526 {"feature_digest":"e0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff526","subjective_restrictions":{"enabled":true,"preactivation_required":true,"earliest_allowed_activation_time":"1970-01-01T00:00:00.000"},"description_digest":"a98241c83511dc86c857221b9372b4aa7cea3aaebc567a48604e1d3db3557050","dependencies":[],"protocol_feature_type":"builtin","specification":[{"name":"builtin_feature_codename","value":"FIX_LINKAUTH_RESTRICTION"}]} DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304002,"value_ex":44262,"consumed":7648},"cpu_usage":{"last_ordinal":1262304002,"value_ex":70607,"consumed":12101},"ram_usage":180802} -DMLOG APPLIED_TRANSACTION 3 72c5e78f690d5d20ec8c8e12ace2a3b34929099b93f621a8671ae43df821bc5b03000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0100d007000010000000000000000080000000000000000001010000010000000000ea30550f86c0418ffb919c58d37997594e446d2d98fd38b1ff3849da2c5da410aa331a08000000000000000800000000000000010000000000ea3055080000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220e0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff5260000000000000000000072c5e78f690d5d20ec8c8e12ace2a3b34929099b93f621a8671ae43df821bc5b03000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0000000000000000 +DMLOG APPLIED_TRANSACTION 3 72c5e78f690d5d20ec8c8e12ace2a3b34929099b93f621a8671ae43df821bc5b03000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50100d007000010000000000000000080000000000000000001010000010000000000ea30550f86c0418ffb919c58d37997594e446d2d98fd38b1ff3849da2c5da410aa331a08000000000000000800000000000000010000000000ea3055080000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220e0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff5260000000000000000000072c5e78f690d5d20ec8c8e12ace2a3b34929099b93f621a8671ae43df821bc5b03000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50000000000000000 DMLOG CREATION_OP ROOT 0 DMLOG FEATURE_OP PRE_ACTIVATE 0 68dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a297428 {"feature_digest":"68dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a297428","subjective_restrictions":{"enabled":true,"preactivation_required":true,"earliest_allowed_activation_time":"1970-01-01T00:00:00.000"},"description_digest":"2853617cec3eabd41881eb48882e6fc5e81a0db917d375057864b3befbe29acd","dependencies":[],"protocol_feature_type":"builtin","specification":[{"name":"builtin_feature_codename","value":"DISALLOW_EMPTY_PRODUCER_SCHEDULE"}]} DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304002,"value_ex":45003,"consumed":7776},"cpu_usage":{"last_ordinal":1262304002,"value_ex":82182,"consumed":14101},"ram_usage":180802} -DMLOG APPLIED_TRANSACTION 3 e358ede0d30a5ac5fa03a484a5142b0a38f658e0fb57644adb5b60c94206f9e003000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0100d007000010000000000000000080000000000000000001010000010000000000ea3055659dd999c0cb81c2eea85d3eda39898997e4a9bd57bcebcac06cc25db35e000b09000000000000000900000000000000010000000000ea3055090000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed32322068dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a29742800000000000000000000e358ede0d30a5ac5fa03a484a5142b0a38f658e0fb57644adb5b60c94206f9e003000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0000000000000000 +DMLOG APPLIED_TRANSACTION 3 e358ede0d30a5ac5fa03a484a5142b0a38f658e0fb57644adb5b60c94206f9e003000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50100d007000010000000000000000080000000000000000001010000010000000000ea3055659dd999c0cb81c2eea85d3eda39898997e4a9bd57bcebcac06cc25db35e000b09000000000000000900000000000000010000000000ea3055090000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed32322068dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a29742800000000000000000000e358ede0d30a5ac5fa03a484a5142b0a38f658e0fb57644adb5b60c94206f9e003000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50000000000000000 DMLOG CREATION_OP ROOT 0 DMLOG FEATURE_OP PRE_ACTIVATE 0 ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c43 {"feature_digest":"ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c43","subjective_restrictions":{"enabled":true,"preactivation_required":true,"earliest_allowed_activation_time":"1970-01-01T00:00:00.000"},"description_digest":"e71b6712188391994c78d8c722c1d42c477cf091e5601b5cf1befd05721a57f3","dependencies":[],"protocol_feature_type":"builtin","specification":[{"name":"builtin_feature_codename","value":"RESTRICT_ACTION_TO_SELF"}]} DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304002,"value_ex":45744,"consumed":7904},"cpu_usage":{"last_ordinal":1262304002,"value_ex":93757,"consumed":16101},"ram_usage":180802} -DMLOG APPLIED_TRANSACTION 3 60b8a605178774eed85eb65b3ae743e5f3dc9b11d4672e1d00be33a0d21c8dae03000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0100d007000010000000000000000080000000000000000001010000010000000000ea3055d209fd21b66b7e1f62b25302fd208120700fb20e0a9a0151d3909e1ca7a98f460a000000000000000a00000000000000010000000000ea30550a0000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c430000000000000000000060b8a605178774eed85eb65b3ae743e5f3dc9b11d4672e1d00be33a0d21c8dae03000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0000000000000000 +DMLOG APPLIED_TRANSACTION 3 60b8a605178774eed85eb65b3ae743e5f3dc9b11d4672e1d00be33a0d21c8dae03000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50100d007000010000000000000000080000000000000000001010000010000000000ea3055d209fd21b66b7e1f62b25302fd208120700fb20e0a9a0151d3909e1ca7a98f460a000000000000000a00000000000000010000000000ea30550a0000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c430000000000000000000060b8a605178774eed85eb65b3ae743e5f3dc9b11d4672e1d00be33a0d21c8dae03000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50000000000000000 DMLOG CREATION_OP ROOT 0 DMLOG FEATURE_OP PRE_ACTIVATE 0 8ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a405 {"feature_digest":"8ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a405","subjective_restrictions":{"enabled":true,"preactivation_required":true,"earliest_allowed_activation_time":"1970-01-01T00:00:00.000"},"description_digest":"2f1f13e291c79da5a2bbad259ed7c1f2d34f697ea460b14b565ac33b063b73e2","dependencies":[],"protocol_feature_type":"builtin","specification":[{"name":"builtin_feature_codename","value":"ONLY_BILL_FIRST_AUTHORIZER"}]} DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304002,"value_ex":46485,"consumed":8032},"cpu_usage":{"last_ordinal":1262304002,"value_ex":105332,"consumed":18101},"ram_usage":180802} -DMLOG APPLIED_TRANSACTION 3 689db7ff0751fd6025dbc997d9a7ca1fe4e525ee48e55e5fb2aee8403077dd3e03000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0100d007000010000000000000000080000000000000000001010000010000000000ea3055fd71f42952743b790fcaa82dabd6a843676b9bd5b91c891fc050f9c41374a35e0b000000000000000b00000000000000010000000000ea30550b0000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232208ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a40500000000000000000000689db7ff0751fd6025dbc997d9a7ca1fe4e525ee48e55e5fb2aee8403077dd3e03000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0000000000000000 +DMLOG APPLIED_TRANSACTION 3 689db7ff0751fd6025dbc997d9a7ca1fe4e525ee48e55e5fb2aee8403077dd3e03000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50100d007000010000000000000000080000000000000000001010000010000000000ea3055fd71f42952743b790fcaa82dabd6a843676b9bd5b91c891fc050f9c41374a35e0b000000000000000b00000000000000010000000000ea30550b0000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232208ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a40500000000000000000000689db7ff0751fd6025dbc997d9a7ca1fe4e525ee48e55e5fb2aee8403077dd3e03000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50000000000000000 DMLOG CREATION_OP ROOT 0 DMLOG FEATURE_OP PRE_ACTIVATE 0 2652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed25 {"feature_digest":"2652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed25","subjective_restrictions":{"enabled":true,"preactivation_required":true,"earliest_allowed_activation_time":"1970-01-01T00:00:00.000"},"description_digest":"898082c59f921d0042e581f00a59d5ceb8be6f1d9c7a45b6f07c0e26eaee0222","dependencies":[],"protocol_feature_type":"builtin","specification":[{"name":"builtin_feature_codename","value":"FORWARD_SETCODE"}]} DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304002,"value_ex":47226,"consumed":8160},"cpu_usage":{"last_ordinal":1262304002,"value_ex":116907,"consumed":20101},"ram_usage":180802} -DMLOG APPLIED_TRANSACTION 3 48ed94d5a6fa7dd478278b29bbff0a72bd9d9a5431423ed3f0b1ce393643108303000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0100d007000010000000000000000080000000000000000001010000010000000000ea305512250767854476ab3904c7f604b0322bfa91821d01ddb20ecfaaff1beef8e04b0c000000000000000c00000000000000010000000000ea30550c0000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232202652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed250000000000000000000048ed94d5a6fa7dd478278b29bbff0a72bd9d9a5431423ed3f0b1ce393643108303000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0000000000000000 +DMLOG APPLIED_TRANSACTION 3 48ed94d5a6fa7dd478278b29bbff0a72bd9d9a5431423ed3f0b1ce393643108303000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50100d007000010000000000000000080000000000000000001010000010000000000ea305512250767854476ab3904c7f604b0322bfa91821d01ddb20ecfaaff1beef8e04b0c000000000000000c00000000000000010000000000ea30550c0000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232202652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed250000000000000000000048ed94d5a6fa7dd478278b29bbff0a72bd9d9a5431423ed3f0b1ce393643108303000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50000000000000000 DMLOG CREATION_OP ROOT 0 DMLOG FEATURE_OP PRE_ACTIVATE 0 f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d {"feature_digest":"f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d","subjective_restrictions":{"enabled":true,"preactivation_required":true,"earliest_allowed_activation_time":"1970-01-01T00:00:00.000"},"description_digest":"1eab748b95a2e6f4d7cb42065bdee5566af8efddf01a55a0a8d831b823f8828a","dependencies":[],"protocol_feature_type":"builtin","specification":[{"name":"builtin_feature_codename","value":"GET_SENDER"}]} DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304002,"value_ex":47967,"consumed":8288},"cpu_usage":{"last_ordinal":1262304002,"value_ex":128482,"consumed":22101},"ram_usage":180802} -DMLOG APPLIED_TRANSACTION 3 aa192243a78a9d8954a3af3f044207536068d3ad3f7ffb3b7de53b959de190b003000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0100d007000010000000000000000080000000000000000001010000010000000000ea3055063f8bf038af0888c33fcfdd66c2f91fd6b060df73aaa32a1e905b143ceb9ac00d000000000000000d00000000000000010000000000ea30550d0000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d00000000000000000000aa192243a78a9d8954a3af3f044207536068d3ad3f7ffb3b7de53b959de190b003000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0000000000000000 +DMLOG APPLIED_TRANSACTION 3 aa192243a78a9d8954a3af3f044207536068d3ad3f7ffb3b7de53b959de190b003000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50100d007000010000000000000000080000000000000000001010000010000000000ea3055063f8bf038af0888c33fcfdd66c2f91fd6b060df73aaa32a1e905b143ceb9ac00d000000000000000d00000000000000010000000000ea30550d0000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d00000000000000000000aa192243a78a9d8954a3af3f044207536068d3ad3f7ffb3b7de53b959de190b003000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50000000000000000 DMLOG CREATION_OP ROOT 0 DMLOG FEATURE_OP PRE_ACTIVATE 0 4e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d67 {"feature_digest":"4e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d67","subjective_restrictions":{"enabled":true,"preactivation_required":true,"earliest_allowed_activation_time":"1970-01-01T00:00:00.000"},"description_digest":"1812fdb5096fd854a4958eb9d53b43219d114de0e858ce00255bd46569ad2c68","dependencies":[],"protocol_feature_type":"builtin","specification":[{"name":"builtin_feature_codename","value":"RAM_RESTRICTIONS"}]} DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304002,"value_ex":48708,"consumed":8416},"cpu_usage":{"last_ordinal":1262304002,"value_ex":140057,"consumed":24101},"ram_usage":180802} -DMLOG APPLIED_TRANSACTION 3 a9e581a81302c707c14f5985458d2ef53faf24afacb03115f5cbc17271d7504803000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0100d007000010000000000000000080000000000000000001010000010000000000ea3055f279231a0740adb280f58749e984c932e17897073e9aedc1c33a102df52498430e000000000000000e00000000000000010000000000ea30550e0000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232204e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d6700000000000000000000a9e581a81302c707c14f5985458d2ef53faf24afacb03115f5cbc17271d7504803000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0000000000000000 +DMLOG APPLIED_TRANSACTION 3 a9e581a81302c707c14f5985458d2ef53faf24afacb03115f5cbc17271d7504803000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50100d007000010000000000000000080000000000000000001010000010000000000ea3055f279231a0740adb280f58749e984c932e17897073e9aedc1c33a102df52498430e000000000000000e00000000000000010000000000ea30550e0000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232204e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d6700000000000000000000a9e581a81302c707c14f5985458d2ef53faf24afacb03115f5cbc17271d7504803000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50000000000000000 DMLOG CREATION_OP ROOT 0 DMLOG FEATURE_OP PRE_ACTIVATE 0 4fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c2 {"feature_digest":"4fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c2","subjective_restrictions":{"enabled":true,"preactivation_required":true,"earliest_allowed_activation_time":"1970-01-01T00:00:00.000"},"description_digest":"927fdf78c51e77a899f2db938249fb1f8bb38f4e43d9c1f75b190492080cbc34","dependencies":[],"protocol_feature_type":"builtin","specification":[{"name":"builtin_feature_codename","value":"WEBAUTHN_KEY"}]} DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304002,"value_ex":49449,"consumed":8544},"cpu_usage":{"last_ordinal":1262304002,"value_ex":151632,"consumed":26101},"ram_usage":180802} -DMLOG APPLIED_TRANSACTION 3 4185b6265a360d2bf774af7d82bd837333cfb6b976390dac78c284207b6bbce103000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0100d007000010000000000000000080000000000000000001010000010000000000ea305578e423734b3bacaadd9c1864e7a7c612255a9c0d9fcdeba49708ee6b147e13170f000000000000000f00000000000000010000000000ea30550f0000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232204fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c2000000000000000000004185b6265a360d2bf774af7d82bd837333cfb6b976390dac78c284207b6bbce103000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0000000000000000 +DMLOG APPLIED_TRANSACTION 3 4185b6265a360d2bf774af7d82bd837333cfb6b976390dac78c284207b6bbce103000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50100d007000010000000000000000080000000000000000001010000010000000000ea305578e423734b3bacaadd9c1864e7a7c612255a9c0d9fcdeba49708ee6b147e13170f000000000000000f00000000000000010000000000ea30550f0000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232204fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c2000000000000000000004185b6265a360d2bf774af7d82bd837333cfb6b976390dac78c284207b6bbce103000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50000000000000000 DMLOG CREATION_OP ROOT 0 DMLOG FEATURE_OP PRE_ACTIVATE 0 299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b4476707 {"feature_digest":"299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b4476707","subjective_restrictions":{"enabled":true,"preactivation_required":true,"earliest_allowed_activation_time":"1970-01-01T00:00:00.000"},"description_digest":"ab76031cad7a457f4fd5f5fca97a3f03b8a635278e0416f77dcc91eb99a48e10","dependencies":[],"protocol_feature_type":"builtin","specification":[{"name":"builtin_feature_codename","value":"WTMSIG_BLOCK_SIGNATURES"}]} DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304002,"value_ex":50190,"consumed":8672},"cpu_usage":{"last_ordinal":1262304002,"value_ex":163207,"consumed":28101},"ram_usage":180802} -DMLOG APPLIED_TRANSACTION 3 f6025d888ddcfb8fdfeee18204122f8b7a71908a96ac4e52bf9542ff398b0d4403000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0100d007000010000000000000000080000000000000000001010000010000000000ea3055368a5df8e81472fb54f3424401fba4956a6e0737806b4f642b2d7014cf66fc2c10000000000000001000000000000000010000000000ea3055100000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b447670700000000000000000000f6025d888ddcfb8fdfeee18204122f8b7a71908a96ac4e52bf9542ff398b0d4403000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0000000000000000 +DMLOG APPLIED_TRANSACTION 3 f6025d888ddcfb8fdfeee18204122f8b7a71908a96ac4e52bf9542ff398b0d4403000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50100d007000010000000000000000080000000000000000001010000010000000000ea3055368a5df8e81472fb54f3424401fba4956a6e0737806b4f642b2d7014cf66fc2c10000000000000001000000000000000010000000000ea3055100000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b447670700000000000000000000f6025d888ddcfb8fdfeee18204122f8b7a71908a96ac4e52bf9542ff398b0d4403000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50000000000000000 DMLOG CREATION_OP ROOT 0 DMLOG FEATURE_OP PRE_ACTIVATE 0 c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead45071 {"feature_digest":"c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead45071","subjective_restrictions":{"enabled":true,"preactivation_required":true,"earliest_allowed_activation_time":"1970-01-01T00:00:00.000"},"description_digest":"69b064c5178e2738e144ed6caa9349a3995370d78db29e494b3126ebd9111966","dependencies":[],"protocol_feature_type":"builtin","specification":[{"name":"builtin_feature_codename","value":"ACTION_RETURN_VALUE"}]} DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304002,"value_ex":50931,"consumed":8800},"cpu_usage":{"last_ordinal":1262304002,"value_ex":174782,"consumed":30101},"ram_usage":180802} -DMLOG APPLIED_TRANSACTION 3 116b232e8995b25d7bab8c5134bc993bcd84e72bc35d0b27fe723d7d25e98ac703000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0100d007000010000000000000000080000000000000000001010000010000000000ea30552acd5ab1218225e0cc0a013d8e86b58cfc4d998058708fb1eb0116c1124f7c7f11000000000000001100000000000000010000000000ea3055110000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead4507100000000000000000000116b232e8995b25d7bab8c5134bc993bcd84e72bc35d0b27fe723d7d25e98ac703000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0000000000000000 +DMLOG APPLIED_TRANSACTION 3 116b232e8995b25d7bab8c5134bc993bcd84e72bc35d0b27fe723d7d25e98ac703000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50100d007000010000000000000000080000000000000000001010000010000000000ea30552acd5ab1218225e0cc0a013d8e86b58cfc4d998058708fb1eb0116c1124f7c7f11000000000000001100000000000000010000000000ea3055110000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead4507100000000000000000000116b232e8995b25d7bab8c5134bc993bcd84e72bc35d0b27fe723d7d25e98ac703000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50000000000000000 DMLOG CREATION_OP ROOT 0 DMLOG FEATURE_OP PRE_ACTIVATE 0 5443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b4 {"feature_digest":"5443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b4","subjective_restrictions":{"enabled":true,"preactivation_required":true,"earliest_allowed_activation_time":"1970-01-01T00:00:00.000"},"description_digest":"70787548dcea1a2c52c913a37f74ce99e6caae79110d7ca7b859936a0075b314","dependencies":[],"protocol_feature_type":"builtin","specification":[{"name":"builtin_feature_codename","value":"BLOCKCHAIN_PARAMETERS"}]} DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304002,"value_ex":51672,"consumed":8928},"cpu_usage":{"last_ordinal":1262304002,"value_ex":186357,"consumed":32101},"ram_usage":180802} -DMLOG APPLIED_TRANSACTION 3 11a09bc0cc023daf656af6dadf37577a9d4c0cea8020c1d007a2c3d6dc1e52c103000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0100d007000010000000000000000080000000000000000001010000010000000000ea3055db17f5e8a451e3814885ec6d61c420ac422f1e0de77043c9024e592b64f8bd1412000000000000001200000000000000010000000000ea3055120000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232205443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b40000000000000000000011a09bc0cc023daf656af6dadf37577a9d4c0cea8020c1d007a2c3d6dc1e52c103000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0000000000000000 +DMLOG APPLIED_TRANSACTION 3 11a09bc0cc023daf656af6dadf37577a9d4c0cea8020c1d007a2c3d6dc1e52c103000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50100d007000010000000000000000080000000000000000001010000010000000000ea3055db17f5e8a451e3814885ec6d61c420ac422f1e0de77043c9024e592b64f8bd1412000000000000001200000000000000010000000000ea3055120000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232205443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b40000000000000000000011a09bc0cc023daf656af6dadf37577a9d4c0cea8020c1d007a2c3d6dc1e52c103000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50000000000000000 DMLOG CREATION_OP ROOT 0 DMLOG FEATURE_OP PRE_ACTIVATE 0 bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e99 {"feature_digest":"bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e99","subjective_restrictions":{"enabled":true,"preactivation_required":true,"earliest_allowed_activation_time":"1970-01-01T00:00:00.000"},"description_digest":"d2596697fed14a0840013647b99045022ae6a885089f35a7e78da7a43ad76ed4","dependencies":[],"protocol_feature_type":"builtin","specification":[{"name":"builtin_feature_codename","value":"GET_CODE_HASH"}]} DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304002,"value_ex":52413,"consumed":9056},"cpu_usage":{"last_ordinal":1262304002,"value_ex":197932,"consumed":34101},"ram_usage":180802} -DMLOG APPLIED_TRANSACTION 3 76bcbbd871a26403befd2ebf5491d6b84ded9f29cb95bfd54ca6ec46b1dfad5903000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0100d007000010000000000000000080000000000000000001010000010000000000ea3055693240e7063adb7478594592f8a6e6cb76e33cabc605272575b687e3a0fa5f5e13000000000000001300000000000000010000000000ea3055130000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e990000000000000000000076bcbbd871a26403befd2ebf5491d6b84ded9f29cb95bfd54ca6ec46b1dfad5903000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0000000000000000 +DMLOG APPLIED_TRANSACTION 3 76bcbbd871a26403befd2ebf5491d6b84ded9f29cb95bfd54ca6ec46b1dfad5903000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50100d007000010000000000000000080000000000000000001010000010000000000ea3055693240e7063adb7478594592f8a6e6cb76e33cabc605272575b687e3a0fa5f5e13000000000000001300000000000000010000000000ea3055130000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e990000000000000000000076bcbbd871a26403befd2ebf5491d6b84ded9f29cb95bfd54ca6ec46b1dfad5903000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50000000000000000 DMLOG CREATION_OP ROOT 0 DMLOG FEATURE_OP PRE_ACTIVATE 0 d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb40 {"feature_digest":"d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb40","subjective_restrictions":{"enabled":true,"preactivation_required":true,"earliest_allowed_activation_time":"1970-01-01T00:00:00.000"},"description_digest":"8139e99247b87f18ef7eae99f07f00ea3adf39ed53f4d2da3f44e6aa0bfd7c62","dependencies":[],"protocol_feature_type":"builtin","specification":[{"name":"builtin_feature_codename","value":"CONFIGURABLE_WASM_LIMITS2"}]} DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304002,"value_ex":53154,"consumed":9184},"cpu_usage":{"last_ordinal":1262304002,"value_ex":209507,"consumed":36101},"ram_usage":180802} -DMLOG APPLIED_TRANSACTION 3 1948411767455fe23b05b44fe5fb737422ce3831a41f2c68064990fd6f52fdaf03000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0100d007000010000000000000000080000000000000000001010000010000000000ea3055a40aa97866a6e0814065142f7d1038aaccb2e8a73661f6554c415c331ab8ec8b14000000000000001400000000000000010000000000ea3055140000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb40000000000000000000001948411767455fe23b05b44fe5fb737422ce3831a41f2c68064990fd6f52fdaf03000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0000000000000000 +DMLOG APPLIED_TRANSACTION 3 1948411767455fe23b05b44fe5fb737422ce3831a41f2c68064990fd6f52fdaf03000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50100d007000010000000000000000080000000000000000001010000010000000000ea3055a40aa97866a6e0814065142f7d1038aaccb2e8a73661f6554c415c331ab8ec8b14000000000000001400000000000000010000000000ea3055140000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb40000000000000000000001948411767455fe23b05b44fe5fb737422ce3831a41f2c68064990fd6f52fdaf03000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50000000000000000 DMLOG CREATION_OP ROOT 0 DMLOG FEATURE_OP PRE_ACTIVATE 0 6bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc {"feature_digest":"6bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc","subjective_restrictions":{"enabled":true,"preactivation_required":true,"earliest_allowed_activation_time":"1970-01-01T00:00:00.000"},"description_digest":"68d6405cb8df3de95bd834ebb408196578500a9f818ff62ccc68f60b932f7d82","dependencies":[],"protocol_feature_type":"builtin","specification":[{"name":"builtin_feature_codename","value":"CRYPTO_PRIMITIVES"}]} DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304002,"value_ex":53895,"consumed":9312},"cpu_usage":{"last_ordinal":1262304002,"value_ex":221082,"consumed":38101},"ram_usage":180802} -DMLOG APPLIED_TRANSACTION 3 3cea935e0deaa090b14d4ee01f3fee31a1c426779f1c32840aefaa99cb83ec5f03000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0100d007000010000000000000000080000000000000000001010000010000000000ea30555705a61c2ae1877963ee8e857abb78d2975071d25ce32f1235b4d4803967a9fa15000000000000001500000000000000010000000000ea3055150000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232206bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc000000000000000000003cea935e0deaa090b14d4ee01f3fee31a1c426779f1c32840aefaa99cb83ec5f03000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0000000000000000 +DMLOG APPLIED_TRANSACTION 3 3cea935e0deaa090b14d4ee01f3fee31a1c426779f1c32840aefaa99cb83ec5f03000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50100d007000010000000000000000080000000000000000001010000010000000000ea30555705a61c2ae1877963ee8e857abb78d2975071d25ce32f1235b4d4803967a9fa15000000000000001500000000000000010000000000ea3055150000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232206bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc000000000000000000003cea935e0deaa090b14d4ee01f3fee31a1c426779f1c32840aefaa99cb83ec5f03000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50000000000000000 DMLOG CREATION_OP ROOT 0 DMLOG FEATURE_OP PRE_ACTIVATE 0 35c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b {"feature_digest":"35c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b","subjective_restrictions":{"enabled":true,"preactivation_required":true,"earliest_allowed_activation_time":"1970-01-01T00:00:00.000"},"description_digest":"e5d7992006e628a38c5e6c28dd55ff5e57ea682079bf41fef9b3cced0f46b491","dependencies":[],"protocol_feature_type":"builtin","specification":[{"name":"builtin_feature_codename","value":"GET_BLOCK_NUM"}]} DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304002,"value_ex":54636,"consumed":9440},"cpu_usage":{"last_ordinal":1262304002,"value_ex":232657,"consumed":40101},"ram_usage":180802} -DMLOG APPLIED_TRANSACTION 3 04ba316cf9ddd86690833edc0f4548f8c07f0d66c09dca029b0a1fb96f16c62803000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0100d007000010000000000000000080000000000000000001010000010000000000ea3055302a2f1713925c939a997367c967b457bfc2c580304f9686b1de22fc5946e40616000000000000001600000000000000010000000000ea3055160000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed32322035c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b0000000000000000000004ba316cf9ddd86690833edc0f4548f8c07f0d66c09dca029b0a1fb96f16c62803000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0000000000000000 -DMLOG RLIMIT_OP STATE UPD {"average_block_net_usage":{"last_ordinal":2,"value_ex":0,"consumed":0},"average_block_cpu_usage":{"last_ordinal":2,"value_ex":833334,"consumed":100},"pending_net_usage":9440,"pending_cpu_usage":40100,"total_net_weight":0,"total_cpu_weight":0,"total_ram_bytes":0,"virtual_net_limit":1049625,"virtual_cpu_limit":200200} -DMLOG RLIMIT_OP STATE UPD {"average_block_net_usage":{"last_ordinal":3,"value_ex":78666667,"consumed":9440},"average_block_cpu_usage":{"last_ordinal":3,"value_ex":334993056,"consumed":40101},"pending_net_usage":0,"pending_cpu_usage":0,"total_net_weight":0,"total_cpu_weight":0,"total_ram_bytes":0,"virtual_net_limit":1050675,"virtual_cpu_limit":200400} -DMLOG ACCEPTED_BLOCK 3 03000000030000000200000000000000010000000000ea3055000100000001000240e54a7b27e042b80a810153bec1dd166eef95fa69f6c9886ae283363bc2add80100012d5b1b639d6ae94fcdd0536b224644931573d1ccb2a0c548613cd1feea18888b0200000000000000010000000000ea305503000000010000000000ea305502000000000100000001000240e54a7b27e042b80a810153bec1dd166eef95fa69f6c9886ae283363bc2add8010000000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd023b3d4b0000000000ea305500000000000213588be25132b4167ced6df22b5439e376d5a20284190bb94a43e3e86c50d366bd80731342402e85b2ddc0052985fd31301156b938d7325ded2582756e40bfbc4f83b79f8de2f5d0c5394ffcc2f724830bb6b5ed9dcd5dbb4a09139800000000000000205d7ce507e9dbea47687e80fceaf2794b22bd883902adeb8c97de9f7283b614b0590bc4251ba5410cb035f88e60ffdf6fccecd10d83edfe36021227d1ee9e18830000000029807708239aa7de914d3ed61e9009ab2280bfbc50f1d9769f27f8341ef26198000000000001010ec7e080177b2c02b278d5088611686b49d739925a92d9bfcacd7fc6b74053bd0001023b3d4b0000000000ea305500000000000213588be25132b4167ced6df22b5439e376d5a20284190bb94a43e3e86c50d366bd80731342402e85b2ddc0052985fd31301156b938d7325ded2582756e40bfbc4f83b79f8de2f5d0c5394ffcc2f724830bb6b5ed9dcd5dbb4a09139800000000000000205d7ce507e9dbea47687e80fceaf2794b22bd883902adeb8c97de9f7283b614b0590bc4251ba5410cb035f88e60ffdf6fccecd10d83edfe36021227d1ee9e18831400d0070000fb05010100203b7de491b51d3d74624078bc2c5dc4420985f0350afb6923a5585b5621750c9f126d7cff0efeade2068c7b618fc754b2abb5bff8cdb9bd0ecb4432b72ae1ed380100a82f78daed5c7b8c5ce755ff1ef7357b67e3ebc6d94c3609f9e662d0b8a4659bb8eb2575dbbddbc476694b9cca2dfea3b0bbd99d647776bdbb9e1da70e0adead081045158a7894b6405524a4d21424545aa8cacb0d0815a94891fa20414284ff2a025511a245ad54737ee77cf7ceeccb71f09a87545b9e7be77b9cef7ce79cef3cbf71f44fe94f1bf5d03d9f1951f447e343fdf3d87be873f2879efef473830dea77fff59e7bbef7f440d3bfd197d9f57368d1bfa54767949ab11b9736d48cd9b8840f7a0b372ed11f35136cf0436fe80dfac0b80dbc2afa67f84d6306e6063201ad97a8ff9234d00880f033d54c84469e48cd68b03c8b3ea54dd0909531c1fc52d0b0ed95c70e2dae4f3fd29eed5de8b6a767e77a8b8fcdf6daf32a42d7cd6bdd76d9548e51317aeaedd5f5c5d5e9d9f5f576b7a72c9aa273ed73ebed9e4af025c3b4d595e9f9d9deecf4fae2cfb4558d9b09defcf4409f1a2aa7cead3d2e53ebddf6f90b8b40e6426f41a568ba89e04eaf75171f5b5c6e3f4ac8d519393476dbebab17ba73ede9e5c5738bbd75358c9e70f6e155c24ae17d44a6aeaeadaeb7e7f1327f61aedd5d5737a1d3a1f3e1e5d5b9a5b985d9c595e9b5d9eeecb9768ffae9756e8956e29db9475f6918efa23e77a1db6daff4a67b8be7daea00d316339982ed81b579743afff0f4238b2bf3d38be347558696da34d17361b9b778af3a88ef0707693c3db73adf56868958aed36dcfb5097257d61a2280580ef09890d1fac2ec3d6f1c57af61e4a877bdb74a6445ffcd681aa6a60b6bf3e02dda0ed993275414abb8369444511c0f0d594b9f517c8b1e31237624a07ff4371cd123d60e51efd0adb7da86ff63ab8f46725b10ea353d34145aad7434623774b17959a51baaf8d45f568fb8a6c3d9b5b5e5c7d5eb6a07b42a745a7bfdd83d47c727ee7bd39b87fe66539f0854767bbaa9b5dd3093f2d7a9078655417f5be683f4a5c81ecb752737e3f44d5a9f9cccad539d22ee1417cfe76a9c1a9c29b29e53ef1ad64e4faa62e3c4b0a9dbb45007e81ff5e90e663b4d2fe83d39aca9bdf8cdcb2a33ce1e489d4d8d4ac7b5def8415a6e29a755c64d9d66d262f59651832ba175dc6cd2f3ad0a40313352c533b4f3ffd03ada2854d3601718b7043ccf3b757258611fef0076d96d07d2ecce62649cc0127ae5968b8d4e1e38ddc96ecbb17da75c405b74f67c6e4ed034553cd1c92da19207457c3ed70f0c1b0c21ac685a71b19387d4d78c9c75da192c1c776901daf9131d02648088f62d173b2e62184ec68434c5f29bca465367881c84970c54f4d1c22c80549d0a2430a126fe9ede4b742b469a9637a28be0ed843e6191fd00d024d49de6bd366d0a5a6777d2dc74429b0dde36f5df9e6bec7a5859225a9339fce1c9dc60ae39a894d39e26292146a426345d7a93f272c2484b6b9e2e1154e1a0398c01a6a8778011febd839629d7b3d95d34d54c62415e4c31a2584ca6381a31acea26051d200bf4245168a23feb1ca6d5d2043cd2d9e1eda8f8f61f4e43950da9f42744a85e22fae9c3a08b2e5e0021137ecde82da8ded0adb2d78ef257a75be822622d65756a7949d1bae92fd774c0846b1104fa0872b354c43fcee7e5eb2cceaa08c0b2a62194695a9245a3dc961b6c411509c9112f456fcd80799088f838bb54d8415018cf5c23410b00c783082a10f50e84dded3abb44840118013088481f4a76fd881cda17441ad78fc81dfb8288bb7e440eef0b22adeb47e4ee7d4164ecfa1139ba2f884c5c3f22c7f70591cb6a174cf45e9898014c4c05e33982a10750d17ba2a2050223a0592d1118361ae9778cd51be612eb3957aa3975c4aadc4cb9a78eab14d660aa456f43fc36466f357e9ba03728426c01e32d8f870db33cdef01bc66b7ec378b62d9fc883fbd4017a0b8ae4b1fbd44dfc96d1db30bf35e8ad8e193c2eaec645d5b8b01a17f0fa0d5edf1c57b70aee99c7e5f60a97d10a97db2a5c1abc0b8cbbb9dae36baa3d1eacf69809ce8a9118e10581c42db234bd1d1264d57dea2e2107b5fd4035eece6adc1d6459c844b286602bf4adefd3fe7f92f6da533efd522076fd194daed5619535e0fa38f56e78155bff121a57aefcf1b77ee7d73ffde2d44f929380af57ae7cf6db5fc35720b9b9b9f9fca7fff04f3e72cf43c356be5efe95ef50ef43c3817cddfc230c7ef770e22c7c910f12ba05b9544fd1d3d923f6297dccb263414ecb8f8ed693d42f71e55b1f7e71ea3dbcc4339f7cf1c57ff8e047bef6f98d3ed0bfffbddfa0efef1e8e05ea3c3dc8c59e119833c76c4b409205c8de305a8f539ef639d94705e5437ffbf257805a244096e9419a6541802c1cb3ce03719decded17a94fab537bffde13e10c0fc28808402e4494c08c8c5f6fbdba4fd251e4ed2c9de385a0f531979861ee1b8392de34e1fb3137ed844273b365a0ffcb01e3da271b326c3d68ed9861fd6e8643f365ab77ed83be9118f9b5332ecd4313be98791a20538e3c73d013cc6cd451977f198cdfcb8ac931d1fad6b3fec7df4a88d9bb332ecec313be6878d75b2b78c52f891dd415f9ed190a6d7283eb3194e0bf99b27b324fdb2d131046c8ce4ab19389231e8eea0198a568f24ccc8823c7e4064cec5c507d8f58eb3db9a86d1a0a6039d62ed3cbbc37007e32c240f3f2848d65b2e98526010b5769ab010ae038f30f1b0e277b025f8f92fc012a09310635fd260540df077b6d2bce4647f5eea12572b34fae9bc53d4007b414c1f3719351cc2e45a47da98c714f14094031716fa8220d5eabc4ea926751db1ae09479bbacec3d7e6082462fb1461abca25c5157dde4507b51a2086c978c36344650a3d2378e671fa73468757a36d79743d753d30ed296b52d09ec5612f0283b22d4fd91dd44c795b25e102f218997a4c0750d45614c9842289d0ac0145dae9d3e6886dbd0245a283666f5a0cf7652e3b927edb50e84a24f9b8b911f2f6450ad6157d667654f6725c1e13781095c6095c40a756866653a3bc550e555cd032934211daf1045303a7069d09efb9ea4c8ed96760595ee05e97205a1662d29e4bb22a1c7fa6ae9359cfe89cb9c55d2f6881ee71268c99452f700b562d5b1a1523aec20199181db4bb70e1e346d870f3e0d1c79cac96feaa3511197562c7a6be91227a4a1e93f2382d8fb3c29aa3f218ab38045e819050a478bb8c2816e738036dbe496c7b2b734d58365171658c8f34c2d75d5846ebcdc8eced1c6b0d722c138e3564d24cae847bf4581304060ec559728fe871baa9f138454a891e93cda1abf069c8c125c2790976e1d4a6de7960ee4ebf6775c207e6867108142639236748b4227fcf8884fefb560ebe02cf66fa3cdbd4b229614a764ab856bb1ad78840bb706d53ced910b85613ae65c0d8d5ae81718cc54bb2c31a2ca4eaaf98418892b289d978cc2ec8db647f6dac54cd430309821d9c450e083949b2b45f31bbb673bbb9f7b9f5d2f05e4e35e586844ea48239adfc6095dd46019b2246227596a5a3900f24d5c897ec33dbed18927e2e14b3ff4db5b71e8e2b5d9c94ba38f1eb267d5d9c6c93aaa4b4fd7071f6949a44a4060a93c5252b46af76aa9f17f9a8ed38d5a72be161d1b986537d7a40386604cfb395626a99fbd91010518ab173cd9a77ad2db8572bbef6ec575ffbe030ab7ea44c3397c7d43ab6ec7d8b182e223fcef421e535c0d2a77032e9f85b56ebe8815339b682d93966a4d726348cef82e03b431009d0e9a53c06b221840833428f28fca9af13a231231a6e4174461ef38209a000d1b08f682888f2bc15993a2f324be42e6596e6cd88d6f1d0e22c4fa5fdf440fb99b23d19907119c6f957efacdd4fed792a6a1ab27f2015ce672d957a25426f3763619dfd083b3a2f3e074727ad952a33fd4598347de34ddae92d7af1ecdede06fb1ba52dfb22f46243ccbad8b2c957f040763767c99ee6ec2a0ec8cc80ffb1b6c5b5d8d59c5d456f95562cbc8a15bb8c8481bec479f2cb8a83576477103b2134297833766a03e859f16345c3e5014e2ce144f8fbe347e87338f7d17ff9cc37de40bccf5038390595c4d11069b50772d522cd826f2758303e7b993d600b7e247ed49492c8ee0436d4cac3615d2f87d4113d31a3127ecb3a651878d20f7e6058a7a20b8abb3b790492d3493b816202e9da850e1020c1715cd2e19ac0034c1412e8900b3329c7b818a4a038c326b5442e947a482ee11feb6eff967ecc4af4b0a93df57212ab2306e25629e6b054cca1e742d857cce136e90dbd62862e15511a70ca4eeda2a343d6d1c66ba3ad815acb1c45be8e75370825dac2727c717440afb364676ff3ca3de21e7a1b14e6ad2e40eca2bd1db718648f2a151f5d9be326fa1af179c04a964f23407ad373ff00fdbc66e20a9868a6e24b34d070054ab45329e15f30da6e38613b54129f42944b2cca25c1d2568a599fe40cc08a40086639cbca8bf9c04cb15c21c6dd3f90287bec23b44687a34186a6010df5a3dc6e83a6fb395d55ca871ec8e932b4f4dff50d2261b00709d51e2095b84c7b8084d0ecdfa6bf6e593346bcf1a069a6147c3bae9271dabb19d2f18e2ca7f470d0d4db7989efc2d471029d4b6e48579071e69a73cee2097b75459d7711f21379d4fbfd27096e54c49d664487980c1249ee79d2435ea9f20e12d9526d891c083a7af613b97950aaaa2e5ecadeeb7bcb8de5c949d699d0facebc0b03a983cc81613726c1eee85b728274a564f0835229d2eeb4f5cbd2495adaa14e7857b52a5bc14dd007466aba21a8e469a2b7d124d84a934068120dd224649a18a189014d42170dd0049ed95b0cb248f5bedcb868a9703bd0447291c8da1c40b3e93940be207c54a4a6b886bc7b117510e2401155977b7f1545d441506511065af8da8aa8bb2162b13bfbaa8ba8af0e9143fb8248e3fa11b9635f1071d78fc8e17d41a475fd88dcbd2f888c5d3f2247f7059189eb47e4f8be20b27b11752f4caeb188ba072aba84b05b11f5b7c52f0ff7d1fa243badcfa0a68d5cb2cdfa88ed89c5ba180a3b617822313ce4122f650f55db492aa32ac3c5b925e55d591f52c61c4103346f04d4499660a128307e701712259ca6a0686e2bb738620389fe53f74397cc27502417c677740825f24bab6b48755e104ec1521e88c7b8f1ce61d6e6e46052e81dba402e3489b3cf8fa03f5130266727d7127d87f065450042870b65e4efa896783641cea40b386e534211cd496d89d4789ce65d6a7642602ea55261d877e1a00417a5b0469efa6b46c81821b6fe0b6b62899edd12a79ce47a13416de4108f3b1855443db8d34456556e6d69dc1c433585c2a0f0a4bfcf147074c48d4027e4ea1c9132aceea269dcb2cb0ee54c30d0ed0301b22bf0edfa910ba49183f2e21b12d20588700a0d3bcc63b343a374ba98ce0a914bc8ac629a6cad8684a5810d61c3622925253cf062a7b86bcbd8d82585e3b1a0d551445308dce98108b526112af5d4ab6b75779010321fe9dd61c70f725aa32665158d143697eb10a2b01cc41c82e32d92405471e94a3e90612401c97eca45083c25b8268fb4d1d41e0ce8076632174bd2a67fa5ad2106a2649c079c11d2888b9504c57fc69b03ba4896dcfc1037be2c3b66998e24f0e18f983d667203d9e6e771760b4d8c789c4cfcd873c20fe2dfe94e19df97c5a6b314ac09050981a3ac1d5bd9ad0c0195f7337251b13375c94553fa09faf8d9f7de4e6c232e51b0fa5d4d7e93d4cd82c39c1c3a46b84cf2da25da4ffb1217d21d874a0a071c1712754422ac5c05e864ef1b958188092d5f02909091a01ecd43cf46f60724b28fd9aa7b26c6583e41264cea100a706249b344b44b6622b49296b48eeb94c50a30904f218e9b5c4f844a75c8b130982d4c948a59fa211b0a0b858d14ae8b0ae228c9ee0c4228a4b96bb72004210dc270e5d930600b1c3026c54f683635ab00d6fa688af860cb443a244c1583c0389a4a7e01d9bc3728f5641e4c4d3cf524498b2e363ad80cf5b1f9206340d0ab2081149a08de95e7fc098c40c9b084430c670cf840c2c30f80c1001c72a3194cc61aa744850e3d04b1b03d3ab8d9413ec822bd068f000b0550d7b21ea77848e6d0820405be34e44ba3c3bb979b21d294f9a6ac6c324898105f3eef85321bd08c03a944affa37399518f854a264b612a46b78e9665837e93605c7df919d97b17e9c682fbe3dbc5d7dd9d216f910179773b795c36d3596d57b7a3f85d95244a87095c41ae3ab3cbe7a2fd4522e197c1fc80d02f26553a9bb6d92b5975c9529ea3da1226175581e8e9d003afca4be5a223c8d1dd6b1ca4d86d089879b7c07a5515d1e6079e220f730fc4f674e6e99ea7c4a6fcbec5b315b97b3f59eb3ab0923db26f00ea026b3fed1701dc9cabe6d5492748924e97c0ed7882d6435fae7b86830703b4af160f1a12cd9b407799af2ae171cad3c821f620a5c698a59f511d988b0c5f7a8016e3f291dc2ab0777d1456fbf1dd503b80a996be23700e23d231d6c71ef05b7b3011d3bf7fefb062960728e82342d8b6b900cc5e50dbec311c38292e1586a4afa350f91f328e15902d5b4151ce636bcf6509cd8a85526bf902f5e62d5e00b4f7cc58ebdddca313462bd02c9e921b5ca387a6374204d9fd7261057f07f5de10d68ba6d6a8ec28b4a668ed804fecbeb540c5394c5d81d5f712a95e0a70ced28d8eedc5edb8e1a7e478d6bd851c38f7ba51d855e77e73bb7c585403f322b4766db062503831a25811a7bd801efdd8148311e194556f468346b4cab1ae221176535ef4aa65ff6d6eed590ea1a69b4cfc4317b11a74ca76571b9a9bfb6b2295454fcae08e7607b2565b3aaa404a2baab4a4a807d04be9262717acec8035703032e989c159d754a640147f079ae90f81a37d0872a65dff3ac04ce72a710f181af81841c78579d196a20b6ac8184acb2b8936f32c9302e78707dade56f56a20632263d6b825352ba0e16c569cb65eec0578e41c4c1dab154bf387e0dfaa5635b2e17c0a3adc0700c2faa861597e8700e1ffad5e320f5fa3b9b280b2c81e86e0616488598c1f5dbefe7769ac8451714c7a02d898f57d1edb4a36dea1dc96dafe17d65bcf82a3dd99b868e47bf293ef9d5676f19d0f2b401d6f296b53c59956552f441a5e80df39698a53c4dfd83ec68f9e6aab746f596f937291396399eb1dd6d848574f66d44c0587438c5cd2ca9ec036cf37f0b0de3ebb0c8d80d9a1672b079a95dac8b45a2e2f439ee36e2e48b8db192b550550564771bc377292cdb98a735bb4ffca3a5fdf47ccec8e3b4f77ce450ca314cf8d69fe8047a3f22878e20fcdaff19f79e7434a3c746ebefac0dca7bf7dfbc36328542a6edb820b046600432719855c908c5604614532916a51dc32363fdba353d22d40c25b264e141fc88e82de6f851fa0349af1889da620490914b38808c3880440e860248c3c16513f65ae35786fd00d2ec08206309203d9c12f92a808ca6b80254c19100d29401a447c5226ea72f6500697d00197b3be92355e5d713a3238999b16dc1a2646ac606e245d6be134c3ebc8d41b32bcfd0ec6ed1e3c48a97becfd8ffff8cf51750b65c46aa38fcb211ed36e06ddc30edc657387689ea5ae68c04575f54db8239f95583c21d259e3d51a9c80984574c3ab62bd2debfb351fa2b49df5f09d88a559dc9167f25e0247f69659ca9fc9586f82b6ec05f69f5fd9506dfb13c25f8bc593c83898168ef7819edb16790fea93656c29531b92dc3e9b631e7adb35c01e3727499d6e15008d849b3385d64ef9638319907d92dcef6af04245d64f6d8be210d990cdc472248b8432a9797f8f46523e3e668992de55ca7de35d729a1aa53e9b3b8ea53ba3241e5b634cec1ad82dbf229f257908c2c9ec50b0e635956966141f1157268c47b09e0bdc470e7254625ff212e1ae2bd9832f41c702bb4fca25bfb4b4174e61acb79826461243f15364c32fc34462ea121730a88b0635c868d7c0e5c2e0918c13f3ec1ee2049d102d7fe49ea16fc85002be94fc0ae8acafc3b702f455adcf7b5f2e46906e10294915cc077a9785d5d9574627f8904bb8a21f13edb8a7ed9063b20a15ccd22152117b762a0148b24c4e5c5ad7e469696ab344d799b2b4dffd1a6fc93fef49d8fcc2e2eb7e75d6fd5cd2e2fafcecdf6da6e6df6d1f6ba5a7db8d39eebd197f575e95fecb5bbb3bdd5ee34ded7ddca6acf2daeb87317967b8bd38b2bf3ed8b8a7f0c99def9fe2e0d55ed6e77b5ebf07f5b2cae3c5a4d567cacd310ed8a33e0e9bd73b32b0036476db4baacbb0ed8bdd98797a9e111374bfd0bedae9b5b5de97567e77a8aeb00e9eb77e0786e757ef191c7f744efe581e5fcd06b5cee63cfa9f44df21f4350bb47786176e551225777f1dc6cf771b7d47edcbd7fa1bde22163d7b32b1ebe62cd9ae66bddd5deeadceab2f3ff71488969ffff18e132651a3cdac61cb22ce9dd1756da17d70806ed50684aa83eb278b13d3ffdf0e3bdf63ab05cef752fcc097569ee1f349552ff05ee7357f400d00700008101010100204b21f3cba072cc493e70861540df4677b498b0505a8b8e2a346b85a0c2dd2fc4263c4a7d8629026c4eb594ad96fac2bfe5f8ffebb9c841c353920b7b8ec11abc0100d90778da8d563b8f1c4510eedbf7e37cf209d9e60808402496c0dcdaac4e8ece01090112afe83043ef74ed4e6b677a86ee9edd5b3b2121b049888d842c84c0c1456702eb20b036424242c2e00408800c24fe03d53db3f33a58e860b6bbeaebeaeaaaafaab7f55bff9d1a796df0e5798263c37cc89f2fbe657e1eb8c7cb92e0de5f83c1eded95e4fded2d08150faf5ea5237e69f7855db2d3c199e351e5915a339c0b900d4103681849dff5c09daa3818bc34ec5057f319d54036b6c640752cc1617c024a17515d1a6b2f945c2f48a3ab3d09ca0b7dd68ab9d097078d292cd4267e9c39f089a70faea351378c85563b11c8802bf44c383eccc0cf20cd39e55a9d31df4c766ee487eed4f528174e4425baab412ab2fd44400f1dab73046827567402f6ece195a73495139455b44ee4ead4bb1db3594b2a94b929fa51367179f0f4882adc00722dea6c6edb0798d3452a7fd60d858643ed8c2598c8297bf18227220efe2f948148a1851bbb515c72a47ce34cbbeec655133b0106781de0c9aa059f8f41f3200b19833148090c41870e1c465c528b9b73c1c2798a3a57b5c2c0cfe276de28b9f0b90027552b7e6375c085d35a0691f6ac7a7768c39351b2a4eabb54b8e0dba3486d2b597131b1f0b3553ab68cff9c15a9dec3adc83b0327b5764a645b3bbd7c77b2ce294f6a755cf4a278e473d7c1692b91a74e75d083a9b5d828596cb8218364a6175132eb4b782fe61202581d2b906ec926dcee4a2cd2302de6ec9354785ea52d5bd5900bda21ea652849adab4030243b676debdc60af83126d32d91c2d34a85341c20682e6d233ab41b8f02f154e6a05e4e9b897c2b319c990c52e3a859123b533d932bbdf76c276c527c2e4b21ceb4d8cd8aa8bb1b56dac6d90260d1b8db10c036bbaa54063abace4ba8ea2241c3da3f77980ddaa92bd2e7628c7629ab617f54c2527174b05a6ae8a8236da3229af186acd0293fea689c65e7716ccb0eb61a892b5e548eeca2475a55ec7d3d32658c78357533c329d62a2b5eda28a6cb492c93f3758e35524f9ac128236578e11276e742c286468aca330a42cf661ab98b783ebbd58643cafff27cf7b71c4685a678db575669c5f1543c3e0735af70bef07a975ec4a819b769132cbcc6379f1637c36f3278f7c7debe2cb1f7c7eadd434c8feb73fdd3bfaf4956223c0f1fcb4fec587792193fd4fee3cc31edc2956278e5f1fdd7cfc59566c1fbd39fc19d8d14999a138ee42707492b171f5c0afa848c877af9e78c7cb22f570ec3f77fb789951c882be4940930cf4f0d1db6fdc5f16528fe3ddaf0eee2fb324e3d8fb1e057942cd851ffef1fb8fc5fcd920f8af3f2e66c9fcffb84b7ff865b7ce875708c9ff60d8f137aa5a1fa900d00700001001010020742877c36a520b152b1337ea1ecd37b0c98ad07289c32fec392e7eebab9f0ac71f7bc8c718cfa75317b2e15702372a9222c4616783ee7b3f0ec6358f8c328eea00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232201a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b72410000d00700001001010020058e23368b919493d6ac61d27f66b829a53893e88ddde857d3b82d913960960d22fa36f397752b98c295e3b31927f740127c0a99e76f8bfeea88f44466b8fbfd00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea990000d0070000100101001f43fe868e263d8134cf705aa85e26ce78ebb058edd558865fa3d240f5cb9e50c2389e9c8276eac800b7233a552045b2e79124c97e5156a0649849cc7f5d09eee600005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232204a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0f0000d0070000100101001f29e82b08ccf15e2187f29fea11ee3f4974f41b51e45b19f353348d8848b86fb71cadd88630456b7a1c60803c7b402487d41fbf18f0b0a13b4cca1f740447938300005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220e0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff5260000d0070000100101002047a8b784c3765b5c63ac52e3d8461b80bc2d3e3f62434f8accb277d9f2487cfd3c0728fcd26b5119a11288e5db46bc5b547877e220971609d1cef8cba443340800005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed32322068dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a2974280000d007000010010100203e701fbafd4149bc95b55a6bfc3b78246f5c2668ccc05ed4059a36ceb38f140b31e3b69e15f2579571e5bde39e034947271599c200e540b3949112bef163074c00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c430000d0070000100101001f0cc7352e60f4f8476783d6d1b48766a111c56fee2c1a552e76a75c92bc17de172f994ffc854c09717c904054819ca7a17379ddecaf531c439b35337ba099b81300005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232208ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a4050000d0070000100101002040965063a83be2d53b36c8d7e0775f503c2caa1407e586314562aace52c272fe60659e196413a6c9db4168470bcabb9a5851121c10c7b665f363f6cd4d1e4bda00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232202652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed250000d0070000100101002074ea7468b2a031c4cd53bf10ec3ac66b0c4b5c8779e045f1ef8d9c7b116be649217ff340107d0163397b99918ee2ce822b66cd6fce7b385af97a04671136e2ee00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d0000d007000010010100204dfb21ca5140582379bc026792c16b4cf97827143a4a9cd99ae70b3e6016cd6316bcbb9f1cb1233f12a0bbcd9debafa64724d0459b5c8d3cb67ceddfb2e3962500005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232204e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d670000d0070000100101002033446a3a94ade71dff3edb786259679487ab701bbc147490b1d4159fecf545fa22fee0698db16bf616465e5cebb985bfc4d9ed1ec4a55e38997dd4b4bbc427eb00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232204fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c20000d0070000100101001f3f67edd35bf731a07f40c638e8812112cd7d1baa39ec7dac4a1b2f0c83ac8bd53689b56dba69a7386e3860a6f8976695ac0bc2b5dacae91080f1d54df2dac0c000005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b44767070000d0070000100101001f1e030564013603d54f9e983b63cd940f8ff09ae038b14813f4021bb0c09ebb640d90cb4f8d57be2809f492a51737b671a5f549d4efa8e7efdaeaa9663c09d1ad00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead450710000d007000010010100205cea642eecf05568ce8c5564e63349eea3b816108914ba2ab5efffbb8ea467265f0b6d474f03ed02a3bf529fd6e55a595cbf8dd1adf4311cb9c51e862f8a535400005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232205443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b40000d0070000100101001f4556076cc86e0840bf69664f1ef8fcd4d91abda313d08e7840d24ba45cb429cf12b7d3a1f64250c19d1b975e7b107853beff70ebfc4c27c44f825dc05cdc9cd600005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e990000d0070000100101001f354d903ad0f2c6cc9d9a377d681ffaa00475d1e559e48074b4c8cce3111d5c172903b2f179ad4d736dda4e7d1b6a859baeab9dde5e5e495ce09733ec4650634400005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb400000d0070000100101001f1766fa716a828da244c9ce52919b7a19acb38dbd110d1bb0039bb2477c17e4465dceecb8330ed5ee9de1330930dfcfa1a5e8149ce8536a82c0093642adf7328200005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232206bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc0000d00700001001010020488923db1c78fa430a3a9eab75f4ee467c7b9a3d3b4eb3bd08e183c82ef79b9102a4d2a7d1ec79c96b404911ae1b10f579bd82a660011c1ca2b872b30ef7dcac00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed32322035c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b000000 +DMLOG APPLIED_TRANSACTION 3 04ba316cf9ddd86690833edc0f4548f8c07f0d66c09dca029b0a1fb96f16c62803000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50100d007000010000000000000000080000000000000000001010000010000000000ea3055302a2f1713925c939a997367c967b457bfc2c580304f9686b1de22fc5946e40616000000000000001600000000000000010000000000ea3055160000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed32322035c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b0000000000000000000004ba316cf9ddd86690833edc0f4548f8c07f0d66c09dca029b0a1fb96f16c62803000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50000000000000000 +DMLOG CREATION_OP ROOT 0 +DMLOG FEATURE_OP PRE_ACTIVATE 0 98c4175db53ed27e7911a1b5adf0e7db0fc96c2cae172cf594dfa9a742ca9e88 {"feature_digest":"98c4175db53ed27e7911a1b5adf0e7db0fc96c2cae172cf594dfa9a742ca9e88","subjective_restrictions":{"enabled":true,"preactivation_required":true,"earliest_allowed_activation_time":"1970-01-01T00:00:00.000"},"description_digest":"01969c44de35999b924095ae7f50081a7f274409fdbccb9fc54fa7836c76089c","dependencies":[],"protocol_feature_type":"builtin","specification":[{"name":"builtin_feature_codename","value":"BLS_PRIMITIVES"}]} +DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304002,"value_ex":55377,"consumed":9568},"cpu_usage":{"last_ordinal":1262304002,"value_ex":244232,"consumed":42101},"ram_usage":180802} +DMLOG APPLIED_TRANSACTION 3 793b276fb55f2f81cbdcfcaf882555ea5dde340f80c16e5dc652ffad52eea87c03000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50100d007000010000000000000000080000000000000000001010000010000000000ea30553a97dc6254ea785e8c6ee5994044fae975bfc8ef1916a24b476a984724cc5cf017000000000000001700000000000000010000000000ea3055170000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed32322098c4175db53ed27e7911a1b5adf0e7db0fc96c2cae172cf594dfa9a742ca9e8800000000000000000000793b276fb55f2f81cbdcfcaf882555ea5dde340f80c16e5dc652ffad52eea87c03000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50000000000000000 +DMLOG RLIMIT_OP STATE UPD {"average_block_net_usage":{"last_ordinal":2,"value_ex":0,"consumed":0},"average_block_cpu_usage":{"last_ordinal":2,"value_ex":833334,"consumed":100},"pending_net_usage":9568,"pending_cpu_usage":42100,"total_net_weight":0,"total_cpu_weight":0,"total_ram_bytes":0,"virtual_net_limit":1049625,"virtual_cpu_limit":200200} +DMLOG RLIMIT_OP STATE UPD {"average_block_net_usage":{"last_ordinal":3,"value_ex":79733334,"consumed":9568},"average_block_cpu_usage":{"last_ordinal":3,"value_ex":351659723,"consumed":42101},"pending_net_usage":0,"pending_cpu_usage":0,"total_net_weight":0,"total_cpu_weight":0,"total_ram_bytes":0,"virtual_net_limit":1050675,"virtual_cpu_limit":200400} +DMLOG ACCEPTED_BLOCK 3 03000000030000000200000000000000010000000000ea3055000100000001000240e54a7b27e042b80a810153bec1dd166eef95fa69f6c9886ae283363bc2add80100012d5b1b639d6ae94fcdd0536b224644931573d1ccb2a0c548613cd1feea18888b0200000000000000010000000000ea305503000000010000000000ea305502000000000100000001000240e54a7b27e042b80a810153bec1dd166eef95fa69f6c9886ae283363bc2add8010000000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b5023b3d4b0000000000ea305500000000000213588be25132b4167ced6df22b5439e376d5a20284190bb94a43e3e841639eb3a733e9536932b85f63002945d82e25a0ef948f220ba098df51ab2f5d9d5fc55180118b2a44ae7b7ad158b7de8fee6df8ac1c5afd3681c5b11460ac9600000000000000205965a329efe657efedb21975c97dab14e1d8cfbdcd9492177294fcfe876d7c0a1ffb656f523795bea8035bb945520efcb50606d38965fd0fc8c94a2a99f28e510000000029807708239aa7de914d3ed61e9009ab2280bfbc50f1d9769f27f8341ef26198000000000001010ec7e080177b2c02b278d5088611686b49d739925a92d9bfcacd7fc6b74053bd0001023b3d4b0000000000ea305500000000000213588be25132b4167ced6df22b5439e376d5a20284190bb94a43e3e841639eb3a733e9536932b85f63002945d82e25a0ef948f220ba098df51ab2f5d9d5fc55180118b2a44ae7b7ad158b7de8fee6df8ac1c5afd3681c5b11460ac9600000000000000205965a329efe657efedb21975c97dab14e1d8cfbdcd9492177294fcfe876d7c0a1ffb656f523795bea8035bb945520efcb50606d38965fd0fc8c94a2a99f28e511500d0070000fb05010100203b7de491b51d3d74624078bc2c5dc4420985f0350afb6923a5585b5621750c9f126d7cff0efeade2068c7b618fc754b2abb5bff8cdb9bd0ecb4432b72ae1ed380100a82f78daed5c7b8c5ce755ff1ef7357b67e3ebc6d94c3609f9e662d0b8a4659bb8eb2575dbbddbc476694b9cca2dfea3b0bbd99d647776bdbb9e1da70e0adead081045158a7894b6405524a4d21424545aa8cacb0d0815a94891fa20414284ff2a025511a245ad54737ee77cf7ceeccb71f09a87545b9e7be77b9cef7ce79cef3cbf71f44fe94f1bf5d03d9f1951f447e343fdf3d87be873f2879efef473830dea77fff59e7bbef7f440d3bfd197d9f57368d1bfa54767949ab11b9736d48cd9b8840f7a0b372ed11f35136cf0436fe80dfac0b80dbc2afa67f84d6306e6063201ad97a8ff9234d00880f033d54c84469e48cd68b03c8b3ea54dd0909531c1fc52d0b0ed95c70e2dae4f3fd29eed5de8b6a767e77a8b8fcdf6daf32a42d7cd6bdd76d9548e51317aeaedd5f5c5d5e9d9f5f576b7a72c9aa273ed73ebed9e4af025c3b4d595e9f9d9deecf4fae2cfb4558d9b09defcf4409f1a2aa7cead3d2e53ebddf6f90b8b40e6426f41a568ba89e04eaf75171f5b5c6e3f4ac8d519393476dbebab17ba73ede9e5c5738bbd75358c9e70f6e155c24ae17d44a6aeaeadaeb7e7f1327f61aedd5d5737a1d3a1f3e1e5d5b9a5b985d9c595e9b5d9eeecb9768ffae9756e8956e29db9475f6918efa23e77a1db6daff4a67b8be7daea00d316339982ed81b579743afff0f4238b2bf3d38be347558696da34d17361b9b778af3a88ef0707693c3db73adf56868958aed36dcfb5097257d61a2280580ef09890d1fac2ec3d6f1c57af61e4a877bdb74a6445ffcd681aa6a60b6bf3e02dda0ed993275414abb8369444511c0f0d594b9f517c8b1e31237624a07ff4371cd123d60e51efd0adb7da86ff63ab8f46725b10ea353d34145aad7434623774b17959a51baaf8d45f568fb8a6c3d9b5b5e5c7d5eb6a07b42a745a7bfdd83d47c727ee7bd39b87fe66539f0854767bbaa9b5dd3093f2d7a9078655417f5be683f4a5c81ecb752737e3f44d5a9f9cccad539d22ee1417cfe76a9c1a9c29b29e53ef1ad64e4faa62e3c4b0a9dbb45007e81ff5e90e663b4d2fe83d39aca9bdf8cdcb2a33ce1e489d4d8d4ac7b5def8415a6e29a755c64d9d66d262f59651832ba175dc6cd2f3ad0a40313352c533b4f3ffd03ada2854d3601718b7043ccf3b757258611fef0076d96d07d2ecce62649cc0127ae5968b8d4e1e38ddc96ecbb17da75c405b74f67c6e4ed034553cd1c92da19207457c3ed70f0c1b0c21ac685a71b19387d4d78c9c75da192c1c776901daf9131d02648088f62d173b2e62184ec68434c5f29bca465367881c84970c54f4d1c22c80549d0a2430a126fe9ede4b742b469a9637a28be0ed843e6191fd00d024d49de6bd366d0a5a6777d2dc74429b0dde36f5df9e6bec7a5859225a9339fce1c9dc60ae39a894d39e26292146a426345d7a93f272c2484b6b9e2e1154e1a0398c01a6a8778011febd839629d7b3d95d34d54c62415e4c31a2584ca6381a31acea26051d200bf4245168a23feb1ca6d5d2043cd2d9e1eda8f8f61f4e43950da9f42744a85e22fae9c3a08b2e5e0021137ecde82da8ded0adb2d78ef257a75be822622d65756a7949d1bae92fd774c0846b1104fa0872b354c43fcee7e5eb2cceaa08c0b2a62194695a9245a3dc961b6c411509c9112f456fcd80799088f838bb54d8415018cf5c23410b00c783082a10f50e84dded3abb44840118013088481f4a76fd881cda17441ad78fc81dfb8288bb7e440eef0b22adeb47e4ee7d4164ecfa1139ba2f884c5c3f22c7f70591cb6a174cf45e9898014c4c05e33982a10750d17ba2a2050223a0592d1118361ae9778cd51be612eb3957aa3975c4aadc4cb9a78eab14d660aa456f43fc36466f357e9ba03728426c01e32d8f870db33cdef01bc66b7ec378b62d9fc883fbd4017a0b8ae4b1fbd44dfc96d1db30bf35e8ad8e193c2eaec645d5b8b01a17f0fa0d5edf1c57b70aee99c7e5f60a97d10a97db2a5c1abc0b8cbbb9dae36baa3d1eacf69809ce8a9118e10581c42db234bd1d1264d57dea2e2107b5fd4035eece6adc1d6459c844b286602bf4adefd3fe7f92f6da533efd522076fd194daed5619535e0fa38f56e78155bff121a57aefcf1b77ee7d73ffde2d44f929380af57ae7cf6db5fc35720b9b9b9f9fca7fff04f3e72cf43c356be5efe95ef50ef43c3817cddfc230c7ef770e22c7c910f12ba05b9544fd1d3d923f6297dccb263414ecb8f8ed693d42f71e55b1f7e71ea3dbcc4339f7cf1c57ff8e047bef6f98d3ed0bfffbddfa0efef1e8e05ea3c3dc8c59e119833c76c4b409205c8de305a8f539ef639d94705e5437ffbf257805a244096e9419a6541802c1cb3ce03719decded17a94fab537bffde13e10c0fc28808402e4494c08c8c5f6fbdba4fd251e4ed2c9de385a0f531979861ee1b8392de34e1fb3137ed844273b365a0ffcb01e3da271b326c3d68ed9861fd6e8643f365ab77ed83be9118f9b5332ecd4313be98791a20538e3c73d013cc6cd451977f198cdfcb8ac931d1fad6b3fec7df4a88d9bb332ecec313be6878d75b2b78c52f891dd415f9ed190a6d7283eb3194e0bf99b27b324fdb2d131046c8ce4ab19389231e8eea0198a568f24ccc8823c7e4064cec5c507d8f58eb3db9a86d1a0a6039d62ed3cbbc37007e32c240f3f2848d65b2e98526010b5769ab010ae038f30f1b0e277b025f8f92fc012a09310635fd260540df077b6d2bce4647f5eea12572b34fae9bc53d4007b414c1f3719351cc2e45a47da98c714f14094031716fa8220d5eabc4ea926751db1ae09479bbacec3d7e6082462fb1461abca25c5157dde4507b51a2086c978c36344650a3d2378e671fa73468757a36d79743d753d30ed296b52d09ec5612f0283b22d4fd91dd44c795b25e102f218997a4c0750d45614c9842289d0ac0145dae9d3e6886dbd0245a283666f5a0cf7652e3b927edb50e84a24f9b8b911f2f6450ad6157d667654f6725c1e13781095c6095c40a756866653a3bc550e555cd032934211daf1045303a7069d09efb9ea4c8ed96760595ee05e97205a1662d29e4bb22a1c7fa6ae9359cfe89cb9c55d2f6881ee71268c99452f700b562d5b1a1523aec20199181db4bb70e1e346d870f3e0d1c79cac96feaa3511197562c7a6be91227a4a1e93f2382d8fb3c29aa3f218ab38045e819050a478bb8c2816e738036dbe496c7b2b734d58365171658c8f34c2d75d5846ebcdc8eced1c6b0d722c138e3564d24cae847bf4581304060ec559728fe871baa9f138454a891e93cda1abf069c8c125c2790976e1d4a6de7960ee4ebf6775c207e6867108142639236748b4227fcf8884fefb560ebe02cf66fa3cdbd4b229614a764ab856bb1ad78840bb706d53ced910b85613ae65c0d8d5ae81718cc54bb2c31a2ca4eaaf98418892b289d978cc2ec8db647f6dac54cd430309821d9c450e083949b2b45f31bbb673bbb9f7b9f5d2f05e4e35e586844ea48239adfc6095dd46019b2246227596a5a3900f24d5c897ec33dbed18927e2e14b3ff4db5b71e8e2b5d9c94ba38f1eb267d5d9c6c93aaa4b4fd7071f6949a44a4060a93c5252b46af76aa9f17f9a8ed38d5a72be161d1b986537d7a40386604cfb395626a99fbd91010518ab173cd9a77ad2db8572bbef6ec575ffbe030ab7ea44c3397c7d43ab6ec7d8b182e223fcef421e535c0d2a77032e9f85b56ebe8815339b682d93966a4d726348cef82e03b431009d0e9a53c06b221840833428f28fca9af13a231231a6e4174461ef38209a000d1b08f682888f2bc15993a2f324be42e6596e6cd88d6f1d0e22c4fa5fdf440fb99b23d19907119c6f957efacdd4fed792a6a1ab27f2015ce672d957a25426f3763619dfd083b3a2f3e074727ad952a33fd4598347de34ddae92d7af1ecdede06fb1ba52dfb22f46243ccbad8b2c957f040763767c99ee6ec2a0ec8cc80ffb1b6c5b5d8d59c5d456f95562cbc8a15bb8c8481bec479f2cb8a83576477103b2134297833766a03e859f16345c3e5014e2ce144f8fbe347e87338f7d17ff9cc37de40bccf5038390595c4d11069b50772d522cd826f2758303e7b993d600b7e247ed49492c8ee0436d4cac3615d2f87d4113d31a3127ecb3a651878d20f7e6058a7a20b8abb3b790492d3493b816202e9da850e1020c1715cd2e19ac0034c1412e8900b3329c7b818a4a038c326b5442e947a482ee11feb6eff967ecc4af4b0a93df57212ab2306e25629e6b054cca1e742d857cce136e90dbd62862e15511a70ca4eeda2a343d6d1c66ba3ad815acb1c45be8e75370825dac2727c717440afb364676ff3ca3de21e7a1b14e6ad2e40eca2bd1db718648f2a151f5d9be326fa1af179c04a964f23407ad373ff00fdbc66e20a9868a6e24b34d070054ab45329e15f30da6e38613b54129f42944b2cca25c1d2568a599fe40cc08a40086639cbca8bf9c04cb15c21c6dd3f90287bec23b44687a34186a6010df5a3dc6e83a6fb395d55ca871ec8e932b4f4dff50d2261b00709d51e2095b84c7b8084d0ecdfa6bf6e593346bcf1a069a6147c3bae9271dabb19d2f18e2ca7f470d0d4db7989efc2d471029d4b6e48579071e69a73cee2097b75459d7711f21379d4fbfd27096e54c49d664487980c1249ee79d2435ea9f20e12d9526d891c083a7af613b97950aaaa2e5ecadeeb7bcb8de5c949d699d0facebc0b03a983cc81613726c1eee85b728274a564f0835229d2eeb4f5cbd2495adaa14e7857b52a5bc14dd007466aba21a8e469a2b7d124d84a934068120dd224649a18a189014d42170dd0049ed95b0cb248f5bedcb868a9703bd0447291c8da1c40b3e93940be207c54a4a6b886bc7b117510e2401155977b7f1545d441506511065af8da8aa8bb2162b13bfbaa8ba8af0e9143fb8248e3fa11b9635f1071d78fc8e17d41a475fd88dcbd2f888c5d3f2247f7059189eb47e4f8be20b27b11752f4caeb188ba072aba84b05b11f5b7c52f0ff7d1fa243badcfa0a68d5cb2cdfa88ed89c5ba180a3b617822313ce4122f650f55db492aa32ac3c5b925e55d591f52c61c4103346f04d4499660a128307e701712259ca6a0686e2bb738620389fe53f74397cc27502417c677740825f24bab6b48755e104ec1521e88c7b8f1ce61d6e6e46052e81dba402e3489b3cf8fa03f5130266727d7127d87f065450042870b65e4efa896783641cea40b386e534211cd496d89d4789ce65d6a7642602ea55261d877e1a00417a5b0469efa6b46c81821b6fe0b6b62899edd12a79ce47a13416de4108f3b1855443db8d34456556e6d69dc1c433585c2a0f0a4bfcf147074c48d4027e4ea1c9132aceea269dcb2cb0ee54c30d0ed0301b22bf0edfa910ba49183f2e21b12d20588700a0d3bcc63b343a374ba98ce0a914bc8ac629a6cad8684a5810d61c3622925253cf062a7b86bcbd8d82585e3b1a0d551445308dce98108b526112af5d4ab6b75779010321fe9dd61c70f725aa32665158d143697eb10a2b01cc41c82e32d92405471e94a3e90612401c97eca45083c25b8268fb4d1d41e0ce8076632174bd2a67fa5ad2106a2649c079c11d2888b9504c57fc69b03ba4896dcfc1037be2c3b66998e24f0e18f983d667203d9e6e771760b4d8c789c4cfcd873c20fe2dfe94e19df97c5a6b314ac09050981a3ac1d5bd9ad0c0195f7337251b13375c94553fa09faf8d9f7de4e6c232e51b0fa5d4d7e93d4cd82c39c1c3a46b84cf2da25da4ffb1217d21d874a0a071c1712754422ac5c05e864ef1b958188092d5f02909091a01ecd43cf46f60724b28fd9aa7b26c6583e41264cea100a706249b344b44b6622b49296b48eeb94c50a30904f218e9b5c4f844a75c8b130982d4c948a59fa211b0a0b858d14ae8b0ae228c9ee0c4228a4b96bb72004210dc270e5d930600b1c3026c54f683635ab00d6fa688af860cb443a244c1583c0389a4a7e01d9bc3728f5641e4c4d3cf524498b2e363ad80cf5b1f9206340d0ab2081149a08de95e7fc098c40c9b084430c670cf840c2c30f80c1001c72a3194cc61aa744850e3d04b1b03d3ab8d9413ec822bd068f000b0550d7b21ea77848e6d0820405be34e44ba3c3bb979b21d294f9a6ac6c324898105f3eef85321bd08c03a944affa37399518f854a264b612a46b78e9665837e93605c7df919d97b17e9c682fbe3dbc5d7dd9d216f910179773b795c36d3596d57b7a3f85d95244a87095c41ae3ab3cbe7a2fd4522e197c1fc80d02f26553a9bb6d92b5975c9529ea3da1226175581e8e9d003afca4be5a223c8d1dd6b1ca4d86d089879b7c07a5515d1e6079e220f730fc4f674e6e99ea7c4a6fcbec5b315b97b3f59eb3ab0923db26f00ea026b3fed1701dc9cabe6d5492748924e97c0ed7882d6435fae7b86830703b4af160f1a12cd9b407799af2ae171cad3c821f620a5c698a59f511d988b0c5f7a8016e3f291dc2ab0777d1456fbf1dd503b80a996be23700e23d231d6c71ef05b7b3011d3bf7fefb062960728e82342d8b6b900cc5e50dbec311c38292e1586a4afa350f91f328e15902d5b4151ce636bcf6509cd8a85526bf902f5e62d5e00b4f7cc58ebdddca313462bd02c9e921b5ca387a6374204d9fd7261057f07f5de10d68ba6d6a8ec28b4a668ed804fecbeb540c5394c5d81d5f712a95e0a70ced28d8eedc5edb8e1a7e478d6bd851c38f7ba51d855e77e73bb7c585403f322b4766db062503831a25811a7bd801efdd8148311e194556f468346b4cab1ae221176535ef4aa65ff6d6eed590ea1a69b4cfc4317b11a74ca76571b9a9bfb6b2295454fcae08e7607b2565b3aaa404a2baab4a4a807d04be9262717acec8035703032e989c159d754a640147f079ae90f81a37d0872a65dff3ac04ce72a710f181af81841c78579d196a20b6ac8184acb2b8936f32c9302e78707dade56f56a20632263d6b825352ba0e16c569cb65eec0578e41c4c1dab154bf387e0dfaa5635b2e17c0a3adc0700c2faa861597e8700e1ffad5e320f5fa3b9b280b2c81e86e0616488598c1f5dbefe7769ac8451714c7a02d898f57d1edb4a36dea1dc96dafe17d65bcf82a3dd99b868e47bf293ef9d5676f19d0f2b401d6f296b53c59956552f441a5e80df39698a53c4dfd83ec68f9e6aab746f596f937291396399eb1dd6d848574f66d44c0587438c5cd2ca9ec036cf37f0b0de3ebb0c8d80d9a1672b079a95dac8b45a2e2f439ee36e2e48b8db192b550550564771bc377292cdb98a735bb4ffca3a5fdf47ccec8e3b4f77ce450ca314cf8d69fe8047a3f22878e20fcdaff19f79e7434a3c746ebefac0dca7bf7dfbc36328542a6edb820b046600432719855c908c5604614532916a51dc32363fdba353d22d40c25b264e141fc88e82de6f851fa0349af1889da620490914b38808c3880440e860248c3c16513f65ae35786fd00d2ec08206309203d9c12f92a808ca6b80254c19100d29401a447c5226ea72f6500697d00197b3be92355e5d713a3238999b16dc1a2646ac606e245d6be134c3ebc8d41b32bcfd0ec6ed1e3c48a97becfd8ffff8cf51750b65c46aa38fcb211ed36e06ddc30edc657387689ea5ae68c04575f54db8239f95583c21d259e3d51a9c80984574c3ab62bd2debfb351fa2b49df5f09d88a559dc9167f25e0247f69659ca9fc9586f82b6ec05f69f5fd9506dfb13c25f8bc593c83898168ef7819edb16790fea93656c29531b92dc3e9b631e7adb35c01e3727499d6e15008d849b3385d64ef9638319907d92dcef6af04245d64f6d8be210d990cdc472248b8432a9797f8f46523e3e668992de55ca7de35d729a1aa53e9b3b8ea53ba3241e5b634cec1ad82dbf229f257908c2c9ec50b0e635956966141f1157268c47b09e0bdc470e7254625ff212e1ae2bd9832f41c702bb4fca25bfb4b4174e61acb79826461243f15364c32fc34462ea121730a88b0635c868d7c0e5c2e0918c13f3ec1ee2049d102d7fe49ea16fc85002be94fc0ae8acafc3b702f455adcf7b5f2e46906e10294915cc077a9785d5d9574627f8904bb8a21f13edb8a7ed9063b20a15ccd22152117b762a0148b24c4e5c5ad7e469696ab344d799b2b4dffd1a6fc93fef49d8fcc2e2eb7e75d6fd5cd2e2fafcecdf6da6e6df6d1f6ba5a7db8d39eebd197f575e95fecb5bbb3bdd5ee34ded7ddca6acf2daeb87317967b8bd38b2bf3ed8b8a7f0c99def9fe2e0d55ed6e77b5ebf07f5b2cae3c5a4d567cacd310ed8a33e0e9bd73b32b0036476db4baacbb0ed8bdd98797a9e111374bfd0bedae9b5b5de97567e77a8aeb00e9eb77e0786e757ef191c7f744efe581e5fcd06b5cee63cfa9f44df21f4350bb47786176e551225777f1dc6cf771b7d47edcbd7fa1bde22163d7b32b1ebe62cd9ae66bddd5deeadceab2f3ff71488969ffff18e132651a3cdac61cb22ce9dd1756da17d70806ed50684aa83eb278b13d3ffdf0e3bdf63ab05cef752fcc097569ee1f349552ff05ee7357f400d00700008101010100204b21f3cba072cc493e70861540df4677b498b0505a8b8e2a346b85a0c2dd2fc4263c4a7d8629026c4eb594ad96fac2bfe5f8ffebb9c841c353920b7b8ec11abc0100d90778da8d563b8f1c4510eedbf7e37cf209d9e60808402496c0dcdaac4e8ece01090112afe83043ef74ed4e6b677a86ee9edd5b3b2121b049888d842c84c0c1456702eb20b036424242c2e00408800c24fe03d53db3f33a58e860b6bbeaebeaeaaaafaab7f55bff9d1a796df0e5798263c37cc89f2fbe657e1eb8c7cb92e0de5f83c1eded95e4fded2d08150faf5ea5237e69f7855db2d3c199e351e5915a339c0b900d4103681849dff5c09daa3818bc34ec5057f319d54036b6c640752cc1617c024a17515d1a6b2f945c2f48a3ab3d09ca0b7dd68ab9d097078d292cd4267e9c39f089a70faea351378c85563b11c8802bf44c383eccc0cf20cd39e55a9d31df4c766ee487eed4f528174e4425baab412ab2fd44400f1dab73046827567402f6ece195a73495139455b44ee4ead4bb1db3594b2a94b929fa51367179f0f4882adc00722dea6c6edb0798d3452a7fd60d858643ed8c2598c8297bf18227220efe2f948148a1851bbb515c72a47ce34cbbeec655133b0106781de0c9aa059f8f41f3200b19833148090c41870e1c465c528b9b73c1c2798a3a57b5c2c0cfe276de28b9f0b90027552b7e6375c085d35a0691f6ac7a7768c39351b2a4eabb54b8e0dba3486d2b597131b1f0b3553ab68cff9c15a9dec3adc83b0327b5764a645b3bbd7c77b2ce294f6a755cf4a278e473d7c1692b91a74e75d083a9b5d828596cb8218364a6175132eb4b782fe61202581d2b906ec926dcee4a2cd2302de6ec9354785ea52d5bd5900bda21ea652849adab4030243b676debdc60af83126d32d91c2d34a85341c20682e6d233ab41b8f02f154e6a05e4e9b897c2b319c990c52e3a859123b533d932bbdf76c276c527c2e4b21ceb4d8cd8aa8bb1b56dac6d90260d1b8db10c036bbaa54063abace4ba8ea2241c3da3f77980ddaa92bd2e7628c7629ab617f54c2527174b05a6ae8a8236da3229af186acd0293fea689c65e7716ccb0eb61a892b5e548eeca2475a55ec7d3d32658c78357533c329d62a2b5eda28a6cb492c93f3758e35524f9ac128236578e11276e742c286468aca330a42cf661ab98b783ebbd58643cafff27cf7b71c4685a678db575669c5f1543c3e0735af70bef07a975ec4a819b769132cbcc6379f1637c36f3278f7c7debe2cb1f7c7eadd434c8feb73fdd3bfaf4956223c0f1fcb4fec587792193fd4fee3cc31edc2956278e5f1fdd7cfc59566c1fbd39fc19d8d14999a138ee42707492b171f5c0afa848c877af9e78c7cb22f570ec3f77fb789951c882be4940930cf4f0d1db6fdc5f16528fe3ddaf0eee2fb324e3d8fb1e057942cd851ffef1fb8fc5fcd920f8af3f2e66c9fcffb84b7ff865b7ce875708c9ff60d8f137aa5a1fa900d00700001001010020742877c36a520b152b1337ea1ecd37b0c98ad07289c32fec392e7eebab9f0ac71f7bc8c718cfa75317b2e15702372a9222c4616783ee7b3f0ec6358f8c328eea00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232201a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b72410000d00700001001010020058e23368b919493d6ac61d27f66b829a53893e88ddde857d3b82d913960960d22fa36f397752b98c295e3b31927f740127c0a99e76f8bfeea88f44466b8fbfd00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea990000d0070000100101001f43fe868e263d8134cf705aa85e26ce78ebb058edd558865fa3d240f5cb9e50c2389e9c8276eac800b7233a552045b2e79124c97e5156a0649849cc7f5d09eee600005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232204a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0f0000d0070000100101001f29e82b08ccf15e2187f29fea11ee3f4974f41b51e45b19f353348d8848b86fb71cadd88630456b7a1c60803c7b402487d41fbf18f0b0a13b4cca1f740447938300005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220e0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff5260000d0070000100101002047a8b784c3765b5c63ac52e3d8461b80bc2d3e3f62434f8accb277d9f2487cfd3c0728fcd26b5119a11288e5db46bc5b547877e220971609d1cef8cba443340800005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed32322068dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a2974280000d007000010010100203e701fbafd4149bc95b55a6bfc3b78246f5c2668ccc05ed4059a36ceb38f140b31e3b69e15f2579571e5bde39e034947271599c200e540b3949112bef163074c00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c430000d0070000100101001f0cc7352e60f4f8476783d6d1b48766a111c56fee2c1a552e76a75c92bc17de172f994ffc854c09717c904054819ca7a17379ddecaf531c439b35337ba099b81300005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232208ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a4050000d0070000100101002040965063a83be2d53b36c8d7e0775f503c2caa1407e586314562aace52c272fe60659e196413a6c9db4168470bcabb9a5851121c10c7b665f363f6cd4d1e4bda00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232202652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed250000d0070000100101002074ea7468b2a031c4cd53bf10ec3ac66b0c4b5c8779e045f1ef8d9c7b116be649217ff340107d0163397b99918ee2ce822b66cd6fce7b385af97a04671136e2ee00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d0000d007000010010100204dfb21ca5140582379bc026792c16b4cf97827143a4a9cd99ae70b3e6016cd6316bcbb9f1cb1233f12a0bbcd9debafa64724d0459b5c8d3cb67ceddfb2e3962500005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232204e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d670000d0070000100101002033446a3a94ade71dff3edb786259679487ab701bbc147490b1d4159fecf545fa22fee0698db16bf616465e5cebb985bfc4d9ed1ec4a55e38997dd4b4bbc427eb00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232204fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c20000d0070000100101001f3f67edd35bf731a07f40c638e8812112cd7d1baa39ec7dac4a1b2f0c83ac8bd53689b56dba69a7386e3860a6f8976695ac0bc2b5dacae91080f1d54df2dac0c000005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b44767070000d0070000100101001f1e030564013603d54f9e983b63cd940f8ff09ae038b14813f4021bb0c09ebb640d90cb4f8d57be2809f492a51737b671a5f549d4efa8e7efdaeaa9663c09d1ad00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead450710000d007000010010100205cea642eecf05568ce8c5564e63349eea3b816108914ba2ab5efffbb8ea467265f0b6d474f03ed02a3bf529fd6e55a595cbf8dd1adf4311cb9c51e862f8a535400005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232205443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b40000d0070000100101001f4556076cc86e0840bf69664f1ef8fcd4d91abda313d08e7840d24ba45cb429cf12b7d3a1f64250c19d1b975e7b107853beff70ebfc4c27c44f825dc05cdc9cd600005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e990000d0070000100101001f354d903ad0f2c6cc9d9a377d681ffaa00475d1e559e48074b4c8cce3111d5c172903b2f179ad4d736dda4e7d1b6a859baeab9dde5e5e495ce09733ec4650634400005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb400000d0070000100101001f1766fa716a828da244c9ce52919b7a19acb38dbd110d1bb0039bb2477c17e4465dceecb8330ed5ee9de1330930dfcfa1a5e8149ce8536a82c0093642adf7328200005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232206bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc0000d00700001001010020488923db1c78fa430a3a9eab75f4ee467c7b9a3d3b4eb3bd08e183c82ef79b9102a4d2a7d1ec79c96b404911ae1b10f579bd82a660011c1ca2b872b30ef7dcac00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed32322035c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b0000d0070000100101002031ca6aeda725c01ed6aa6199dd2767930803051d3bc2897956bc9f97f8db5abf3bf243b775b4020f0c96d8ad197d591d11f8a51760c19fdc81134eff06a1941f00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed32322098c4175db53ed27e7911a1b5adf0e7db0fc96c2cae172cf594dfa9a742ca9e88000000 DMLOG START_BLOCK 4 DMLOG FEATURE_OP ACTIVATE 1a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b7241 {"feature_digest":"1a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b7241","subjective_restrictions":{"enabled":true,"preactivation_required":true,"earliest_allowed_activation_time":"1970-01-01T00:00:00.000"},"description_digest":"f3c3d91c4603cde2397268bfed4e662465293aab10cd9416db0d442b8cec2949","dependencies":[],"protocol_feature_type":"builtin","specification":[{"name":"builtin_feature_codename","value":"ONLY_LINK_TO_EXISTING_PERMISSION"}]} DMLOG FEATURE_OP ACTIVATE ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea99 {"feature_digest":"ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea99","subjective_restrictions":{"enabled":true,"preactivation_required":true,"earliest_allowed_activation_time":"1970-01-01T00:00:00.000"},"description_digest":"9908b3f8413c8474ab2a6be149d3f4f6d0421d37886033f27d4759c47a26d944","dependencies":[],"protocol_feature_type":"builtin","specification":[{"name":"builtin_feature_codename","value":"REPLACE_DEFERRED"}]} @@ -141,40 +145,41 @@ DMLOG FEATURE_OP ACTIVATE bcd2a26394b36614fd4894241d3c451ab0f6fd110958c342307362 DMLOG FEATURE_OP ACTIVATE d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb40 {"feature_digest":"d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb40","subjective_restrictions":{"enabled":true,"preactivation_required":true,"earliest_allowed_activation_time":"1970-01-01T00:00:00.000"},"description_digest":"8139e99247b87f18ef7eae99f07f00ea3adf39ed53f4d2da3f44e6aa0bfd7c62","dependencies":[],"protocol_feature_type":"builtin","specification":[{"name":"builtin_feature_codename","value":"CONFIGURABLE_WASM_LIMITS2"}]} DMLOG FEATURE_OP ACTIVATE 6bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc {"feature_digest":"6bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc","subjective_restrictions":{"enabled":true,"preactivation_required":true,"earliest_allowed_activation_time":"1970-01-01T00:00:00.000"},"description_digest":"68d6405cb8df3de95bd834ebb408196578500a9f818ff62ccc68f60b932f7d82","dependencies":[],"protocol_feature_type":"builtin","specification":[{"name":"builtin_feature_codename","value":"CRYPTO_PRIMITIVES"}]} DMLOG FEATURE_OP ACTIVATE 35c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b {"feature_digest":"35c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b","subjective_restrictions":{"enabled":true,"preactivation_required":true,"earliest_allowed_activation_time":"1970-01-01T00:00:00.000"},"description_digest":"e5d7992006e628a38c5e6c28dd55ff5e57ea682079bf41fef9b3cced0f46b491","dependencies":[],"protocol_feature_type":"builtin","specification":[{"name":"builtin_feature_codename","value":"GET_BLOCK_NUM"}]} +DMLOG FEATURE_OP ACTIVATE 98c4175db53ed27e7911a1b5adf0e7db0fc96c2cae172cf594dfa9a742ca9e88 {"feature_digest":"98c4175db53ed27e7911a1b5adf0e7db0fc96c2cae172cf594dfa9a742ca9e88","subjective_restrictions":{"enabled":true,"preactivation_required":true,"earliest_allowed_activation_time":"1970-01-01T00:00:00.000"},"description_digest":"01969c44de35999b924095ae7f50081a7f274409fdbccb9fc54fa7836c76089c","dependencies":[],"protocol_feature_type":"builtin","specification":[{"name":"builtin_feature_codename","value":"BLS_PRIMITIVES"}]} DMLOG CREATION_OP ROOT 0 -DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304003,"value_ex":54635,"consumed":1},"cpu_usage":{"last_ordinal":1262304003,"value_ex":233234,"consumed":101},"ram_usage":180802} -DMLOG TRX_OP CREATE onblock 89d482b30a16a7019245292abb20393bdde4ccd1ff2331b1039efc77ef70b7b9 0000000000000000000000000000010000000000ea305500000000221acfa4010000000000ea305500000000a8ed323274023b3d4b0000000000ea305500000000000213588be25132b4167ced6df22b5439e376d5a20284190bb94a43e3e86c50d366bd80731342402e85b2ddc0052985fd31301156b938d7325ded2582756e40bfbc4f83b79f8de2f5d0c5394ffcc2f724830bb6b5ed9dcd5dbb4a091398000000000000000000 -DMLOG APPLIED_TRANSACTION 4 89d482b30a16a7019245292abb20393bdde4ccd1ff2331b1039efc77ef70b7b904000000033b3d4b01000000044444a224a7e16ae04e24e6640d6a909fb89ca6e5e8c1e5397e1e03ef01006400000000000000000000000000000000000000000001010000010000000000ea30552786c63374c90aa8c0387b85266147ed008f53eb19b299f255e57ea78b33f69417000000000000001700000000000000010000000000ea3055170000000000000001010000000000ea30550000000000ea305500000000221acfa4010000000000ea305500000000a8ed323274023b3d4b0000000000ea305500000000000213588be25132b4167ced6df22b5439e376d5a20284190bb94a43e3e86c50d366bd80731342402e85b2ddc0052985fd31301156b938d7325ded2582756e40bfbc4f83b79f8de2f5d0c5394ffcc2f724830bb6b5ed9dcd5dbb4a0913980000000000000000000000000000000089d482b30a16a7019245292abb20393bdde4ccd1ff2331b1039efc77ef70b7b904000000033b3d4b01000000044444a224a7e16ae04e24e6640d6a909fb89ca6e5e8c1e5397e1e03ef0000000000000000 +DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304003,"value_ex":55376,"consumed":1},"cpu_usage":{"last_ordinal":1262304003,"value_ex":244809,"consumed":101},"ram_usage":180802} +DMLOG TRX_OP CREATE onblock e11ba456c63db33e0320a8f51418e4e0af5ee0d38fd7d6cf13a089eda823f8f3 0000000000000000000000000000010000000000ea305500000000221acfa4010000000000ea305500000000a8ed323274023b3d4b0000000000ea305500000000000213588be25132b4167ced6df22b5439e376d5a20284190bb94a43e3e841639eb3a733e9536932b85f63002945d82e25a0ef948f220ba098df51ab2f5d9d5fc55180118b2a44ae7b7ad158b7de8fee6df8ac1c5afd3681c5b11460ac96000000000000000000 +DMLOG APPLIED_TRANSACTION 4 e11ba456c63db33e0320a8f51418e4e0af5ee0d38fd7d6cf13a089eda823f8f304000000033b3d4b010000000446ce40fcba331770d4e40c1a69d054d3a9a5ed89ef08b50cc808e32501006400000000000000000000000000000000000000000001010000010000000000ea305518ea4ce1eae6e5bb75076db4c0bc4ba7f64bac448aa056072cc35f5c5e62230218000000000000001800000000000000010000000000ea3055180000000000000001010000000000ea30550000000000ea305500000000221acfa4010000000000ea305500000000a8ed323274023b3d4b0000000000ea305500000000000213588be25132b4167ced6df22b5439e376d5a20284190bb94a43e3e841639eb3a733e9536932b85f63002945d82e25a0ef948f220ba098df51ab2f5d9d5fc55180118b2a44ae7b7ad158b7de8fee6df8ac1c5afd3681c5b11460ac9600000000000000000000000000000000e11ba456c63db33e0320a8f51418e4e0af5ee0d38fd7d6cf13a089eda823f8f304000000033b3d4b010000000446ce40fcba331770d4e40c1a69d054d3a9a5ed89ef08b50cc808e3250000000000000000 DMLOG CREATION_OP ROOT 0 DMLOG RAM_OP 0 eosio code update setcode eosio 199492 18690 -DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304003,"value_ex":94450,"consumed":6881},"cpu_usage":{"last_ordinal":1262304003,"value_ex":244809,"consumed":2101},"ram_usage":199492} -DMLOG APPLIED_TRANSACTION 4 09a000d4f60add54d14ba0cc4ad9573fbd96346a4d3f59278ebdf8e3455556ed04000000033b3d4b01000000044444a224a7e16ae04e24e6640d6a909fb89ca6e5e8c1e5397e1e03ef0100d0070000dc060000000000000000e01a0000000000000001010000010000000000ea3055378d583c2888f3564b4db37bfb52d74d038e54fcc63aeb57cf27b03c001e97a518000000000000001800000000000000010000000000ea3055180000000000000002010000000000ea30550000000000ea305500000040258ab2c2010000000000ea305500000000a8ed3232cb99010000000000ea30550000be99010061736d010000000198011960000060027f7f0060037f7f7f0060047e7e7e7e017f6000017e60047f7e7e7f0060057f7f7f7f7f017f60037f7f7f017f60027f7f017f60027f7f017e60057f7f7f7f7f0060067e7e7e7e7f7f017f60017e0060027e7f0060047e7e7e7e0060037e7f7f017e60017f0060017f017f6000017f60027f7e0060047f7e7f7f0060037e7e7e0060037f7e7f0060047f7f7f7f0060027e7e0002f0052403656e760b64625f66696e645f693634000303656e760c656f73696f5f617373657274000103656e761063757272656e745f7265636569766572000403656e760561626f7274000003656e760d6173736572745f736861323536000203656e760b6173736572745f73686131000203656e760d6173736572745f736861353132000203656e76106173736572745f726970656d64313630000203656e7606736861323536000203656e76095f5f6173686c746933000503656e760473686131000203656e7606736861353132000203656e7609726970656d64313630000203656e760b7265636f7665725f6b6579000603656e76207365745f626c6f636b636861696e5f706172616d65746572735f7061636b6564000103656e76066d656d637079000703656e76206765745f626c6f636b636861696e5f706172616d65746572735f7061636b6564000803656e76167365745f70726f706f7365645f70726f647563657273000903656e760c63757272656e745f74696d65000403656e76146765745f6163746976655f70726f647563657273000803656e76087072696e74735f6c000103656e76126173736572745f7265636f7665725f6b6579000a03656e760c64625f73746f72655f693634000b03656e760c726571756972655f61757468000c03656e760e7365745f70726976696c65676564000d03656e76137365745f7265736f757263655f6c696d697473000e03656e76197365745f70726f706f7365645f70726f6475636572735f6578000f03656e761370726561637469766174655f66656174757265001003656e76067072696e7473001003656e761469735f666561747572655f616374697661746564001103656e7610616374696f6e5f646174615f73697a65001203656e7610726561645f616374696f6e5f64617461000803656e7611656f73696f5f6173736572745f636f6465001303656e760a64625f6765745f693634000703656e760d64625f7570646174655f693634001403656e76087072696e7468657800010346450015111000111010100c100802101608020817010110011818181818181808011818181818080101180818181808000808010101080101010801010102080108020202020804050170010d0d05030100010616037f014180c0000b7f0041e2c5000b7f0041e2c5000b070901056170706c7900250912010041010b0c555657595a5b5d5e5f6465660aab8b0145040010280bdd03002000102d102420002001510440428080f9d4a98499dc9a7f200251044020002001103b05428080add68d959ba955200251044020002001103c05428080add68d95abd1ca00200251044020002001103d0542808080e8b2edc0d38b7f200251044020002001103e05428080add68db8baf154200251044020002001103f054280f8a6d4d2a8a1d3c1002002510440200020011040054280808080d4c4a2d942200251044020002001104105428080808080f798d9422002510440200020011044054280808080aefadeeaa47f2002510440200020011045054280808080b6f7d6d942200251044020002001104605428080b8f6a4979ad94220025104402000200110470542808080c093fad6d9422002510440200020011048054280808096cdebd4d942200251044020002001104c054280808080daac9bd6ba7f200251044020002001104e0542808080d0b2b3bb9932200251044020002001104f054290a9d9d9dd8c99d6ba7f2002510440200020011050052000428080808080c0ba98d500520440410042808080d9d3b3ed82ef0010200b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b05428080808080c0ba98d50020015104404280808080aefadeeaa47f2002510440410042818080d9d3b3ed82ef0010200b0b0b410010310b7201037f024020000d0041000f0b4100410028028c40200041107622016a220236028c404100410028028440220320006a410f6a4170712200360284400240200241107420004b0d004100200241016a36028c40200141016a21010b024020014000417f470d0041004190c00010010b20030b02000b3601017f230041106b2200410036020c4100200028020c280200410f6a417071220036028040410020003602844041003f0036028c400b3301027f2000410120001b2101024003402001102622000d01410021004100280284412202450d0120021100000c000b0b20000b0600200010270b05001003000b05001003000b0a0041002000370388410b4e01017f230041e0006b220124002001200141d8006a3602082001200141106a3602042001200141106a36020020012000102f1a200141106a200128020420012802006b100e200141e0006a24000ba20801027f02402000280208200028020422026b41074a0d0041004190c1001001200028020421020b200220014108100f1a2000200028020441086a2202360204200141086a21030240200028020820026b41034a0d0041004190c1001001200028020421020b200220034104100f1a2000200028020441046a22023602042001410c6a21030240200028020820026b41034a0d0041004190c1001001200028020421020b200220034104100f1a2000200028020441046a2202360204200141106a21030240200028020820026b41034a0d0041004190c1001001200028020421020b200220034104100f1a2000200028020441046a2202360204200141146a21030240200028020820026b41034a0d0041004190c1001001200028020421020b200220034104100f1a2000200028020441046a2202360204200141186a21030240200028020820026b41034a0d0041004190c1001001200028020421020b200220034104100f1a2000200028020441046a22023602042001411c6a21030240200028020820026b41034a0d0041004190c1001001200028020421020b200220034104100f1a2000200028020441046a2202360204200141206a21030240200028020820026b41034a0d0041004190c1001001200028020421020b200220034104100f1a2000200028020441046a2202360204200141246a21030240200028020820026b41034a0d0041004190c1001001200028020421020b200220034104100f1a2000200028020441046a2202360204200141286a21030240200028020820026b41034a0d0041004190c1001001200028020421020b200220034104100f1a2000200028020441046a22023602042001412c6a21030240200028020820026b41034a0d0041004190c1001001200028020421020b200220034104100f1a2000200028020441046a2202360204200141306a21030240200028020820026b41034a0d0041004190c1001001200028020421020b200220034104100f1a2000200028020441046a2202360204200141346a21030240200028020820026b41034a0d0041004190c1001001200028020421020b200220034104100f1a2000200028020441046a2202360204200141386a21030240200028020820026b41034a0d0041004190c1001001200028020421020b200220034104100f1a2000200028020441046a22023602042001413c6a21030240200028020820026b41034a0d0041004190c1001001200028020421020b200220034104100f1a2000200028020441046a2202360204200141c0006a21030240200028020820026b41014a0d0041004190c1001001200028020421020b200220034102100f1a2000200028020441026a2202360204200141c2006a21010240200028020820026b41014a0d0041004190c1001001200028020421020b200220014102100f1a2000200028020441026a36020420000bfa0103017f027e017f230041306b2203240020012002200341106a1008420021044110210141002102420021050340200341106a20026a21060240024020014102490d002005420886200420063100008422044238888421052001417f6a2101200442088621040c010b024020014101460d00410041a9c00010010b200020053703082000200420063100008437030041102101200041106a210042002104420021050b200241016a22024120470d000b024020014110460d00024020014102490d00200320042005200141037441786a1009200341086a2903002105200329030021040b20002004370300200020053703080b200341306a24000b02000b970503017f017e047f230041f0006b22032400200341206a4100360200200342003703182003427f37031020032000290300220437030820032004370300024002402004200442808080809aecb4ee312001100022004100480d00024020032000103322002802302003460d00410041c0c20010010b2003200236023020032000200341306a10340c010b024020041002510d004100418ac30010010b41c000102922004200370310200041286a22054200370300200041206a22064200370300200041186a220742003703002000200336023020002001370300200341306a20022802002208200228020420086b10302005200341306a41186a2903003703002006200341306a41106a29030037030020072003290338370300200020032903303703102003200341306a41286a3602682003200341306a360260200341306a20004108100f1a2003200341306a410872360264200341e0006a200041106a10351a2000200329030842808080809aecb4ee31200120002903002204200341306a412810162205360234024020042003290310540d002003427e200442017c2004427d561b3703100b200320003602602003200029030022043703302003200536022c02400240200328021c220220032802204f0d00200220053602102002200437030820034100360260200220003602002003200241186a36021c0c010b200341186a200341e0006a200341306a2003412c6a10360b20032802602100200341003602602000450d002000102a0b024020032802182205450d0002400240200328021c22002005470d00200521000c010b0340200041686a220028020021022000410036020002402002450d002002102a0b20052000470d000b200328021821000b2003200536021c2000102a0b200341f0006a24000b840603097f027e017f230041e0006b220221032002240002400240200028021822042000411c6a2802002205460d0002400340200541786a2802002001460d012004200541686a2205470d000c020b0b20042005460d00200541686a28020021060c010b024002400240024020014100410010212205417f4a0d00410041f3c20010010c010b2005418104490d010b200510262107410121080c010b20022005410f6a4170716b22072400410021080b20012007200510211a41c0001029220642003703102006420037030020062000360230200641186a4200370300200641206a4200370300200641286a42003703000240200541074b0d00410041d9c40010010b200620074108100f1a200741086a21040240200541786a411f4b0d00410041d9c40010010b200041186a2109200641106a210a200341c0006a20044120100f1a4200210b41102105200341206a2102410021044200210c0340200341c0006a20046a210d0240024020054102490d00200c420886200b200d31000084220b42388884210c2005417f6a2105200b420886210b0c010b024020054101460d00410041b6c50010010b2002200c3703082002200b200d3100008437030041102105200241106a21024200210b4200210c0b200441016a22044120470d000b024020054110460d00024020054102490d00200341086a200b200c200541037441786a1009200341106a290300210c2003290308210b0b2002200b3703002002200c3703080b200a2003290320370300200a41086a2003290328370300200a41186a200341206a41186a290300370300200a41106a200341206a41106a290300370300200620013602342003200636022020032006290300220b3703402003200136021c02400240200028021c2205200041206a2802004f0d00200520013602102005200b37030820034100360220200520063602002000200541186a36021c0c010b2009200341206a200341c0006a2003411c6a10360b02402008450d00200710270b20032802202105200341003602202005450d002005102a0b200341e0006a240020060b980203027f017e017f230041206b2203210420032400024020012802302000460d00410041bdc30010010b024010022000290300510d00410041ebc30010010b200129030021052004200228020022022802002206200228020420066b1030200141286a200441186a290300370300200141206a200441106a290300370300200141186a200429030837030020012004290300370310200141106a2102024020052001290300510d004100419ec40010010b200341506a220324002004200341286a36020820042003360200200320014108100f1a2004200341086a3602042004200210351a20012802344200200341281022024020052000290310540d002000427e200542017c2005427d561b3703100b200441206a24000bd20303017f027e017f230041206b220224002002200141186a29030022033c00172002200141086a29030022044220883c0003200220044228883c0002200220044230883c0001200220044238883c0000200220034220883c001320022003a722054108763a0016200220054110763a0015200220054118763a001420022004a722053a0007200220054108763a0006200220054110763a0005200220054118763a0004200220012903002204423886200442288642808080808080c0ff0083842004421886428080808080e03f8320044208864280808080f01f838484200442088842808080f80f832004421888428080fc07838420044228884280fe03832004423888848484370308200220012903102204423886200442288642808080808080c0ff0083842004421886428080808080e03f8320044208864280808080f01f838484200442088842808080f80f832004421888428080fc07838420044228884280fe03832004423888848484370318200220034230883c0011200220034228883c0012200220034238883c001002402000280208200028020422016b411f4a0d0041004188c2001001200028020421010b200120024120100f1a2000200028020441206a360204200241206a240020000b9a0301057f0240024002402000280204200028020022046b41186d220541016a220641abd5aad5004f0d0041aad5aad500210702400240200028020820046b41186d220441d4aad52a4b0d0020062004410174220720072006491b22070d0041002107410021040c010b200741186c102921040b20012802002106200141003602002004200541186c22086a2201200328020036021020012002290300370308200120063602002004200741186c6a2105200141186a21062000280204220220002802002207460d01200420086a41686a21010340200241686a220428020021032004410036020020012003360200200141086a200241706a2202290300370300200141106a200241086a280200360200200141686a21012004210220072004470d000b200141186a210120002802042107200028020021040c020b2000102c000b200721040b200020053602082000200636020420002001360200024020072004460d000340200741686a220728020021012007410036020002402001450d002001102a0b20042007470d000b0b02402004450d002004102a0b0bd00203047f017e017f230041106b220224004100210320004100360208200042003702002002410036020020012802042204200128020022056b410575ad21060340200341016a2103200642078822064200520d000b2002200336020002400240024020052004460d0003402002200341086a3602002003410c6a2103200541186a2802002207ad21060340200341016a2103200642078822064200520d000b20022003417c6a3602002007417f460d022002200336020020022005410c6a10511a20022802002103200541206a22052004470d000b20002802002105200028020421070c020b41002105410021070c010b1052000b024002402003200720056b22074d0d002000200320076b1043200028020021050c010b200320074f0d002000200520036a3602040b2002200536020420022005360200200220002802043602082002200110531a200241106a24000baf0302017f027e230041206b22022400200029030010172002200141186a29030022033c00172002200141086a29030022044220883c0003200220044228883c0002200220044230883c0001200220044238883c0000200220034220883c001320022003a722004108763a0016200220004110763a0015200220004118763a001420022004a722003a0007200220004108763a0006200220004110763a0005200220004118763a0004200220012903002204423886200442288642808080808080c0ff0083842004421886428080808080e03f8320044208864280808080f01f838484200442088842808080f80f832004421888428080fc07838420044228884280fe03832004423888848484370308200220012903102204423886200442288642808080808080c0ff0083842004421886428080808080e03f8320044208864280808080f01f838484200442088842808080f80f832004421888428080fc07838420044228884280fe03832004423888848484370318200220034230883c0011200220034228883c0012200220034238883c00102002101b41bdc100101c2001103941bbc100101c200241206a24000b9c0303017f027e017f230041206b220124002001200041186a29030022023c00172001200041086a29030022034220883c0003200120034228883c0002200120034230883c0001200120034238883c0000200120024220883c001320012002a722044108763a0016200120044110763a0015200120044118763a001420012003a722043a0007200120044108763a0006200120044110763a0005200120044118763a0004200120002903002203423886200342288642808080808080c0ff0083842003421886428080808080e03f8320034208864280808080f01f838484200342088842808080f80f832003421888428080fc07838420034228884280fe03832003423888848484370308200120002903102203423886200342288642808080808080c0ff0083842003421886428080808080e03f8320034208864280808080f01f838484200342088842808080f80f832003421888428080fc07838420034228884280fe03832003423888848484370318200120024230883c0011200120024228883c0012200120024238883c0010200141201023200141206a24000ba70303017f027e017f230041206b220224002002200141186a29030022033c00172002200141086a29030022044220883c0003200220044228883c0002200220044230883c0001200220044238883c0000200220034220883c001320022003a722054108763a0016200220054110763a0015200220054118763a001420022004a722053a0007200220054108763a0006200220054110763a0005200220054118763a0004200220012903002204423886200442288642808080808080c0ff0083842004421886428080808080e03f8320044208864280808080f01f838484200442088842808080f80f832004421888428080fc07838420044228884280fe03832004423888848484370308200220012903102204423886200442288642808080808080c0ff0083842004421886428080808080e03f8320044208864280808080f01f838484200442088842808080f80f832004421888428080fc07838420044228884280fe03832004423888848484370318200220034230883c0011200220034228883c0012200220034238883c001002402002101d0d00410041d8c10010010b200241206a24000bb90101047f230041106b2202210320022400024002400240101e22040d002003420037030841002102200341086a21050c010b024002402004418004490d002004102621020c010b20022004410f6a4170716b220224000b20022004101f1a20034200370308200341086a2105200441074b0d010b410041d9c40010010b200520024108100f1a20034200370300200241086a2102024020044178714108470d00410041d9c40010010b200320024108100f1a200341106a24000b4401037f2300220221030240101e2204450d00024002402004418004490d002004102621020c010b20022004410f6a4170716b220224000b20022004101f1a0b200324000b4401037f2300220221030240101e2204450d00024002402004418004490d002004102621020c010b20022004410f6a4170716b220224000b20022004101f1a0b200324000b4401037f2300220221030240101e2204450d00024002402004418004490d002004102621020c010b20022004410f6a4170716b220224000b20022004101f1a0b200324000b4401037f2300220221030240101e2204450d00024002402004418004490d002004102621020c010b20022004410f6a4170716b220224000b20022004101f1a0b200324000b4401037f2300220221030240101e2204450d00024002402004418004490d002004102621020c010b20022004410f6a4170716b220224000b20022004101f1a0b200324000bc90201047f230041306b220221032002240002400240101e22040d00410021020c010b024002402004418004490d002004102621020c010b20022004410f6a4170716b220224000b20022004101f1a0b20032002360224200320023602202003200220046a2205360228200342003703180240200441074b0d00410041d9c400100120032802282105200328022421020b200341186a20024108100f1a2003200241086a2202360224024020052002470d00410041d9c400100120032802282105200328022421020b200341176a20024101100f1a2003200241016a2202360224024020052002470d00410041d9c4001001200328022421020b200341166a20024101100f1a2003200241016a3602242003410036021020034200370308200341206a200341086a10421a024020032802082202450d002003200236020c2002102a0b200341306a24000bff0103017f017e047f2000280204210242002103410021040340024020022000280208490d0041004183c5001001200028020421020b20022d000021052000200241016a22063602042003200541ff0071200441ff0171220274ad842103200241076a2104200621022005418001710d000b0240024020012802042205200128020022026b22072003a722044f0d002001200420076b10432000280204210620012802042105200128020021020c010b200720044d0d002001200220046a22053602040b0240200028020820066b200520026b22054f0d00410041d9c4001001200028020421060b200220062005100f1a2000200028020420056a36020420000b980201057f02400240024020002802082202200028020422036b2001490d000340200341003a00002000200028020441016a22033602042001417f6a22010d000c020b0b2003200028020022046b220520016a2206417f4c0d0141ffffffff07210302400240200220046b220241feffffff034b0d0020062002410174220320032006491b22030d0041002103410021020c010b2003102921020b200220036a2106200220056a220421030340200341003a0000200341016a21032001417f6a22010d000b20042000280204200028020022016b22026b2104024020024101480d00200420012002100f1a200028020021010b2000200636020820002003360204200020043602002001450d002001102a0b0f0b2000102c000bb20202037f017e23004180016b220221032002240002400240101e22040d00410021020c010b024002402004418004490d002004102621020c010b20022004410f6a4170716b220224000b20022004101f1a0b20032002360254200320023602502003200220046a360258200342003703480240200441074b0d00410041d9c4001001200328025421020b200341c8006a20024108100f1a2003200241086a3602542003410036024020034200370338200341d0006a200341386a10421a200341086a41086a200341d0006a41086a2802002202360200200341306a2002360200200320032903502205370308200320013703202003200037031820032005370328200341186a2003290348200341386a1032024020032802382202450d002003200236023c2002102a0b20034180016a24000b4c01037f2300220221030240101e2204450d00024002402004418004490d002004102621020c010b20022004410f6a4170716b220224000b20022004101f1a0b410041d5c0001001200324000bcf0102047f017e230041106b2202210320022400024002400240101e22040d002003420037030841002102200341086a21050c010b024002402004418004490d002004102621020c010b20022004410f6a4170716b220224000b20022004101f1a20034200370308200341086a2105200441074b0d010b410041d9c40010010b200520024108100f1a200241086a2102024020044108470d00410041d9c40010010b200341076a20024101100f1a2003290308210620032d0007210420001017200620044100471018200341106a24000baa0202047f047e230041206b2202210320022400024002400240101e22040d002003420037031841002102200341186a21050c010b024002402004418004490d002004102621020c010b20022004410f6a4170716b220224000b20022004101f1a20034200370318200341186a2105200441074b0d010b410041d9c40010010b200520024108100f1a200241086a21050240200441787122044108470d00410041d9c40010010b200341106a20054108100f1a200241106a2105024020044110470d00410041d9c40010010b200341086a20054108100f1a200241186a2102024020044118470d00410041d9c40010010b200320024108100f1a200329030021062003290308210720032903102108200329031821092000101720092008200720061019200341206a24000ba103010b7f230041306b2202210320022400410021040240101e2205450d00024002402005418004490d002005102621040c010b20022005410f6a4170716b220424000b20042005101f1a0b20032004360214200320043602102003200420056a3602182003410036020820034200370300200341106a200310491a20001017200341206a20031037420120032802202204200328022420046b101a1a024020032802202204450d00200320043602242004102a0b024020032802002206450d0002400240200328020422072006470d00200621040c010b03402007220441606a21070240200441786a2208280200417f460d002004416c6a2209280200220a450d00200a21050240200441706a220b2802002204200a460d000340200441486a21050240200441786a2202280200220c417f460d00200341206a200441486a200c4102744188c5006a2802001101000b2002417f36020020052104200a2005470d000b200928020021050b200b200a3602002005102a0b2008417f36020020072006470d000b200328020021040b200320063602042004102a0b200341306a24000bcc0303027f017e097f230041206b220224002000280204210342002104410021050340024020032000280208490d0041004183c5001001200028020421030b20032d000021062000200341016a22033602042004200641ff0071200541ff0171220574ad842104200541076a2105200321032006418001710d000b0240024020012802042207200128020022056b41057522062004a722034f0d002001200320066b104a200128020421070c010b200620034d0d000240200520034105746a22082007460d0003402007220341606a21070240200341786a2209280200417f460d002003416c6a220a280200220b450d00200b21060240200341706a220c2802002203200b460d000340200341486a21060240200341786a2205280200220d417f460d00200241186a200341486a200d4102744188c5006a2802001101000b2005417f36020020062103200b2006470d000b200a28020021060b200c200b3602002006102a0b2009417f36020020072008470d000b0b20012008360204200821070b0240200128020022032007460d00034020022000360208200220033602102002200341086a360214200241106a200241086a104b200341206a22032007470d000b0b200241206a240020000b9f06030a7f017e037f230041106b220224000240024020002802082203200028020422046b4105752001490d000340200441186a2203420037030020044200370300200441106a4200370300200441086a4200370300200341003602002000200028020441206a22043602042001417f6a22010d000c020b0b02400240024002402004200028020022056b410575220620016a220741808080c0004f0d0041ffffff3f210402400240200320056b220341057541feffff1f4b0d00024020072003410475220420042007491b22040d0041002104410021030c020b200441808080c0004f0d030b2004410574102921030b200320044105746a2108200320064105746a22092104034020044200370300200441186a4200370300200441106a4200370300200441086a4200370300200441206a21042001417f6a22010d000b2000280204220a20002802002206460d022006200a6b210b410021050340200920056a220141786a2206417f360200200a20056a220341606a290300210c200141686a220741003a0000200141606a200c3703000240200341786a280200220d417f460d00200141706a220e42003702002001416c6a220f4100360200200e200341706a280200360200200f2003416c6a220e280200360200200141746a200341746a22012802003602002007200341686a2802003602002006200d36020020014100360200200e42003702000b200b200541606a2205470d000b200920056a2109200028020421062000280200210d0c030b2000102c000b1003000b2006210d0b20002008360208200020043602042000200936020002402006200d460d0003402006220441606a21060240200441786a2207280200417f460d002004416c6a220e2802002200450d00200021010240200441706a220f28020022042000460d000340200441486a21010240200441786a22032802002205417f460d00200241086a200441486a20054102744188c5006a2802001101000b2003417f3602002001210420002001470d000b200e28020021010b200f20003602002001102a0b2007417f3602002006200d470d000b0b200d450d00200d102a0b200241106a24000bca0102037f017e20002802002102024020012802002203280208200328020422046b41074b0d00410041d9c4001001200328020421040b200220044108100f1a2003200328020441086a3602042000280204210220012802002201280204210342002105410021040340024020032001280208490d0041004183c5001001200128020421030b20032d000021002001200341016a22033602042005200041ff0071200441ff0171220474ad842105200441076a2104200321032000418001710d000b200120022005a710600b890101037f230041e0006b220221032002240002400240101e22040d00410021020c010b024002402004418004490d002004102621020c010b20022004410f6a4170716b220224000b20022004101f1a0b20032002360254200320023602502003200220046a360258200341d0006a200341086a104d1a20001017200341086a102e200341e0006a24000ba20801027f02402000280208200028020422026b41074b0d00410041d9c4001001200028020421020b200120024108100f1a2000200028020441086a2202360204200141086a21030240200028020820026b41034b0d00410041d9c4001001200028020421020b200320024104100f1a2000200028020441046a22023602042001410c6a21030240200028020820026b41034b0d00410041d9c4001001200028020421020b200320024104100f1a2000200028020441046a2202360204200141106a21030240200028020820026b41034b0d00410041d9c4001001200028020421020b200320024104100f1a2000200028020441046a2202360204200141146a21030240200028020820026b41034b0d00410041d9c4001001200028020421020b200320024104100f1a2000200028020441046a2202360204200141186a21030240200028020820026b41034b0d00410041d9c4001001200028020421020b200320024104100f1a2000200028020441046a22023602042001411c6a21030240200028020820026b41034b0d00410041d9c4001001200028020421020b200320024104100f1a2000200028020441046a2202360204200141206a21030240200028020820026b41034b0d00410041d9c4001001200028020421020b200320024104100f1a2000200028020441046a2202360204200141246a21030240200028020820026b41034b0d00410041d9c4001001200028020421020b200320024104100f1a2000200028020441046a2202360204200141286a21030240200028020820026b41034b0d00410041d9c4001001200028020421020b200320024104100f1a2000200028020441046a22023602042001412c6a21030240200028020820026b41034b0d00410041d9c4001001200028020421020b200320024104100f1a2000200028020441046a2202360204200141306a21030240200028020820026b41034b0d00410041d9c4001001200028020421020b200320024104100f1a2000200028020441046a2202360204200141346a21030240200028020820026b41034b0d00410041d9c4001001200028020421020b200320024104100f1a2000200028020441046a2202360204200141386a21030240200028020820026b41034b0d00410041d9c4001001200028020421020b200320024104100f1a2000200028020441046a22023602042001413c6a21030240200028020820026b41034b0d00410041d9c4001001200028020421020b200320024104100f1a2000200028020441046a2202360204200141c0006a21030240200028020820026b41014b0d00410041d9c4001001200028020421020b200320024102100f1a2000200028020441026a2202360204200141c2006a21010240200028020820026b41014b0d00410041d9c4001001200028020421020b200120024102100f1a2000200028020441026a36020420000b940101047f230041106b2202210320022400024002400240101e22040d002003420037030841002102200341086a21050c010b024002402004418004490d002004102621020c010b20022004410f6a4170716b220224000b20022004101f1a20034200370308200341086a2105200441074b0d010b410041d9c40010010b200520024108100f1a20032903081017200341106a24000b8c0405047f017e037f017e017f230041f0006b220221032002240002400240101e22040d00410021050c010b024002402004418004490d002004102621050c010b20022004410f6a4170716b220524000b20052004101f1a0b42002106200341286a420037030041102102200341106a41106a4200370300200342003703182003420037031002402004411f4b0d00410041d9c40010010b200520046a2107200341d0006a20054120100f1a200541206a2108200341306a2109410021044200210a0340200341d0006a20046a210b0240024020024102490d00200a4208862006200b31000084220642388884210a2002417f6a2102200642088621060c010b024020024101460d00410041b6c50010010b2009200a37030820092006200b3100008437030041102102200941106a2109420021064200210a0b200441016a22044120470d000b024020024110460d00024020024102490d0020032006200a200241037441786a1009200341086a290300210a200329030021060b200920063703002009200a3703080b200341106a41186a200341306a41186a290300370300200341106a41106a200341306a41106a2903003703002003200329033837031820032003290330370310200341d0006a41186a2007360200200341e4006a2008360200200320053602602003200137035820032000370350200341d0006a200341106a1038200341f0006a24000bc80303047f027e017f230041f0006b220221032002240002400240101e22040d00410021050c010b024002402004418004490d002004102621050c010b20022004410f6a4170716b220524000b20052004101f1a0b42002106200341286a420037030041102102200341106a41106a4200370300200342003703182003420037031002402004411f4b0d00410041d9c40010010b200341d0006a20054120100f1a200341306a210541002104420021070340200341d0006a20046a21080240024020024102490d002007420886200620083100008422064238888421072002417f6a2102200642088621060c010b024020024101460d00410041b6c50010010b200520073703082005200620083100008437030041102102200541106a210542002106420021070b200441016a22044120470d000b024020024110460d00024020024102490d00200320062007200241037441786a1009200341086a2903002107200329030021060b20052006370300200520073703080b200341106a41186a200341306a41186a290300370300200341106a41106a200341306a41106a29030037030020032003290338370318200320032903303703102002200341106a103a200341f0006a24000bd50103037f017e017f230041106b2202240020012802042203200128020022046b41386dad2105200028020021010340200141016a2101200542078822054200520d000b200020013602000240024020042003460d00034020042802302206ad21050340200141016a2101200542078822054200520d000b20002001360200200220003602002006417f460d0220022002360208200241086a2004200641027441fcc1006a2802001101002000200028020041026a2201360200200441386a22042003470d000b0b200241106a240020000f0b1052000b05001003000bfe0103017f017e037f230041106b22022400200128020420012802006b410575ad21032000280204210403402003a721052002200342078822034200522206410774200541ff0071723a000f0240200028020820046b41004a0d0041004188c2001001200028020421040b20042002410f6a4101100f1a2000200028020441016a220436020420060d000b02402001280200220520012802042206460d0003400240200028020820046b41074a0d0041004188c2001001200028020421040b200420054108100f1a2000200028020441086a3602042000200541086a10541a200541206a22052006460d01200028020421040c000b0b200241106a240020000bdd0103027f017e027f230041106b22022400200028020421032001350210210403402004a721052002200442078822044200522206410774200541ff0071723a000f0240200028020820036b41004a0d0041004188c2001001200028020421030b20032002410f6a4101100f1a2000200028020441016a220336020420060d000b02402001280210417f460d00200141046a21050240200028020820036b41034a0d0041004188c2001001200028020421030b200320014104100f1a2000200028020441046a3602042000200510581a200241106a240020000f0b1052000b170020002802002802002200200028020041216a3602000b170020002802002802002200200028020041216a3602000b7602017f017e20002802002802002202200228020041226a2200360200200141286a350200420020012d00244101711b21030340200041016a2100200342078822034200520d000b200220003602000240200128022820012d0024220141017620014101711b2201450d002002200120006a3602000b0b990303017f017e047f230041106b22022400200128020420012802006b41386dad21032000280204210403402003a721052002200342078822034200522206410774200541ff0071723a000f0240200028020820046b41004a0d0041004188c2001001200028020421040b20042002410f6a4101100f1a2000200028020441016a220436020420060d000b024002402001280200220720012802042201460d0003402007350230210303402003a721052002200342078822034200522206410774200541ff0071723a000e0240200028020820046b41004a0d0041004188c2001001200028020421040b20042002410e6a4101100f1a2000200028020441016a220436020420060d000b2002200036020020072802302204417f460d0220022002360208200241086a2007200441027441b4c2006a280200110100200741346a210502402000280208200028020422046b41014a0d0041004188c2001001200028020421040b200420054102100f1a2000200028020441026a2204360204200741386a22072001470d000b0b200241106a240020000f0b1052000b6401037f200028020028020022002802042102410021030340200120036a21040240200028020820026b41004a0d0041004188c2001001200028020421020b200220044101100f1a2000200028020441016a2202360204200341016a22034121470d000b0b6401037f200028020028020022002802042102410021030340200120036a21040240200028020820026b41004a0d0041004188c2001001200028020421020b200220044101100f1a2000200028020441016a2202360204200341016a22034121470d000b0baa0101037f200028020028020022002802042102410021030340200120036a21040240200028020820026b41004a0d0041004188c2001001200028020421020b200220044101100f1a2000200028020441016a2202360204200341016a22034121470d000b200141216a21030240200028020820026b41004a0d0041004188c2001001200028020421020b200220034101100f1a2000200028020441016a3602042000200141246a105c1a0bfd0103027f017e027f230041106b22022400200128020420012d0000220341017620034101711bad21042000280204210303402004a721052002200442078822044200522206410774200541ff0071723a000f0240200028020820036b41004a0d0041004188c2001001200028020421030b20032002410f6a4101100f1a2000200028020441016a220336020420060d000b0240200128020420012d00002205410176200541017122061b2205450d002001280208200141016a20061b21060240200028020820036b20054e0d0041004188c2001001200028020421030b200320062005100f1a2000200028020420056a3602040b200241106a240020000b02000b02000b1a00024020012d0024410171450d002001412c6a280200102a0b0bae0201047f230041206b220324000240024020020d00200341146a41003602002003420037020c200341086a410472210402402000280208200028020422026b41034b0d00410041d9c4001001200028020421020b200341086a20024104100f1a2000200028020441046a3602042000200410611a02402001280210417f460d0020012802042205450d00200521020240200141086a28020022002005460d000340200041486a21020240200041786a22042802002206417f460d00200341186a200041486a20064102744188c5006a2802001101000b2004417f3602002002210020052002470d000b200128020421020b200120053602082002102a0b2001200329030837020020014100360210200141086a20032903103702000c010b410041a0c50010010b200341206a24000b870303027f017e047f230041106b220224002000280204210342002104410021050340024020032000280208490d0041004183c5001001200028020421030b20032d000021062000200341016a22033602042004200641ff0071200541ff0171220574ad842104200541076a2105200321032006418001710d000b0240024020012802042205200128020022076b41386d22062004a722034f0d002001200320066b1062200128020421050c010b200620034d0d0002402007200341386c6a22082005460d000340200541486a21030240200541786a22062802002207417f460d00200241086a200541486a20074102744188c5006a2802001101000b2006417f3602002003210520082003470d000b0b20012008360204200821050b0240200128020022032005460d0003402000200310631a02402000280208200028020422066b41014b0d00410041d9c4001001200028020421060b200341346a20064102100f1a2000200028020441026a360204200341386a22032005470d000b0b200241106a240020000ba105010c7f230041106b2202240002400240024020002802082203200028020422046b41386d2001490d000340200441306a2203420037020020044200370200200441286a4200370200200441186a4200370200200441106a4200370200200441086a4200370200200441206a4200370200200341003602002000200028020441386a22043602042001417f6a22010d000c020b0b2004200028020022056b41386d220620016a220741a592c9244f0d0141a492c924210402400240200320056b41386d22034191c9a4124b0d0020072003410174220420042007491b22040d0041002104410021030c010b200441386c102921030b2003200441386c6a21082003200641386c6a22092104034020044200370200200441286a4200370200200441186a4200370200200441106a4200370200200441086a4200370200200441206a4200370200200441306a4200370200200441386a21042001417f6a22010d000b024002402000280204220a20002802002205470d002000200836020820002004360204200020093602000c010b2005200a6b210b410021010340200920016a220341786a2206417f360200200341486a220741003a00000240200a20016a220541786a220c280200220d417f460d00200241086a2007200541486a200d4102744194c5006a2802001102002006200c2802003602000b2003417c6a2005417c6a2f01003b0100200b200141486a2201470d000b200020083602082000280204210320002004360204200028020021052000200920016a36020020032005460d000340200341486a21040240200341786a22012802002200417f460d002002200341486a20004102744188c5006a2802001101000b2001417f3602002004210320052004470d000b0b2005450d002005102a0b200241106a24000f0b2000102c000bdf0203027f017e037f230041306b220224002000280204210342002104410021050340024020032000280208490d0041004183c5001001200028020421030b20032d000021062000200341016a22073602042004200641ff0071200541ff0171220374ad842104200341076a2105200721032006418001710d000b024002402004a722030d00410021030340200220036a2106024020002802082007470d00410041d9c4001001200028020421070b200620074101100f1a2000200028020441016a2207360204200341016a22034121470d000b024020012802302203417f460d00200241286a200120034102744188c5006a2802001101000b2001200229030037000020014100360230200141206a200241206a2d00003a0000200141186a200241186a290300370000200141106a200241106a290300370000200141086a200241086a2903003700000c010b20002001200310670b200241306a240020000b4c0020012002290000370000200141206a200241206a2d00003a0000200141186a200241186a290000370000200141106a200241106a290000370000200141086a200241086a2900003700000b4c0020012002290000370000200141206a200241206a2d00003a0000200141186a200241186a290000370000200141106a200241106a290000370000200141086a200241086a2900003700000b7801017f20012002290200370200200141206a200241206a2f01003b0100200141186a200241186a290200370200200141106a200241106a290200370200200141086a200241086a2902003702002001412c6a2002412c6a22032802003602002001200229022437022420024200370224200341003602000be70401037f230041c0006b22032400024002402002417f6a220241014b0d000240024020020e020001000b20002802042102410021040340200341086a20046a2105024020002802082002470d00410041d9c4001001200028020421020b200520024101100f1a2000200028020441016a2202360204200441016a22044121470d000b024020012802302200417f460d00200341386a200120004102744188c5006a2802001101000b2001200329030837000020014101360230200141206a200341086a41206a2d00003a0000200141186a200341086a41186a290300370000200141106a200341086a41106a290300370000200141086a200341086a41086a2903003700000c020b200341346a41003602002003420037022c20002802042102410021040340200341086a20046a2105024020002802082002470d00410041d9c4001001200028020421020b200520024101100f1a2000200028020441016a2202360204200441016a22044121470d000b200341296a2104024020002802082002470d00410041d9c4001001200028020421020b200420024101100f1a2000200028020441016a36020420002003412c6a220210681a024020012802302200417f460d00200341386a200120004102744188c5006a2802001101000b200120032903083702002001410236023020012002290200370224200141206a200341086a41206a2f01003b0100200141186a200341086a41186a290300370200200141106a200341086a41106a290300370200200141086a200341086a41086a2903003702002001412c6a200241086a2802003602000c010b410041a0c50010010b200341c0006a24000ba00301057f230041206b2202240020024100360218200242003703102000200241106a10421a0240024002402002280214200228021022036b2204450d00200241086a410036020020024200370300200441704f0d02024002402004410a4b0d00200220044101743a0000200241017221050c010b200441106a4170712206102921052002200436020420022006410172360200200220053602080b0340200520032d00003a0000200541016a2105200341016a21032004417f6a22040d000b200541003a00000240024020012d00004101710d00200141003b01000c010b200128020841003a00002001410036020420012d0000410171450d002001280208102a200141003602000b20012002290300370200200141086a200241086a2802003602000c010b0240024020012d00004101710d00200141003b01000c010b200128020841003a00002001410036020420012d0000410171450d002001280208102a200141003602000b20014100360208200142003702000b024020022802102205450d00200220053602142005102a0b200241206a240020000f0b2002102b000b0beb0503004190c0000b796661696c656420746f20616c6c6f6361746520706167657300756e6578706563746564206572726f7220696e2066697865645f627974657320636f6e7374727563746f7200746865206f6e6572726f7220616374696f6e2063616e6e6f742062652063616c6c6564206469726563746c790000000000000000004189c1000bd904000000000000006461746173747265616d20617474656d7074656420746f20777269746520706173742074686520656e64000a006665617475726520646967657374206163746976617465643a200070726f746f636f6c2066656174757265206973206e6f74206163746976617465640000000100000002000000030000006461746173747265616d20617474656d7074656420746f20777269746520706173742074686520656e6400000400000005000000060000006f626a6563742070617373656420746f206974657261746f725f746f206973206e6f7420696e206d756c74695f696e646578006572726f722072656164696e67206974657261746f720063616e6e6f7420637265617465206f626a6563747320696e207461626c65206f6620616e6f7468657220636f6e7472616374006f626a6563742070617373656420746f206d6f64696679206973206e6f7420696e206d756c74695f696e6465780063616e6e6f74206d6f64696679206f626a6563747320696e207461626c65206f6620616e6f7468657220636f6e747261637400757064617465722063616e6e6f74206368616e6765207072696d617279206b6579207768656e206d6f64696679696e6720616e206f626a656374006461746173747265616d20617474656d7074656420746f207265616420706173742074686520656e640067657400000700000008000000090000000a0000000b0000000c000000696e76616c69642076617269616e7420696e64657800756e6578706563746564206572726f7220696e2066697865645f627974657320636f6e7374727563746f72000041000b04e82200000000000000000000000009a000d4f60add54d14ba0cc4ad9573fbd96346a4d3f59278ebdf8e3455556ed04000000033b3d4b01000000044444a224a7e16ae04e24e6640d6a909fb89ca6e5e8c1e5397e1e03ef010000000000ea3055024900000000000000000000000000 +DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304003,"value_ex":95191,"consumed":6881},"cpu_usage":{"last_ordinal":1262304003,"value_ex":256384,"consumed":2101},"ram_usage":199492} +DMLOG APPLIED_TRANSACTION 4 3d5251a1c9a3cd8d7baad33a381b9e09858e0503df1751181fd60202251c23fb04000000033b3d4b010000000446ce40fcba331770d4e40c1a69d054d3a9a5ed89ef08b50cc808e3250100d0070000dc060000000000000000e01a0000000000000001010000010000000000ea3055378d583c2888f3564b4db37bfb52d74d038e54fcc63aeb57cf27b03c001e97a519000000000000001900000000000000010000000000ea3055190000000000000002010000000000ea30550000000000ea305500000040258ab2c2010000000000ea305500000000a8ed3232cb99010000000000ea30550000be99010061736d010000000198011960000060027f7f0060037f7f7f0060047e7e7e7e017f6000017e60047f7e7e7f0060057f7f7f7f7f017f60037f7f7f017f60027f7f017f60027f7f017e60057f7f7f7f7f0060067e7e7e7e7f7f017f60017e0060027e7f0060047e7e7e7e0060037e7f7f017e60017f0060017f017f6000017f60027f7e0060047f7e7f7f0060037e7e7e0060037f7e7f0060047f7f7f7f0060027e7e0002f0052403656e760b64625f66696e645f693634000303656e760c656f73696f5f617373657274000103656e761063757272656e745f7265636569766572000403656e760561626f7274000003656e760d6173736572745f736861323536000203656e760b6173736572745f73686131000203656e760d6173736572745f736861353132000203656e76106173736572745f726970656d64313630000203656e7606736861323536000203656e76095f5f6173686c746933000503656e760473686131000203656e7606736861353132000203656e7609726970656d64313630000203656e760b7265636f7665725f6b6579000603656e76207365745f626c6f636b636861696e5f706172616d65746572735f7061636b6564000103656e76066d656d637079000703656e76206765745f626c6f636b636861696e5f706172616d65746572735f7061636b6564000803656e76167365745f70726f706f7365645f70726f647563657273000903656e760c63757272656e745f74696d65000403656e76146765745f6163746976655f70726f647563657273000803656e76087072696e74735f6c000103656e76126173736572745f7265636f7665725f6b6579000a03656e760c64625f73746f72655f693634000b03656e760c726571756972655f61757468000c03656e760e7365745f70726976696c65676564000d03656e76137365745f7265736f757263655f6c696d697473000e03656e76197365745f70726f706f7365645f70726f6475636572735f6578000f03656e761370726561637469766174655f66656174757265001003656e76067072696e7473001003656e761469735f666561747572655f616374697661746564001103656e7610616374696f6e5f646174615f73697a65001203656e7610726561645f616374696f6e5f64617461000803656e7611656f73696f5f6173736572745f636f6465001303656e760a64625f6765745f693634000703656e760d64625f7570646174655f693634001403656e76087072696e7468657800010346450015111000111010100c100802101608020817010110011818181818181808011818181818080101180818181808000808010101080101010801010102080108020202020804050170010d0d05030100010616037f014180c0000b7f0041e2c5000b7f0041e2c5000b070901056170706c7900250912010041010b0c555657595a5b5d5e5f6465660aab8b0145040010280bdd03002000102d102420002001510440428080f9d4a98499dc9a7f200251044020002001103b05428080add68d959ba955200251044020002001103c05428080add68d95abd1ca00200251044020002001103d0542808080e8b2edc0d38b7f200251044020002001103e05428080add68db8baf154200251044020002001103f054280f8a6d4d2a8a1d3c1002002510440200020011040054280808080d4c4a2d942200251044020002001104105428080808080f798d9422002510440200020011044054280808080aefadeeaa47f2002510440200020011045054280808080b6f7d6d942200251044020002001104605428080b8f6a4979ad94220025104402000200110470542808080c093fad6d9422002510440200020011048054280808096cdebd4d942200251044020002001104c054280808080daac9bd6ba7f200251044020002001104e0542808080d0b2b3bb9932200251044020002001104f054290a9d9d9dd8c99d6ba7f2002510440200020011050052000428080808080c0ba98d500520440410042808080d9d3b3ed82ef0010200b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b05428080808080c0ba98d50020015104404280808080aefadeeaa47f2002510440410042818080d9d3b3ed82ef0010200b0b0b410010310b7201037f024020000d0041000f0b4100410028028c40200041107622016a220236028c404100410028028440220320006a410f6a4170712200360284400240200241107420004b0d004100200241016a36028c40200141016a21010b024020014000417f470d0041004190c00010010b20030b02000b3601017f230041106b2200410036020c4100200028020c280200410f6a417071220036028040410020003602844041003f0036028c400b3301027f2000410120001b2101024003402001102622000d01410021004100280284412202450d0120021100000c000b0b20000b0600200010270b05001003000b05001003000b0a0041002000370388410b4e01017f230041e0006b220124002001200141d8006a3602082001200141106a3602042001200141106a36020020012000102f1a200141106a200128020420012802006b100e200141e0006a24000ba20801027f02402000280208200028020422026b41074a0d0041004190c1001001200028020421020b200220014108100f1a2000200028020441086a2202360204200141086a21030240200028020820026b41034a0d0041004190c1001001200028020421020b200220034104100f1a2000200028020441046a22023602042001410c6a21030240200028020820026b41034a0d0041004190c1001001200028020421020b200220034104100f1a2000200028020441046a2202360204200141106a21030240200028020820026b41034a0d0041004190c1001001200028020421020b200220034104100f1a2000200028020441046a2202360204200141146a21030240200028020820026b41034a0d0041004190c1001001200028020421020b200220034104100f1a2000200028020441046a2202360204200141186a21030240200028020820026b41034a0d0041004190c1001001200028020421020b200220034104100f1a2000200028020441046a22023602042001411c6a21030240200028020820026b41034a0d0041004190c1001001200028020421020b200220034104100f1a2000200028020441046a2202360204200141206a21030240200028020820026b41034a0d0041004190c1001001200028020421020b200220034104100f1a2000200028020441046a2202360204200141246a21030240200028020820026b41034a0d0041004190c1001001200028020421020b200220034104100f1a2000200028020441046a2202360204200141286a21030240200028020820026b41034a0d0041004190c1001001200028020421020b200220034104100f1a2000200028020441046a22023602042001412c6a21030240200028020820026b41034a0d0041004190c1001001200028020421020b200220034104100f1a2000200028020441046a2202360204200141306a21030240200028020820026b41034a0d0041004190c1001001200028020421020b200220034104100f1a2000200028020441046a2202360204200141346a21030240200028020820026b41034a0d0041004190c1001001200028020421020b200220034104100f1a2000200028020441046a2202360204200141386a21030240200028020820026b41034a0d0041004190c1001001200028020421020b200220034104100f1a2000200028020441046a22023602042001413c6a21030240200028020820026b41034a0d0041004190c1001001200028020421020b200220034104100f1a2000200028020441046a2202360204200141c0006a21030240200028020820026b41014a0d0041004190c1001001200028020421020b200220034102100f1a2000200028020441026a2202360204200141c2006a21010240200028020820026b41014a0d0041004190c1001001200028020421020b200220014102100f1a2000200028020441026a36020420000bfa0103017f027e017f230041306b2203240020012002200341106a1008420021044110210141002102420021050340200341106a20026a21060240024020014102490d002005420886200420063100008422044238888421052001417f6a2101200442088621040c010b024020014101460d00410041a9c00010010b200020053703082000200420063100008437030041102101200041106a210042002104420021050b200241016a22024120470d000b024020014110460d00024020014102490d00200320042005200141037441786a1009200341086a2903002105200329030021040b20002004370300200020053703080b200341306a24000b02000b970503017f017e047f230041f0006b22032400200341206a4100360200200342003703182003427f37031020032000290300220437030820032004370300024002402004200442808080809aecb4ee312001100022004100480d00024020032000103322002802302003460d00410041c0c20010010b2003200236023020032000200341306a10340c010b024020041002510d004100418ac30010010b41c000102922004200370310200041286a22054200370300200041206a22064200370300200041186a220742003703002000200336023020002001370300200341306a20022802002208200228020420086b10302005200341306a41186a2903003703002006200341306a41106a29030037030020072003290338370300200020032903303703102003200341306a41286a3602682003200341306a360260200341306a20004108100f1a2003200341306a410872360264200341e0006a200041106a10351a2000200329030842808080809aecb4ee31200120002903002204200341306a412810162205360234024020042003290310540d002003427e200442017c2004427d561b3703100b200320003602602003200029030022043703302003200536022c02400240200328021c220220032802204f0d00200220053602102002200437030820034100360260200220003602002003200241186a36021c0c010b200341186a200341e0006a200341306a2003412c6a10360b20032802602100200341003602602000450d002000102a0b024020032802182205450d0002400240200328021c22002005470d00200521000c010b0340200041686a220028020021022000410036020002402002450d002002102a0b20052000470d000b200328021821000b2003200536021c2000102a0b200341f0006a24000b840603097f027e017f230041e0006b220221032002240002400240200028021822042000411c6a2802002205460d0002400340200541786a2802002001460d012004200541686a2205470d000c020b0b20042005460d00200541686a28020021060c010b024002400240024020014100410010212205417f4a0d00410041f3c20010010c010b2005418104490d010b200510262107410121080c010b20022005410f6a4170716b22072400410021080b20012007200510211a41c0001029220642003703102006420037030020062000360230200641186a4200370300200641206a4200370300200641286a42003703000240200541074b0d00410041d9c40010010b200620074108100f1a200741086a21040240200541786a411f4b0d00410041d9c40010010b200041186a2109200641106a210a200341c0006a20044120100f1a4200210b41102105200341206a2102410021044200210c0340200341c0006a20046a210d0240024020054102490d00200c420886200b200d31000084220b42388884210c2005417f6a2105200b420886210b0c010b024020054101460d00410041b6c50010010b2002200c3703082002200b200d3100008437030041102105200241106a21024200210b4200210c0b200441016a22044120470d000b024020054110460d00024020054102490d00200341086a200b200c200541037441786a1009200341106a290300210c2003290308210b0b2002200b3703002002200c3703080b200a2003290320370300200a41086a2003290328370300200a41186a200341206a41186a290300370300200a41106a200341206a41106a290300370300200620013602342003200636022020032006290300220b3703402003200136021c02400240200028021c2205200041206a2802004f0d00200520013602102005200b37030820034100360220200520063602002000200541186a36021c0c010b2009200341206a200341c0006a2003411c6a10360b02402008450d00200710270b20032802202105200341003602202005450d002005102a0b200341e0006a240020060b980203027f017e017f230041206b2203210420032400024020012802302000460d00410041bdc30010010b024010022000290300510d00410041ebc30010010b200129030021052004200228020022022802002206200228020420066b1030200141286a200441186a290300370300200141206a200441106a290300370300200141186a200429030837030020012004290300370310200141106a2102024020052001290300510d004100419ec40010010b200341506a220324002004200341286a36020820042003360200200320014108100f1a2004200341086a3602042004200210351a20012802344200200341281022024020052000290310540d002000427e200542017c2005427d561b3703100b200441206a24000bd20303017f027e017f230041206b220224002002200141186a29030022033c00172002200141086a29030022044220883c0003200220044228883c0002200220044230883c0001200220044238883c0000200220034220883c001320022003a722054108763a0016200220054110763a0015200220054118763a001420022004a722053a0007200220054108763a0006200220054110763a0005200220054118763a0004200220012903002204423886200442288642808080808080c0ff0083842004421886428080808080e03f8320044208864280808080f01f838484200442088842808080f80f832004421888428080fc07838420044228884280fe03832004423888848484370308200220012903102204423886200442288642808080808080c0ff0083842004421886428080808080e03f8320044208864280808080f01f838484200442088842808080f80f832004421888428080fc07838420044228884280fe03832004423888848484370318200220034230883c0011200220034228883c0012200220034238883c001002402000280208200028020422016b411f4a0d0041004188c2001001200028020421010b200120024120100f1a2000200028020441206a360204200241206a240020000b9a0301057f0240024002402000280204200028020022046b41186d220541016a220641abd5aad5004f0d0041aad5aad500210702400240200028020820046b41186d220441d4aad52a4b0d0020062004410174220720072006491b22070d0041002107410021040c010b200741186c102921040b20012802002106200141003602002004200541186c22086a2201200328020036021020012002290300370308200120063602002004200741186c6a2105200141186a21062000280204220220002802002207460d01200420086a41686a21010340200241686a220428020021032004410036020020012003360200200141086a200241706a2202290300370300200141106a200241086a280200360200200141686a21012004210220072004470d000b200141186a210120002802042107200028020021040c020b2000102c000b200721040b200020053602082000200636020420002001360200024020072004460d000340200741686a220728020021012007410036020002402001450d002001102a0b20042007470d000b0b02402004450d002004102a0b0bd00203047f017e017f230041106b220224004100210320004100360208200042003702002002410036020020012802042204200128020022056b410575ad21060340200341016a2103200642078822064200520d000b2002200336020002400240024020052004460d0003402002200341086a3602002003410c6a2103200541186a2802002207ad21060340200341016a2103200642078822064200520d000b20022003417c6a3602002007417f460d022002200336020020022005410c6a10511a20022802002103200541206a22052004470d000b20002802002105200028020421070c020b41002105410021070c010b1052000b024002402003200720056b22074d0d002000200320076b1043200028020021050c010b200320074f0d002000200520036a3602040b2002200536020420022005360200200220002802043602082002200110531a200241106a24000baf0302017f027e230041206b22022400200029030010172002200141186a29030022033c00172002200141086a29030022044220883c0003200220044228883c0002200220044230883c0001200220044238883c0000200220034220883c001320022003a722004108763a0016200220004110763a0015200220004118763a001420022004a722003a0007200220004108763a0006200220004110763a0005200220004118763a0004200220012903002204423886200442288642808080808080c0ff0083842004421886428080808080e03f8320044208864280808080f01f838484200442088842808080f80f832004421888428080fc07838420044228884280fe03832004423888848484370308200220012903102204423886200442288642808080808080c0ff0083842004421886428080808080e03f8320044208864280808080f01f838484200442088842808080f80f832004421888428080fc07838420044228884280fe03832004423888848484370318200220034230883c0011200220034228883c0012200220034238883c00102002101b41bdc100101c2001103941bbc100101c200241206a24000b9c0303017f027e017f230041206b220124002001200041186a29030022023c00172001200041086a29030022034220883c0003200120034228883c0002200120034230883c0001200120034238883c0000200120024220883c001320012002a722044108763a0016200120044110763a0015200120044118763a001420012003a722043a0007200120044108763a0006200120044110763a0005200120044118763a0004200120002903002203423886200342288642808080808080c0ff0083842003421886428080808080e03f8320034208864280808080f01f838484200342088842808080f80f832003421888428080fc07838420034228884280fe03832003423888848484370308200120002903102203423886200342288642808080808080c0ff0083842003421886428080808080e03f8320034208864280808080f01f838484200342088842808080f80f832003421888428080fc07838420034228884280fe03832003423888848484370318200120024230883c0011200120024228883c0012200120024238883c0010200141201023200141206a24000ba70303017f027e017f230041206b220224002002200141186a29030022033c00172002200141086a29030022044220883c0003200220044228883c0002200220044230883c0001200220044238883c0000200220034220883c001320022003a722054108763a0016200220054110763a0015200220054118763a001420022004a722053a0007200220054108763a0006200220054110763a0005200220054118763a0004200220012903002204423886200442288642808080808080c0ff0083842004421886428080808080e03f8320044208864280808080f01f838484200442088842808080f80f832004421888428080fc07838420044228884280fe03832004423888848484370308200220012903102204423886200442288642808080808080c0ff0083842004421886428080808080e03f8320044208864280808080f01f838484200442088842808080f80f832004421888428080fc07838420044228884280fe03832004423888848484370318200220034230883c0011200220034228883c0012200220034238883c001002402002101d0d00410041d8c10010010b200241206a24000bb90101047f230041106b2202210320022400024002400240101e22040d002003420037030841002102200341086a21050c010b024002402004418004490d002004102621020c010b20022004410f6a4170716b220224000b20022004101f1a20034200370308200341086a2105200441074b0d010b410041d9c40010010b200520024108100f1a20034200370300200241086a2102024020044178714108470d00410041d9c40010010b200320024108100f1a200341106a24000b4401037f2300220221030240101e2204450d00024002402004418004490d002004102621020c010b20022004410f6a4170716b220224000b20022004101f1a0b200324000b4401037f2300220221030240101e2204450d00024002402004418004490d002004102621020c010b20022004410f6a4170716b220224000b20022004101f1a0b200324000b4401037f2300220221030240101e2204450d00024002402004418004490d002004102621020c010b20022004410f6a4170716b220224000b20022004101f1a0b200324000b4401037f2300220221030240101e2204450d00024002402004418004490d002004102621020c010b20022004410f6a4170716b220224000b20022004101f1a0b200324000b4401037f2300220221030240101e2204450d00024002402004418004490d002004102621020c010b20022004410f6a4170716b220224000b20022004101f1a0b200324000bc90201047f230041306b220221032002240002400240101e22040d00410021020c010b024002402004418004490d002004102621020c010b20022004410f6a4170716b220224000b20022004101f1a0b20032002360224200320023602202003200220046a2205360228200342003703180240200441074b0d00410041d9c400100120032802282105200328022421020b200341186a20024108100f1a2003200241086a2202360224024020052002470d00410041d9c400100120032802282105200328022421020b200341176a20024101100f1a2003200241016a2202360224024020052002470d00410041d9c4001001200328022421020b200341166a20024101100f1a2003200241016a3602242003410036021020034200370308200341206a200341086a10421a024020032802082202450d002003200236020c2002102a0b200341306a24000bff0103017f017e047f2000280204210242002103410021040340024020022000280208490d0041004183c5001001200028020421020b20022d000021052000200241016a22063602042003200541ff0071200441ff0171220274ad842103200241076a2104200621022005418001710d000b0240024020012802042205200128020022026b22072003a722044f0d002001200420076b10432000280204210620012802042105200128020021020c010b200720044d0d002001200220046a22053602040b0240200028020820066b200520026b22054f0d00410041d9c4001001200028020421060b200220062005100f1a2000200028020420056a36020420000b980201057f02400240024020002802082202200028020422036b2001490d000340200341003a00002000200028020441016a22033602042001417f6a22010d000c020b0b2003200028020022046b220520016a2206417f4c0d0141ffffffff07210302400240200220046b220241feffffff034b0d0020062002410174220320032006491b22030d0041002103410021020c010b2003102921020b200220036a2106200220056a220421030340200341003a0000200341016a21032001417f6a22010d000b20042000280204200028020022016b22026b2104024020024101480d00200420012002100f1a200028020021010b2000200636020820002003360204200020043602002001450d002001102a0b0f0b2000102c000bb20202037f017e23004180016b220221032002240002400240101e22040d00410021020c010b024002402004418004490d002004102621020c010b20022004410f6a4170716b220224000b20022004101f1a0b20032002360254200320023602502003200220046a360258200342003703480240200441074b0d00410041d9c4001001200328025421020b200341c8006a20024108100f1a2003200241086a3602542003410036024020034200370338200341d0006a200341386a10421a200341086a41086a200341d0006a41086a2802002202360200200341306a2002360200200320032903502205370308200320013703202003200037031820032005370328200341186a2003290348200341386a1032024020032802382202450d002003200236023c2002102a0b20034180016a24000b4c01037f2300220221030240101e2204450d00024002402004418004490d002004102621020c010b20022004410f6a4170716b220224000b20022004101f1a0b410041d5c0001001200324000bcf0102047f017e230041106b2202210320022400024002400240101e22040d002003420037030841002102200341086a21050c010b024002402004418004490d002004102621020c010b20022004410f6a4170716b220224000b20022004101f1a20034200370308200341086a2105200441074b0d010b410041d9c40010010b200520024108100f1a200241086a2102024020044108470d00410041d9c40010010b200341076a20024101100f1a2003290308210620032d0007210420001017200620044100471018200341106a24000baa0202047f047e230041206b2202210320022400024002400240101e22040d002003420037031841002102200341186a21050c010b024002402004418004490d002004102621020c010b20022004410f6a4170716b220224000b20022004101f1a20034200370318200341186a2105200441074b0d010b410041d9c40010010b200520024108100f1a200241086a21050240200441787122044108470d00410041d9c40010010b200341106a20054108100f1a200241106a2105024020044110470d00410041d9c40010010b200341086a20054108100f1a200241186a2102024020044118470d00410041d9c40010010b200320024108100f1a200329030021062003290308210720032903102108200329031821092000101720092008200720061019200341206a24000ba103010b7f230041306b2202210320022400410021040240101e2205450d00024002402005418004490d002005102621040c010b20022005410f6a4170716b220424000b20042005101f1a0b20032004360214200320043602102003200420056a3602182003410036020820034200370300200341106a200310491a20001017200341206a20031037420120032802202204200328022420046b101a1a024020032802202204450d00200320043602242004102a0b024020032802002206450d0002400240200328020422072006470d00200621040c010b03402007220441606a21070240200441786a2208280200417f460d002004416c6a2209280200220a450d00200a21050240200441706a220b2802002204200a460d000340200441486a21050240200441786a2202280200220c417f460d00200341206a200441486a200c4102744188c5006a2802001101000b2002417f36020020052104200a2005470d000b200928020021050b200b200a3602002005102a0b2008417f36020020072006470d000b200328020021040b200320063602042004102a0b200341306a24000bcc0303027f017e097f230041206b220224002000280204210342002104410021050340024020032000280208490d0041004183c5001001200028020421030b20032d000021062000200341016a22033602042004200641ff0071200541ff0171220574ad842104200541076a2105200321032006418001710d000b0240024020012802042207200128020022056b41057522062004a722034f0d002001200320066b104a200128020421070c010b200620034d0d000240200520034105746a22082007460d0003402007220341606a21070240200341786a2209280200417f460d002003416c6a220a280200220b450d00200b21060240200341706a220c2802002203200b460d000340200341486a21060240200341786a2205280200220d417f460d00200241186a200341486a200d4102744188c5006a2802001101000b2005417f36020020062103200b2006470d000b200a28020021060b200c200b3602002006102a0b2009417f36020020072008470d000b0b20012008360204200821070b0240200128020022032007460d00034020022000360208200220033602102002200341086a360214200241106a200241086a104b200341206a22032007470d000b0b200241206a240020000b9f06030a7f017e037f230041106b220224000240024020002802082203200028020422046b4105752001490d000340200441186a2203420037030020044200370300200441106a4200370300200441086a4200370300200341003602002000200028020441206a22043602042001417f6a22010d000c020b0b02400240024002402004200028020022056b410575220620016a220741808080c0004f0d0041ffffff3f210402400240200320056b220341057541feffff1f4b0d00024020072003410475220420042007491b22040d0041002104410021030c020b200441808080c0004f0d030b2004410574102921030b200320044105746a2108200320064105746a22092104034020044200370300200441186a4200370300200441106a4200370300200441086a4200370300200441206a21042001417f6a22010d000b2000280204220a20002802002206460d022006200a6b210b410021050340200920056a220141786a2206417f360200200a20056a220341606a290300210c200141686a220741003a0000200141606a200c3703000240200341786a280200220d417f460d00200141706a220e42003702002001416c6a220f4100360200200e200341706a280200360200200f2003416c6a220e280200360200200141746a200341746a22012802003602002007200341686a2802003602002006200d36020020014100360200200e42003702000b200b200541606a2205470d000b200920056a2109200028020421062000280200210d0c030b2000102c000b1003000b2006210d0b20002008360208200020043602042000200936020002402006200d460d0003402006220441606a21060240200441786a2207280200417f460d002004416c6a220e2802002200450d00200021010240200441706a220f28020022042000460d000340200441486a21010240200441786a22032802002205417f460d00200241086a200441486a20054102744188c5006a2802001101000b2003417f3602002001210420002001470d000b200e28020021010b200f20003602002001102a0b2007417f3602002006200d470d000b0b200d450d00200d102a0b200241106a24000bca0102037f017e20002802002102024020012802002203280208200328020422046b41074b0d00410041d9c4001001200328020421040b200220044108100f1a2003200328020441086a3602042000280204210220012802002201280204210342002105410021040340024020032001280208490d0041004183c5001001200128020421030b20032d000021002001200341016a22033602042005200041ff0071200441ff0171220474ad842105200441076a2104200321032000418001710d000b200120022005a710600b890101037f230041e0006b220221032002240002400240101e22040d00410021020c010b024002402004418004490d002004102621020c010b20022004410f6a4170716b220224000b20022004101f1a0b20032002360254200320023602502003200220046a360258200341d0006a200341086a104d1a20001017200341086a102e200341e0006a24000ba20801027f02402000280208200028020422026b41074b0d00410041d9c4001001200028020421020b200120024108100f1a2000200028020441086a2202360204200141086a21030240200028020820026b41034b0d00410041d9c4001001200028020421020b200320024104100f1a2000200028020441046a22023602042001410c6a21030240200028020820026b41034b0d00410041d9c4001001200028020421020b200320024104100f1a2000200028020441046a2202360204200141106a21030240200028020820026b41034b0d00410041d9c4001001200028020421020b200320024104100f1a2000200028020441046a2202360204200141146a21030240200028020820026b41034b0d00410041d9c4001001200028020421020b200320024104100f1a2000200028020441046a2202360204200141186a21030240200028020820026b41034b0d00410041d9c4001001200028020421020b200320024104100f1a2000200028020441046a22023602042001411c6a21030240200028020820026b41034b0d00410041d9c4001001200028020421020b200320024104100f1a2000200028020441046a2202360204200141206a21030240200028020820026b41034b0d00410041d9c4001001200028020421020b200320024104100f1a2000200028020441046a2202360204200141246a21030240200028020820026b41034b0d00410041d9c4001001200028020421020b200320024104100f1a2000200028020441046a2202360204200141286a21030240200028020820026b41034b0d00410041d9c4001001200028020421020b200320024104100f1a2000200028020441046a22023602042001412c6a21030240200028020820026b41034b0d00410041d9c4001001200028020421020b200320024104100f1a2000200028020441046a2202360204200141306a21030240200028020820026b41034b0d00410041d9c4001001200028020421020b200320024104100f1a2000200028020441046a2202360204200141346a21030240200028020820026b41034b0d00410041d9c4001001200028020421020b200320024104100f1a2000200028020441046a2202360204200141386a21030240200028020820026b41034b0d00410041d9c4001001200028020421020b200320024104100f1a2000200028020441046a22023602042001413c6a21030240200028020820026b41034b0d00410041d9c4001001200028020421020b200320024104100f1a2000200028020441046a2202360204200141c0006a21030240200028020820026b41014b0d00410041d9c4001001200028020421020b200320024102100f1a2000200028020441026a2202360204200141c2006a21010240200028020820026b41014b0d00410041d9c4001001200028020421020b200120024102100f1a2000200028020441026a36020420000b940101047f230041106b2202210320022400024002400240101e22040d002003420037030841002102200341086a21050c010b024002402004418004490d002004102621020c010b20022004410f6a4170716b220224000b20022004101f1a20034200370308200341086a2105200441074b0d010b410041d9c40010010b200520024108100f1a20032903081017200341106a24000b8c0405047f017e037f017e017f230041f0006b220221032002240002400240101e22040d00410021050c010b024002402004418004490d002004102621050c010b20022004410f6a4170716b220524000b20052004101f1a0b42002106200341286a420037030041102102200341106a41106a4200370300200342003703182003420037031002402004411f4b0d00410041d9c40010010b200520046a2107200341d0006a20054120100f1a200541206a2108200341306a2109410021044200210a0340200341d0006a20046a210b0240024020024102490d00200a4208862006200b31000084220642388884210a2002417f6a2102200642088621060c010b024020024101460d00410041b6c50010010b2009200a37030820092006200b3100008437030041102102200941106a2109420021064200210a0b200441016a22044120470d000b024020024110460d00024020024102490d0020032006200a200241037441786a1009200341086a290300210a200329030021060b200920063703002009200a3703080b200341106a41186a200341306a41186a290300370300200341106a41106a200341306a41106a2903003703002003200329033837031820032003290330370310200341d0006a41186a2007360200200341e4006a2008360200200320053602602003200137035820032000370350200341d0006a200341106a1038200341f0006a24000bc80303047f027e017f230041f0006b220221032002240002400240101e22040d00410021050c010b024002402004418004490d002004102621050c010b20022004410f6a4170716b220524000b20052004101f1a0b42002106200341286a420037030041102102200341106a41106a4200370300200342003703182003420037031002402004411f4b0d00410041d9c40010010b200341d0006a20054120100f1a200341306a210541002104420021070340200341d0006a20046a21080240024020024102490d002007420886200620083100008422064238888421072002417f6a2102200642088621060c010b024020024101460d00410041b6c50010010b200520073703082005200620083100008437030041102102200541106a210542002106420021070b200441016a22044120470d000b024020024110460d00024020024102490d00200320062007200241037441786a1009200341086a2903002107200329030021060b20052006370300200520073703080b200341106a41186a200341306a41186a290300370300200341106a41106a200341306a41106a29030037030020032003290338370318200320032903303703102002200341106a103a200341f0006a24000bd50103037f017e017f230041106b2202240020012802042203200128020022046b41386dad2105200028020021010340200141016a2101200542078822054200520d000b200020013602000240024020042003460d00034020042802302206ad21050340200141016a2101200542078822054200520d000b20002001360200200220003602002006417f460d0220022002360208200241086a2004200641027441fcc1006a2802001101002000200028020041026a2201360200200441386a22042003470d000b0b200241106a240020000f0b1052000b05001003000bfe0103017f017e037f230041106b22022400200128020420012802006b410575ad21032000280204210403402003a721052002200342078822034200522206410774200541ff0071723a000f0240200028020820046b41004a0d0041004188c2001001200028020421040b20042002410f6a4101100f1a2000200028020441016a220436020420060d000b02402001280200220520012802042206460d0003400240200028020820046b41074a0d0041004188c2001001200028020421040b200420054108100f1a2000200028020441086a3602042000200541086a10541a200541206a22052006460d01200028020421040c000b0b200241106a240020000bdd0103027f017e027f230041106b22022400200028020421032001350210210403402004a721052002200442078822044200522206410774200541ff0071723a000f0240200028020820036b41004a0d0041004188c2001001200028020421030b20032002410f6a4101100f1a2000200028020441016a220336020420060d000b02402001280210417f460d00200141046a21050240200028020820036b41034a0d0041004188c2001001200028020421030b200320014104100f1a2000200028020441046a3602042000200510581a200241106a240020000f0b1052000b170020002802002802002200200028020041216a3602000b170020002802002802002200200028020041216a3602000b7602017f017e20002802002802002202200228020041226a2200360200200141286a350200420020012d00244101711b21030340200041016a2100200342078822034200520d000b200220003602000240200128022820012d0024220141017620014101711b2201450d002002200120006a3602000b0b990303017f017e047f230041106b22022400200128020420012802006b41386dad21032000280204210403402003a721052002200342078822034200522206410774200541ff0071723a000f0240200028020820046b41004a0d0041004188c2001001200028020421040b20042002410f6a4101100f1a2000200028020441016a220436020420060d000b024002402001280200220720012802042201460d0003402007350230210303402003a721052002200342078822034200522206410774200541ff0071723a000e0240200028020820046b41004a0d0041004188c2001001200028020421040b20042002410e6a4101100f1a2000200028020441016a220436020420060d000b2002200036020020072802302204417f460d0220022002360208200241086a2007200441027441b4c2006a280200110100200741346a210502402000280208200028020422046b41014a0d0041004188c2001001200028020421040b200420054102100f1a2000200028020441026a2204360204200741386a22072001470d000b0b200241106a240020000f0b1052000b6401037f200028020028020022002802042102410021030340200120036a21040240200028020820026b41004a0d0041004188c2001001200028020421020b200220044101100f1a2000200028020441016a2202360204200341016a22034121470d000b0b6401037f200028020028020022002802042102410021030340200120036a21040240200028020820026b41004a0d0041004188c2001001200028020421020b200220044101100f1a2000200028020441016a2202360204200341016a22034121470d000b0baa0101037f200028020028020022002802042102410021030340200120036a21040240200028020820026b41004a0d0041004188c2001001200028020421020b200220044101100f1a2000200028020441016a2202360204200341016a22034121470d000b200141216a21030240200028020820026b41004a0d0041004188c2001001200028020421020b200220034101100f1a2000200028020441016a3602042000200141246a105c1a0bfd0103027f017e027f230041106b22022400200128020420012d0000220341017620034101711bad21042000280204210303402004a721052002200442078822044200522206410774200541ff0071723a000f0240200028020820036b41004a0d0041004188c2001001200028020421030b20032002410f6a4101100f1a2000200028020441016a220336020420060d000b0240200128020420012d00002205410176200541017122061b2205450d002001280208200141016a20061b21060240200028020820036b20054e0d0041004188c2001001200028020421030b200320062005100f1a2000200028020420056a3602040b200241106a240020000b02000b02000b1a00024020012d0024410171450d002001412c6a280200102a0b0bae0201047f230041206b220324000240024020020d00200341146a41003602002003420037020c200341086a410472210402402000280208200028020422026b41034b0d00410041d9c4001001200028020421020b200341086a20024104100f1a2000200028020441046a3602042000200410611a02402001280210417f460d0020012802042205450d00200521020240200141086a28020022002005460d000340200041486a21020240200041786a22042802002206417f460d00200341186a200041486a20064102744188c5006a2802001101000b2004417f3602002002210020052002470d000b200128020421020b200120053602082002102a0b2001200329030837020020014100360210200141086a20032903103702000c010b410041a0c50010010b200341206a24000b870303027f017e047f230041106b220224002000280204210342002104410021050340024020032000280208490d0041004183c5001001200028020421030b20032d000021062000200341016a22033602042004200641ff0071200541ff0171220574ad842104200541076a2105200321032006418001710d000b0240024020012802042205200128020022076b41386d22062004a722034f0d002001200320066b1062200128020421050c010b200620034d0d0002402007200341386c6a22082005460d000340200541486a21030240200541786a22062802002207417f460d00200241086a200541486a20074102744188c5006a2802001101000b2006417f3602002003210520082003470d000b0b20012008360204200821050b0240200128020022032005460d0003402000200310631a02402000280208200028020422066b41014b0d00410041d9c4001001200028020421060b200341346a20064102100f1a2000200028020441026a360204200341386a22032005470d000b0b200241106a240020000ba105010c7f230041106b2202240002400240024020002802082203200028020422046b41386d2001490d000340200441306a2203420037020020044200370200200441286a4200370200200441186a4200370200200441106a4200370200200441086a4200370200200441206a4200370200200341003602002000200028020441386a22043602042001417f6a22010d000c020b0b2004200028020022056b41386d220620016a220741a592c9244f0d0141a492c924210402400240200320056b41386d22034191c9a4124b0d0020072003410174220420042007491b22040d0041002104410021030c010b200441386c102921030b2003200441386c6a21082003200641386c6a22092104034020044200370200200441286a4200370200200441186a4200370200200441106a4200370200200441086a4200370200200441206a4200370200200441306a4200370200200441386a21042001417f6a22010d000b024002402000280204220a20002802002205470d002000200836020820002004360204200020093602000c010b2005200a6b210b410021010340200920016a220341786a2206417f360200200341486a220741003a00000240200a20016a220541786a220c280200220d417f460d00200241086a2007200541486a200d4102744194c5006a2802001102002006200c2802003602000b2003417c6a2005417c6a2f01003b0100200b200141486a2201470d000b200020083602082000280204210320002004360204200028020021052000200920016a36020020032005460d000340200341486a21040240200341786a22012802002200417f460d002002200341486a20004102744188c5006a2802001101000b2001417f3602002004210320052004470d000b0b2005450d002005102a0b200241106a24000f0b2000102c000bdf0203027f017e037f230041306b220224002000280204210342002104410021050340024020032000280208490d0041004183c5001001200028020421030b20032d000021062000200341016a22073602042004200641ff0071200541ff0171220374ad842104200341076a2105200721032006418001710d000b024002402004a722030d00410021030340200220036a2106024020002802082007470d00410041d9c4001001200028020421070b200620074101100f1a2000200028020441016a2207360204200341016a22034121470d000b024020012802302203417f460d00200241286a200120034102744188c5006a2802001101000b2001200229030037000020014100360230200141206a200241206a2d00003a0000200141186a200241186a290300370000200141106a200241106a290300370000200141086a200241086a2903003700000c010b20002001200310670b200241306a240020000b4c0020012002290000370000200141206a200241206a2d00003a0000200141186a200241186a290000370000200141106a200241106a290000370000200141086a200241086a2900003700000b4c0020012002290000370000200141206a200241206a2d00003a0000200141186a200241186a290000370000200141106a200241106a290000370000200141086a200241086a2900003700000b7801017f20012002290200370200200141206a200241206a2f01003b0100200141186a200241186a290200370200200141106a200241106a290200370200200141086a200241086a2902003702002001412c6a2002412c6a22032802003602002001200229022437022420024200370224200341003602000be70401037f230041c0006b22032400024002402002417f6a220241014b0d000240024020020e020001000b20002802042102410021040340200341086a20046a2105024020002802082002470d00410041d9c4001001200028020421020b200520024101100f1a2000200028020441016a2202360204200441016a22044121470d000b024020012802302200417f460d00200341386a200120004102744188c5006a2802001101000b2001200329030837000020014101360230200141206a200341086a41206a2d00003a0000200141186a200341086a41186a290300370000200141106a200341086a41106a290300370000200141086a200341086a41086a2903003700000c020b200341346a41003602002003420037022c20002802042102410021040340200341086a20046a2105024020002802082002470d00410041d9c4001001200028020421020b200520024101100f1a2000200028020441016a2202360204200441016a22044121470d000b200341296a2104024020002802082002470d00410041d9c4001001200028020421020b200420024101100f1a2000200028020441016a36020420002003412c6a220210681a024020012802302200417f460d00200341386a200120004102744188c5006a2802001101000b200120032903083702002001410236023020012002290200370224200141206a200341086a41206a2f01003b0100200141186a200341086a41186a290300370200200141106a200341086a41106a290300370200200141086a200341086a41086a2903003702002001412c6a200241086a2802003602000c010b410041a0c50010010b200341c0006a24000ba00301057f230041206b2202240020024100360218200242003703102000200241106a10421a0240024002402002280214200228021022036b2204450d00200241086a410036020020024200370300200441704f0d02024002402004410a4b0d00200220044101743a0000200241017221050c010b200441106a4170712206102921052002200436020420022006410172360200200220053602080b0340200520032d00003a0000200541016a2105200341016a21032004417f6a22040d000b200541003a00000240024020012d00004101710d00200141003b01000c010b200128020841003a00002001410036020420012d0000410171450d002001280208102a200141003602000b20012002290300370200200141086a200241086a2802003602000c010b0240024020012d00004101710d00200141003b01000c010b200128020841003a00002001410036020420012d0000410171450d002001280208102a200141003602000b20014100360208200142003702000b024020022802102205450d00200220053602142005102a0b200241206a240020000f0b2002102b000b0beb0503004190c0000b796661696c656420746f20616c6c6f6361746520706167657300756e6578706563746564206572726f7220696e2066697865645f627974657320636f6e7374727563746f7200746865206f6e6572726f7220616374696f6e2063616e6e6f742062652063616c6c6564206469726563746c790000000000000000004189c1000bd904000000000000006461746173747265616d20617474656d7074656420746f20777269746520706173742074686520656e64000a006665617475726520646967657374206163746976617465643a200070726f746f636f6c2066656174757265206973206e6f74206163746976617465640000000100000002000000030000006461746173747265616d20617474656d7074656420746f20777269746520706173742074686520656e6400000400000005000000060000006f626a6563742070617373656420746f206974657261746f725f746f206973206e6f7420696e206d756c74695f696e646578006572726f722072656164696e67206974657261746f720063616e6e6f7420637265617465206f626a6563747320696e207461626c65206f6620616e6f7468657220636f6e7472616374006f626a6563742070617373656420746f206d6f64696679206973206e6f7420696e206d756c74695f696e6465780063616e6e6f74206d6f64696679206f626a6563747320696e207461626c65206f6620616e6f7468657220636f6e747261637400757064617465722063616e6e6f74206368616e6765207072696d617279206b6579207768656e206d6f64696679696e6720616e206f626a656374006461746173747265616d20617474656d7074656420746f207265616420706173742074686520656e640067657400000700000008000000090000000a0000000b0000000c000000696e76616c69642076617269616e7420696e64657800756e6578706563746564206572726f7220696e2066697865645f627974657320636f6e7374727563746f72000041000b04e8220000000000000000000000003d5251a1c9a3cd8d7baad33a381b9e09858e0503df1751181fd60202251c23fb04000000033b3d4b010000000446ce40fcba331770d4e40c1a69d054d3a9a5ed89ef08b50cc808e325010000000000ea3055024900000000000000000000000000 DMLOG CREATION_OP ROOT 0 DMLOG RAM_OP 0 eosio abi update setabi eosio 199629 137 DMLOG DB_OP UPD 0 eosio:eosio eosio eosio abihash eosio 0000000000ea3055d7abd75d188060de8a01ab2672d1cc2cd768fddc56203181b43685cc11f5ce46:0000000000ea3055fc470c7761cfe2530d91ab199fc6326b456e254a57fcc882544eb4c0e488fd39 -DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304003,"value_ex":100469,"consumed":7921},"cpu_usage":{"last_ordinal":1262304003,"value_ex":256384,"consumed":4101},"ram_usage":199629} -DMLOG APPLIED_TRANSACTION 4 d276f624b0262b174fe373d5bcb026f4b5c87dd77d794b246b77a75e4d22525504000000033b3d4b01000000044444a224a7e16ae04e24e6640d6a909fb89ca6e5e8c1e5397e1e03ef0100d00700008201000000000000000010040000000000000001010000010000000000ea30552deb8b0eef2f2bfd027d20727a96e4b30eb6ccdc27488670d57bf488395c48fc19000000000000001900000000000000010000000000ea3055190000000000000002020000000000ea30550000000000ea305500000000b863b2c2010000000000ea305500000000a8ed323293120000000000ea305589120e656f73696f3a3a6162692f312e320117626c6f636b5f7369676e696e675f617574686f726974792276617269616e745f626c6f636b5f7369676e696e675f617574686f726974795f763019086162695f686173680002056f776e6572046e616d6504686173680b636865636b73756d32353608616374697661746500010e666561747572655f6469676573740b636865636b73756d32353609617574686f726974790004097468726573686f6c640675696e743332046b6579730c6b65795f7765696768745b5d086163636f756e7473197065726d697373696f6e5f6c6576656c5f7765696768745b5d0577616974730d776169745f7765696768745b5d1a626c6f636b5f7369676e696e675f617574686f726974795f76300002097468726573686f6c640675696e743332046b6579730c6b65795f7765696768745b5d15626c6f636b636861696e5f706172616d65746572730011136d61785f626c6f636b5f6e65745f75736167650675696e7436341a7461726765745f626c6f636b5f6e65745f75736167655f7063740675696e743332196d61785f7472616e73616374696f6e5f6e65745f75736167650675696e7433321e626173655f7065725f7472616e73616374696f6e5f6e65745f75736167650675696e743332106e65745f75736167655f6c65657761790675696e74333223636f6e746578745f667265655f646973636f756e745f6e65745f75736167655f6e756d0675696e74333223636f6e746578745f667265655f646973636f756e745f6e65745f75736167655f64656e0675696e743332136d61785f626c6f636b5f6370755f75736167650675696e7433321a7461726765745f626c6f636b5f6370755f75736167655f7063740675696e743332196d61785f7472616e73616374696f6e5f6370755f75736167650675696e743332196d696e5f7472616e73616374696f6e5f6370755f75736167650675696e743332186d61785f7472616e73616374696f6e5f6c69666574696d650675696e7433321e64656665727265645f7472785f65787069726174696f6e5f77696e646f770675696e743332156d61785f7472616e73616374696f6e5f64656c61790675696e743332166d61785f696e6c696e655f616374696f6e5f73697a650675696e743332176d61785f696e6c696e655f616374696f6e5f64657074680675696e743136136d61785f617574686f726974795f64657074680675696e7431360b63616e63656c64656c617900020e63616e63656c696e675f61757468107065726d697373696f6e5f6c6576656c067472785f69640b636865636b73756d3235360a64656c657465617574680002076163636f756e74046e616d650a7065726d697373696f6e046e616d650a6b65795f7765696768740002036b65790a7075626c69635f6b6579067765696768740675696e743136086c696e6b617574680004076163636f756e74046e616d6504636f6465046e616d650474797065046e616d650b726571756972656d656e74046e616d650a6e65776163636f756e7400040763726561746f72046e616d65046e616d65046e616d65056f776e657209617574686f726974790661637469766509617574686f72697479076f6e6572726f7200020973656e6465725f69640775696e743132380873656e745f747278056279746573107065726d697373696f6e5f6c6576656c0002056163746f72046e616d650a7065726d697373696f6e046e616d65177065726d697373696f6e5f6c6576656c5f77656967687400020a7065726d697373696f6e107065726d697373696f6e5f6c6576656c067765696768740675696e7431361270726f64756365725f617574686f7269747900020d70726f64756365725f6e616d65046e616d6509617574686f7269747917626c6f636b5f7369676e696e675f617574686f726974790c72657161637469766174656400010e666561747572655f6469676573740b636865636b73756d323536077265716175746800010466726f6d046e616d65067365746162690002076163636f756e74046e616d65036162690562797465730a736574616c696d6974730004076163636f756e74046e616d650972616d5f627974657305696e7436340a6e65745f77656967687405696e7436340a6370755f77656967687405696e74363407736574636f64650004076163636f756e74046e616d6506766d747970650575696e743809766d76657273696f6e0575696e743804636f646505627974657309736574706172616d73000106706172616d7315626c6f636b636861696e5f706172616d657465727307736574707269760002076163636f756e74046e616d650769735f707269760575696e74380873657470726f64730001087363686564756c651470726f64756365725f617574686f726974795b5d0a756e6c696e6b617574680003076163636f756e74046e616d6504636f6465046e616d650474797065046e616d650a757064617465617574680004076163636f756e74046e616d650a7065726d697373696f6e046e616d6506706172656e74046e616d65046175746809617574686f726974790b776169745f776569676874000208776169745f7365630675696e743332067765696768740675696e743136100000002a9bed32320861637469766174650000bc892a4585a6410b63616e63656c64656c6179000040cbdaa8aca24a0a64656c65746561757468000000002d6b03a78b086c696e6b617574680000409e9a2264b89a0a6e65776163636f756e7400000000e0d27bd5a4076f6e6572726f7200905436db6564acba0c72657161637469766174656400000000a0656dacba07726571617574680000000000b863b2c206736574616269000000ce4eba68b2c20a736574616c696d6974730000000040258ab2c207736574636f6465000000c0d25c53b3c209736574706172616d730000000060bb5bb3c207736574707269760000000038d15bb3c20873657470726f6473000040cbdac0e9e2d40a756e6c696e6b61757468000040cbdaa86c52d50a757064617465617574680001000000a061d3dc31036936340000086162695f68617368000000012276617269616e745f626c6f636b5f7369676e696e675f617574686f726974795f7630011a626c6f636b5f7369676e696e675f617574686f726974795f76300000000000000000000000d276f624b0262b174fe373d5bcb026f4b5c87dd77d794b246b77a75e4d22525504000000033b3d4b01000000044444a224a7e16ae04e24e6640d6a909fb89ca6e5e8c1e5397e1e03ef010000000000ea3055890000000000000000000000000000 -DMLOG RLIMIT_OP STATE UPD {"average_block_net_usage":{"last_ordinal":3,"value_ex":78666667,"consumed":9440},"average_block_cpu_usage":{"last_ordinal":3,"value_ex":334993056,"consumed":40101},"pending_net_usage":7920,"pending_cpu_usage":4100,"total_net_weight":0,"total_cpu_weight":0,"total_ram_bytes":0,"virtual_net_limit":1050675,"virtual_cpu_limit":200400} -DMLOG RLIMIT_OP STATE UPD {"average_block_net_usage":{"last_ordinal":4,"value_ex":144011111,"consumed":7999},"average_block_cpu_usage":{"last_ordinal":4,"value_ex":366368114,"consumed":4433},"pending_net_usage":0,"pending_cpu_usage":0,"total_net_weight":0,"total_cpu_weight":0,"total_ram_bytes":0,"virtual_net_limit":1051726,"virtual_cpu_limit":200600} -DMLOG ACCEPTED_BLOCK 4 04000000040000000300000000000000010000000000ea3055000100000001000240e54a7b27e042b80a810153bec1dd166eef95fa69f6c9886ae283363bc2add8010003000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd2d5b1b639d6ae94fcdd0536b224644931573d1ccb2a0c548613cd1feea18888ba1daaeb8ca4a99a2fdb182ebb462ceb26de69d76f024586207a1159226ea43de0300000000000000010000000000ea305504000000010000000000ea305503000000000100000001000240e54a7b27e042b80a810153bec1dd166eef95fa69f6c9886ae283363bc2add8010000000000044444a224a7e16ae04e24e6640d6a909fb89ca6e5e8c1e5397e1e03ef033b3d4b0000000000ea30550000000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cdded9794b7e6d10923376031cef59e6d6d809ee653bcc37297cb644078a507a6bd26c416dc790f2b35815f1d6741bc63e1c235f13e809df666ddea0ba2e5f45c80000000000010000c104121a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b7241ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea994a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0fe0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff52668dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a297428ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c438ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a4052652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed25f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d4e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d674fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c2299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b4476707c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead450715443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b4bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e99d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb406bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc35c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b001f5505dc47adebb683205c6cd618df9385777f5ffb29d307479ace7cc07533ec5d3b9e648ee95c2a1dbea8d971cd9e980c6185867556035db58109f2678ce179e30000000029807708239aa7de914d3ed61e9009ab2280bfbc50f1d9769f27f8341ef26198000000000001130ec7e080177b2c02b278d5088611686b49d739925a92d9bfcacd7fc6b74053bd1a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b72412652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed25299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b447670735c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b4a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0f4e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d674fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c25443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b468dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a2974286bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc8ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a405ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c43bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e99c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead45071d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb40e0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff526ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea99f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d0001033b3d4b0000000000ea30550000000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cdded9794b7e6d10923376031cef59e6d6d809ee653bcc37297cb644078a507a6bd26c416dc790f2b35815f1d6741bc63e1c235f13e809df666ddea0ba2e5f45c80000000000010000c104121a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b7241ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea994a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0fe0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff52668dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a297428ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c438ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a4052652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed25f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d4e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d674fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c2299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b4476707c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead450715443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b4bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e99d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb406bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc35c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b001f5505dc47adebb683205c6cd618df9385777f5ffb29d307479ace7cc07533ec5d3b9e648ee95c2a1dbea8d971cd9e980c6185867556035db58109f2678ce179e30200d0070000dc060101002026bcc48f2a2332b2fcb39133cc9226405049c824dba512d79415009b403b107d7dade3a3173c6cc9657b7662dd1fd267156e076ac91df0aea1d8172e65d676fe0100b13578daed3c0b90645755f7f33e3dfdba77df862569665773fb31606fdcc8246c66c710cdbe91ec872424c480c10fb3bd33bd3bddf3dd9e9e65d7c2edc56ce1f2b10a1525099602150d0906ab02456128ac4d245504b58c24a108258a965552201acb2a410a89e773efebd73d33614327912a9964a7efbbef9e73ef3dff73eeed09ff317a8b166ffef2e3e705fc48fc25be3efe46f8bdef15ef7ae0e17c87f8c837afbcf22fefcc75fd393cd45717b147de215f765888c3aadb158775177f7ba7e147760f0b79fab0d73d7d1abafc2efe409fe60f95fd3e6ddf89c3018251bf3c0df84e3b4c80f6340d94d023bb841861e10560a769795497401899821ef5b43fa61b4b27a2d923d3479b4bb3d3cd893d42634fa9b1bcda5c9eaeafae36da1d21b12b9e596bb71b4b9de97663a6d13cd1680b0fbbfdfa91651822b05de6f1d3ab73f52baf9a108a70f7faaee09edca8abaeb892fb62dbd76eae341667af9818e7ee208f69641ad633b7d069be5af8f8ecf55006795c2303482258f032ac777abe714a04d863561b9de9230bcb33f33373f5e6d2f44abd5d5f6c741aed5568cecc376679c7c162637166e5940809e6d8f78329e0b08b11f54a7b796579b5318b8dd9b51918234688aa8e849de66283c9b71dd1d6673a40d0dc684255586937973aabd30bbc9a8b1c8972bb291256e0de6a67b9dd20f645d4d56e1c5f6b424f7dad33274ad8b58517d63cd15c681c83d596b1f325d8d96eac2eafb5671ad30bcdc56667556cc1372fdb781fd38d93622b41aeb41bb4ec7aa7317db451efacb51b2226aaf1b2f9617b73d5bd9d76c367c53666393c2f2f4dcfd63bf5e9d5e6af36c445d40d7867a773ef9818dbf202393db33cdb102fc1fe226c1e49885b273e95a1636d651697857ddb7b949c83b54bbdff3af1d26db1d816c771292ea8f8e2822a5c22652c2bfc5390f643560af8290ad094ee9f2ac882829f82e7cb15592efb5a0a195cacbb323d735e445d91fed323d9473822fdfacacac229f18a918ba44865547ae39b7ee1cdbff84bbff296e9d9c6d1e247df2daff3445c8bbea28511f1e5f1981146bec1db3775e6cc7f3f71efd93bffeeaeae51f08cddf16b7ce8beff8bbff9bb1fb8f78dbdde6b5cef47fff6f3a2d7fd33d87de66b0f7cf3fce3efcee1f8593bfa530ffec7adbdde6ba1f7db7ffcc4173ef2a1c71fcae1d84738ce3cf1d90f3f35d5eb4db9f7ccb7eec8f7be967b3ff69dbffffaddb9f9aee3ee4f7eeb8bf9c1fbb1f753ff75f7fbefcaf71ea0b1e77fe73b7d630f52efeffdf5379ec8f7dec078bffc271ff8e283b9e95e4fdd8f3df0f14fdf7965aff7267feabdf73ef5d457de7367dfe09b7d23782be71fbce349718bb72fa5e7a71efff8377ffddf456ca2c11f3f37dcf1a96fcf80e0edfd0852115f11b5a5ee2a98b42c52b115ba525153ef81e7343e91c856a226e0897bcfee4bb411ad746b2b5d399e8809e8004095c61d23ae477068cb168e37121a5519c16bb94fa4dd03f8367def7911cbc8e848896842caeecb618ef904de4ca81200c30ca59a123df467f6612f4e938a6b05e28d5e2d551796268dd851956a9f06fcf12b135196a9a8f21ad3445d5796466d13a224a2c8882840f1fd89c8079d17f67711172bf6ea7369f47a5ec857c57c22c78070b0f42f09d844819a31b4bcac85af45fcaa517a34b286af60c5f3f116e8f9aa688d89e8c305582192b30618e09797a8f9347c1defff21d83f7556556414c014e2ada38676eea505a2b587bdadaa7628005a6f0cad532f07ed65d0a5a1a0e3a1a0b70f055d190a7ae750d06628e8b1a1a06b4341ef1e0a7a7c28e83d43414f0e057dcd50d0e7453fb8dc0c5ce5c05506fe3080cbef0f2e07c0115844df915a76d569b23be3f38926b38373c5adb83025aa5e1a57d1a02968fb60e2f08551ad6aa0d0de02ce436561fca9c23b8c67822b84389b785393e7ce567d78d78575190fde55bd12dbdf54eea7b5ddcbd61720f76a304d0e76af16381ddafb5655e0ec386b44a63c51a901d3cd686240d39b5e033ccea73be9c9563c026b2cb4766980341a3f3c9cc8db8b9103cd07561f440dec2398fef7435802f98087db7f5af0fe352820fa01684d815daec04777af8e611a01e8120f97ac0921d1c0832da277bbeb5f3ff16f57800b10e8450ed2fa00227e7502f41e379a377efe61763b0678378eef692df11ea68f17ab37d0b077fd050e03c1887725021711034d6aadc4c736ec03569804ae5d6925a16d1b8d688185f884988d029f9014f0c33385f9781c0885fd00047bc151013fc7ee3944a24d5a6cbbf438ef9cc6d44066e6ecc3843acc1308761c7648a13da166a1090e88b8185f35ca780a791a59425aacf1c5893fa1f6102961647c2bb274ea349055be0d7efdda9b76c01a90668226cdb880f403c0ddc4055d533b13851fe6268057f826860fe6564aa0ca3057419e2ab0819d25e40434ed7a693b1a6c583c1121a2c355e120c5756574dc97453c5325f1af2b8bdebc205707500daa02506a8c57e65ac876501b4321050a83421c0a70000b044a3261aae2272e7627e187099f26df7d36d0234e2f311e505558f618cf297005a0bce06690bb3e29034ceb83f8d73030d80f4107a804ae02175652107bc0f37e5c2374e2c2029238fe0f5407561957133fedb2edf84f1453248f9fbedd3b54c646fcca6a98ca6a017b81ba1c19cd27e1188caf824e49901c3fae8eb2d0062cb456460324fcb80980d6b60304d8b56adc52b8fe9042b7f4a9cf9296042664e10a310cf114ef30bdb46f10ca7f7504f080c92802f9c0981a2f350006b6230273e293425755cae6a444468c46b5aa65dabecf66a484562c3265b2621159b112bc032be69b08ad58c45aea3b2bf6c9476805ca9450c89483652be66330da22bb19e1b4c001b4625e66c57c67c5ecf468b500054ed93364a496b00cd4a06a84734548359e3232457c61b0a788d0f050e307126a9353f322da6dea8a7b9a2f41ed40fa820965f003f50ad0a3dd82373b9daced4c7cb2382036a85a3ebe8ce123ca54cbc05380aa85f295a9d608cd6789ad415841af006301f5208420989495d8c328b0df671da0f8d504d11d4a2b30cfa40506ac73152cc418597eb4a982d9f01932966a5facc834b005fd06751ac97ec0633b48bf023686011a438c77802f199530f682e7b8f70c84f480f6f4802d126b0a4d15b28e26e019ff80e551a737b7c88da079ab51f0eea15946bb63836c8f788dfe17d685161276b3670a25a016278455583328c00cfa6806fdcc0c8200a17df882eef96da00c980672f1b493445f232ee1989e1ebd2973ee1aa1d11a4ed5a0a5a8350e2d49ad496821b8a6712fc1d63d600b0a27ae161793aec7d07a29b52ad0da8e4030e06a11521f8e0bb2717e36cec325f0fc93efc0a9dfc159e199f3cf88dbcf4247c5767cf5dadb294ca0a7a72fbdfd2cbe2c9cc3c76f6fc557156c7f3724a01ab4bfa76fa7659f3d7b96350fa6895fe0692a442024da366a21212fa216922fee4bb3e47c7a291bd2730f6741184a23d804930bc20c0981228e422c7697967ed79a647c8fbf807af3696511d801c623483ffae47d4fa216a6f761a31abab1206434cc4b9fb8efc9cbc040827683bde9242198e5e0d08e24c4e5800517148b8145ad2cc4bb303492e40dd005a08ca2d7a82c2490ff49544f819a0eab26b9c72c34e04108dea2180f8c6f60734b5e6ec8cea7d0024753951a737270431ece024113cf225921503ee1f50ac47699be617409dd34353ecf510c097e34341e394d9ad29234a429614710e08a7837bc0d39daf351ed04aed6c368881d30600083012b0a7145214282d372ee59a2f991687e607b38130564d8e94167f498d29eb34431e95b8a1b22ef0e53810b535872e0552339381d4ffcf9d45fbbbf1a90d79110e7834f0ccfa17fbc0577a3881296e7be5ba0b206024d02a6d0645589b8cf8a297d1bc18469777f5959d4a48da556fc86513281840b8247df5293e8e75b6a021961533eca09c8487c8b8838c441cf0e9efec632c584269c8f7fce02520465c29be80d587294e788832f8f3f7001881da9047a1afffc28f945b0607faa155ab09efd42e31d5ff23c9b3191993191993191376382cd98c8cc98c8cc98f8ff67c6c01fed483f0399e34ee0d54fa79fa6161ba8e8f7fb5d0e57a884e595425ee123f34a5b5e493b85a216f34adac928d3b4bc82d63d60bc9857125d30f10a5bcc2b89ccf49057d8c7bc72e3fc6c9ce7720b8d44d48344d47d44d4fd44d43922ea1c11754644dde3154d13bfc0d3548840cc2b6c31afb0c5bc8268257e39c52cc09d7b7e1410fcb005042afe310a02bef410e709cca83f93d2735ea497d441f8fae38957b6358702565cc809908de53a437ac63b44eee89555c55998e7b2304042cff1a5a316810586219053c9a8972f615ec2193b2760e86d2996f5d293c7d3c2817c6ea5b3b16cb25f2b35ac1c97cdcb7549f0052e2dc2e0fd47483640f2a8629918ef930996081485e72803b6c034c61f98db417f0bab2c355bd3225cf96c1ba3bd1a2663353586f542aa8b38ee939060b9718ca21475e0d9e02e4138e9e0e4b3c059808b070068e129859e992c531e5968c553a35c732924544ea1fd95b8aa628b7acf485bd1b3a54fc8bd3546bd9ace8728563e44cbb8fd91befae8e58202215e32058e182a3d238e03a19e91c713d5b9ff2cb2260d5b90850655346a67e4f1b20d9228e6f339e653102c91bbc2b80883611731791868e3070f641642587a6399abaecc232f72317d308f549b4ffc9b7284633cc8ea00d2e52c9930beade8dea1fab2880207e65ea2e78d3c44e125d0e36a215c1202dbd55c48ee42d46fab45dae51eb8274c3cba379465fa0cfc8428e8444a78a9d2ef4197e67c4361bea1b19000f98626c1d556788d8664838bd8982f00ed2025a8eade5a6c44ebd68041782f039230d13cd57f608a8328fe482dda3a05f11187fa05ae7f62c4ef5118ee22faad363b7840290da2017a76463eaf8a762b7fdc6c156d42ddc6927b704335bb95c5fe736240c1080fcafd3e869e84a7c7a8743289824f0a40551eece51c0975cb157ab9c4a077e99b139f4bd472af46dde71a3696be6bb6dcb94b1f64ac57b2364de6b4e91aa74d6724aad30d439a37d8f893e769e3d0f9375279cc80ff6be797f37a032e0ff43b334758740b8cbe5c405a693037c1a45a1c882bce21dea760439ecb6136db50c56ea8f2836ea86281bfdf867cebc693f5bb82bcda77236337321e1854c80daa38fa54360909b0b216308de8cc20ae16f0a3521d21528d9802961ee29791f5861d7d48cba8dfc7a159264a65d574df5205abcdde40a5d91b23b3e05bb50315dfce1f311f0081fe54587f0a2eb6a16debf8d028ad88bd48bc778ab4d0e0f903f8203063f1a8f52a86e49bb18e51decffd220972f57e0fac7b80f5fe80d688050520f8e116566390fcada4805707ba586ef7d285563282188a88b96809bfd24a22b2afa6c819bf971eccd8d7e23a658931682e491e6c9952aa3ae9b947042afe368922927651e97d10ce229d40446684d2f2c844a648af50950b3c8c174d55573a13d35c1ef172bef3af34955b47723904791b4d07817400c8a75a1b39511da1a6a04cb03967af02ae929ca84f4ed447278a35a610a559630d639d130d73859324c0c442b31fd558b37d1d3b502c50e0d1d58d5c418709fd0ed0dd84b6c29368c7108d041dc918a29121459c204286447890099dc010bcef01ee2bda6f7de4c1967d07f03ebe2b3306c5c57560487990213e533a807d4596da452aaf61593fa25748ed11c79002d599606b052415e851c444c07584ae1424b874a2f93c8b0b43db498b49e9e3eb49441082b165e5c43f0c7411b8a97b25ab5e4ca03926f090c82e2cc03a786235c7b31f308b6b155a4ea90497fa6d0933f106a387ec5cc9fa6fc74a908930c53c8c2a9810385c8bfa4f12e5cf03c7fc350c27f07887aa753af5d61294a010e209f6cf28841aab7d9ec3a3b1ed7720bcd06415500ed0108160a1448c60e0d7db4da5b5f9be702f552f178210858abc85002b6a8129ce5723d603b06f10c348148e80d959c40e143b3eb1915464e4e846422f9ed8082b4f396992287a5bb87c285136b73279b79050da32e85616db2d5955b4831208db93b6078935e74607a6cca31811e1468be0c32a126b2660ad68a73924a528aa5cd2364cc24b4920c3650cab0a1c56791c568d70a9142660e10cd8ee05ce6e85fd760fd79bf0d1295d5020bbb795ed9ec8d93de9e0c9d4fa4ecd0ad6eef9836aa699e0b24ac55ddad0161b086ee5235eaae386561b4d9915a38c2b29e31b5b81fcbca47890f7af32d5c3c85b5bed188cddbcaac7aeda1d7af36da9090e55b14e4d38a4b39a7e967a687cd3673565de6a9281cbac261eb8f5520f0fad26397f14504d6567b69a9435f8f7c487a3774a0ad406cf8a5f88c8d606a5607a6e748e15da3fe58eed36b97676fd600aa3f83ce4c2ae9d6d048da1c8855d3b7b6ed0f150d0db8782ae0c05bd7328683314f4d850d0b5a1a0770f053d3e14f49ea1a0278782be6628e875d7ce3603bfc06b679b69f846d7cedef7c3520485f4852c183984f778be4711933de87b7a1363bae172fc81e5f8b81c9f8de914a54aeeaa4b1a57f9865d16856417cdf07a01e1edbfe4e2e36595d09a5e9fcf90f11c0f231d94df117bb9a54891eb637cb98597a8f87649112fb70426a2cb2d015d6e29620201599e09f0720b5f08c2d4b7ef72cb88292221471cac5bfe089ac911dc174ebbee728b72975b94bba207c1133c0c5ed12bda3c12270a90123c1f67ac1c68e72fab59a20d5c59d3f6ca5a855b7c658d8a248020e40ac93f034d0a5c22f1f91a99dcab6fe3eac8cd994f8b5bf1647605eb735a7bee44e5874612fa448078ef5bde8779de17f2bc0f99f7851cefc30be1bd6f42e4bdef60dd827daa2058de8717c4fb7003de8719ef7de63dcf373cefedf5d5ab334e3e29b5ee3fbce7545373b40671dee4e2fd7c0c2ee8ce027f65c0f878c0eedb0376778f80ef29daf0b5a6c693e07e4a08368771170f037730af28a5a300173a21bafdee432eba654329d0ce12a8072e022b152eb78b29b7db4aa7f3fcfd81ef71c15b0f6c8ebf0d40970f38d9a34c48df8317d340bc60912063b740f21276b8ceddbe5a6ccd5d2611eb2eb078587e5128d43267d1a54d00037b37974278266f4044cae10c37c6e90f04819c6cf81855de3aeaee2b0478af84614a7952445f9154b450b9fd733dc2c8ab54ccf91fefdac35d7b9bef5a6fb46bcd3e70fdae75ffae6397cf795cc87118f5c618e58053b67b8e6f1b1d60f2252c10944ab16854f196c7a6fd279474390d1588e9da479ab4129b3ad65a57293105adcbc5582a8fefa02abc40d9153db1e00b25ee664c4dd56838a4bbf204caf9f11d0915d7f1545fd0acd19dba77917abd14a27abd8852e8e430643994b62874951ae73387679d7ecb854cbf65f3e99db687681bbcf52a1f824e83ca7fe2e14ce5430c22fdbe8cc9cbaef1af579681708c260ed14c849c0c0f9a8959c80c7bb24281199651d064e1718c978be1d6ef57b1271bd82c85809caea6559af34599e43ef922cc02025eed0f8c3741a50750d9cb669009c5bf3c1afdcf7ab3c40a01d93e4c058aa45191eeafdaca817e91ec945d818f2b805fc7936007d5dfa93c414ecc043ba8a463e732feeb379c6b83d3c79c5556f4ff28d90fb6343407a46ac03abc50f7317be46de84b171cae507d767beecb17aac4a75e5ebbc75b5751d838dbe12b851bd9562fae8ff69b6a3ab2a55bc75cfdb1676a826eca93553cc88720028b531ed5015d15b9d2a2d7ecbef3c5298fab4eaa2aec8977c4851e4a86e85e229daf494a3df6ba3a5dcc9721f11805fa4a94ab7cf0111bf1d1f1c96f706dde5be7e65eccdabc3de00ed1a2afafcd1fb187db7db579cc5a2617b0366fa9ea2355b5bdcc9f04842f57f2c3d760ce06a86a6bac1a565670c1505636f7736573c73aa3e399d13e9109364a5103a4ef1e62e3ba2c154f481163bf4d8d3ee4cb527f497d7d517d72b157541fe7a2bae2a23a857414fdabac20adb282b4ca0ad28a0bd2dcea2fb94f6e5072cf95da8933546affa3df7e74eca6b24cef86cf5ca51d47e8f4b71ebdfb223cb747fec8ce86757689d23cb9d0abad031f6d6d1d39daabadff409b42cab8d6645fe53dbb00edaaeff4ed9a8d8ad1f4151557959754952743deabcae3418d2dc303d222be26b92bf59de8905bf6b3339df759c9a3ea7189cbea11ddaf85416f6bbd4a8ad780db464f01c8b900ed56c791a75ba4bd5d4bcbb2c967ee78c973c74b24bbb672aef86c490c6a80e4fd20767b7937ca7d6582a5d35d74f807feda8476c7adc3d98a70bdadd06c2b34db8a70d056a05de0fb1f7c99b9d5f327e18141150cf98b3e035e2b1c74cbf64b1ff06879566b51c97c904c7c595d58bb3ace5fe9c03331d8139fc5d0c5264e2b4576e53cee3d17f8608d9f4b74bb04268a8f2195c7d906dc40f77576090bb1d90c6260063130033d3fbfc84e4ad92574ca1e29597456667be8dc7b87ce3d3b74ee79373eefe6b319bebb0fb8c7f6aa31a3507bed552d11fd8bc70710e745cea1a3462b32bbfcbc4509694fd6f80b59a40a052a596401b03ab08163f7dda58c81c8cdd61efa44243bea9d6cd195e4752242ae9788273311a138a39fecd4d52f28d4d52f2bf65a8e1517c50e2517c2ec7ea1b60ba876e563de8df078ebf0b0f1c4af39262a9e1b7d6e342389a0afae3a111beba35e5eca72d453eba9a7d653af276eeefb1f0371d0792ae67c10bf2593bbe48ca4ae9030e2b7644998e99a204b5c0dcfca21e44bf43c5fee40eccc1de5ce7d576e2a2b5bc42b5e4f2618bf3a836200c46b733c83be0cff144400de906274fe86430003ecb72cc0fce35d109fac2702e35776e8eb6d74b5cd435df0ca744b80bd1187c6907a1fa7c818298733611cee8e8dc5848dd75dfc0cefe2cbecd16e66ecf27a9b11ee79c1cfb769241f213339630e9969c3db9df33136dd84d8f627c1317dc3d7f41736a25347ebcd85c6ace92c9bfac2c2f24cbdd3302bf5638d55b1b6d438b9d298e9c0cb46bbbddc36cd2573b479b2313b7de454a7b16a669697563bedb599ce725b74e61a66798987f19fbb3133f5a5a5e58e39d280d602ce30db6c03b68553c2fda4ef7c48444f79f609ff3c0ee06bd4174dbdd3692cae7478556f6d376949ab1d83b33496664551d83fc3033861a51d93fd359eab8d58692f77966796178c1bd35c35b890de5fece13f80a5e09f7e6ef30a5cab0fff02f8b77ca405dbc101ab0c00c3db7520c634b6794ea0d8e2da42a739dd5c9a6d9c144c1ffc9b40cda563d978612935032f6046c6bb8ab09dfa9105e8386aeaf07eaed1469277dab091f5932f2ecf368f9eda645e3b811d734113f05f1d6a3b2ececcd5978e0135dacdc57afb94996f9c326f9d6b2c5994b89bfa9245bc294171dffdf43cd6e80811022d0bf06f04fe15e15f24f04fb108d15c3a515f68ce9a13f576b3be847bc2ad3c17a1045b1b795f4b00d7ff02b86d754e00d007000082010101001f5be06ae972efdca372f145881855ab035fc9b761243d0042d6d39703ea6e94a86cd3b37db4b18cdc3f21d6403bc80f91005cf01ed88a02858ec4a7b9fe9ba77f0100e60778da8d56bd6f1c45149ffb3edf25966308c6292882682205e24bb0ac54a6a0a1a0e0a340262c733bef6e47b73bbb9999bdf3414d116890e88284228420852ba7890c85752d121209690205d081c4ffc09bd9bdddbd353e3cc57ebcf7e6cdbcf77eef37d3faa3fb418dbcf7f4f131c151310ff2f7b577cdeba17b385b10dcffa7d7fb627d2eb9b3be0aa1e2e1cd9bb4cf5fd97ab957d9e8fba13b72141f0a2e860e8db5174aaea797c754722ab4738ade195fdb6ca313c7a3ca23d546381120eb8206503792aeeb813b5271d07b75bb4d5dcdc75403a9ac0e80ea5882c3f810942e5aad64ae497d457b129417faac1973a1aff7ea2398aa73f87026c0879edebb854edd30165a6d462003ae3028e1f830063f33694c28d7eabc7966b24ba78743aa6758f6a29def7a940b27a212c3d52015b9f04c40f7d35409d04eace810ac93ed1b97349543d065ad13b93a5d66d34cd6920a653285712cbab8de7ba14f154e00b9d46a2df7ed034ce83495bfe88642c3be7606124ce6954d5c6127220ece6aca40a4a68588dd285ed8c862c4997659c465179b01267899c1f3650f3e1f80e641963206039012181aed3bb01f7149addd840b164e52ab8b652f0cfc2c6fcf1925173e17e0a46ac53f9a2fb07152cb20d29e556f6ddbf4e4f02aaaba2e152ef87629525d4dfee6685c2bc3b969f6cf59b1553a38157167cc49b5953682edbd4e3e3bf9cfb14baa35fce94471dfe7ae839fcd449e6eaa8d3b18598ff5058f753764907ce969947c7525dc8eb98400e6cb0a845b3209a7bb129b3c4cc9207b240c917779d3b202e48256887a194aec43058221d8396bd9cdf576da28d1a6928dfe54833a912424207497ae594ec2c6290c41aa05cb93795f48cf7a244316bbb8a99ca6aae7336116651ece69c47a0e93372744b694115bc6d254a4521fc830b0fe9b0a34b26ea9ec35142599e918bdcf0324be52215790ac1c6bd3b0b4d4314d9dc4980a4c8b15052df465aa5f72d41c0706090d93989d9571304602c4ac25ff162ec956b08ada52a4229566f2f1dfec69d689241f97826a71e51871e2b86d8d4286ceda0a93c4621f9e3d5994bd5b9d586450aefd2f943b71c468da4af5a5ad644298e3bd6eecf352770b470ca9b6ed9f0237258a4520ade1417ce54b3c94f35391fc70e7caeb9f7cfbda022f90dd1f9fde3ff8fa8d62afe3b83aaa7df759deab64f7abbb97d9c3bbc506c4f1fba38f9f7c93f5d3e7ef6cff0aece068117938ee41707094a16c7e7d98438c909fde3cf20e674548e1d87de9d3c359060d428e1fbdfff68359a1d8383efc7eefc12c2b2b8e9d9f519097d00477fcd79fbf146b6503f6df7a52ac88b9c9dca38f7fdbaaf1ed1b84e4f70dbcf59ce182525976da937f01d36959fa0000 +DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304003,"value_ex":101210,"consumed":7921},"cpu_usage":{"last_ordinal":1262304003,"value_ex":267959,"consumed":4101},"ram_usage":199629} +DMLOG APPLIED_TRANSACTION 4 befaff75b7a38d724c06bd3cf84cec04cb9b771d261f3937b82f0f29a6ecd12c04000000033b3d4b010000000446ce40fcba331770d4e40c1a69d054d3a9a5ed89ef08b50cc808e3250100d00700008201000000000000000010040000000000000001010000010000000000ea30552deb8b0eef2f2bfd027d20727a96e4b30eb6ccdc27488670d57bf488395c48fc1a000000000000001a00000000000000010000000000ea30551a0000000000000002020000000000ea30550000000000ea305500000000b863b2c2010000000000ea305500000000a8ed323293120000000000ea305589120e656f73696f3a3a6162692f312e320117626c6f636b5f7369676e696e675f617574686f726974792276617269616e745f626c6f636b5f7369676e696e675f617574686f726974795f763019086162695f686173680002056f776e6572046e616d6504686173680b636865636b73756d32353608616374697661746500010e666561747572655f6469676573740b636865636b73756d32353609617574686f726974790004097468726573686f6c640675696e743332046b6579730c6b65795f7765696768745b5d086163636f756e7473197065726d697373696f6e5f6c6576656c5f7765696768745b5d0577616974730d776169745f7765696768745b5d1a626c6f636b5f7369676e696e675f617574686f726974795f76300002097468726573686f6c640675696e743332046b6579730c6b65795f7765696768745b5d15626c6f636b636861696e5f706172616d65746572730011136d61785f626c6f636b5f6e65745f75736167650675696e7436341a7461726765745f626c6f636b5f6e65745f75736167655f7063740675696e743332196d61785f7472616e73616374696f6e5f6e65745f75736167650675696e7433321e626173655f7065725f7472616e73616374696f6e5f6e65745f75736167650675696e743332106e65745f75736167655f6c65657761790675696e74333223636f6e746578745f667265655f646973636f756e745f6e65745f75736167655f6e756d0675696e74333223636f6e746578745f667265655f646973636f756e745f6e65745f75736167655f64656e0675696e743332136d61785f626c6f636b5f6370755f75736167650675696e7433321a7461726765745f626c6f636b5f6370755f75736167655f7063740675696e743332196d61785f7472616e73616374696f6e5f6370755f75736167650675696e743332196d696e5f7472616e73616374696f6e5f6370755f75736167650675696e743332186d61785f7472616e73616374696f6e5f6c69666574696d650675696e7433321e64656665727265645f7472785f65787069726174696f6e5f77696e646f770675696e743332156d61785f7472616e73616374696f6e5f64656c61790675696e743332166d61785f696e6c696e655f616374696f6e5f73697a650675696e743332176d61785f696e6c696e655f616374696f6e5f64657074680675696e743136136d61785f617574686f726974795f64657074680675696e7431360b63616e63656c64656c617900020e63616e63656c696e675f61757468107065726d697373696f6e5f6c6576656c067472785f69640b636865636b73756d3235360a64656c657465617574680002076163636f756e74046e616d650a7065726d697373696f6e046e616d650a6b65795f7765696768740002036b65790a7075626c69635f6b6579067765696768740675696e743136086c696e6b617574680004076163636f756e74046e616d6504636f6465046e616d650474797065046e616d650b726571756972656d656e74046e616d650a6e65776163636f756e7400040763726561746f72046e616d65046e616d65046e616d65056f776e657209617574686f726974790661637469766509617574686f72697479076f6e6572726f7200020973656e6465725f69640775696e743132380873656e745f747278056279746573107065726d697373696f6e5f6c6576656c0002056163746f72046e616d650a7065726d697373696f6e046e616d65177065726d697373696f6e5f6c6576656c5f77656967687400020a7065726d697373696f6e107065726d697373696f6e5f6c6576656c067765696768740675696e7431361270726f64756365725f617574686f7269747900020d70726f64756365725f6e616d65046e616d6509617574686f7269747917626c6f636b5f7369676e696e675f617574686f726974790c72657161637469766174656400010e666561747572655f6469676573740b636865636b73756d323536077265716175746800010466726f6d046e616d65067365746162690002076163636f756e74046e616d65036162690562797465730a736574616c696d6974730004076163636f756e74046e616d650972616d5f627974657305696e7436340a6e65745f77656967687405696e7436340a6370755f77656967687405696e74363407736574636f64650004076163636f756e74046e616d6506766d747970650575696e743809766d76657273696f6e0575696e743804636f646505627974657309736574706172616d73000106706172616d7315626c6f636b636861696e5f706172616d657465727307736574707269760002076163636f756e74046e616d650769735f707269760575696e74380873657470726f64730001087363686564756c651470726f64756365725f617574686f726974795b5d0a756e6c696e6b617574680003076163636f756e74046e616d6504636f6465046e616d650474797065046e616d650a757064617465617574680004076163636f756e74046e616d650a7065726d697373696f6e046e616d6506706172656e74046e616d65046175746809617574686f726974790b776169745f776569676874000208776169745f7365630675696e743332067765696768740675696e743136100000002a9bed32320861637469766174650000bc892a4585a6410b63616e63656c64656c6179000040cbdaa8aca24a0a64656c65746561757468000000002d6b03a78b086c696e6b617574680000409e9a2264b89a0a6e65776163636f756e7400000000e0d27bd5a4076f6e6572726f7200905436db6564acba0c72657161637469766174656400000000a0656dacba07726571617574680000000000b863b2c206736574616269000000ce4eba68b2c20a736574616c696d6974730000000040258ab2c207736574636f6465000000c0d25c53b3c209736574706172616d730000000060bb5bb3c207736574707269760000000038d15bb3c20873657470726f6473000040cbdac0e9e2d40a756e6c696e6b61757468000040cbdaa86c52d50a757064617465617574680001000000a061d3dc31036936340000086162695f68617368000000012276617269616e745f626c6f636b5f7369676e696e675f617574686f726974795f7630011a626c6f636b5f7369676e696e675f617574686f726974795f76300000000000000000000000befaff75b7a38d724c06bd3cf84cec04cb9b771d261f3937b82f0f29a6ecd12c04000000033b3d4b010000000446ce40fcba331770d4e40c1a69d054d3a9a5ed89ef08b50cc808e325010000000000ea3055890000000000000000000000000000 +DMLOG RLIMIT_OP STATE UPD {"average_block_net_usage":{"last_ordinal":3,"value_ex":79733334,"consumed":9568},"average_block_cpu_usage":{"last_ordinal":3,"value_ex":351659723,"consumed":42101},"pending_net_usage":7920,"pending_cpu_usage":4100,"total_net_weight":0,"total_cpu_weight":0,"total_ram_bytes":0,"virtual_net_limit":1050675,"virtual_cpu_limit":200400} +DMLOG RLIMIT_OP STATE UPD {"average_block_net_usage":{"last_ordinal":4,"value_ex":145068889,"consumed":8000},"average_block_cpu_usage":{"last_ordinal":4,"value_ex":382895892,"consumed":4449},"pending_net_usage":0,"pending_cpu_usage":0,"total_net_weight":0,"total_cpu_weight":0,"total_ram_bytes":0,"virtual_net_limit":1051726,"virtual_cpu_limit":200600} +DMLOG ACCEPTED_BLOCK 4 04000000040000000300000000000000010000000000ea3055000100000001000240e54a7b27e042b80a810153bec1dd166eef95fa69f6c9886ae283363bc2add8010003000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b52d5b1b639d6ae94fcdd0536b224644931573d1ccb2a0c548613cd1feea18888b832a8006b631c33ec6afc9ab302513af7c26d7d5bd2a3801f269dd2bf1d13b540300000000000000010000000000ea305504000000010000000000ea305503000000000100000001000240e54a7b27e042b80a810153bec1dd166eef95fa69f6c9886ae283363bc2add80100000000000446ce40fcba331770d4e40c1a69d054d3a9a5ed89ef08b50cc808e325033b3d4b0000000000ea30550000000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b5dafd0f0596077e5010e7d7876a42e26a54669cb6ab0f1f073bf87b3d88a3043bc48e1625ffa8c398daca7e3f8bd15d4b2e191b8fa7d72547f72e57668630f3430000000000010000e104131a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b7241ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea994a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0fe0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff52668dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a297428ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c438ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a4052652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed25f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d4e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d674fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c2299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b4476707c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead450715443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b4bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e99d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb406bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc35c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b98c4175db53ed27e7911a1b5adf0e7db0fc96c2cae172cf594dfa9a742ca9e8800206af0063f6484fc2fa8e6fe0264faec9dba3f7efaa4f888c9998ea3fe0520e42a56cb0a715d87a7ad6434f43fd50065329f5230598c84aa372b6a1ed1735aa13e0000000029807708239aa7de914d3ed61e9009ab2280bfbc50f1d9769f27f8341ef26198000000000001140ec7e080177b2c02b278d5088611686b49d739925a92d9bfcacd7fc6b74053bd1a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b72412652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed25299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b447670735c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b4a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0f4e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d674fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c25443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b468dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a2974286bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc8ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a40598c4175db53ed27e7911a1b5adf0e7db0fc96c2cae172cf594dfa9a742ca9e88ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c43bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e99c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead45071d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb40e0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff526ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea99f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d0001033b3d4b0000000000ea30550000000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b5dafd0f0596077e5010e7d7876a42e26a54669cb6ab0f1f073bf87b3d88a3043bc48e1625ffa8c398daca7e3f8bd15d4b2e191b8fa7d72547f72e57668630f3430000000000010000e104131a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b7241ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea994a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0fe0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff52668dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a297428ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c438ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a4052652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed25f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d4e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d674fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c2299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b4476707c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead450715443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b4bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e99d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb406bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc35c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b98c4175db53ed27e7911a1b5adf0e7db0fc96c2cae172cf594dfa9a742ca9e8800206af0063f6484fc2fa8e6fe0264faec9dba3f7efaa4f888c9998ea3fe0520e42a56cb0a715d87a7ad6434f43fd50065329f5230598c84aa372b6a1ed1735aa13e0200d0070000dc06010100201ba2b33dda3b5437782a9c6370a15fc8f11fa60dbea2c8f918f838e0e4c1842114085668fb0e76c2884e12c516aef88770c3d61341505f165c0940a6b50f141b0100af3578daed3c0b8c5c5775f7f33eb3f366ece7609261ed36771e4b3aa64ed90467bd0d69e3b725fe902f69a0f4c77abc3bf6ceecd7b3b3c6aea8c734566a3e9568a12509550b286d4868a81410a2202a272512d0564d2141b82a2dad2a15416953552a1451d2f3b9f7cd9bd9dde03049402a9b78e7befbee39f7def33fe7ded9f09fa2376af1aa0bdebb04fc48fc25be36fe3af8bdef656f7bf8d17c87f8e037aebefa2fefc975fd393cd45717b147de2d5f725888c3aadb158775177f7ba7e147760f0b79fab0d73d7d1abafc2efe409fe60f95fd3e6ddf89c3018251bf3c0df84e3b4c80f6340d94d023bb841861e10560a769795497401899821ef5943fa61b4b27a2d923d3479b4bb3d3cd893d42634fa9b1bcda5c9eaeafae36da1d21b12b9e596bb71b4b9de97663a6d13cd1680b0fbbfdfa91651822b05de6f1d3ab73f5abaf99108a70f7faaee29edca86baeba9afb62dbd76eae341667af9a18e7ee208f69641ad633b7d069be52f8f8ecf55006795c2303482258f032ac777abe714a04d863561b9de9230bcb33f33373f5e6d2f44abd5d5f6c741aed5568cecc376679c7c162637166e5940809e6d8f78229e0b04b11f54a7b796579b5318b8dd9b51918234688aa8e849de66283c9b71dd1d6673a40d0dc684255586937973aabd30bbc9a4b1c8972bb291256e0de6a67b9dd20f645d4d56e1c5f6b424f7dad33274ad8b58517d63cd15c681c83d596b1f345d8d96eac2eafb5671ad30bcdc56667556cc1372fd9781fd38d93622b41aeb41bb4ec7aa7317db451efacb51b2226aaf1b2f9617b73d5bd9d76c367c53666393c2f2f4dcfd63bf5e9d5e6af35c425d40d7867a773ef9818dbf202393db33cdb102fc2fe226c1e49885b273e95a1636d651697857ddb7b949c83b54bbdff06f1e26db1d816c771292ea8f8d2822a5c26652c2bfc5390f643560af8290ad094ee9f2ac882829f82e7cb15592efb5a0a195caabb323d735e445d91fef363d9473822fdfacacac229f1b2914ba44865547addeb7fe1177fe9977ff58dd3b38da3c50fbd5ddee089b8167d590b23e22be331238c7cadb76feacc99ff79e281b3f7fcfdbd5da3e019bbe357f9d0fdd0177feb77dffbc0eb7abdd7b9de0ffdede744affb67b0fbcc571ffec6f92fbc3d87e367ede88f7fe23fefe8f55e0fbddffae3273effc1f77fe1911c8e7d84e3cc139ffec085a95e6fcabd67be7977bef7d5dcfbe16fffc3d7eecbcd7703777fec9b5fcc0fde8fbd1fffeffbde736fbef7008d3dffae6ff78d3d48bdbff7d75f7f22df7b13e3fdbb3f79ef173f919bee16ea7efce18f7cf29eab7bbdb7fa53ef7ce0c2852fbfe39ebec1b7f946f056ce7fe2ee27c5eddebe949e2f7ce123dff88dff10b189067ffcdc70c7a7be3d0382b7f42348457c55d496baab60d2b248c556e84a454dbd039ed3f844225b899a8027ee3dbb2fd146b4d2adad74e5782226a00300551a778cb811c1a12d5b38de4868546504afe53e91760fe0dbf49de7452c23a32325a20929bb2f8539e6137833a14a000c33946a4af4d09fd987bd384d2aae1788377aa5545d589a34624755aa7d1af0c75724a22c5351e535a689baa12c8dda2644494491115180e2fb13910f3a2fecef222e56ecd5e7d2e8165ec857c47c22c78070b0f42f09d844819a31b4bcac85af45fc8a517a34b286af60c5f3f116e8f98a688d89e80305582192b30618e09797a8f9347c0defff11d83f7556556414c014e2ada38676eea505a2b587bdadaa7628005a6f0cad532f07ed65d0a5a1a0e3a1a0b70f055d190a7ae750d06628e8b1a1a06b4341ef1e0a7a7c28e83d43414f0e057ddd50d0e7453fb8dc0c5ce5c05506fe2880cbef0d2e07c0115844df965a76d569b23be3f38926b38373c5adb83025aa5e1a57d1a02968fb60e2f08551ad6aa0d0de02ce436561fca9c25dc633c155429c4dbca9c97367ab3ebcebc2ba8c07efaa5e89ed6f2af7d3da1e60eb0b907b35982607bb570b9c0eed7dab2a70769c3522539ea8d480e9663431a0e94daf011ee7d39df4642b1e8135165abb34401a8d1f1e4ee4edc5c881e603ab0fa206f6114cff7b202c817cc0c3ed3f2578ff1a1410fd00b4a6c02e57e0a3bb57c7308d007489874bd6849068e0c116d1bbddfb6f1ffdf7abc00508f42207697d0011bf32017a8f1bcd1b3fff28bb1d03bc1bc7f7b496780fd3c78bd56b69d8dbfe02878160c4bb12818b888126b556e2631bf6012b4c02d7aeb492d0b68d46b4c0427c42cc46814f480af8e199c27c3c0e84c27e0082bde0a8809f63f71c22d1262db65d7a9c774e636a203373f661421de609043b0e3ba4d09e50b3d00407445c8caf19653c853c8d2c212dd6f8d2c49f507b88943032be03593a751ac82adf0cbf7efdf53b600d48334193665c40fa01e06ee282aea99d89c20f732bc02b7c13c307732b25506598ab204f15d8c0ce1272029a76bdb41d0d362c9e8810d1e1aa7090e286323aee97473c5325f16f288bdebc205707500daa02506a8c57e65ac876501b4321050a83421c0a70000b044a3261aae2272e7627e187099f22df7d36d0234e2f311e505558f618cf297005a0bce06690bb3e29034ceb83f8d73030d80f4107a804ae02175652107bc0f37e5c2374e2c2029238fe0f5407561957133fedb2edf82f1453248f9fbec53b54c6467c45354c65b580bd405d8e8ce693700cc65741a724488e1f5747596803165a2ba301127edc04406bdb0102ec5a356e295c7f48a15b7ae1d3a425810959b8420c433cc53b4c2fef1b84f25f1d013c60328a403e30a6c64b0d8081ed88c09cf8a4d05595b239299111a351ad6a99b6efb31929a1158b4c99ac584456ac04efc08af926422b16b196face8a7dec315a8132251432e560d98af9188cb6c86e46382d7000ad98975931df59313b3d5a2d408153f60c19a9252c0335a81ae15c11528da78c4c115f18ec2922343cd4f88184dae4d4bc88769bbae29ee64b503b90be604219fc40bd02f468b7e0cd4e276b3b139f2c0e880daa968f2f63f88832d532f014a06aa17c65aa3542f359626b1056d02bc058403d082108266525f6300aecf75907287e354174b7d20acc33698101eb5c050b3146961f6daa60367c8a8ca5da172b320d6c41bf4e9d46b21ff0d80ed2af808d6180c610e31de04b46258cbde039ee3d03213da03d3d608bc49a425385aca30978c63f6079d4e96d2d722368de6a14bc7b6896d1eed820db235ea3ff8575a18584ddec994209a8c5096115d60c0a30833e9a413f33832040681f3eaf7b7e1b2803a6815c3ced24d1d789cb38a6a7476fca9cbb4e68b486533568296a8d434b526b125a08ae69dc8bb0753fd882c2896bc5a5a4eb31b45e4cad0ab4b623100cb85684d487e3826c9c9f8df370093cffe45d38f55d9c159e39ffb4b8f32c74546cc757aebf93c2047a7aeaf23bcfe2cbc2397cfcd6567c55c1f6774202aa41fbbbfa4e5af6d9b36759f3609af8799ea6420442a26da31612f2126a21f9e2be344bcea797b3213df7681684a134824d30b920cc901028e228c462f76ae977ad49c6f7f80ba8379f5616811d603c82f4434f3ef8246a61fa2036aaa11b0b4246c3bcf489079f7c391848d06eb0379d2404b31c1cda9184b81cb0e0826231b0a895857817864692bc01ba009451f41a958504f23f89ea2950d361d524f79885063c08c15b14e381f10d6c6ec9cb0dd9f9145ae068aa52634e0e6ec8c3592068e259242b04ca27bc5e81d82ed3378c2ea19ba6c6e7398a21c18f86c623a749535a92863425ec08025c11ef86b721477b3eaa9dc0d57a180db103060c6030604521ae284448705ace3d4b343f12cd0f6c0f67a2800c3b3de88c1e57da739628267d4b7143e4dd612a70610a4b0ebc6a2407a7e3893f9ffa6b0f5503f23a12e27cf089e139f48fb7e36e1451c2f2dc770b54d640a049c0149aac2a11f71931a56f269830edee2f2b8b9ab4b1d48a5f3b4a26907041f0e85b6a12fd7c4b4d20236cca47390119896f17118738e8d9c1d3df5ca698d084f3f1cf59408aa04c782bbd014b8ef21c71f0e5f1072e00b12395404fe39f1f25bf0816ec4fb5420bd6b35f68bce3cb9e633326323326323326f2664cb01913991913991913ffffcc18f8a31de9a72073dc09bcfae9f493d4620315fd7ebfcbe10a95b0bc52c82b7c645e69cb2b69a750d4625e493b19659a9657d0ba1f8c17f34aa20b265e618b792591991ef20afb98576e9c9f8df35c6ea191887a9088ba8f88ba9f883a47449d23a2ce88a87bbca269e2e7799a0a118879852de615b6985710adc42fa59805b873ff8f02821fb68040c53f4641c0971ee13c8119f567527ace8bf4923a085f7f3cf1cab6e650c08a0b3901b2b15c6748cf7887c81d5d51559c85792e0b0324f41c5f3e6a115860180239958c7af912e6259cb1730286de9662592f3d793c2d1cc8e7563a1bcb26fbd552c3ca71d9bc5c97045fe4d2220cde7f846403249f552c13e37d32c11281a2f02c65c01698c6f803733be86f6195a5666b5a842b9f6d63b457c364aca6c6b05e487511c77d12122c378e5194a20e3c13dc6508271d9c7c06380b70e900002d3ca5d0339365ca230bad786a946b2e8584ca29b4bf1257556c51ef69692b7ab6f409b9b7c6a857d3f910c5ca876819773ed6571fbd525020c44ba6c01143a5a7c57120d4d3f278a23a0f9d45d6a4610bb2d0a08a46ed8c3c5eb64112c57c3ec77c0a8225725718176130ec22260f036dfce081cc42084b6f2e73d59579e4452ea60fe6916af3897f6b8e708c07591d40ba9c2513c6b715ddbb555f1651e0c0dc4bf4bc918728bc047a5c2b844b4260bb9a0bc95d88fa6db548bbdc03f7848947f7a6b24c9f869f10059d48092f55fa5de8d29c6f28cc3734161220dfd024b8da0aafd1906c70111bf305a01da40455dd5b8b8d68dd1a3008ef654012269aa7fa0f4c7110c51fa9455ba7203ee250bfc0f54f8cf83d0ac35d44bfd566070f2ba5413440cfcec8e754d1eee08fdbaca24da837b0e41edc50cdee60b1ff8c185030c28372bf8fa127e1e9712a9d4ca2e093025095077b394742dd72855e2e31e85dfab6c4e712b5dcab51f7b9868da5ef9a2d77eed20719ebd5ac4d93396dbace69d31989ea74d390e60d36fee479da3874fe8d541e33e007edfc725e6fc0e5817e67e6088b6e81d1570a482b0de62698548b0371c539c407156cc87339cc661baad80d55bedf0d552cf0f7da906fdd78b27e579057fb6e64ec46c603830ab94115479fca26210156d602a6119d19c4d5027e54aa2344aa1153c0d243fc12b2deb0a3f76b19f5fb3834cb44a9ac9aee5baa60b5d91ba8347b6364167cab76a0e2dbf923e60320d09f0aeb4fc1c536b46d1d1f1aa515b11789f74e91161a3c7f001f04662c1eb55ec5907c33d631cafbb95f2441aedeef81750fb0de1fd01ab1a000043fdcc26a0c92bf9514f0ea4017cbed5ebad04a4610431131172de1575a4944f6d51439e3f7d28319fb5a5ca72c3106cd25c9832d534a55273df79840c5df265144d22e2abd0fc259a41388c88c505a1e99c814e915aa728187f1a2a9ea4a67629acb235ece77fe95a672eb482e87206fa3e920900e00f9546b2327aa23d414940936e7ec55c0559213f5c989fae844b1c614a2346bac61ac73a261ae709204985868f6a31a6bb6af61078a050a3cbaba992be830a1df01ba9bd0567812ed18a291a02319433432a4881344c890080f32a1131882f73dc07d45fbad8f3cd8b2ef00dec77765c6a0b8b80e0c290f32c4674a07b0afc852bb48e5352ceb47f40aa93de21852a03a136cad80a4023d8a9808b88ed0958204974e349f677161683b6931297d7c2389084230b6ac9cf887812e023775af64d58b0934c7041e12d9850558074face678f6036671ad42cb2995e052bf2d6126de60f4909d2b59ffed58093211a698875105130287eb51ff49a2fc79e098bf86e1041eef50b54ea7de5a821214423cc1fe19855063b5cf737834b6fd0e84179aac02ca011a22102c9488110cfc7abba9b436df17eea5eae54210a25091b71060452d30c5f96ac47a00f60d621889c211303b8bd88162c72736928a8c1cdd48e8c5131b61e529274d12456f0b970f25cae65626ef16124a5b06ddca62bb25ab8a765002617bd2f620b1e6dce8c09479142322dc68117c584562cd04ac15ed3487a41445954bda864978290964b88c615581c32a8fc3aa112e95c2042c9c01dbbdc0d9adb0dfeee17a133e3aa50b0a64f7b6b2dd1339bb271d3c995adfa959c1da3d7f50cd34135c56a9b84b1bda6203c1ad7cc44b75dcd06aa329b362947125657c632b909f93140ff2fe55a67a18796bab1d83b19b57f5d855bb436fbe2d35c1a12ad6a909877456d3cf520f8d6ffaaca6cc5b4d327099d5c403b75eeae1a1d524e78f02aaa9eccc5693b206fffef870f4564981dae059f1f311d9daa0144ccfcdceb142fba7dcb1dd26d7ce6e1c4c61149f875cdcb5b38da03114b9b86b67cf0e3a1e0a7afb50d095a1a0770e056d86821e1b0aba3614f4eea1a0c78782de3314f4e450d0d70d05bdeedad966e01779ed6c330ddfe8dad9bb7f588aa090be90052387f00ecff72862b2077d4f6d624c375c8e3fb01c1f97e3b3319da254c95d7549e32adfb0cba290eca2195e2f20bcfd975c7cbcac125ad3ebf319329ee361a483f23b622fb71429727d9c2fb7f01215df2e29e2e596c04474b925a0cb2d454c2020cb33015e6ee10b4198faf65d6e19314524e4888375cb1f41333982fbc269d75d6e51ee728b7257f420788287c12b7a459b47e244015282e7e38c9503edfc65354bb4812b6bda5e59ab708bafac51910410845c21f917a049814b243e5f23937bf51bb83a725be6d3e2563c995dc1fa8cd69e3b51f9a191843e1120defb96f7619ef7853cef43e67d21c7fbf06278ef9b1079ef3b58b7609f2a0896f7e145f13edc80f761c67b9f79cff30dcf7b7b7df5da8c934f4aadfb0fef39d5d41cad419c37b9f8101f830bbab3c05f19303e1eb0fbf680dddd23e07b8a367cada9f12478881282cd61dcc5c3c01dcc2b4ae928c0854e886ebff3888b6ed9500ab4b304ea818bc04a85cbed62caedb6d2e93c7f7fe0bb5cf0d6039be36f03d0e5034ef62813d2f7e3c534102f5824c8d8ed90bc841dae73b7af155b739749c4ba0b2c1e965f140ab5cc59746913c0c0decda5109ec91b10917238c38d71fa034120271b3e4695778cbafb0a01de2b6198529e14d19725152d546eff5c8f30f21a1573fec7bbf670d7dee6bbd61bed5ab30f5cbf6bddbfebd8e5731e17721c46bd314639e094ed9ee3378c0e30f93216084aa55834aa78cb63d3fe134aba9c860ac474ed234d5a894d1d6bad6b949882d695622c95c77750155ea0ec8a9e58f085127733a6a66a341cd25d7902e5fcf88e848aeb78aa2f68d6e81eddbb48bd5e0a51bd5e4029747218b21c4a5b14ba468df399c3334ebfe562a6dfb2f9f44edb43b40dde7a950f41a741e53ffa68a6f22106917e5fc6e465d7f8d72bcb40384613876826424e8607cdc42c64863d59a1c00ccb2868b2f038c6cbc570ebf7abd8930d6c9642404e57d32acdf9824cf2a07c01660101aff607c69ba0d203a8ec6533c884e25f198dfe77bd596285806c1fa60245d2a8480f556de540bf4076caaec0c715c0afe349b083eaef549e202766821d54d2b17319ff960de7dae0f431679515fd3f4af6832d0dcd01a91ab00e2fd47dd81e791bfad205872b549fdd9efbf2852af1a997d7eef1d6551436ce76f84ae146b6d58beba3fda69a8e6ce9d631577fec999aa09bf264150ff22188c0e2944775405745aeb4e835bbef7c71cae3aa93aa0a7be21d71a1879221ba9748e76b92528fbdae4e17f365483c4681be12e52aef7bcc467c747cf29b5c9bf7d6b9b917b2366f0fb843b4e8eb6bf347ece1765f6d1eb396c905accd5baafa48556d2ff32701e1cb95fcf03598b301aada1aab8695155c309495cdfd5cd9dcb1cee87866b44f64828d52d400e9bb87d8b82e4bc51352c4d86f53a3f7fbb2d45f525f5f549f5cec15d5c7b9a8aeb8a84e211d45ff2a2b48abac20adb282b4e28234b7fa4bee931b94dc73a576e20c95daffe8773e3b766b59a6f7c167aed28e2374fadb9fbdef123cb747fec8ce86757689d23cb9d0abad031f6d6d1d39daabad7f5f9b42cab8d6645fe53dbb00edaaeff4ed9a8d8ad1f4151557959754952743deabcae3418d2dc303d222be26b92bf59de8905bf6b3339d775bc9a3ea7189cbea11ddaf85416f6ebd428a5781db464f01c8b900ed56c791a75ba4bd5d4bcbb2c967ee78c973c74b24bbb672aef86c490c6a80e4fd20767b7937ca7d6582a5d35d74f847feda8476c7adc3d98a70bdadd06c2b34db8a70d056a05de0fb1f7c99b9d5f327e18141150cf98b3e035e2b1c74cbf64b1ff06879566b51c97c904c7c595d58bb3ace5fe9c03331d8139fc5d0c5264e2b4576e53cee3d17f8608d9f4b74bb04268a8f2195c7d906dc44f77576090bb1d90c6260063130033d3fb7c84e4ad92574ca1e29597456667be8dc7b87ce3d3b74ee79373eefe6b319bebb0fb8c7f6aa31a3507bed552d11fdabc70710e745cea1a3462b32bbfcbc4509694fd6f80b59a40a052a596401b03ab08163f7dda58c81c8cdd61efa44243bea9d6cd195e4752242ae9788273311a138a39fecd4d52f28d4d52f2bf65a8e1517c50e2517c2ec7ebeb60ba876e563de8df078ebf0b0f1c4af39262a9e1b7d76342389a0afae3a111beba35e5eca72d453eba9a7d653af276eeefb1f0371d0792ae6bc0fbf2593bbe48ca4ae9030e2b7644998e99a204b5c0dcfca21e44bf43c5fee40eccc1de5ce7d576e2d2b5bc42bde482618bf3a836200c46b733c83be0cff144400de906274fe86430003ecb72cc0fce35d109fac2702e35776e8eb6d74b5cd435df0ca744b80bd1187c6907a1fa7c818298733611cee8e8dc5848dd75dfc0cefe297dba3ddccd8e5f53623dc73829f6fd3483e426672c61c32d386b73be7636cba09b1ed4f8263fabaafe92f6c44a78ed69b0b8d59d35936f58585e5997aa76156eac71aab626da97172a531d381978d767bb96d9a4be668f3646376fac8a94e63d5cc2c2fad76da6b339de5b6e8cc35ccf2120fe33f776366ea4b4bcb1d73a401ad059c61b6d9066c0ba784fb49dffa88882e78f609ff3c0ee06bd4174dbdd3692cae7478556f6a376949ab1d83b33496664551d83fc3033861a51d93fd359e6b8d58692f77966796178c1bd35c35b890de5fece13f80a5e09f7e76f30a5cab0fff02f8b77ca405dbc101ab0c00c3db7520c634b6794ea0d8e2da42a739dd5c9a6d9c144c1ffc9b40cda563d978612935032f6046c6bb8ab09dfa9105e8386aeaf07eaed1469277dab091f5932f2ecf368f9eda645e3b811d735113f05f1d6a3b2ececcd5978e0135dacdc57afb94996f9c326f9a6b2c5994b89bfa9245bc294171dffdf43cd6e80811022d0bf06f04fe15e15f24f04fb108d15c3a515f68ce9a13f576b3be847bc2ad3c1ba1045b1b795f4d00d7ff019e55743300d007000082010101002071c6cbdee3f4d6824fb9876d6362d085242ac20ad2e5cff92667c7f9a21e805874361f0f0af17fbbb704e35533a3678c5f59434140ff314085ad604beb1fb0640100e60778da8d563b8f1c4510eedd9d7ddcae7d3a0ecc710e088c482c197c6bb33a99e408480808784487197aa76b775a3bd33374f7ecde424c6048909c1909590881838bce897510589b22216170c023003290f80f54cfccceebb8e53a984755757557d5575f77fb8fdebb0df2f2cfd66d82a3661ee4efab6f9bd703e7685112dcfba7dfbfbdb994dcda5c8740f1e0c60d3ae42feebcd0af6d0dbdc099d88a8f0517639b46da0d24d7f34b532a3915da3e456f4faf6e77d089ed52e5927a3398099096a03e5846d2735c70262af2fb2f0d3ad4d17c4a3590dafa08a88e24d88c8f41e9a2d55ae69a586bda95a0dcc063ad880b7dad6f4d60aecee1c39e011fbb7aff263a75824868b51d82f4b9c2a084edc114bccca439a35cabf3e699c92e9e1e0ea99f61d90bf17cc7a55cd8219518ae06a9c8134ffaf4204d95006d478a8e217632b87e515339065dd5daa1a3d365b6cd642da95026531847d9c5b5feb343aa7002c895561bb96f0f6046e7a9fc3927101a0eb43d926032afe2c415762222ffaca60c446a5a88d809a3d246ca1167da5511575d6cfb98e05506cf543d787c049afb59ca188c404a60687460c341c8258ded665cb060965a5da87a61e065797bda28b9f0b8003b552bfec17281ad935a06a17663f5ce204e4f0eafa2aae750e180172f45eaebc9df128d1b5538b7ccfe392bb64a17a722ee8c39a9b7d346887baf9bcf4efe73ec927a037fba6134f4b863e3672b91a79beae00e26b147abe4d1720206c9979e87c9574fc2fb1197e0c3725981704b26e174476293072919648f8421f22e6fc5ac00b9a01da05e0612fb5081600876cedaf1e6fabb1d946853c9e670ae419d48121210ba4bd7ac2661eb148620f582e5c9bc97d2b319ca80450e6e2aa7a9faf94c98459987731ab19ec3e42d0991ad64c4b6b13415a9592319f8b1ff96028dac5b297b03454966ba46ef711f89af52c835242b3bb669c6b4d4354d9dc4980a4c8b15056df465aa5f71d49afa06094d9398ddb5a93f4502c4ac25ff315c92ad6015754c918ad45ac9c77fb3a75927947c5a09aacd956dc489e34e6c143074d65198241679f0d4c9a2ecdfec46228372e37fa1dc8d4246d356b256b69209618977cbd8e7a5ee158e1852efc47f0a9c9428ca40dac083f8f2677828e7a722f9f6d6e5573ffaea95122f90bdef7eb977f8c56bc55ec77165d2f8fa93bc57c9dee7772eb107778a0d88e3f7471f3efe32eba74fdf1afc0aecf0b88c3c1c77c13f3cce50b6bc3e2c2146c8f7af1fbb478b22a470ec3dfff1d1228306210f1fbdf3e6fd45a1d838defb66fffe222b2b8edd1f509097d004f7f0af3f7f2ad62a0ed87be371b122e6267397fef8db4e830fae1392df37f0d673860b4a6dd5694ffe059b3958df0000 DMLOG START_BLOCK 5 DMLOG CREATION_OP ROOT 0 -DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304004,"value_ex":100468,"consumed":1},"cpu_usage":{"last_ordinal":1262304004,"value_ex":256961,"consumed":101},"ram_usage":199629} -DMLOG TRX_OP CREATE onblock 48f08a7ea5ea23750c7f9b142fb4bb947bb3fc73d42fc59f26339f2487773087 0000000000000000000000000000010000000000ea305500000000221acfa4010000000000ea305500000000a8ed3232b905033b3d4b0000000000ea30550000000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cdded9794b7e6d10923376031cef59e6d6d809ee653bcc37297cb644078a507a6bd26c416dc790f2b35815f1d6741bc63e1c235f13e809df666ddea0ba2e5f45c80000000000010000c104121a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b7241ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea994a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0fe0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff52668dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a297428ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c438ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a4052652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed25f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d4e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d674fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c2299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b4476707c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead450715443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b4bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e99d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb406bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc35c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b000000 -DMLOG APPLIED_TRANSACTION 5 48f08a7ea5ea23750c7f9b142fb4bb947bb3fc73d42fc59f26339f248777308705000000043b3d4b010000000596867aec674ebb58c23ffcafefab5119fdbdbb08736a63fbdc64e75101006400000000000000000000000000000000000000000001010000010000000000ea3055080cda2e60a87185264b067ea2e9e32dceeca3c6727a538c215223e312a9327d1a000000000000001a00000000000000010000000000ea30551a0000000000000002020000000000ea30550000000000ea305500000000221acfa4010000000000ea305500000000a8ed3232b905033b3d4b0000000000ea30550000000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cdded9794b7e6d10923376031cef59e6d6d809ee653bcc37297cb644078a507a6bd26c416dc790f2b35815f1d6741bc63e1c235f13e809df666ddea0ba2e5f45c80000000000010000c104121a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b7241ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea994a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0fe0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff52668dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a297428ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c438ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a4052652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed25f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d4e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d674fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c2299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b4476707c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead450715443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b4bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e99d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb406bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc35c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b0000000000000000000048f08a7ea5ea23750c7f9b142fb4bb947bb3fc73d42fc59f26339f248777308705000000043b3d4b010000000596867aec674ebb58c23ffcafefab5119fdbdbb08736a63fbdc64e7510000000000000000 +DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304004,"value_ex":101209,"consumed":1},"cpu_usage":{"last_ordinal":1262304004,"value_ex":268536,"consumed":101},"ram_usage":199629} +DMLOG TRX_OP CREATE onblock 0ade48384338de601ffbb688f58852a52cf6521566de6b975ca79fe2468d120e 0000000000000000000000000000010000000000ea305500000000221acfa4010000000000ea305500000000a8ed3232d905033b3d4b0000000000ea30550000000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b5dafd0f0596077e5010e7d7876a42e26a54669cb6ab0f1f073bf87b3d88a3043bc48e1625ffa8c398daca7e3f8bd15d4b2e191b8fa7d72547f72e57668630f3430000000000010000e104131a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b7241ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea994a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0fe0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff52668dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a297428ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c438ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a4052652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed25f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d4e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d674fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c2299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b4476707c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead450715443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b4bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e99d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb406bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc35c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b98c4175db53ed27e7911a1b5adf0e7db0fc96c2cae172cf594dfa9a742ca9e88000000 +DMLOG APPLIED_TRANSACTION 5 0ade48384338de601ffbb688f58852a52cf6521566de6b975ca79fe2468d120e05000000043b3d4b010000000551fa877e4307b47a58bb19e36497ab2df3119c5c9cc1b9d80c307b5f01006400000000000000000000000000000000000000000001010000010000000000ea3055356768ae7dd9c5cb13c0d9456d144417f7a4834c9f71ebbc935a749e6f52cd861b000000000000001b00000000000000010000000000ea30551b0000000000000002020000000000ea30550000000000ea305500000000221acfa4010000000000ea305500000000a8ed3232d905033b3d4b0000000000ea30550000000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b5dafd0f0596077e5010e7d7876a42e26a54669cb6ab0f1f073bf87b3d88a3043bc48e1625ffa8c398daca7e3f8bd15d4b2e191b8fa7d72547f72e57668630f3430000000000010000e104131a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b7241ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea994a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0fe0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff52668dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a297428ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c438ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a4052652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed25f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d4e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d674fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c2299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b4476707c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead450715443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b4bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e99d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb406bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc35c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b98c4175db53ed27e7911a1b5adf0e7db0fc96c2cae172cf594dfa9a742ca9e88000000000000000000000ade48384338de601ffbb688f58852a52cf6521566de6b975ca79fe2468d120e05000000043b3d4b010000000551fa877e4307b47a58bb19e36497ab2df3119c5c9cc1b9d80c307b5f0000000000000000 DMLOG CREATION_OP ROOT 0 DMLOG PERM_OP INS 0 9 {"usage_id":8,"parent":0,"owner":"alice","name":"owner","last_updated":"2020-01-01T00:00:02.000","auth":{"threshold":1,"keys":[{"key":"EOS6JvuLaCqV8qHbSqUBVRPMo9N7V3vgE8YqHmweG568YmTDJ3opq","weight":1}],"accounts":[{"permission":{"actor":"alice","permission":"eosio.code"},"weight":1}],"waits":[]}} DMLOG PERM_OP INS 0 10 {"usage_id":9,"parent":9,"owner":"alice","name":"active","last_updated":"2020-01-01T00:00:02.000","auth":{"threshold":1,"keys":[{"key":"EOS8d5yGFrYpdXW1SUmaavRZKm5X7Bp9jK634JABCYPciwTkm7Wv2","weight":1}],"accounts":[{"permission":{"actor":"alice","permission":"eosio.code"},"weight":1}],"waits":[]}} DMLOG RLIMIT_OP ACCOUNT_LIMITS INS {"owner":"alice","net_weight":-1,"cpu_weight":-1,"ram_bytes":-1} DMLOG RLIMIT_OP ACCOUNT_USAGE INS {"owner":"alice","net_usage":{"last_ordinal":0,"value_ex":0,"consumed":0},"cpu_usage":{"last_ordinal":0,"value_ex":0,"consumed":0},"ram_usage":0} DMLOG RAM_OP 0 alice account add newaccount alice 2788 2788 -DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304004,"value_ex":101811,"consumed":233},"cpu_usage":{"last_ordinal":1262304004,"value_ex":268536,"consumed":2101},"ram_usage":199629} -DMLOG APPLIED_TRANSACTION 5 2094445d3eb371d7749b54a150f9f9a77644cc551495428fb4f40e0671d755af05000000043b3d4b010000000596867aec674ebb58c23ffcafefab5119fdbdbb08736a63fbdc64e7510100d00700001d0000000000000000e8000000000000000001010000010000000000ea30554895e298f1f3e56596649fb49ff53d0f76174ef57ef7c50f28152765cef1f97f1b000000000000001b00000000000000010000000000ea30551b0000000000000002020000000000ea30550000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed32328a010000000000ea30550000000000855c3401000000010002bb30f6894f29bb6fca635b1df728ad77e48fdd6123ce5e4455b0f71e072e7df80100010000000000855c3400804a1401ea305501000001000000010003ebcf44b45a71d4f225768f602d1e2e2b25ef779ee9897fe744bf1a16e85423d50100010000000000855c3400804a1401ea3055010000000000000000000000002094445d3eb371d7749b54a150f9f9a77644cc551495428fb4f40e0671d755af05000000043b3d4b010000000596867aec674ebb58c23ffcafefab5119fdbdbb08736a63fbdc64e751010000000000855c34e40a00000000000000000000000000 +DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304004,"value_ex":102552,"consumed":233},"cpu_usage":{"last_ordinal":1262304004,"value_ex":280111,"consumed":2101},"ram_usage":199629} +DMLOG APPLIED_TRANSACTION 5 d2f164badf90bb8b9e827bd924baf8168dd8f207ecc205f5b43310ef86253aa405000000043b3d4b010000000551fa877e4307b47a58bb19e36497ab2df3119c5c9cc1b9d80c307b5f0100d00700001d0000000000000000e8000000000000000001010000010000000000ea30554895e298f1f3e56596649fb49ff53d0f76174ef57ef7c50f28152765cef1f97f1c000000000000001c00000000000000010000000000ea30551c0000000000000002020000000000ea30550000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed32328a010000000000ea30550000000000855c3401000000010002bb30f6894f29bb6fca635b1df728ad77e48fdd6123ce5e4455b0f71e072e7df80100010000000000855c3400804a1401ea305501000001000000010003ebcf44b45a71d4f225768f602d1e2e2b25ef779ee9897fe744bf1a16e85423d50100010000000000855c3400804a1401ea305501000000000000000000000000d2f164badf90bb8b9e827bd924baf8168dd8f207ecc205f5b43310ef86253aa405000000043b3d4b010000000551fa877e4307b47a58bb19e36497ab2df3119c5c9cc1b9d80c307b5f010000000000855c34e40a00000000000000000000000000 DMLOG CREATION_OP ROOT 0 DMLOG PERM_OP INS 0 11 {"usage_id":10,"parent":10,"owner":"alice","name":"test1","last_updated":"2020-01-01T00:00:02.000","auth":{"threshold":1,"keys":[],"accounts":[{"permission":{"actor":"eosio","permission":"active"},"weight":1}],"waits":[]}} DMLOG RAM_OP 0 11 auth add updateauth_create alice 3108 320 DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"alice","net_usage":{"last_ordinal":1262304004,"value_ex":834,"consumed":144},"cpu_usage":{"last_ordinal":1262304004,"value_ex":11575,"consumed":2000},"ram_usage":3108} -DMLOG APPLIED_TRANSACTION 5 6cdc68c8257e32da2f6cd8c4f6e6bb7798a47e7da6ac14a7cea45da9cd70c81c05000000043b3d4b010000000596867aec674ebb58c23ffcafefab5119fdbdbb08736a63fbdc64e7510100d007000012000000000000000090000000000000000001010000010000000000ea3055f3d881d2f7fbf2f7cb6081aff84e7aca1dd3914a0948ef4fc9422e734e8d4d571c000000000000001c00000000000000010000000000855c34010000000000000002020000000000ea30550000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c34000000008090b1ca00000000a8ed32320100000000010000000000ea305500000000a8ed3232010000000000000000000000006cdc68c8257e32da2f6cd8c4f6e6bb7798a47e7da6ac14a7cea45da9cd70c81c05000000043b3d4b010000000596867aec674ebb58c23ffcafefab5119fdbdbb08736a63fbdc64e751010000000000855c34400100000000000000000000000000 -DMLOG RLIMIT_OP STATE UPD {"average_block_net_usage":{"last_ordinal":4,"value_ex":144011111,"consumed":7999},"average_block_cpu_usage":{"last_ordinal":4,"value_ex":366368114,"consumed":4433},"pending_net_usage":376,"pending_cpu_usage":4100,"total_net_weight":0,"total_cpu_weight":0,"total_ram_bytes":0,"virtual_net_limit":1051726,"virtual_cpu_limit":200600} -DMLOG RLIMIT_OP STATE UPD {"average_block_net_usage":{"last_ordinal":5,"value_ex":145944352,"consumed":519},"average_block_cpu_usage":{"last_ordinal":5,"value_ex":397481713,"consumed":4464},"pending_net_usage":0,"pending_cpu_usage":0,"total_net_weight":0,"total_cpu_weight":0,"total_ram_bytes":0,"virtual_net_limit":1052778,"virtual_cpu_limit":200800} -DMLOG ACCEPTED_BLOCK 5 05000000050000000400000000000000010000000000ea3055000100000001000240e54a7b27e042b80a810153bec1dd166eef95fa69f6c9886ae283363bc2add80100018b5b706080c8d5ec9456986e611761b17ec82e672f8176e581625f54535c32150400000000000000010000000000ea305505000000010000000000ea305504000000000100000001000240e54a7b27e042b80a810153bec1dd166eef95fa69f6c9886ae283363bc2add80100000000000596867aec674ebb58c23ffcafefab5119fdbdbb08736a63fbdc64e751043b3d4b0000000000ea30550000000000044444a224a7e16ae04e24e6640d6a909fb89ca6e5e8c1e5397e1e03ef08a40bd5b3162bbbe3fb5d540dabc705bada65dd0a276381665c9ed73d4afa451bb28b302f397e60628e8e3a7d3ecb23a8a0bf20f606dd26b93b61511cb87673000000000000001f69207fd55ddaddad96457d633a97f216211989106548974158e1cf70d1f8e5e5262d674a40041040cf394ae3496bb3852b67e15d9c771dfb4a818f6166f590a90000000029807708239aa7de914d3ed61e9009ab2280bfbc50f1d9769f27f8341ef26198000000000001130ec7e080177b2c02b278d5088611686b49d739925a92d9bfcacd7fc6b74053bd1a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b72412652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed25299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b447670735c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b4a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0f4e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d674fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c25443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b468dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a2974286bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc8ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a405ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c43bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e99c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead45071d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb40e0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff526ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea99f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d0001043b3d4b0000000000ea30550000000000044444a224a7e16ae04e24e6640d6a909fb89ca6e5e8c1e5397e1e03ef08a40bd5b3162bbbe3fb5d540dabc705bada65dd0a276381665c9ed73d4afa451bb28b302f397e60628e8e3a7d3ecb23a8a0bf20f606dd26b93b61511cb87673000000000000001f69207fd55ddaddad96457d633a97f216211989106548974158e1cf70d1f8e5e5262d674a40041040cf394ae3496bb3852b67e15d9c771dfb4a818f6166f590a90200d00700001d0101001f55be758d9f4e3d253e069c66875beafbffe405c897ee2da2dd4577b2953a3379758676fd8906c5c3eb7043a30dc8d939af3eef5e73bf7f57f253e854f803dd810000bd0107e10b5e0400a7e16ae000000000010000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed32328a010000000000ea30550000000000855c3401000000010002bb30f6894f29bb6fca635b1df728ad77e48fdd6123ce5e4455b0f71e072e7df80100010000000000855c3400804a1401ea305501000001000000010003ebcf44b45a71d4f225768f602d1e2e2b25ef779ee9897fe744bf1a16e85423d50100010000000000855c3400804a1401ea30550100000000d0070000120101001f504584a3e50ad7d75a7ffd3254fbd363824a5269d57a1d3443644067e42117515242fb12efe17be14590b398489b951a8823f8b5aed4d7de11be3a971498ddb100006307e10b5e0400a7e16ae000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c34000000008090b1ca00000000a8ed32320100000000010000000000ea305500000000a8ed3232010000000000 +DMLOG APPLIED_TRANSACTION 5 530de341efeac006a43329e4748583c9ef216a164c70c7b46a8e93042c45cd8a05000000043b3d4b010000000551fa877e4307b47a58bb19e36497ab2df3119c5c9cc1b9d80c307b5f0100d007000012000000000000000090000000000000000001010000010000000000ea3055f3d881d2f7fbf2f7cb6081aff84e7aca1dd3914a0948ef4fc9422e734e8d4d571d000000000000001d00000000000000010000000000855c34010000000000000002020000000000ea30550000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c34000000008090b1ca00000000a8ed32320100000000010000000000ea305500000000a8ed323201000000000000000000000000530de341efeac006a43329e4748583c9ef216a164c70c7b46a8e93042c45cd8a05000000043b3d4b010000000551fa877e4307b47a58bb19e36497ab2df3119c5c9cc1b9d80c307b5f010000000000855c34400100000000000000000000000000 +DMLOG RLIMIT_OP STATE UPD {"average_block_net_usage":{"last_ordinal":4,"value_ex":145068889,"consumed":8000},"average_block_cpu_usage":{"last_ordinal":4,"value_ex":382895892,"consumed":4449},"pending_net_usage":376,"pending_cpu_usage":4100,"total_net_weight":0,"total_cpu_weight":0,"total_ram_bytes":0,"virtual_net_limit":1051726,"virtual_cpu_limit":200600} +DMLOG RLIMIT_OP STATE UPD {"average_block_net_usage":{"last_ordinal":5,"value_ex":146993315,"consumed":520},"average_block_cpu_usage":{"last_ordinal":5,"value_ex":413871759,"consumed":4480},"pending_net_usage":0,"pending_cpu_usage":0,"total_net_weight":0,"total_cpu_weight":0,"total_ram_bytes":0,"virtual_net_limit":1052778,"virtual_cpu_limit":200800} +DMLOG ACCEPTED_BLOCK 5 05000000050000000400000000000000010000000000ea3055000100000001000240e54a7b27e042b80a810153bec1dd166eef95fa69f6c9886ae283363bc2add8010001b2cd0fd8d0aeb0983cf5b79b35e97f42f204914726c831b95c1ff896ca7cc1f70400000000000000010000000000ea305505000000010000000000ea305504000000000100000001000240e54a7b27e042b80a810153bec1dd166eef95fa69f6c9886ae283363bc2add80100000000000551fa877e4307b47a58bb19e36497ab2df3119c5c9cc1b9d80c307b5f043b3d4b0000000000ea305500000000000446ce40fcba331770d4e40c1a69d054d3a9a5ed89ef08b50cc808e32529e6fd108fe2b5c29c60c4d10b3bcd6dd68fbbaeb8eda2417ea361750429ed07182c0649523b9bcbb941da3c9ba69b7fdd2a061be2e8e19bd532c4532c674074000000000000001f64905c5f3f6b6fea6be1479d459f26f49dabe66f6452d029b4aac534bdae794a5bc74c010be03a9ac8bcd1af835910bff6619dcc993a6b3cda9ef986372bcf900000000029807708239aa7de914d3ed61e9009ab2280bfbc50f1d9769f27f8341ef26198000000000001140ec7e080177b2c02b278d5088611686b49d739925a92d9bfcacd7fc6b74053bd1a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b72412652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed25299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b447670735c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b4a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0f4e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d674fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c25443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b468dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a2974286bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc8ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a40598c4175db53ed27e7911a1b5adf0e7db0fc96c2cae172cf594dfa9a742ca9e88ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c43bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e99c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead45071d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb40e0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff526ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea99f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d0001043b3d4b0000000000ea305500000000000446ce40fcba331770d4e40c1a69d054d3a9a5ed89ef08b50cc808e32529e6fd108fe2b5c29c60c4d10b3bcd6dd68fbbaeb8eda2417ea361750429ed07182c0649523b9bcbb941da3c9ba69b7fdd2a061be2e8e19bd532c4532c674074000000000000001f64905c5f3f6b6fea6be1479d459f26f49dabe66f6452d029b4aac534bdae794a5bc74c010be03a9ac8bcd1af835910bff6619dcc993a6b3cda9ef986372bcf900200d00700001d0101001f281f9a1a1c1db3802dcc9722bc82373b1b7e5e02ee3c23555be869da51384317257214aaabf8797fe97ff3d5c7366353d197575f7ad7dc07b8f6b48f251b39ce0000bd0107e10b5e0400ba33177000000000010000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed32328a010000000000ea30550000000000855c3401000000010002bb30f6894f29bb6fca635b1df728ad77e48fdd6123ce5e4455b0f71e072e7df80100010000000000855c3400804a1401ea305501000001000000010003ebcf44b45a71d4f225768f602d1e2e2b25ef779ee9897fe744bf1a16e85423d50100010000000000855c3400804a1401ea30550100000000d0070000120101001f111f9dacd4b0ca94c80782ea19e40bccd1d211a4ef502ce83a27752116ccd86f1063361a90577bd5654df73be79ba08d45a08d786975c9b93ef6f249558beca000006307e10b5e0400ba33177000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c34000000008090b1ca00000000a8ed32320100000000010000000000ea305500000000a8ed3232010000000000 From 7159dc2934ab5aa7efc349d49e8ae38ebd575e17 Mon Sep 17 00:00:00 2001 From: mschoenebeck Date: Thu, 15 Jun 2023 02:14:52 -0500 Subject: [PATCH 17/79] updated bls module --- libraries/libfc/libraries/bls12-381 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/libfc/libraries/bls12-381 b/libraries/libfc/libraries/bls12-381 index d8c21132eb..f59a612b4b 160000 --- a/libraries/libfc/libraries/bls12-381 +++ b/libraries/libfc/libraries/bls12-381 @@ -1 +1 @@ -Subproject commit d8c21132ebb6f0f13aa36286f794f344ea33992c +Subproject commit f59a612b4b9c5f12451cf16d1fd61ae492d38c3c From 1ca23730b0cf97c0c494210d810c10f8ad2cb9e1 Mon Sep 17 00:00:00 2001 From: mschoenebeck Date: Fri, 16 Jun 2023 01:27:26 -0500 Subject: [PATCH 18/79] updated bls lib --- libraries/libfc/libraries/bls12-381 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/libfc/libraries/bls12-381 b/libraries/libfc/libraries/bls12-381 index f59a612b4b..e43561f9bd 160000 --- a/libraries/libfc/libraries/bls12-381 +++ b/libraries/libfc/libraries/bls12-381 @@ -1 +1 @@ -Subproject commit f59a612b4b9c5f12451cf16d1fd61ae492d38c3c +Subproject commit e43561f9bd036123be81c73372e05016048c8618 From 0d3203ba2e2cc9896ee55c944794c150de732c38 Mon Sep 17 00:00:00 2001 From: mschoenebeck Date: Tue, 27 Jun 2023 18:09:53 -0500 Subject: [PATCH 19/79] added optional return values (instead of throwing exceptions) and enabled checks in 'pairing' and 'map' functions --- libraries/chain/webassembly/crypto.cpp | 64 +++++++++++++++--------- libraries/libfc/libraries/bls12-381 | 2 +- libraries/libfc/test/crypto/test_bls.cpp | 4 +- 3 files changed, 44 insertions(+), 26 deletions(-) diff --git a/libraries/chain/webassembly/crypto.cpp b/libraries/chain/webassembly/crypto.cpp index 937e2fe298..baff2374e9 100644 --- a/libraries/chain/webassembly/crypto.cpp +++ b/libraries/chain/webassembly/crypto.cpp @@ -255,9 +255,11 @@ namespace eosio { namespace chain { namespace webassembly { { if(op1.size() != 144 || op2.size() != 144 || result.size() != 144) return return_code::failure; - bls12_381::g1 a = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(op1.data()), 144}, false, true); - bls12_381::g1 b = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(op2.data()), 144}, false, true); - bls12_381::g1 c = a.add(b); + std::optional a = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(op1.data()), 144}, false, true); + std::optional b = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(op2.data()), 144}, false, true); + if(!a.has_value() || !b.has_value()) + return return_code::failure; + bls12_381::g1 c = a.value().add(b.value()); c.toJacobianBytesLE({reinterpret_cast(result.data()), 144}, true); return return_code::success; } @@ -266,9 +268,11 @@ namespace eosio { namespace chain { namespace webassembly { { if(op1.size() != 288 || op2.size() != 288 || result.size() != 288) return return_code::failure; - bls12_381::g2 a = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(op1.data()), 288}, false, true); - bls12_381::g2 b = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(op2.data()), 288}, false, true); - bls12_381::g2 c = a.add(b); + std::optional a = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(op1.data()), 288}, false, true); + std::optional b = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(op2.data()), 288}, false, true); + if(!a.has_value() || !b.has_value()) + return return_code::failure; + bls12_381::g2 c = a.value().add(b.value()); c.toJacobianBytesLE({reinterpret_cast(result.data()), 288}, true); return return_code::success; } @@ -277,9 +281,11 @@ namespace eosio { namespace chain { namespace webassembly { { if(point.size() != 144 || scalar.size() != 32 || result.size() != 144) return return_code::failure; - bls12_381::g1 a = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(point.data()), 144}, false, true); + std::optional a = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(point.data()), 144}, false, true); + if(!a.has_value()) + return return_code::failure; std::array b = bls12_381::scalar::fromBytesLE<4>({reinterpret_cast(scalar.data()), 32}); - bls12_381::g1 c = a.mulScalar(b); + bls12_381::g1 c = a.value().mulScalar(b); c.toJacobianBytesLE({reinterpret_cast(result.data()), 144}, true); return return_code::success; } @@ -288,9 +294,11 @@ namespace eosio { namespace chain { namespace webassembly { { if(point.size() != 288 || scalar.size() != 32 || result.size() != 288) return return_code::failure; - bls12_381::g2 a = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(point.data()), 288}, false, true); + std::optional a = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(point.data()), 288}, false, true); + if(!a.has_value()) + return return_code::failure; std::array b = bls12_381::scalar::fromBytesLE<4>({reinterpret_cast(scalar.data()), 32}); - bls12_381::g2 c = a.mulScalar(b); + bls12_381::g2 c = a.value().mulScalar(b); c.toJacobianBytesLE({reinterpret_cast(result.data()), 288}, true); return return_code::success; } @@ -305,14 +313,16 @@ namespace eosio { namespace chain { namespace webassembly { sv.reserve(n); for(uint32_t i = 0; i < n; i++) { - bls12_381::g1 p = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(points.data() + i*144), 144}, false, true); + std::optional p = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(points.data() + i*144), 144}, false, true); + if(!p.has_value()) + return return_code::failure; std::array s = bls12_381::scalar::fromBytesLE<4>({reinterpret_cast(scalars.data() + i*32), 32}); - pv.push_back(p); + pv.push_back(p.value()); sv.push_back(s); if(i%10 == 0) context.trx_context.checktime(); } - bls12_381::g1 r = bls12_381::g1::multiExp(pv, sv); + bls12_381::g1 r = bls12_381::g1::multiExp(pv, sv).value(); // accessing value is safe r.toJacobianBytesLE({reinterpret_cast(result.data()), 144}, true); return return_code::success; } @@ -327,14 +337,16 @@ namespace eosio { namespace chain { namespace webassembly { sv.reserve(n); for(uint32_t i = 0; i < n; i++) { - bls12_381::g2 p = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(points.data() + i*288), 288}, false, true); + std::optional p = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(points.data() + i*288), 288}, false, true); + if(!p.has_value()) + return return_code::failure; std::array s = bls12_381::scalar::fromBytesLE<4>({reinterpret_cast(scalars.data() + i*32), 32}); - pv.push_back(p); + pv.push_back(p.value()); sv.push_back(s); if(i%6 == 0) context.trx_context.checktime(); } - bls12_381::g2 r = bls12_381::g2::multiExp(pv, sv, [this](){ context.trx_context.checktime(); }); + bls12_381::g2 r = bls12_381::g2::multiExp(pv, sv, [this](){ context.trx_context.checktime(); }).value(); // accessing value is safe r.toJacobianBytesLE({reinterpret_cast(result.data()), 288}, true); return return_code::success; } @@ -347,9 +359,11 @@ namespace eosio { namespace chain { namespace webassembly { v.reserve(n); for(uint32_t i = 0; i < n; i++) { - bls12_381::g1 p_g1 = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(g1_points.data() + i*144), 144}, false, true); - bls12_381::g2 p_g2 = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(g2_points.data() + i*288), 288}, false, true); - bls12_381::pairing::add_pair(v, p_g1, p_g2); + std::optional p_g1 = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(g1_points.data() + i*144), 144}, true, true); + std::optional p_g2 = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(g2_points.data() + i*288), 288}, true, true); + if(!p_g1.has_value() || !p_g2.has_value()) + return return_code::failure; + bls12_381::pairing::add_pair(v, p_g1.value(), p_g2.value()); if(i%4 == 0) context.trx_context.checktime(); } @@ -362,8 +376,10 @@ namespace eosio { namespace chain { namespace webassembly { { if(e.size() != 48 || result.size() != 144) return return_code::failure; - bls12_381::fp a = bls12_381::fp::fromBytesLE({reinterpret_cast(e.data()), 48}, false, true); - bls12_381::g1 c = bls12_381::g1::mapToCurve(a); + std::optional a = bls12_381::fp::fromBytesLE({reinterpret_cast(e.data()), 48}, true, true); + if(!a.has_value()) + return return_code::failure; + bls12_381::g1 c = bls12_381::g1::mapToCurve(a.value()); c.toJacobianBytesLE({reinterpret_cast(result.data()), 144}, true); return return_code::success; } @@ -372,8 +388,10 @@ namespace eosio { namespace chain { namespace webassembly { { if(e.size() != 96 || result.size() != 288) return return_code::failure; - bls12_381::fp2 a = bls12_381::fp2::fromBytesLE({reinterpret_cast(e.data()), 96}, false, true); - bls12_381::g2 c = bls12_381::g2::mapToCurve(a); + std::optional a = bls12_381::fp2::fromBytesLE({reinterpret_cast(e.data()), 96}, true, true); + if(!a.has_value()) + return return_code::failure; + bls12_381::g2 c = bls12_381::g2::mapToCurve(a.value()); c.toJacobianBytesLE({reinterpret_cast(result.data()), 288}, true); return return_code::success; } diff --git a/libraries/libfc/libraries/bls12-381 b/libraries/libfc/libraries/bls12-381 index e43561f9bd..17c3dc17d8 160000 --- a/libraries/libfc/libraries/bls12-381 +++ b/libraries/libfc/libraries/bls12-381 @@ -1 +1 @@ -Subproject commit e43561f9bd036123be81c73372e05016048c8618 +Subproject commit 17c3dc17d87f051fe2689ea923ee8628487e1d31 diff --git a/libraries/libfc/test/crypto/test_bls.cpp b/libraries/libfc/test/crypto/test_bls.cpp index 3e8853a171..a67a9d9395 100644 --- a/libraries/libfc/test/crypto/test_bls.cpp +++ b/libraries/libfc/test/crypto/test_bls.cpp @@ -38,8 +38,8 @@ BOOST_AUTO_TEST_CASE(bls_serialization_test) try { cout << pk_string << std::endl; cout << signature_string << std::endl; - g1 pk2 = g1::fromJacobianBytesBE(hexToBytes(pk_string)); - g2 signature2 = g2::fromJacobianBytesBE(hexToBytes(signature_string)); + g1 pk2 = g1::fromJacobianBytesBE(hexToBytes(pk_string)).value(); + g2 signature2 = g2::fromJacobianBytesBE(hexToBytes(signature_string)).value(); bool ok = verify(pk2, message_1, signature2); BOOST_CHECK_EQUAL(ok, true); } FC_LOG_AND_RETHROW(); From 233ae01a92caf4160a905ccb00ac3c7bc55091df Mon Sep 17 00:00:00 2001 From: mschoenebeck Date: Wed, 28 Jun 2023 07:41:58 -0500 Subject: [PATCH 20/79] added unit tests for garbage io --- libraries/libfc/libraries/bls12-381 | 2 +- libraries/libfc/test/crypto/test_bls.cpp | 82 ++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-) diff --git a/libraries/libfc/libraries/bls12-381 b/libraries/libfc/libraries/bls12-381 index 17c3dc17d8..b5442c2f4d 160000 --- a/libraries/libfc/libraries/bls12-381 +++ b/libraries/libfc/libraries/bls12-381 @@ -1 +1 @@ -Subproject commit 17c3dc17d87f051fe2689ea923ee8628487e1d31 +Subproject commit b5442c2f4d73e77baeaebc2989c58ec62e175c3f diff --git a/libraries/libfc/test/crypto/test_bls.cpp b/libraries/libfc/test/crypto/test_bls.cpp index a67a9d9395..8d5fbbf538 100644 --- a/libraries/libfc/test/crypto/test_bls.cpp +++ b/libraries/libfc/test/crypto/test_bls.cpp @@ -133,5 +133,87 @@ BOOST_AUTO_TEST_CASE(bls_pop_verify) try { BOOST_CHECK_EQUAL(ok, true); } FC_LOG_AND_RETHROW(); +BOOST_AUTO_TEST_CASE(g1_add_garbage) try { + fp x({0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}); + g1 p({x, x, x}); + BOOST_CHECK_EQUAL(x.isValid(), false); + BOOST_CHECK_EQUAL(p.isOnCurve(), false); + BOOST_CHECK_EQUAL(p.inCorrectSubgroup(), false); + p = p.add(p); + BOOST_CHECK_EQUAL(p.isOnCurve(), false); + BOOST_CHECK_EQUAL(p.inCorrectSubgroup(), false); + g1 p_res = g1::fromJacobianBytesBE(hexToBytes<144>("0x16ebb8f4fc6d887a8de3892d7765b224e3be0f36357a686712241e5767c245ec7d9fc4130046ed883e31ec7d2400d69b02c2a8b22ceaac76c93d771a681011c66189e08d3a16e69aa7484528ffe9d89fbe1664fdff95578c830e0fbfc72447800ffc7c19987633398fa120983552fa3ecab80aa3bdcc0913014c80513279e56ce11624eaffddf5f82fa804b27016e591"), false, true).value(); + BOOST_CHECK_EQUAL(p.equal(p_res), true); +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_CASE(g2_add_garbage) try { + fp x({0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}); + g2 p({fp2({x, x}), fp2({x, x}), fp2({x, x})}); + BOOST_CHECK_EQUAL(x.isValid(), false); + BOOST_CHECK_EQUAL(p.isOnCurve(), false); + BOOST_CHECK_EQUAL(p.inCorrectSubgroup(), false); + p = p.add(p); + BOOST_CHECK_EQUAL(p.isOnCurve(), false); + BOOST_CHECK_EQUAL(p.inCorrectSubgroup(), false); + g2 p_res = g2::fromJacobianBytesBE(hexToBytes<288>("0x121776a6107dd86184188133433092b521527d235a298207529d4ca1679f9794cd3cb7b659cdccbfea32ada2d46fdf3ef7f0b08b6d3cfbad209ba461e8bdc55aadc7da5ac22f4e67b5a88062646f2ece0934d01ca6485f299f47cd132da484600df7cabe551c79ec8622ec6c73e03e2635ee50e36584b13b7f371b634bc00910932bd543a35b45dc33d90bc36d38c88202988dd47f01acf772efd5446c81949ebdc19ca53273a1f07a449b084faf4c8c329179e392dd49ffd4d0c81ce02ae50b35ef56f72b6d4b067b495bc80cfce0eb0d3e6d9aebea696b61e198f9b8bb2394ae2049e1c3c7ebf2d5590964e030cb27000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), false, true).value(); + BOOST_CHECK_EQUAL(p.equal(p_res), true); +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_CASE(g1_mul_garbage) try { + fp x({0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}); + g1 p({x, x, x}); + BOOST_CHECK_EQUAL(x.isValid(), false); + BOOST_CHECK_EQUAL(p.isOnCurve(), false); + BOOST_CHECK_EQUAL(p.inCorrectSubgroup(), false); + array s = {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}; + p = p.mulScalar(s); + BOOST_CHECK_EQUAL(p.isOnCurve(), false); + BOOST_CHECK_EQUAL(p.inCorrectSubgroup(), false); + g1 p_res = g1::fromJacobianBytesBE(hexToBytes<144>("0x0cf5e7694dd3cbfd944aa8a1412826451b247cc74148a1c289831a869c2bf644d8eacf23970af6d167fe0efe4e79b8b61183d39242b00320670c7474c28aeda64187e877d9972619702fc9459876563ea9f8054a4a22262a3566e3af5a4970510e9213062adcdd95878b09e3901d27f47b77a2dc03923eb313856cf2991eb7ec1f76d8da7a832bfc4db4735821ff9081"), false, true).value(); + BOOST_CHECK_EQUAL(p.equal(p_res), true); +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_CASE(g2_mul_garbage) try { + fp x({0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}); + g2 p({fp2({x, x}), fp2({x, x}), fp2({x, x})}); + BOOST_CHECK_EQUAL(x.isValid(), false); + BOOST_CHECK_EQUAL(p.isOnCurve(), false); + BOOST_CHECK_EQUAL(p.inCorrectSubgroup(), false); + array s = {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}; + p = p.mulScalar(s); + BOOST_CHECK_EQUAL(p.isOnCurve(), false); + BOOST_CHECK_EQUAL(p.inCorrectSubgroup(), false); + g2 p_res = g2::fromJacobianBytesBE(hexToBytes<288>("0x1203754ff2c1cd33f92b7fbad909540237721c0311f3935762719feca1d4e8d5006824434283611b87fadcc93b41b79318f1bb3b6a6ce403bfac295e096ea17a61d553fbed89f453a78232e88eab2767907eb9f75e9e325db106abd65f5de13d013ed4f63b9142ecdaf225888e13285adb14384fb623ce33a640e04dadcb38090f60d99767be09abe35b3c2337819e50038f9df049cbf0ee1c481560d7fe03be89e3fa68a5f69aab20a40ac2c522ecd89e5e5859753dfa4ecbde951b2e5ae732146f8f94d30becf0c33b7833728f9a0e8292f574d85fd1bf82fef8cb79ff1b5e6bf15e3000027fa9e9e6f670f956220b02fb798444358ffed2efa8999e5ffc27a57a08c8cc44c02ee47cc2ee4e535c046217196095c26de1f4a5ba9866c15c93"), false, true).value(); + BOOST_CHECK_EQUAL(p.equal(p_res), true); +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_CASE(g1_exp_garbage) try { + fp x({0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}); + g1 p({x, x, x}); + BOOST_CHECK_EQUAL(x.isValid(), false); + BOOST_CHECK_EQUAL(p.isOnCurve(), false); + BOOST_CHECK_EQUAL(p.inCorrectSubgroup(), false); + array s = {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}; + p = g1::multiExp({p}, {s}).value(); + BOOST_CHECK_EQUAL(p.isOnCurve(), false); + BOOST_CHECK_EQUAL(p.inCorrectSubgroup(), false); + g1 p_res = g1::fromJacobianBytesBE(hexToBytes<144>("0x181b676153b877407d2622e91af6057f5ff445f160c178517828841670debdd61957f8d5376ddeeb1ba0a204eb1eafb007f9d1417540591155acddd91f1fb9c97da24d6eecae002c50a779372dfc247efb1823e27abbdae09fb515f390e982311239b452c1ef85156c979f981ac69208f6fd0014fa9dd66a1999df7fa4a0a4234a4cc14ec62291fd3f924b8353b326b9"), false, true).value(); + BOOST_CHECK_EQUAL(p.equal(p_res), true); +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_CASE(g2_exp_garbage) try { + fp x({0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}); + g2 p({fp2({x, x}), fp2({x, x}), fp2({x, x})}); + BOOST_CHECK_EQUAL(x.isValid(), false); + BOOST_CHECK_EQUAL(p.isOnCurve(), false); + BOOST_CHECK_EQUAL(p.inCorrectSubgroup(), false); + array s = {0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF}; + p = g2::multiExp({p}, {s}).value(); + BOOST_CHECK_EQUAL(p.isOnCurve(), false); + BOOST_CHECK_EQUAL(p.inCorrectSubgroup(), false); + g2 p_res = g2::fromJacobianBytesBE(hexToBytes<288>("0x158a2a1e3ce68c49f9795908aa3779c6919ed5de5cbcd1d2a331d0742d1eb3cb28014006b5f686204adb5fdca73aea570ee0f0d58880907c8de5867dd99b6b7306b2c3de4a1537e6d042f2b8e44c8086853728cc246726016b0fcf993db3d759005f8ac0cb55113c857c5cf3f83d9b624ce9a2a0a00a1206777cf935721c857b322a611ed0703cf3e922bfb8b19a1f5e10a341b2191ab5a15d35f69850d2adb633e5425eecb7f38dd486a95b3f74d60f3ee6cf692b3c76813407710630763f7605b3828c19203f661732a02f7f546ab354694128bbe5a792a9db4a443c0fe10af0df2bc1b8d07aee99bd6f8c6b26847011aa31634f42f722d52022c736369db470576687fdf819cf15a0db4c01a0bd7028ee17cefdf6d66557d47fb725b6d00f"), false, true).value(); + BOOST_CHECK_EQUAL(p.equal(p_res), true); +} FC_LOG_AND_RETHROW(); + BOOST_AUTO_TEST_SUITE_END() From 76e4fd9dd6b4ac72d6a766a46567364fb995e8d2 Mon Sep 17 00:00:00 2001 From: mschoenebeck Date: Fri, 30 Jun 2023 08:47:09 -0500 Subject: [PATCH 21/79] added bls lib to EosioTester to make CDT integration tests work --- CMakeModules/EosioTester.cmake.in | 2 ++ CMakeModules/EosioTesterBuild.cmake.in | 2 ++ 2 files changed, 4 insertions(+) diff --git a/CMakeModules/EosioTester.cmake.in b/CMakeModules/EosioTester.cmake.in index a12004f73f..72c8442384 100644 --- a/CMakeModules/EosioTester.cmake.in +++ b/CMakeModules/EosioTester.cmake.in @@ -55,6 +55,7 @@ find_library(libchain eosio_chain @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH) find_library(libfc fc @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH) find_library(libsecp256k1 secp256k1 @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH) find_library(libbn256 bn256 @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH) +find_library(libbls12-381 bls12-381 @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH) find_library(libwasm WASM @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH) find_library(libwast WAST @CMAKE_INSTALL_FULL_LIBDIR@ NO_DEFAULT_PATH) @@ -92,6 +93,7 @@ macro(add_eosio_test_executable test_name) ${libbuiltins} ${libsecp256k1} ${libbn256} + ${libbls12-381} @GMP_LIBRARY@ ${Boost_FILESYSTEM_LIBRARY} diff --git a/CMakeModules/EosioTesterBuild.cmake.in b/CMakeModules/EosioTesterBuild.cmake.in index aa67d25595..2874eb800c 100644 --- a/CMakeModules/EosioTesterBuild.cmake.in +++ b/CMakeModules/EosioTesterBuild.cmake.in @@ -52,6 +52,7 @@ find_library(libchain eosio_chain @CMAKE_BINARY_DIR@/libraries/chain NO_DEFAULT_ find_library(libfc fc @CMAKE_BINARY_DIR@/libraries/libfc NO_DEFAULT_PATH) find_library(libsecp256k1 secp256k1 @CMAKE_BINARY_DIR@/libraries/libfc/secp256k1 NO_DEFAULT_PATH) find_library(libbn256 bn256 @CMAKE_BINARY_DIR@/libraries/libfc/libraries/bn256/src NO_DEFAULT_PATH) +find_library(libbls12-381 bls12-381 @CMAKE_BINARY_DIR@/libraries/libfc/libraries/bls12-381/src NO_DEFAULT_PATH) find_library(libwasm WASM @CMAKE_BINARY_DIR@/libraries/wasm-jit/Source/WASM NO_DEFAULT_PATH) find_library(libwast WAST @CMAKE_BINARY_DIR@/libraries/wasm-jit/Source/WAST NO_DEFAULT_PATH) @@ -89,6 +90,7 @@ macro(add_eosio_test_executable test_name) ${libbuiltins} ${libsecp256k1} ${libbn256} + ${libbls12-381} @GMP_LIBRARY@ ${Boost_FILESYSTEM_LIBRARY} From e050376ad66598612a95f9b8f4e8938d724e5821 Mon Sep 17 00:00:00 2001 From: mschoenebeck Date: Mon, 17 Jul 2023 08:34:44 -0500 Subject: [PATCH 22/79] added test contract for bls primitives --- libraries/chain/webassembly/crypto.cpp | 2 +- libraries/libfc/libraries/bls12-381 | 2 +- unittests/bls_primitives_tests.cpp | 511 ++++++++++++++++++ unittests/test-contracts/CMakeLists.txt | 1 + .../bls_primitives_test/CMakeLists.txt | 6 + .../bls_primitives_test.abi | 260 +++++++++ .../bls_primitives_test.cpp | 138 +++++ .../bls_primitives_test.hpp | 78 +++ .../bls_primitives_test.wasm | Bin 0 -> 6239 bytes unittests/test_contracts.hpp.in | 1 + 10 files changed, 997 insertions(+), 2 deletions(-) create mode 100644 unittests/bls_primitives_tests.cpp create mode 100644 unittests/test-contracts/bls_primitives_test/CMakeLists.txt create mode 100644 unittests/test-contracts/bls_primitives_test/bls_primitives_test.abi create mode 100644 unittests/test-contracts/bls_primitives_test/bls_primitives_test.cpp create mode 100644 unittests/test-contracts/bls_primitives_test/bls_primitives_test.hpp create mode 100755 unittests/test-contracts/bls_primitives_test/bls_primitives_test.wasm diff --git a/libraries/chain/webassembly/crypto.cpp b/libraries/chain/webassembly/crypto.cpp index baff2374e9..b2a05b5e1e 100644 --- a/libraries/chain/webassembly/crypto.cpp +++ b/libraries/chain/webassembly/crypto.cpp @@ -322,7 +322,7 @@ namespace eosio { namespace chain { namespace webassembly { if(i%10 == 0) context.trx_context.checktime(); } - bls12_381::g1 r = bls12_381::g1::multiExp(pv, sv).value(); // accessing value is safe + bls12_381::g1 r = bls12_381::g1::multiExp(pv, sv, [this](){ context.trx_context.checktime(); }).value(); // accessing value is safe r.toJacobianBytesLE({reinterpret_cast(result.data()), 144}, true); return return_code::success; } diff --git a/libraries/libfc/libraries/bls12-381 b/libraries/libfc/libraries/bls12-381 index b5442c2f4d..82a137ecdc 160000 --- a/libraries/libfc/libraries/bls12-381 +++ b/libraries/libfc/libraries/bls12-381 @@ -1 +1 @@ -Subproject commit b5442c2f4d73e77baeaebc2989c58ec62e175c3f +Subproject commit 82a137ecdc010563a78673ddabf014dd0ec6ae77 diff --git a/unittests/bls_primitives_tests.cpp b/unittests/bls_primitives_tests.cpp new file mode 100644 index 0000000000..fe37fc2895 --- /dev/null +++ b/unittests/bls_primitives_tests.cpp @@ -0,0 +1,511 @@ +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#include "fork_test_utilities.hpp" + +using namespace eosio::chain; +using namespace eosio::testing; +using namespace eosio::chain::webassembly; +using namespace std::literals; + +std::vector hex2bin(const std::string& source) { + std::vector output(source.length()/2); + fc::from_hex(source, output.data(), output.size()); + return output; +} + +BOOST_AUTO_TEST_SUITE(bls_primitives_tests) + +BOOST_AUTO_TEST_CASE( bls_testg1add ) { try { + tester c( setup_policy::preactivate_feature_and_new_bios ); + + const auto& tester1_account = account_name("tester1"); + c.create_accounts( {tester1_account} ); + c.produce_block(); + + const auto& pfm = c.control->get_protocol_feature_manager(); + const auto& d = pfm.get_builtin_digest( builtin_protocol_feature_t::bls_primitives ); + BOOST_REQUIRE( d ); + + c.preactivate_protocol_features( {*d} ); + c.produce_block(); + + c.set_code( tester1_account, test_contracts::bls_primitives_test_wasm() ); + c.set_abi( tester1_account, test_contracts::bls_primitives_test_abi().data() ); + c.produce_block(); + + using test_add = std::tuple; + const std::vector tests = { + //test (2 valid points, both on curve) + { + "160c53fd9087b35cf5ff769967fc1778c1a13b14c7954f1547e7d0f3cd6aaef040f4db21cc6eceed75fb0b9e417701127122e70cd593acba8efd18791a63228cce250757135f59dd945140502958ac51c05900ad3f8c1c0e6aa20850fc3ebc0bfdff02000000097602000cc40b00f4ebba58c7535798485f455752705358ce776dec56a2971a075c93e480fac35ef615", + "160c53fd9087b35cf5ff769967fc1778c1a13b14c7954f1547e7d0f3cd6aaef040f4db21cc6eceed75fb0b9e417701127122e70cd593acba8efd18791a63228cce250757135f59dd945140502958ac51c05900ad3f8c1c0e6aa20850fc3ebc0bfdff02000000097602000cc40b00f4ebba58c7535798485f455752705358ce776dec56a2971a075c93e480fac35ef615", + "2b90dabdf4613e10d269d70050e61bdc53c6d01ac517ad33cd8e82799d5515dfba05bc172fd280e2a73ff01aca77e30cbf82182b9005141106ef83a6d33dcda8bece738c9f9d6313f7e05945fd92c23a208efbe7a2048c6250f7f14df9f5c215e244ce19aa2759751dfb31f234c644189d4b0eae26beb2ba29a380a052b058a380b3005a7f18391cd44411a0f87d7817", + return_code::success + }, + + //test (2 invalid points, garbage output) + { + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "9bd600247dec313e88ed460013c49f7dec45c267571e241267687a35360fbee324b265772d89e38d7a886dfcf4b8eb16804724c7bf0f0e838c5795fffd6416be9fd8e9ff284548a79ae6163a8de08961c61110681a773dc976acea2cb2a8c20291e51670b204a82ff8f5ddffea2416e16ce5793251804c011309ccbda30ab8ca3efa52359820a18f39337698197cfc0f", + return_code::success + }, + }; + + for(const auto& test : tests) { + auto op1 = hex2bin(std::get<0>(test)); + auto op2 = hex2bin(std::get<1>(test)); + auto expected_result = hex2bin(std::get<2>(test)); + auto expected_error = std::get<3>(test); + + c.push_action( tester1_account, "testg1add"_n, tester1_account, mutable_variant_object() + ("op1", op1) + ("op2", op2) + ("res", expected_result) + ("expected_error", expected_error) + ); + } + +} FC_LOG_AND_RETHROW() } + +BOOST_AUTO_TEST_CASE( bls_testg2add ) { try { + tester c( setup_policy::preactivate_feature_and_new_bios ); + + const auto& tester1_account = account_name("tester1"); + c.create_accounts( {tester1_account} ); + c.produce_block(); + + const auto& pfm = c.control->get_protocol_feature_manager(); + const auto& d = pfm.get_builtin_digest( builtin_protocol_feature_t::bls_primitives ); + BOOST_REQUIRE( d ); + + c.preactivate_protocol_features( {*d} ); + c.produce_block(); + + c.set_code( tester1_account, test_contracts::bls_primitives_test_wasm() ); + c.set_abi( tester1_account, test_contracts::bls_primitives_test_abi().data() ); + c.produce_block(); + + using test_add = std::tuple; + const std::vector tests = { + //test (2 valid points, both on curve) + { + "100a9402a28ff2f51a96b48726fbf5b380e52a3eb593a8a1e9ae3c1a9d9994986b36631863b7676fd7bc50439291810506f6239e75c0a9a5c360cdbc9dc5a0aa067886e2187eb13b67b34185ccb61a1b478515f20eedb6c2f3ed6073092a92114a4c4960f80a734c5a9c365e1ffa7c595a630aaa6c85e6e75f490d6ee9b5efbba225eff075a9d307e5da807e8efd83005db064df92fcc0addc61142b0a27aa18a0ebe43b6aacad863aa33dc94e5c4979edca3ca4505817e7f21bde63a1c22b0bfdff02000000097602000cc40b00f4ebba58c7535798485f455752705358ce776dec56a2971a075c93e480fac35ef615000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "100a9402a28ff2f51a96b48726fbf5b380e52a3eb593a8a1e9ae3c1a9d9994986b36631863b7676fd7bc50439291810506f6239e75c0a9a5c360cdbc9dc5a0aa067886e2187eb13b67b34185ccb61a1b478515f20eedb6c2f3ed6073092a92114a4c4960f80a734c5a9c365e1ffa7c595a630aaa6c85e6e75f490d6ee9b5efbba225eff075a9d307e5da807e8efd83005db064df92fcc0addc61142b0a27aa18a0ebe43b6aacad863aa33dc94e5c4979edca3ca4505817e7f21bde63a1c22b0bfdff02000000097602000cc40b00f4ebba58c7535798485f455752705358ce776dec56a2971a075c93e480fac35ef615000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "1987cff592d8ae5c83ba9e9a1a016afd3a4e80d646e10a1274ba259b60a405c189945d07b3608d4d339a96429d60f80d8290d66f4e963c0e8c00e35db541ab46e93148fd7e41449f0be0a1883e36e4b56cf87121991d6d4778d499fdf1501c09a9220f11cdfe60560b15d7e6ec33825a8d9ce209fe8e20391d32210ba83dbd77ce4cd6019ca50465f8f5fed4a8a631048739c8d9b8fdc26a962b24f0306f8293a00d72d37fb2fb1b0643d9a8453cbf6a520463a54e25e8c42134d6798d7cce00949892c0f015e698b4386dbc3ef4f9b2b4c61454d90acdcfbf921adcd26bdf77454bdee1eb52a70fcab501fd1cfb0701ba60c9be25f9815bb9c32856144e543140d7c977d4585b0d75467b929db892f2da957948a1b02ecee537bcc742855716", + return_code::success + }, + + //test (2 invalid points, garbage output) + { + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "6084a42d13cd479f295f48a61cd03409ce2e6f646280a8b5674e2fc25adac7ad5ac5bde861a49b20adfb3c6d8bb0f0f73edf6fd4a2ad32eabfcccd59b6b73ccd94979f67a14c9d520782295a237d5221b59230433381188461d87d10a67617120be52ae01cc8d0d4ff49dd92e37991328c4caf4f089b447af0a17332a59cc1bd9e94816c44d5ef72f7ac017fd48d980282c8386dc30bd933dc455ba343d52b931009c04b631b377f3bb18465e350ee35263ee0736cec2286ec791c55becaf70d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027cb30e0640959d5f2ebc7c3e14920ae9423bbb8f998e1616b69eaeb9a6d3e0debe0fc0cc85b497b064b6d2bf756ef35", + return_code::success + }, + }; + + for(const auto& test : tests) { + auto op1 = hex2bin(std::get<0>(test)); + auto op2 = hex2bin(std::get<1>(test)); + auto expected_result = hex2bin(std::get<2>(test)); + auto expected_error = std::get<3>(test); + + c.push_action( tester1_account, "testg2add"_n, tester1_account, mutable_variant_object() + ("op1", op1) + ("op2", op2) + ("res", expected_result) + ("expected_error", expected_error) + ); + } + +} FC_LOG_AND_RETHROW() } + +BOOST_AUTO_TEST_CASE( bls_testg1mul ) { try { + tester c( setup_policy::preactivate_feature_and_new_bios ); + + const auto& tester1_account = account_name("tester1"); + c.create_accounts( {tester1_account} ); + c.produce_block(); + + const auto& pfm = c.control->get_protocol_feature_manager(); + const auto& d = pfm.get_builtin_digest( builtin_protocol_feature_t::bls_primitives ); + BOOST_REQUIRE( d ); + + c.preactivate_protocol_features( {*d} ); + c.produce_block(); + + c.set_code( tester1_account, test_contracts::bls_primitives_test_wasm() ); + c.set_abi( tester1_account, test_contracts::bls_primitives_test_abi().data() ); + c.produce_block(); + + using test_add = std::tuple; + const std::vector tests = { + //test (valid point, on curve) + { + "160c53fd9087b35cf5ff769967fc1778c1a13b14c7954f1547e7d0f3cd6aaef040f4db21cc6eceed75fb0b9e417701127122e70cd593acba8efd18791a63228cce250757135f59dd945140502958ac51c05900ad3f8c1c0e6aa20850fc3ebc0bfdff02000000097602000cc40b00f4ebba58c7535798485f455752705358ce776dec56a2971a075c93e480fac35ef615", + "2a000000000000002a000000000000002a000000000000002a00000000000000", + "de3e7eeee055abe12a480e58411508d51a356ff6692b14b43426d22cc354cd5d7469c41e0f1f5e40503c91e11419a30285cb057a62c93e2caaaff6c9c1dbc8f88c0a122157f51a617ce0e2890442cd9ce004a8ba972442e61bce9dabf1c6780c191984ae3c11ef21884a536f0d3450974df37295e9579d16cdb8dfdf9252091ca3cd9d05f4c6e645535add05ac197b08", + return_code::success + }, + + //test (invalid point, garbage output) + { + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "2a000000000000002a000000000000002a000000000000002a00000000000000", + "759c3833cb6907e6f1a7fdd6a9c748957498bb8d0282cc641e6020bb18e070170140a4206477882e42a8b551dafe5d11a7e67cff45922bf2a49eea6d64fc5fecb26445170a6ec62233235cc2ac22bbecbf3271cf44f7a59ea0861376b7fe3f130b1865a3ee0d7f5a4bf360b6135c227f46644421caefe01ba82390a8756b7248e24ac4f89c94de92c385abfd6e8fbb11", + return_code::success + }, + }; + + for(const auto& test : tests) { + auto point = hex2bin(std::get<0>(test)); + auto scalar = hex2bin(std::get<1>(test)); + auto expected_result = hex2bin(std::get<2>(test)); + auto expected_error = std::get<3>(test); + + c.push_action( tester1_account, "testg1mul"_n, tester1_account, mutable_variant_object() + ("point", point) + ("scalar", scalar) + ("res", expected_result) + ("expected_error", expected_error) + ); + } + +} FC_LOG_AND_RETHROW() } + +BOOST_AUTO_TEST_CASE( bls_testg2mul ) { try { + tester c( setup_policy::preactivate_feature_and_new_bios ); + + const auto& tester1_account = account_name("tester1"); + c.create_accounts( {tester1_account} ); + c.produce_block(); + + const auto& pfm = c.control->get_protocol_feature_manager(); + const auto& d = pfm.get_builtin_digest( builtin_protocol_feature_t::bls_primitives ); + BOOST_REQUIRE( d ); + + c.preactivate_protocol_features( {*d} ); + c.produce_block(); + + c.set_code( tester1_account, test_contracts::bls_primitives_test_wasm() ); + c.set_abi( tester1_account, test_contracts::bls_primitives_test_abi().data() ); + c.produce_block(); + + using test_add = std::tuple; + const std::vector tests = { + //test (valid point, on curve) + { + "100a9402a28ff2f51a96b48726fbf5b380e52a3eb593a8a1e9ae3c1a9d9994986b36631863b7676fd7bc50439291810506f6239e75c0a9a5c360cdbc9dc5a0aa067886e2187eb13b67b34185ccb61a1b478515f20eedb6c2f3ed6073092a92114a4c4960f80a734c5a9c365e1ffa7c595a630aaa6c85e6e75f490d6ee9b5efbba225eff075a9d307e5da807e8efd83005db064df92fcc0addc61142b0a27aa18a0ebe43b6aacad863aa33dc94e5c4979edca3ca4505817e7f21bde63a1c22b0bfdff02000000097602000cc40b00f4ebba58c7535798485f455752705358ce776dec56a2971a075c93e480fac35ef615000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "2a000000000000002a000000000000002a000000000000002a00000000000000", + "aa25f3f539b6f3215318d81b22d14bf9108294790e8a50545a404ae2057278304d8c3b5844271202b757767d1555a106ede90a9967cdc27b527d4a5720efda79a68b17072ad9402ed373ce9a2d28f5496106fc4cd23234b083181e8325734417f8330d2ced14040b815a006f7f905361f654d483c45abb90b4a958b4ca20ee2bb97cc1c9b6ff45644539abb32149610f33858c88450dad3d2adb82df72f9ed9c42dc2ef78e17f5a2a1abd0468853d55f05f6458179fdf5671db784795a686c0ffae139afaed0212d18d615b0ff90a9deba090f723190521dc8c822621b0a7e70a03b9f3faaeb862846dccd418855d70406fc57e73783c2da92433c1a3873640217539ec7c01f3d354506d86db49fddad225e82421506d99c19b749170aa4f805", + return_code::success + }, + + //test (invalid point, garbage output) + { + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "2a000000000000002a000000000000002a000000000000002a00000000000000", + "50b11bda450431471dc45148066c514489bdc886a8353f382ea4992279d5f01ecec4b1b2782cdc2546cbf6bc070e3701123658149032e1f3af1e63a5ad402549900a42698de7064c9eb7a1b9a344b709073cf033649c01ac6249ab26909b1d194a8d4379563b2ed355b4b63047fc6c0ea9e9b99f75f474db88cee948733dbfd7ddf175d3e67badbce68e3b8515b8e504e666696422b760a10821a881e01d9249ba388eb86f5e8698ebf5cef4454c39144d89b050611a94685ce4505a19422009ef420ad74837caee3ad9a0128c8969e30c130ecbe76ca7157cb12fe59979b777a4df8411519e3137269a05866bd12b1964cc1e6474ea7555e03215a61b2997af51847b27c00fcda059b18be464d51ad8866ce243ca826a184ea25b03d0f9c10b", + return_code::success + }, + }; + + for(const auto& test : tests) { + auto point = hex2bin(std::get<0>(test)); + auto scalar = hex2bin(std::get<1>(test)); + auto expected_result = hex2bin(std::get<2>(test)); + auto expected_error = std::get<3>(test); + + c.push_action( tester1_account, "testg2mul"_n, tester1_account, mutable_variant_object() + ("point", point) + ("scalar", scalar) + ("res", expected_result) + ("expected_error", expected_error) + ); + } + +} FC_LOG_AND_RETHROW() } + +BOOST_AUTO_TEST_CASE( bls_testg1exp ) { try { + tester c( setup_policy::preactivate_feature_and_new_bios ); + + const auto& tester1_account = account_name("tester1"); + c.create_accounts( {tester1_account} ); + c.produce_block(); + + const auto& pfm = c.control->get_protocol_feature_manager(); + const auto& d = pfm.get_builtin_digest( builtin_protocol_feature_t::bls_primitives ); + BOOST_REQUIRE( d ); + + c.preactivate_protocol_features( {*d} ); + c.produce_block(); + + c.set_code( tester1_account, test_contracts::bls_primitives_test_wasm() ); + c.set_abi( tester1_account, test_contracts::bls_primitives_test_abi().data() ); + c.produce_block(); + + using test_add = std::tuple; + const std::vector tests = { + //test (two valid points, on curve) + { + "160c53fd9087b35cf5ff769967fc1778c1a13b14c7954f1547e7d0f3cd6aaef040f4db21cc6eceed75fb0b9e417701127122e70cd593acba8efd18791a63228cce250757135f59dd945140502958ac51c05900ad3f8c1c0e6aa20850fc3ebc0bfdff02000000097602000cc40b00f4ebba58c7535798485f455752705358ce776dec56a2971a075c93e480fac35ef615160c53fd9087b35cf5ff769967fc1778c1a13b14c7954f1547e7d0f3cd6aaef040f4db21cc6eceed75fb0b9e417701127122e70cd593acba8efd18791a63228cce250757135f59dd945140502958ac51c05900ad3f8c1c0e6aa20850fc3ebc0bfdff02000000097602000cc40b00f4ebba58c7535798485f455752705358ce776dec56a2971a075c93e480fac35ef615", + "2a000000000000002a000000000000002a000000000000002a000000000000002a000000000000002a000000000000002a000000000000002a00000000000000", + 2, + "9e80ed609e62978a3a7f0d6bf57e1df4070725c1bf4dab43a6b710adef7450fb41f0cf14a7895ec26fd8c830c327cc0e2c8fe7687d23ff84647b47bbad04cf77625dee1049e53ad5162fe772278e5fe3ceb0bdc472f31952343da7b75532f7016613af892092131ad77d13afc8c9192487ac19f8454ad932653145f06e25790d26b23ac6b83025326f3397efbd845511", + return_code::success + }, + + //test (two invalid points, garbage output) + { + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "2a000000000000002a000000000000002a000000000000002a000000000000002a000000000000002a000000000000002a000000000000002a00000000000000", + 2, + "a4a01d651d82bd2e4f6f0df09b5f57254f2fb3294a83dddda170312f752c6107511739d935d6e5cf9f5ab245ff29b3057c41e220165e0a104493ead21fa8fee939026a77c031ba9f27edeb233375a2172f8cb0fae434365f6a65e1677ef72f00018da74a79be5f8e856f58b7b57f01cce6e1c082309a00612992714c5aed692dd8dba9061dfd04fb8e9dd61acaf3620f", + return_code::success + }, + }; + + for(const auto& test : tests) { + auto points = hex2bin(std::get<0>(test)); + auto scalars = hex2bin(std::get<1>(test)); + auto num = std::get<2>(test); + auto expected_result = hex2bin(std::get<3>(test)); + auto expected_error = std::get<4>(test); + + c.push_action( tester1_account, "testg1exp"_n, tester1_account, mutable_variant_object() + ("points", points) + ("scalars", scalars) + ("num", num) + ("res", expected_result) + ("expected_error", expected_error) + ); + } + +} FC_LOG_AND_RETHROW() } + +BOOST_AUTO_TEST_CASE( bls_testg2exp ) { try { + tester c( setup_policy::preactivate_feature_and_new_bios ); + + const auto& tester1_account = account_name("tester1"); + c.create_accounts( {tester1_account} ); + c.produce_block(); + + const auto& pfm = c.control->get_protocol_feature_manager(); + const auto& d = pfm.get_builtin_digest( builtin_protocol_feature_t::bls_primitives ); + BOOST_REQUIRE( d ); + + c.preactivate_protocol_features( {*d} ); + c.produce_block(); + + c.set_code( tester1_account, test_contracts::bls_primitives_test_wasm() ); + c.set_abi( tester1_account, test_contracts::bls_primitives_test_abi().data() ); + c.produce_block(); + + using test_add = std::tuple; + const std::vector tests = { + //test (two valid points, on curve) + { + "100a9402a28ff2f51a96b48726fbf5b380e52a3eb593a8a1e9ae3c1a9d9994986b36631863b7676fd7bc50439291810506f6239e75c0a9a5c360cdbc9dc5a0aa067886e2187eb13b67b34185ccb61a1b478515f20eedb6c2f3ed6073092a92114a4c4960f80a734c5a9c365e1ffa7c595a630aaa6c85e6e75f490d6ee9b5efbba225eff075a9d307e5da807e8efd83005db064df92fcc0addc61142b0a27aa18a0ebe43b6aacad863aa33dc94e5c4979edca3ca4505817e7f21bde63a1c22b0bfdff02000000097602000cc40b00f4ebba58c7535798485f455752705358ce776dec56a2971a075c93e480fac35ef615000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100a9402a28ff2f51a96b48726fbf5b380e52a3eb593a8a1e9ae3c1a9d9994986b36631863b7676fd7bc50439291810506f6239e75c0a9a5c360cdbc9dc5a0aa067886e2187eb13b67b34185ccb61a1b478515f20eedb6c2f3ed6073092a92114a4c4960f80a734c5a9c365e1ffa7c595a630aaa6c85e6e75f490d6ee9b5efbba225eff075a9d307e5da807e8efd83005db064df92fcc0addc61142b0a27aa18a0ebe43b6aacad863aa33dc94e5c4979edca3ca4505817e7f21bde63a1c22b0bfdff02000000097602000cc40b00f4ebba58c7535798485f455752705358ce776dec56a2971a075c93e480fac35ef615000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "2a000000000000002a000000000000002a000000000000002a000000000000002a000000000000002a000000000000002a000000000000002a00000000000000", + 2, + "595a2cbaa4315ecc0dd9838a81712e0cfb88cb2c4468640ff382abb321b3a9bedebb0aad985a9057f664fc52eb52cd194b1c9611b25ef4281e439a52d1832813decd66c22440821f0288dcb7a82151386aa0240e943b6905e61619be2e11c208fa03df16e11a1b1368abac90598bb237f785701d5d1d5cb0af6934ed633d366de28703431b8d70899d92797689207c0cd35c345460f971dff5d648d9ddec8f5fabef99b15ea7c4440ac1564d6e0326076f32a4ec9cf0d10059593d64afd35c03d10f16794821628b565c9319f4af3c96b98c4fb11bc0c04172bb57372531f6e76798142d4b00488adbea850a2649a305b71fa389c3c226f2df4a58c8bce5d90698452f4126046be0c82d8817b64162a53787f1cb73af27d969adc626c1392716", + return_code::success + }, + + //test (two invalid points, garbage output) + { + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "2a000000000000002a000000000000002a000000000000002a000000000000002a000000000000002a000000000000002a000000000000002a00000000000000", + 2, + "71aa03189998d6bec41f070fe01d38efc3b60e77b6dd7a7676b3f0b8939e2fda916c4609b5d3313e04c382107aac7f014f65cf46d614729fc4255e6e045a1a13e851a81a2f03036973b211ac18152231e24d93805f4b64792d573f490791c20d451af61e3081a4b8f40919969a87bd015363da93d1b7f1ff4c625dae5fa6c95492fefb689e66a10a8d5e9f3d0190e9119e6c11550ac6a09c6ded21e9d67c0ba1e71bcc4ef28879a4d3af1beaf0a9394b7a01c28bd01d0b09818bb8274a275e11d0a3859c637c455a28eef74d4ba33e7a9f0550ef58e5f0e960a4c29b2800ed1697408c7331b198efcd5eda01705640118ef8a64c4e8eb7c5397b9d6e0d8799935be4e973ada583bddf13f2c17129f6ae60f0ec4f39971af53bc154c953312419", + return_code::success + }, + }; + + for(const auto& test : tests) { + auto points = hex2bin(std::get<0>(test)); + auto scalars = hex2bin(std::get<1>(test)); + auto num = std::get<2>(test); + auto expected_result = hex2bin(std::get<3>(test)); + auto expected_error = std::get<4>(test); + + c.push_action( tester1_account, "testg2exp"_n, tester1_account, mutable_variant_object() + ("points", points) + ("scalars", scalars) + ("num", num) + ("res", expected_result) + ("expected_error", expected_error) + ); + } + +} FC_LOG_AND_RETHROW() } +/* +BOOST_AUTO_TEST_CASE( bls_testpairing ) { try { + tester c( setup_policy::preactivate_feature_and_new_bios ); + + const auto& tester1_account = account_name("tester1"); + c.create_accounts( {tester1_account} ); + c.produce_block(); + + const auto& pfm = c.control->get_protocol_feature_manager(); + const auto& d = pfm.get_builtin_digest( builtin_protocol_feature_t::bls_primitives ); + BOOST_REQUIRE( d ); + + c.preactivate_protocol_features( {*d} ); + c.produce_block(); + + c.set_code( tester1_account, test_contracts::bls_primitives_test_wasm() ); + c.set_abi( tester1_account, test_contracts::bls_primitives_test_abi().data() ); + c.produce_block(); + + using test_add = std::tuple; + const std::vector tests = { + //test (three valid g1 and g2 points, on curve) + { + "160c53fd9087b35cf5ff769967fc1778c1a13b14c7954f1547e7d0f3cd6aaef040f4db21cc6eceed75fb0b9e417701127122e70cd593acba8efd18791a63228cce250757135f59dd945140502958ac51c05900ad3f8c1c0e6aa20850fc3ebc0bfdff02000000097602000cc40b00f4ebba58c7535798485f455752705358ce776dec56a2971a075c93e480fac35ef615160c53fd9087b35cf5ff769967fc1778c1a13b14c7954f1547e7d0f3cd6aaef040f4db21cc6eceed75fb0b9e417701127122e70cd593acba8efd18791a63228cce250757135f59dd945140502958ac51c05900ad3f8c1c0e6aa20850fc3ebc0bfdff02000000097602000cc40b00f4ebba58c7535798485f455752705358ce776dec56a2971a075c93e480fac35ef615160c53fd9087b35cf5ff769967fc1778c1a13b14c7954f1547e7d0f3cd6aaef040f4db21cc6eceed75fb0b9e417701127122e70cd593acba8efd18791a63228cce250757135f59dd945140502958ac51c05900ad3f8c1c0e6aa20850fc3ebc0bfdff02000000097602000cc40b00f4ebba58c7535798485f455752705358ce776dec56a2971a075c93e480fac35ef615", + "100a9402a28ff2f51a96b48726fbf5b380e52a3eb593a8a1e9ae3c1a9d9994986b36631863b7676fd7bc50439291810506f6239e75c0a9a5c360cdbc9dc5a0aa067886e2187eb13b67b34185ccb61a1b478515f20eedb6c2f3ed6073092a92114a4c4960f80a734c5a9c365e1ffa7c595a630aaa6c85e6e75f490d6ee9b5efbba225eff075a9d307e5da807e8efd83005db064df92fcc0addc61142b0a27aa18a0ebe43b6aacad863aa33dc94e5c4979edca3ca4505817e7f21bde63a1c22b0bfdff02000000097602000cc40b00f4ebba58c7535798485f455752705358ce776dec56a2971a075c93e480fac35ef615000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100a9402a28ff2f51a96b48726fbf5b380e52a3eb593a8a1e9ae3c1a9d9994986b36631863b7676fd7bc50439291810506f6239e75c0a9a5c360cdbc9dc5a0aa067886e2187eb13b67b34185ccb61a1b478515f20eedb6c2f3ed6073092a92114a4c4960f80a734c5a9c365e1ffa7c595a630aaa6c85e6e75f490d6ee9b5efbba225eff075a9d307e5da807e8efd83005db064df92fcc0addc61142b0a27aa18a0ebe43b6aacad863aa33dc94e5c4979edca3ca4505817e7f21bde63a1c22b0bfdff02000000097602000cc40b00f4ebba58c7535798485f455752705358ce776dec56a2971a075c93e480fac35ef615000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100a9402a28ff2f51a96b48726fbf5b380e52a3eb593a8a1e9ae3c1a9d9994986b36631863b7676fd7bc50439291810506f6239e75c0a9a5c360cdbc9dc5a0aa067886e2187eb13b67b34185ccb61a1b478515f20eedb6c2f3ed6073092a92114a4c4960f80a734c5a9c365e1ffa7c595a630aaa6c85e6e75f490d6ee9b5efbba225eff075a9d307e5da807e8efd83005db064df92fcc0addc61142b0a27aa18a0ebe43b6aacad863aa33dc94e5c4979edca3ca4505817e7f21bde63a1c22b0bfdff02000000097602000cc40b00f4ebba58c7535798485f455752705358ce776dec56a2971a075c93e480fac35ef615000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 3, + "af587ca8f5f0760b888e4ec66748623d1b13986547b5de2042ce89233c2c837bbb080329a505285c948d8bb4c88a5914ae216a64db582ba084178db4364a7b3843ef7fb9056a90526d27dc9e252b38600fc54ce7a5ec15771c555816edc26d0166e75d3315789c846387c8c234b1c98b50baf233b7312aa317ae56a2bfa170b1bc43f0e046b4a1f45cb7aacea7d0ae0320496e3960d4dbc2039027ba8cfe1ca120ea98fa94cf25034ccb5e74033f447b837a78b03affd44b87f865f3d713000de78ab5629dbde8d0c8b7a28941717be3ebd23924cf16897144bb69730f68bff5a109fc2e6d563b15e2eb883cf4becd11edcbc2ec4402c93249389ed612fa0396ed6eadcbe4d703667d46b0150ee3a5158caef956791e4f527e1312c8402f8509acf7001dc0dc311549d76398c247e79b737b614d0a6663f7dbdb314e5b51eace14457ee7b1f3f54d5987c16c8f89d1022d91d4649f5f6a204047077e5791a654cd2277506cd0af77f9ea789278b364c115ec07ba14390a9c22d59aa9c97a9c09ce025b5e14443f3c4e4cd602ef34105fadd82837fc5ce60a461e6ea11b13ae67b82e3366a2b2d1bbe78b2579173b3c0c5aed88b2949403060c3e065782bcb742c55c559e75e373293d80dec54120773d80144b21b353ead58dc8427e5b9cbd0c1431f1a74caf5f57c4b55b89810029cdd24ef4a029797ced68ff882492a8f55f31fe52217356366983e35d2a5640e818cc8bddf9274de0100e624a6bf03e2b9ff22f8dda09a46b50b1b305cb6adfa2ae775febbce4a2b507cd2390db968ceb13", + return_code::success + }, + + //test (three invalid g1 and g2 points, should fail) + { + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + 3, + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + return_code::failure + }, + }; + + for(const auto& test : tests) { + auto g1_points = hex2bin(std::get<0>(test)); + auto g2_points = hex2bin(std::get<1>(test)); + auto num = std::get<2>(test); + auto expected_result = hex2bin(std::get<3>(test)); + auto expected_error = std::get<4>(test); + + c.push_action( tester1_account, "testpairing"_n, tester1_account, mutable_variant_object() + ("g1_points", g1_points) + ("g2_points", g2_points) + ("num", num) + ("res", expected_result) + ("expected_error", expected_error) + ); + } + +} FC_LOG_AND_RETHROW() } +*/ +BOOST_AUTO_TEST_CASE( bls_testg1map ) { try { + tester c( setup_policy::preactivate_feature_and_new_bios ); + + const auto& tester1_account = account_name("tester1"); + c.create_accounts( {tester1_account} ); + c.produce_block(); + + const auto& pfm = c.control->get_protocol_feature_manager(); + const auto& d = pfm.get_builtin_digest( builtin_protocol_feature_t::bls_primitives ); + BOOST_REQUIRE( d ); + + c.preactivate_protocol_features( {*d} ); + c.produce_block(); + + c.set_code( tester1_account, test_contracts::bls_primitives_test_wasm() ); + c.set_abi( tester1_account, test_contracts::bls_primitives_test_abi().data() ); + c.produce_block(); + + using test_add = std::tuple; + const std::vector tests = { + //test (valid field element) + { + "c93f817b159bdf8404dc378514f845192bbae4faac7f4a568924f2d9725125000489408fd796461c288900add00d4618", + "d8e09005badb694b1e5dba8476ba3012cd2bf0c472ee1811ac9b34c869638b47e669bce16933e98ce9b129f83d93d71890d6fd13b77d4ad8df1a5f1c6b81df2b3f305721b7b7874cd81eba23ca05e8bc974b14f7e4c2c77cbdf321c340ba4903a2a46af290abe078e426f913e492b8d9b997232dbe6198aea719a31e73b40e110c4efa9e42d737a42883e0ca5f344d02", + return_code::success + }, + + //test (invalid field element, should fail) + { + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + return_code::failure + }, + }; + + for(const auto& test : tests) { + auto e = hex2bin(std::get<0>(test)); + auto expected_result = hex2bin(std::get<1>(test)); + auto expected_error = std::get<2>(test); + + c.push_action( tester1_account, "testg1map"_n, tester1_account, mutable_variant_object() + ("e", e) + ("res", expected_result) + ("expected_error", expected_error) + ); + } + +} FC_LOG_AND_RETHROW() } + +BOOST_AUTO_TEST_CASE( bls_testg2map ) { try { + tester c( setup_policy::preactivate_feature_and_new_bios ); + + const auto& tester1_account = account_name("tester1"); + c.create_accounts( {tester1_account} ); + c.produce_block(); + + const auto& pfm = c.control->get_protocol_feature_manager(); + const auto& d = pfm.get_builtin_digest( builtin_protocol_feature_t::bls_primitives ); + BOOST_REQUIRE( d ); + + c.preactivate_protocol_features( {*d} ); + c.produce_block(); + + c.set_code( tester1_account, test_contracts::bls_primitives_test_wasm() ); + c.set_abi( tester1_account, test_contracts::bls_primitives_test_abi().data() ); + c.produce_block(); + + using test_add = std::tuple; + const std::vector tests = { + //test (valid field element) + { + "d4f2cfec99387809574fcc2dba105603d950d490e2bebe0c212c05e16b784745ef4fe8e70b554d0a52fe0bed5ea6690ade2348eb8972a96740a430df162d920e175f5923a76d18650ea24a8ec06d414c6d1d218d673dac3619a1a5c142785708", + "9968ae9e9bf3d22ec6c9670efa64ea23d4966b41bb25f76ea2ef71b96fa35e031adb866b3df234065b9aa72d0b12ab14978678279eb944f05b5af53d91e700b57aa87076727def2e9f2fba3cf6784a25591ae1669c2cf15cdcf038b826d1e81178bd7b59b7e911e0c2d11d6805756222201e3364f8010fb651939eca63f7e77709042ee1030cd938f53905a714e815112a7dfeed207757d30382f69617014bc683a175d0dfbd74f2684de26c771f3f55a538e6d2f969eb282bddfec4fc08dd18f37df0889292f288dff631b02f07b88134410fd86526d234d75b9a329bc9a8b6e71c7ad516b87af9717d962cba5d2b19fd1b77746f1e484a54e6aec81ede148f01e2c8283c598a4976182d2ce287fe6888e23996ce03b03ce6709e4aa8e66416", + return_code::success + }, + + //test (invalid field element, should fail) + { + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + return_code::failure + }, + }; + + for(const auto& test : tests) { + auto e = hex2bin(std::get<0>(test)); + auto expected_result = hex2bin(std::get<1>(test)); + auto expected_error = std::get<2>(test); + + c.push_action( tester1_account, "testg2map"_n, tester1_account, mutable_variant_object() + ("e", e) + ("res", expected_result) + ("expected_error", expected_error) + ); + } + +} FC_LOG_AND_RETHROW() } + + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/unittests/test-contracts/CMakeLists.txt b/unittests/test-contracts/CMakeLists.txt index a578ef9e01..a62d82809c 100644 --- a/unittests/test-contracts/CMakeLists.txt +++ b/unittests/test-contracts/CMakeLists.txt @@ -42,5 +42,6 @@ add_subdirectory( action_results ) add_subdirectory( wasm_config_bios ) add_subdirectory( params_test ) add_subdirectory( crypto_primitives_test ) +add_subdirectory( bls_primitives_test ) add_subdirectory( get_block_num_test ) add_subdirectory( nested_container_multi_index ) diff --git a/unittests/test-contracts/bls_primitives_test/CMakeLists.txt b/unittests/test-contracts/bls_primitives_test/CMakeLists.txt new file mode 100644 index 0000000000..01b82bf8ef --- /dev/null +++ b/unittests/test-contracts/bls_primitives_test/CMakeLists.txt @@ -0,0 +1,6 @@ +if( EOSIO_COMPILE_TEST_CONTRACTS ) + add_contract( bls_primitives_test bls_primitives_test bls_primitives_test.cpp ) +else() + configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/bls_primitives_test.wasm ${CMAKE_CURRENT_BINARY_DIR}/bls_primitives_test.wasm COPYONLY ) + configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/bls_primitives_test.abi ${CMAKE_CURRENT_BINARY_DIR}/bls_primitives_test.abi COPYONLY ) +endif() diff --git a/unittests/test-contracts/bls_primitives_test/bls_primitives_test.abi b/unittests/test-contracts/bls_primitives_test/bls_primitives_test.abi new file mode 100644 index 0000000000..27713f8b5b --- /dev/null +++ b/unittests/test-contracts/bls_primitives_test/bls_primitives_test.abi @@ -0,0 +1,260 @@ +{ + "____comment": "This file was generated with eosio-abigen. DO NOT EDIT ", + "version": "eosio::abi/1.2", + "types": [], + "structs": [ + { + "name": "testg1add", + "base": "", + "fields": [ + { + "name": "op1", + "type": "bytes" + }, + { + "name": "op2", + "type": "bytes" + }, + { + "name": "res", + "type": "bytes" + }, + { + "name": "expected_error", + "type": "int32" + } + ] + }, + { + "name": "testg1exp", + "base": "", + "fields": [ + { + "name": "points", + "type": "bytes" + }, + { + "name": "scalars", + "type": "bytes" + }, + { + "name": "num", + "type": "uint32" + }, + { + "name": "res", + "type": "bytes" + }, + { + "name": "expected_error", + "type": "int32" + } + ] + }, + { + "name": "testg1map", + "base": "", + "fields": [ + { + "name": "e", + "type": "bytes" + }, + { + "name": "res", + "type": "bytes" + }, + { + "name": "expected_error", + "type": "int32" + } + ] + }, + { + "name": "testg1mul", + "base": "", + "fields": [ + { + "name": "point", + "type": "bytes" + }, + { + "name": "scalar", + "type": "bytes" + }, + { + "name": "res", + "type": "bytes" + }, + { + "name": "expected_error", + "type": "int32" + } + ] + }, + { + "name": "testg2add", + "base": "", + "fields": [ + { + "name": "op1", + "type": "bytes" + }, + { + "name": "op2", + "type": "bytes" + }, + { + "name": "res", + "type": "bytes" + }, + { + "name": "expected_error", + "type": "int32" + } + ] + }, + { + "name": "testg2exp", + "base": "", + "fields": [ + { + "name": "points", + "type": "bytes" + }, + { + "name": "scalars", + "type": "bytes" + }, + { + "name": "num", + "type": "uint32" + }, + { + "name": "res", + "type": "bytes" + }, + { + "name": "expected_error", + "type": "int32" + } + ] + }, + { + "name": "testg2map", + "base": "", + "fields": [ + { + "name": "e", + "type": "bytes" + }, + { + "name": "res", + "type": "bytes" + }, + { + "name": "expected_error", + "type": "int32" + } + ] + }, + { + "name": "testg2mul", + "base": "", + "fields": [ + { + "name": "point", + "type": "bytes" + }, + { + "name": "scalar", + "type": "bytes" + }, + { + "name": "res", + "type": "bytes" + }, + { + "name": "expected_error", + "type": "int32" + } + ] + }, + { + "name": "testpairing", + "base": "", + "fields": [ + { + "name": "g1_points", + "type": "bytes" + }, + { + "name": "g2_points", + "type": "bytes" + }, + { + "name": "num", + "type": "uint32" + }, + { + "name": "res", + "type": "bytes" + }, + { + "name": "expected_error", + "type": "int32" + } + ] + } + ], + "actions": [ + { + "name": "testg1add", + "type": "testg1add", + "ricardian_contract": "" + }, + { + "name": "testg1exp", + "type": "testg1exp", + "ricardian_contract": "" + }, + { + "name": "testg1map", + "type": "testg1map", + "ricardian_contract": "" + }, + { + "name": "testg1mul", + "type": "testg1mul", + "ricardian_contract": "" + }, + { + "name": "testg2add", + "type": "testg2add", + "ricardian_contract": "" + }, + { + "name": "testg2exp", + "type": "testg2exp", + "ricardian_contract": "" + }, + { + "name": "testg2map", + "type": "testg2map", + "ricardian_contract": "" + }, + { + "name": "testg2mul", + "type": "testg2mul", + "ricardian_contract": "" + }, + { + "name": "testpairing", + "type": "testpairing", + "ricardian_contract": "" + } + ], + "tables": [], + "ricardian_clauses": [], + "variants": [], + "action_results": [] +} \ No newline at end of file diff --git a/unittests/test-contracts/bls_primitives_test/bls_primitives_test.cpp b/unittests/test-contracts/bls_primitives_test/bls_primitives_test.cpp new file mode 100644 index 0000000000..faea7638a6 --- /dev/null +++ b/unittests/test-contracts/bls_primitives_test/bls_primitives_test.cpp @@ -0,0 +1,138 @@ +#include "bls_primitives_test.hpp" +#include + +using namespace eosio; + +void bls_primitives_test::testg1add(const std::vector& op1, const std::vector& op2, const std::vector& res, int32_t expected_error) +{ + bls_g1 r; + int32_t error = internal_use_do_not_use::bls_g1_add( + reinterpret_cast(op1.data()), + sizeof(bls_g1), + reinterpret_cast(op2.data()), + sizeof(bls_g1), + reinterpret_cast(r), + sizeof(bls_g1) + ); + check(error == expected_error, "bls_g1_add: Error does not match"); + check(0 == std::memcmp(r, res.data(), sizeof(bls_g1)), "bls_g1_add: Result does not match"); +} + +void bls_primitives_test::testg2add(const std::vector& op1, const std::vector& op2, const std::vector& res, int32_t expected_error) +{ + bls_g2 r; + int32_t error = internal_use_do_not_use::bls_g2_add( + reinterpret_cast(op1.data()), + sizeof(bls_g2), + reinterpret_cast(op2.data()), + sizeof(bls_g2), + reinterpret_cast(r), + sizeof(bls_g2) + ); + check(error == expected_error, "bls_g2_add: Error does not match"); + check(0 == std::memcmp(r, res.data(), sizeof(bls_g2)), "bls_g2_add: Result does not match"); +} + +void bls_primitives_test::testg1mul(const std::vector& point, const std::vector& scalar, const std::vector& res, int32_t expected_error) +{ + bls_g1 r; + int32_t error = internal_use_do_not_use::bls_g1_mul( + reinterpret_cast(point.data()), + sizeof(bls_g1), + reinterpret_cast(scalar.data()), + sizeof(bls_scalar), + reinterpret_cast(r), + sizeof(bls_g1) + ); + check(error == expected_error, "bls_g1_mul: Error does not match"); + check(0 == std::memcmp(r, res.data(), sizeof(bls_g1)), "bls_g1_mul: Result does not match"); +} + +void bls_primitives_test::testg2mul(const std::vector& point, const std::vector& scalar, const std::vector& res, int32_t expected_error) +{ + bls_g2 r; + int32_t error = internal_use_do_not_use::bls_g2_mul( + reinterpret_cast(point.data()), + sizeof(bls_g2), + reinterpret_cast(scalar.data()), + sizeof(bls_scalar), + reinterpret_cast(r), + sizeof(bls_g2) + ); + check(error == expected_error, "bls_g2_mul: Error does not match"); + check(0 == std::memcmp(r, res.data(), sizeof(bls_g2)), "bls_g2_mul: Result does not match"); +} + +void bls_primitives_test::testg1exp(const std::vector& points, const std::vector& scalars, const uint32_t num, const std::vector& res, int32_t expected_error) +{ + bls_g1 r; + int32_t error = internal_use_do_not_use::bls_g1_exp( + reinterpret_cast(points.data()), + num * sizeof(bls_g1), + reinterpret_cast(scalars.data()), + num * sizeof(bls_scalar), + num, + reinterpret_cast(r), + sizeof(bls_g1) + ); + check(error == expected_error, "bls_g1_exp: Error does not match"); + check(0 == std::memcmp(r, res.data(), sizeof(bls_g1)), "bls_g1_exp: Result does not match"); +} + +void bls_primitives_test::testg2exp(const std::vector& points, const std::vector& scalars, const uint32_t num, const std::vector& res, int32_t expected_error) +{ + bls_g2 r; + int32_t error = internal_use_do_not_use::bls_g2_exp( + reinterpret_cast(points.data()), + num * sizeof(bls_g2), + reinterpret_cast(scalars.data()), + num * sizeof(bls_scalar), + num, + reinterpret_cast(r), + sizeof(bls_g2) + ); + check(error == expected_error, "bls_g2_exp: Error does not match"); + check(0 == std::memcmp(r, res.data(), sizeof(bls_g2)), "bls_g2_exp: Result does not match"); +} + +void bls_primitives_test::testpairing(const std::vector& g1_points, const std::vector& g2_points, const uint32_t num, const std::vector& res, int32_t expected_error) +{ + bls_gt r; + int32_t error = internal_use_do_not_use::bls_pairing( + reinterpret_cast(g1_points.data()), + num * sizeof(bls_g1), + reinterpret_cast(g2_points.data()), + num * sizeof(bls_g2), + num, + reinterpret_cast(r), + sizeof(bls_gt) + ); + check(error == expected_error, "bls_pairing: Error does not match"); + check(0 == std::memcmp(r, res.data(), sizeof(bls_gt)), "bls_pairing: Result does not match"); +} + +void bls_primitives_test::testg1map(const std::vector& e, const std::vector& res, int32_t expected_error) +{ + bls_g1 r; + int32_t error = internal_use_do_not_use::bls_g1_map( + reinterpret_cast(e.data()), + sizeof(bls_fp), + reinterpret_cast(r), + sizeof(bls_g1) + ); + check(error == expected_error, "bls_g1_map: Error does not match"); + check(0 == std::memcmp(r, res.data(), sizeof(bls_g1)), "bls_g1_map: Result does not match"); +} + +void bls_primitives_test::testg2map(const std::vector& e, const std::vector& res, int32_t expected_error) +{ + bls_g2 r; + int32_t error = internal_use_do_not_use::bls_g2_map( + reinterpret_cast(e.data()), + sizeof(bls_fp2), + reinterpret_cast(r), + sizeof(bls_g2) + ); + check(error == expected_error, "bls_g2_map: Error does not match"); + check(0 == std::memcmp(r, res.data(), sizeof(bls_g2)), "bls_g2_map: Result does not match"); +} diff --git a/unittests/test-contracts/bls_primitives_test/bls_primitives_test.hpp b/unittests/test-contracts/bls_primitives_test/bls_primitives_test.hpp new file mode 100644 index 0000000000..7af146e94e --- /dev/null +++ b/unittests/test-contracts/bls_primitives_test/bls_primitives_test.hpp @@ -0,0 +1,78 @@ +#pragma once + +#include + +using bls_scalar = uint8_t[32]; +using bls_fp = uint8_t[48]; +using bls_fp2 = bls_fp[2]; +using bls_g1 = uint8_t[144]; +using bls_g2 = uint8_t[288]; +using bls_gt = uint8_t[576]; + +namespace eosio { + namespace internal_use_do_not_use { + extern "C" { + __attribute__((eosio_wasm_import)) + int32_t bls_g1_add(const char* op1, uint32_t op1_len, const char* op2, uint32_t op2_len, char* res, uint32_t res_len); + + __attribute__((eosio_wasm_import)) + int32_t bls_g2_add(const char* op1, uint32_t op1_len, const char* op2, uint32_t op2_len, char* res, uint32_t res_len); + + __attribute__((eosio_wasm_import)) + int32_t bls_g1_mul(const char* point, uint32_t point_len, const char* scalar, uint32_t scalar_len, char* res, uint32_t res_len); + + __attribute__((eosio_wasm_import)) + int32_t bls_g2_mul(const char* point, uint32_t point_len, const char* scalar, uint32_t scalar_len, char* res, uint32_t res_len); + + __attribute__((eosio_wasm_import)) + int32_t bls_g1_exp(const char* points, uint32_t points_len, const char* scalars, uint32_t scalars_len, uint32_t n, char* res, uint32_t res_len); + + __attribute__((eosio_wasm_import)) + int32_t bls_g2_exp(const char* points, uint32_t points_len, const char* scalars, uint32_t scalars_len, uint32_t n, char* res, uint32_t res_len); + + __attribute__((eosio_wasm_import)) + int32_t bls_pairing(const char* g1_points, uint32_t g1_points_len, const char* g2_points, uint32_t g2_points_len, uint32_t n, char* res, uint32_t res_len); + + __attribute__((eosio_wasm_import)) + int32_t bls_g1_map(const char* e, uint32_t e_len, char* res, uint32_t res_len); + + __attribute__((eosio_wasm_import)) + int32_t bls_g2_map(const char* e, uint32_t e_len, char* res, uint32_t res_len); + + __attribute__((eosio_wasm_import)) + int32_t bls_fp_mod(const char* s, uint32_t s_len, char* res, uint32_t res_len); + } + } +} + +class [[eosio::contract]] bls_primitives_test : public eosio::contract { +public: + using eosio::contract::contract; + + [[eosio::action]] + void testg1add(const std::vector& op1, const std::vector& op2, const std::vector& res, int32_t expected_error); + + [[eosio::action]] + void testg2add(const std::vector& op1, const std::vector& op2, const std::vector& res, int32_t expected_error); + + [[eosio::action]] + void testg1mul(const std::vector& point, const std::vector& scalar, const std::vector& res, int32_t expected_error); + + [[eosio::action]] + void testg2mul(const std::vector& point, const std::vector& scalar, const std::vector& res, int32_t expected_error); + + [[eosio::action]] + void testg1exp(const std::vector& points, const std::vector& scalars, const uint32_t num, const std::vector& res, int32_t expected_error); + + [[eosio::action]] + void testg2exp(const std::vector& points, const std::vector& scalars, const uint32_t num, const std::vector& res, int32_t expected_error); + + [[eosio::action]] + void testpairing(const std::vector& g1_points, const std::vector& g2_points, const uint32_t num, const std::vector& res, int32_t expected_error); + + [[eosio::action]] + void testg1map(const std::vector& e, const std::vector& res, int32_t expected_error); + + [[eosio::action]] + void testg2map(const std::vector& e, const std::vector& res, int32_t expected_error); +}; diff --git a/unittests/test-contracts/bls_primitives_test/bls_primitives_test.wasm b/unittests/test-contracts/bls_primitives_test/bls_primitives_test.wasm new file mode 100755 index 0000000000000000000000000000000000000000..2e2520689316f62637d309e379cb39295bab1c17 GIT binary patch literal 6239 zcmeHL-H#hr6+ic5>}1Dgr&78NNr3BVXblq5Caf0J7d%l)8$N{SAAomaPm}e>+OcON z%EQ{Ah^GiG5=fB{QjiK24}3@{FQ7`>mP&l|Ath8QAXWR&_Mxbv@Yn~!@7!yTXRD2? zqD4wY=fN}goO93D@1E;>F2%#HAR_U#V2x<4FtU#rt;x}d){1U8!dUYs-sE`rRgM5b zu?6xLrfkug+S{* znat^#%yd$Bv*RW?!s+@u2&d}F*ZZXMIx>RKhWqjQV1464UgT808}~`)=VXK+ZlvqI zje0Xq}~-e7=Wxh`-G+N$cl3y+*rnF<#$* z7lXK)q{)CCYP6H43)@_HH!*8wiM90yy?$?)H2I^s*?=lK#HLD(&A}kqNbBi(H=)B! zI>Kt%*~>{z+NwI#M>f)7z2h9XCl5uv(Q78Opzd2DzgQ|$sa*b0d9ffDCy(|-UkKqT zL87pvMj{&TkUyg6+2^xY@v!jXe!uesEiL@yfhA4BG5>}nL%~Obdkq=!Rb4wX9$){% z3p=m9`~@R1WNKhMOTGHc9_sy;`sdg7%AR!8AMcg@xTU`N(q7pI9QFHqWgi6fm$!cN z!&|TCeW+U58?Wxw@CiqKa<7I@dWPUJo}FJ`dx;*?waAYDa_d)be(N6;9PzV<=TGIP z@sGzpfBTg;o*dZ(VCFZ+Xllk47H-g zR@A=~(yF{tWAjmv8u}tn$G2#){KT>kwy04wdW5;r_6`MtO-k}tg&5rr8|@IBRawGh z*ez8h&D4)!*H|+VeGc!dHUHB>jyN7e$1B1HErO#Vl?8GEMOFDiEkr(qk@pal2!WDc zfRf zmk@vi$>yLP>XT%18TiK#n9-~9tb5h?Wjti#QKLA*&l+_Gc9${Qp%#9ZTS4WR<5eBc zWIQwD9d*1Q;|0uvTdK;ctMY89+mW*QkFGtB3|nGF!=I?sGCI;h33eMF=pn)^OGm|pio+FL-eOYTs8fza!?uAyAsT%N zHF6tIk@pN)gLyDz^ly-O@xU1wi4+B{OyS(|P_f50^EOBo9Ir_BS+y#VgtMWpsF^Q{ zw-}ZAz%^lmvR-g;wYjR;#G|kUXN|O>a~6?9m|sP{u!1-e2&_tEo|lxsT3Uoa@R3=y zzJ-+jpH}O2Ab_%p_-(88x(uYN*0-~IoK-8hlWP6JGrac#0lv_oY4?6eAIh|Fr_M;Z5k z5OFo~*Son!+>Y?B2ZF-*t)v?+oW!{y}R(Z z@&3U!SGNrFv~YKHP;}t_K7(&oxZq9>E`QIs2L$f6#|M``N!R(^Jh;wp#q~ev@DL<- zerWl4f6R4v%iQ?w-`rVNuD8SFs$AKxw_Dk_w_CBj-HKZmwzo6Uq}k-A?U2j$cYd1{ zlI=o~(_BmUi;VkTa?LxjZQX87a=LqP=kvQSr@LrUxP!+LJUHx<`eK$g*V=PZXQzsP zW!(3e)LnbR_W$T9dv)SRkH_nsq-oNgi95JGjMK#Q;|s}kqvAB*D9=+d5xBF8$(8dQ9ht Date: Mon, 17 Jul 2023 09:00:09 -0500 Subject: [PATCH 23/79] updated eos-vm submodule --- libraries/eos-vm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/eos-vm b/libraries/eos-vm index 329db27d88..1e9345f96a 160000 --- a/libraries/eos-vm +++ b/libraries/eos-vm @@ -1 +1 @@ -Subproject commit 329db27d888dce32c96b4f209cdea45f1d07e5e7 +Subproject commit 1e9345f96a4dcefa3a16ff51b58e2e7df739eeff From 59cc737a42611ede24d423aaf5fff6c578de039e Mon Sep 17 00:00:00 2001 From: mschoenebeck Date: Tue, 18 Jul 2023 07:09:21 -0500 Subject: [PATCH 24/79] fixed intrinsic mapping and deep-mind.log errors --- .../eos-vm-oc/intrinsic_mapping.hpp | 2 +- unittests/bls_primitives_tests.cpp | 4 +-- unittests/deep-mind/deep-mind.log | 31 ++++++------------- 3 files changed, 13 insertions(+), 24 deletions(-) diff --git a/libraries/chain/include/eosio/chain/webassembly/eos-vm-oc/intrinsic_mapping.hpp b/libraries/chain/include/eosio/chain/webassembly/eos-vm-oc/intrinsic_mapping.hpp index d9ddce7585..ea92a9cf86 100644 --- a/libraries/chain/include/eosio/chain/webassembly/eos-vm-oc/intrinsic_mapping.hpp +++ b/libraries/chain/include/eosio/chain/webassembly/eos-vm-oc/intrinsic_mapping.hpp @@ -274,7 +274,7 @@ inline constexpr auto get_intrinsic_table() { "env.bls_g2_mul", "env.bls_g1_exp", "env.bls_g2_exp", - "env.bls_g1_pairing", + "env.bls_pairing", "env.bls_g1_map", "env.bls_g2_map", "env.bls_fp_mod" diff --git a/unittests/bls_primitives_tests.cpp b/unittests/bls_primitives_tests.cpp index fe37fc2895..08846766de 100644 --- a/unittests/bls_primitives_tests.cpp +++ b/unittests/bls_primitives_tests.cpp @@ -350,7 +350,7 @@ BOOST_AUTO_TEST_CASE( bls_testg2exp ) { try { } } FC_LOG_AND_RETHROW() } -/* + BOOST_AUTO_TEST_CASE( bls_testpairing ) { try { tester c( setup_policy::preactivate_feature_and_new_bios ); @@ -407,7 +407,7 @@ BOOST_AUTO_TEST_CASE( bls_testpairing ) { try { } } FC_LOG_AND_RETHROW() } -*/ + BOOST_AUTO_TEST_CASE( bls_testg1map ) { try { tester c( setup_policy::preactivate_feature_and_new_bios ); diff --git a/unittests/deep-mind/deep-mind.log b/unittests/deep-mind/deep-mind.log index 3096fa67d6..e6531fb652 100644 --- a/unittests/deep-mind/deep-mind.log +++ b/unittests/deep-mind/deep-mind.log @@ -118,10 +118,14 @@ DMLOG APPLIED_TRANSACTION 3 3cea935e0deaa090b14d4ee01f3fee31a1c426779f1c32840aef DMLOG CREATION_OP ROOT 0 DMLOG FEATURE_OP PRE_ACTIVATE 0 35c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b {"feature_digest":"35c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b","subjective_restrictions":{"enabled":true,"preactivation_required":true,"earliest_allowed_activation_time":"1970-01-01T00:00:00.000"},"description_digest":"e5d7992006e628a38c5e6c28dd55ff5e57ea682079bf41fef9b3cced0f46b491","dependencies":[],"protocol_feature_type":"builtin","specification":[{"name":"builtin_feature_codename","value":"GET_BLOCK_NUM"}]} DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304002,"value_ex":54636,"consumed":9440},"cpu_usage":{"last_ordinal":1262304002,"value_ex":232657,"consumed":40101},"ram_usage":180802} -DMLOG APPLIED_TRANSACTION 3 04ba316cf9ddd86690833edc0f4548f8c07f0d66c09dca029b0a1fb96f16c62803000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0100d007000010000000000000000080000000000000000001010000010000000000ea3055302a2f1713925c939a997367c967b457bfc2c580304f9686b1de22fc5946e40616000000000000001600000000000000010000000000ea3055160000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed32322035c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b0000000000000000000004ba316cf9ddd86690833edc0f4548f8c07f0d66c09dca029b0a1fb96f16c62803000000023b3d4b01000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd0000000000000000 -DMLOG RLIMIT_OP STATE UPD {"average_block_net_usage":{"last_ordinal":2,"value_ex":0,"consumed":0},"average_block_cpu_usage":{"last_ordinal":2,"value_ex":833334,"consumed":100},"pending_net_usage":9440,"pending_cpu_usage":40100,"total_net_weight":0,"total_cpu_weight":0,"total_ram_bytes":0,"virtual_net_limit":1049625,"virtual_cpu_limit":200200} -DMLOG RLIMIT_OP STATE UPD {"average_block_net_usage":{"last_ordinal":3,"value_ex":78666667,"consumed":9440},"average_block_cpu_usage":{"last_ordinal":3,"value_ex":334993056,"consumed":40101},"pending_net_usage":0,"pending_cpu_usage":0,"total_net_weight":0,"total_cpu_weight":0,"total_ram_bytes":0,"virtual_net_limit":1050675,"virtual_cpu_limit":200400} -DMLOG ACCEPTED_BLOCK 3 03000000030000000200000000000000010000000000ea3055000100000001000240e54a7b27e042b80a810153bec1dd166eef95fa69f6c9886ae283363bc2add80100012d5b1b639d6ae94fcdd0536b224644931573d1ccb2a0c548613cd1feea18888b0200000000000000010000000000ea305503000000010000000000ea305502000000000100000001000240e54a7b27e042b80a810153bec1dd166eef95fa69f6c9886ae283363bc2add8010000000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd023b3d4b0000000000ea305500000000000213588be25132b4167ced6df22b5439e376d5a20284190bb94a43e3e86c50d366bd80731342402e85b2ddc0052985fd31301156b938d7325ded2582756e40bfbc4f83b79f8de2f5d0c5394ffcc2f724830bb6b5ed9dcd5dbb4a09139800000000000000205d7ce507e9dbea47687e80fceaf2794b22bd883902adeb8c97de9f7283b614b0590bc4251ba5410cb035f88e60ffdf6fccecd10d83edfe36021227d1ee9e18830000000029807708239aa7de914d3ed61e9009ab2280bfbc50f1d9769f27f8341ef26198000000000001010ec7e080177b2c02b278d5088611686b49d739925a92d9bfcacd7fc6b74053bd0001023b3d4b0000000000ea305500000000000213588be25132b4167ced6df22b5439e376d5a20284190bb94a43e3e86c50d366bd80731342402e85b2ddc0052985fd31301156b938d7325ded2582756e40bfbc4f83b79f8de2f5d0c5394ffcc2f724830bb6b5ed9dcd5dbb4a09139800000000000000205d7ce507e9dbea47687e80fceaf2794b22bd883902adeb8c97de9f7283b614b0590bc4251ba5410cb035f88e60ffdf6fccecd10d83edfe36021227d1ee9e18831400d0070000fb05010100203b7de491b51d3d74624078bc2c5dc4420985f0350afb6923a5585b5621750c9f126d7cff0efeade2068c7b618fc754b2abb5bff8cdb9bd0ecb4432b72ae1ed380100a82f78daed5c7b8c5ce755ff1ef7357b67e3ebc6d94c3609f9e662d0b8a4659bb8eb2575dbbddbc476694b9cca2dfea3b0bbd99d647776bdbb9e1da70e0adead081045158a7894b6405524a4d21424545aa8cacb0d0815a94891fa20414284ff2a025511a245ad54737ee77cf7ceeccb71f09a87545b9e7be77b9cef7ce79cef3cbf71f44fe94f1bf5d03d9f1951f447e343fdf3d87be873f2879efef473830dea77fff59e7bbef7f440d3bfd197d9f57368d1bfa54767949ab11b9736d48cd9b8840f7a0b372ed11f35136cf0436fe80dfac0b80dbc2afa67f84d6306e6063201ad97a8ff9234d00880f033d54c84469e48cd68b03c8b3ea54dd0909531c1fc52d0b0ed95c70e2dae4f3fd29eed5de8b6a767e77a8b8fcdf6daf32a42d7cd6bdd76d9548e51317aeaedd5f5c5d5e9d9f5f576b7a72c9aa273ed73ebed9e4af025c3b4d595e9f9d9deecf4fae2cfb4558d9b09defcf4409f1a2aa7cead3d2e53ebddf6f90b8b40e6426f41a568ba89e04eaf75171f5b5c6e3f4ac8d519393476dbebab17ba73ede9e5c5738bbd75358c9e70f6e155c24ae17d44a6aeaeadaeb7e7f1327f61aedd5d5737a1d3a1f3e1e5d5b9a5b985d9c595e9b5d9eeecb9768ffae9756e8956e29db9475f6918efa23e77a1db6daff4a67b8be7daea00d316339982ed81b579743afff0f4238b2bf3d38be347558696da34d17361b9b778af3a88ef0707693c3db73adf56868958aed36dcfb5097257d61a2280580ef09890d1fac2ec3d6f1c57af61e4a877bdb74a6445ffcd681aa6a60b6bf3e02dda0ed993275414abb8369444511c0f0d594b9f517c8b1e31237624a07ff4371cd123d60e51efd0adb7da86ff63ab8f46725b10ea353d34145aad7434623774b17959a51baaf8d45f568fb8a6c3d9b5b5e5c7d5eb6a07b42a745a7bfdd83d47c727ee7bd39b87fe66539f0854767bbaa9b5dd3093f2d7a9078655417f5be683f4a5c81ecb752737e3f44d5a9f9cccad539d22ee1417cfe76a9c1a9c29b29e53ef1ad64e4faa62e3c4b0a9dbb45007e81ff5e90e663b4d2fe83d39aca9bdf8cdcb2a33ce1e489d4d8d4ac7b5def8415a6e29a755c64d9d66d262f59651832ba175dc6cd2f3ad0a40313352c533b4f3ffd03ada2854d3601718b7043ccf3b757258611fef0076d96d07d2ecce62649cc0127ae5968b8d4e1e38ddc96ecbb17da75c405b74f67c6e4ed034553cd1c92da19207457c3ed70f0c1b0c21ac685a71b19387d4d78c9c75da192c1c776901daf9131d02648088f62d173b2e62184ec68434c5f29bca465367881c84970c54f4d1c22c80549d0a2430a126fe9ede4b742b469a9637a28be0ed843e6191fd00d024d49de6bd366d0a5a6777d2dc74429b0dde36f5df9e6bec7a5859225a9339fce1c9dc60ae39a894d39e26292146a426345d7a93f272c2484b6b9e2e1154e1a0398c01a6a8778011febd839629d7b3d95d34d54c62415e4c31a2584ca6381a31acea26051d200bf4245168a23feb1ca6d5d2043cd2d9e1eda8f8f61f4e43950da9f42744a85e22fae9c3a08b2e5e0021137ecde82da8ded0adb2d78ef257a75be822622d65756a7949d1bae92fd774c0846b1104fa0872b354c43fcee7e5eb2cceaa08c0b2a62194695a9245a3dc961b6c411509c9112f456fcd80799088f838bb54d8415018cf5c23410b00c783082a10f50e84dded3abb44840118013088481f4a76fd881cda17441ad78fc81dfb8288bb7e440eef0b22adeb47e4ee7d4164ecfa1139ba2f884c5c3f22c7f70591cb6a174cf45e9898014c4c05e33982a10750d17ba2a2050223a0592d1118361ae9778cd51be612eb3957aa3975c4aadc4cb9a78eab14d660aa456f43fc36466f357e9ba03728426c01e32d8f870db33cdef01bc66b7ec378b62d9fc883fbd4017a0b8ae4b1fbd44dfc96d1db30bf35e8ad8e193c2eaec645d5b8b01a17f0fa0d5edf1c57b70aee99c7e5f60a97d10a97db2a5c1abc0b8cbbb9dae36baa3d1eacf69809ce8a9118e10581c42db234bd1d1264d57dea2e2107b5fd4035eece6adc1d6459c844b286602bf4adefd3fe7f92f6da533efd522076fd194daed5619535e0fa38f56e78155bff121a57aefcf1b77ee7d73ffde2d44f929380af57ae7cf6db5fc35720b9b9b9f9fca7fff04f3e72cf43c356be5efe95ef50ef43c3817cddfc230c7ef770e22c7c910f12ba05b9544fd1d3d923f6297dccb263414ecb8f8ed693d42f71e55b1f7e71ea3dbcc4339f7cf1c57ff8e047bef6f98d3ed0bfffbddfa0efef1e8e05ea3c3dc8c59e119833c76c4b409205c8de305a8f539ef639d94705e5437ffbf257805a244096e9419a6541802c1cb3ce03719decded17a94fab537bffde13e10c0fc28808402e4494c08c8c5f6fbdba4fd251e4ed2c9de385a0f531979861ee1b8392de34e1fb3137ed844273b365a0ffcb01e3da271b326c3d68ed9861fd6e8643f365ab77ed83be9118f9b5332ecd4313be98791a20538e3c73d013cc6cd451977f198cdfcb8ac931d1fad6b3fec7df4a88d9bb332ecec313be6878d75b2b78c52f891dd415f9ed190a6d7283eb3194e0bf99b27b324fdb2d131046c8ce4ab19389231e8eea0198a568f24ccc8823c7e4064cec5c507d8f58eb3db9a86d1a0a6039d62ed3cbbc37007e32c240f3f2848d65b2e98526010b5769ab010ae038f30f1b0e277b025f8f92fc012a09310635fd260540df077b6d2bce4647f5eea12572b34fae9bc53d4007b414c1f3719351cc2e45a47da98c714f14094031716fa8220d5eabc4ea926751db1ae09479bbacec3d7e6082462fb1461abca25c5157dde4507b51a2086c978c36344650a3d2378e671fa73468757a36d79743d753d30ed296b52d09ec5612f0283b22d4fd91dd44c795b25e102f218997a4c0750d45614c9842289d0ac0145dae9d3e6886dbd0245a283666f5a0cf7652e3b927edb50e84a24f9b8b911f2f6450ad6157d667654f6725c1e13781095c6095c40a756866653a3bc550e555cd032934211daf1045303a7069d09efb9ea4c8ed96760595ee05e97205a1662d29e4bb22a1c7fa6ae9359cfe89cb9c55d2f6881ee71268c99452f700b562d5b1a1523aec20199181db4bb70e1e346d870f3e0d1c79cac96feaa3511197562c7a6be91227a4a1e93f2382d8fb3c29aa3f218ab38045e819050a478bb8c2816e738036dbe496c7b2b734d58365171658c8f34c2d75d5846ebcdc8eced1c6b0d722c138e3564d24cae847bf4581304060ec559728fe871baa9f138454a891e93cda1abf069c8c125c2790976e1d4a6de7960ee4ebf6775c207e6867108142639236748b4227fcf8884fefb560ebe02cf66fa3cdbd4b229614a764ab856bb1ad78840bb706d53ced910b85613ae65c0d8d5ae81718cc54bb2c31a2ca4eaaf98418892b289d978cc2ec8db647f6dac54cd430309821d9c450e083949b2b45f31bbb673bbb9f7b9f5d2f05e4e35e586844ea48239adfc6095dd46019b2246227596a5a3900f24d5c897ec33dbed18927e2e14b3ff4db5b71e8e2b5d9c94ba38f1eb267d5d9c6c93aaa4b4fd7071f6949a44a4060a93c5252b46af76aa9f17f9a8ed38d5a72be161d1b986537d7a40386604cfb395626a99fbd91010518ab173cd9a77ad2db8572bbef6ec575ffbe030ab7ea44c3397c7d43ab6ec7d8b182e223fcef421e535c0d2a77032e9f85b56ebe8815339b682d93966a4d726348cef82e03b431009d0e9a53c06b221840833428f28fca9af13a231231a6e4174461ef38209a000d1b08f682888f2bc15993a2f324be42e6596e6cd88d6f1d0e22c4fa5fdf440fb99b23d19907119c6f957efacdd4fed792a6a1ab27f2015ce672d957a25426f3763619dfd083b3a2f3e074727ad952a33fd4598347de34ddae92d7af1ecdede06fb1ba52dfb22f46243ccbad8b2c957f040763767c99ee6ec2a0ec8cc80ffb1b6c5b5d8d59c5d456f95562cbc8a15bb8c8481bec479f2cb8a83576477103b2134297833766a03e859f16345c3e5014e2ce144f8fbe347e87338f7d17ff9cc37de40bccf5038390595c4d11069b50772d522cd826f2758303e7b993d600b7e247ed49492c8ee0436d4cac3615d2f87d4113d31a3127ecb3a651878d20f7e6058a7a20b8abb3b790492d3493b816202e9da850e1020c1715cd2e19ac0034c1412e8900b3329c7b818a4a038c326b5442e947a482ee11feb6eff967ecc4af4b0a93df57212ab2306e25629e6b054cca1e742d857cce136e90dbd62862e15511a70ca4eeda2a343d6d1c66ba3ad815acb1c45be8e75370825dac2727c717440afb364676ff3ca3de21e7a1b14e6ad2e40eca2bd1db718648f2a151f5d9be326fa1af179c04a964f23407ad373ff00fdbc66e20a9868a6e24b34d070054ab45329e15f30da6e38613b54129f42944b2cca25c1d2568a599fe40cc08a40086639cbca8bf9c04cb15c21c6dd3f90287bec23b44687a34186a6010df5a3dc6e83a6fb395d55ca871ec8e932b4f4dff50d2261b00709d51e2095b84c7b8084d0ecdfa6bf6e593346bcf1a069a6147c3bae9271dabb19d2f18e2ca7f470d0d4db7989efc2d471029d4b6e48579071e69a73cee2097b75459d7711f21379d4fbfd27096e54c49d664487980c1249ee79d2435ea9f20e12d9526d891c083a7af613b97950aaaa2e5ecadeeb7bcb8de5c949d699d0facebc0b03a983cc81613726c1eee85b728274a564f0835229d2eeb4f5cbd2495adaa14e7857b52a5bc14dd007466aba21a8e469a2b7d124d84a934068120dd224649a18a189014d42170dd0049ed95b0cb248f5bedcb868a9703bd0447291c8da1c40b3e93940be207c54a4a6b886bc7b117510e2401155977b7f1545d441506511065af8da8aa8bb2162b13bfbaa8ba8af0e9143fb8248e3fa11b9635f1071d78fc8e17d41a475fd88dcbd2f888c5d3f2247f7059189eb47e4f8be20b27b11752f4caeb188ba072aba84b05b11f5b7c52f0ff7d1fa243badcfa0a68d5cb2cdfa88ed89c5ba180a3b617822313ce4122f650f55db492aa32ac3c5b925e55d591f52c61c4103346f04d4499660a128307e701712259ca6a0686e2bb738620389fe53f74397cc27502417c677740825f24bab6b48755e104ec1521e88c7b8f1ce61d6e6e46052e81dba402e3489b3cf8fa03f5130266727d7127d87f065450042870b65e4efa896783641cea40b386e534211cd496d89d4789ce65d6a7642602ea55261d877e1a00417a5b0469efa6b46c81821b6fe0b6b62899edd12a79ce47a13416de4108f3b1855443db8d34456556e6d69dc1c433585c2a0f0a4bfcf147074c48d4027e4ea1c9132aceea269dcb2cb0ee54c30d0ed0301b22bf0edfa910ba49183f2e21b12d20588700a0d3bcc63b343a374ba98ce0a914bc8ac629a6cad8684a5810d61c3622925253cf062a7b86bcbd8d82585e3b1a0d551445308dce98108b526112af5d4ab6b75779010321fe9dd61c70f725aa32665158d143697eb10a2b01cc41c82e32d92405471e94a3e90612401c97eca45083c25b8268fb4d1d41e0ce8076632174bd2a67fa5ad2106a2649c079c11d2888b9504c57fc69b03ba4896dcfc1037be2c3b66998e24f0e18f983d667203d9e6e771760b4d8c789c4cfcd873c20fe2dfe94e19df97c5a6b314ac09050981a3ac1d5bd9ad0c0195f7337251b13375c94553fa09faf8d9f7de4e6c232e51b0fa5d4d7e93d4cd82c39c1c3a46b84cf2da25da4ffb1217d21d874a0a071c1712754422ac5c05e864ef1b958188092d5f02909091a01ecd43cf46f60724b28fd9aa7b26c6583e41264cea100a706249b344b44b6622b49296b48eeb94c50a30904f218e9b5c4f844a75c8b130982d4c948a59fa211b0a0b858d14ae8b0ae228c9ee0c4228a4b96bb72004210dc270e5d930600b1c3026c54f683635ab00d6fa688af860cb443a244c1583c0389a4a7e01d9bc3728f5641e4c4d3cf524498b2e363ad80cf5b1f9206340d0ab2081149a08de95e7fc098c40c9b084430c670cf840c2c30f80c1001c72a3194cc61aa744850e3d04b1b03d3ab8d9413ec822bd068f000b0550d7b21ea77848e6d0820405be34e44ba3c3bb979b21d294f9a6ac6c324898105f3eef85321bd08c03a944affa37399518f854a264b612a46b78e9665837e93605c7df919d97b17e9c682fbe3dbc5d7dd9d216f910179773b795c36d3596d57b7a3f85d95244a87095c41ae3ab3cbe7a2fd4522e197c1fc80d02f26553a9bb6d92b5975c9529ea3da1226175581e8e9d003afca4be5a223c8d1dd6b1ca4d86d089879b7c07a5515d1e6079e220f730fc4f674e6e99ea7c4a6fcbec5b315b97b3f59eb3ab0923db26f00ea026b3fed1701dc9cabe6d5492748924e97c0ed7882d6435fae7b86830703b4af160f1a12cd9b407799af2ae171cad3c821f620a5c698a59f511d988b0c5f7a8016e3f291dc2ab0777d1456fbf1dd503b80a996be23700e23d231d6c71ef05b7b3011d3bf7fefb062960728e82342d8b6b900cc5e50dbec311c38292e1586a4afa350f91f328e15902d5b4151ce636bcf6509cd8a85526bf902f5e62d5e00b4f7cc58ebdddca313462bd02c9e921b5ca387a6374204d9fd7261057f07f5de10d68ba6d6a8ec28b4a668ed804fecbeb540c5394c5d81d5f712a95e0a70ced28d8eedc5edb8e1a7e478d6bd851c38f7ba51d855e77e73bb7c585403f322b4766db062503831a25811a7bd801efdd8148311e194556f468346b4cab1ae221176535ef4aa65ff6d6eed590ea1a69b4cfc4317b11a74ca76571b9a9bfb6b2295454fcae08e7607b2565b3aaa404a2baab4a4a807d04be9262717acec8035703032e989c159d754a640147f079ae90f81a37d0872a65dff3ac04ce72a710f181af81841c78579d196a20b6ac8184acb2b8936f32c9302e78707dade56f56a20632263d6b825352ba0e16c569cb65eec0578e41c4c1dab154bf387e0dfaa5635b2e17c0a3adc0700c2faa861597e8700e1ffad5e320f5fa3b9b280b2c81e86e0616488598c1f5dbefe7769ac8451714c7a02d898f57d1edb4a36dea1dc96dafe17d65bcf82a3dd99b868e47bf293ef9d5676f19d0f2b401d6f296b53c59956552f441a5e80df39698a53c4dfd83ec68f9e6aab746f596f937291396399eb1dd6d848574f66d44c0587438c5cd2ca9ec036cf37f0b0de3ebb0c8d80d9a1672b079a95dac8b45a2e2f439ee36e2e48b8db192b550550564771bc377292cdb98a735bb4ffca3a5fdf47ccec8e3b4f77ce450ca314cf8d69fe8047a3f22878e20fcdaff19f79e7434a3c746ebefac0dca7bf7dfbc36328542a6edb820b046600432719855c908c5604614532916a51dc32363fdba353d22d40c25b264e141fc88e82de6f851fa0349af1889da620490914b38808c3880440e860248c3c16513f65ae35786fd00d2ec08206309203d9c12f92a808ca6b80254c19100d29401a447c5226ea72f6500697d00197b3be92355e5d713a3238999b16dc1a2646ac606e245d6be134c3ebc8d41b32bcfd0ec6ed1e3c48a97becfd8ffff8cf51750b65c46aa38fcb211ed36e06ddc30edc657387689ea5ae68c04575f54db8239f95583c21d259e3d51a9c80984574c3ab62bd2debfb351fa2b49df5f09d88a559dc9167f25e0247f69659ca9fc9586f82b6ec05f69f5fd9506dfb13c25f8bc593c83898168ef7819edb16790fea93656c29531b92dc3e9b631e7adb35c01e3727499d6e15008d849b3385d64ef9638319907d92dcef6af04245d64f6d8be210d990cdc472248b8432a9797f8f46523e3e668992de55ca7de35d729a1aa53e9b3b8ea53ba3241e5b634cec1ad82dbf229f257908c2c9ec50b0e635956966141f1157268c47b09e0bdc470e7254625ff212e1ae2bd9832f41c702bb4fca25bfb4b4174e61acb79826461243f15364c32fc34462ea121730a88b0635c868d7c0e5c2e0918c13f3ec1ee2049d102d7fe49ea16fc85002be94fc0ae8acafc3b702f455adcf7b5f2e46906e10294915cc077a9785d5d9574627f8904bb8a21f13edb8a7ed9063b20a15ccd22152117b762a0148b24c4e5c5ad7e469696ab344d799b2b4dffd1a6fc93fef49d8fcc2e2eb7e75d6fd5cd2e2fafcecdf6da6e6df6d1f6ba5a7db8d39eebd197f575e95fecb5bbb3bdd5ee34ded7ddca6acf2daeb87317967b8bd38b2bf3ed8b8a7f0c99def9fe2e0d55ed6e77b5ebf07f5b2cae3c5a4d567cacd310ed8a33e0e9bd73b32b0036476db4baacbb0ed8bdd98797a9e111374bfd0bedae9b5b5de97567e77a8aeb00e9eb77e0786e757ef191c7f744efe581e5fcd06b5cee63cfa9f44df21f4350bb47786176e551225777f1dc6cf771b7d47edcbd7fa1bde22163d7b32b1ebe62cd9ae66bddd5deeadceab2f3ff71488969ffff18e132651a3cdac61cb22ce9dd1756da17d70806ed50684aa83eb278b13d3ffdf0e3bdf63ab05cef752fcc097569ee1f349552ff05ee7357f400d00700008101010100204b21f3cba072cc493e70861540df4677b498b0505a8b8e2a346b85a0c2dd2fc4263c4a7d8629026c4eb594ad96fac2bfe5f8ffebb9c841c353920b7b8ec11abc0100d90778da8d563b8f1c4510eedbf7e37cf209d9e60808402496c0dcdaac4e8ece01090112afe83043ef74ed4e6b677a86ee9edd5b3b2121b049888d842c84c0c1456702eb20b036424242c2e00408800c24fe03d53db3f33a58e860b6bbeaebeaeaaaafaab7f55bff9d1a796df0e5798263c37cc89f2fbe657e1eb8c7cb92e0de5f83c1eded95e4fded2d08150faf5ea5237e69f7855db2d3c199e351e5915a339c0b900d4103681849dff5c09daa3818bc34ec5057f319d54036b6c640752cc1617c024a17515d1a6b2f945c2f48a3ab3d09ca0b7dd68ab9d097078d292cd4267e9c39f089a70faea351378c85563b11c8802bf44c383eccc0cf20cd39e55a9d31df4c766ee487eed4f528174e4425baab412ab2fd44400f1dab73046827567402f6ece195a73495139455b44ee4ead4bb1db3594b2a94b929fa51367179f0f4882adc00722dea6c6edb0798d3452a7fd60d858643ed8c2598c8297bf18227220efe2f948148a1851bbb515c72a47ce34cbbeec655133b0106781de0c9aa059f8f41f3200b19833148090c41870e1c465c528b9b73c1c2798a3a57b5c2c0cfe276de28b9f0b90027552b7e6375c085d35a0691f6ac7a7768c39351b2a4eabb54b8e0dba3486d2b597131b1f0b3553ab68cff9c15a9dec3adc83b0327b5764a645b3bbd7c77b2ce294f6a755cf4a278e473d7c1692b91a74e75d083a9b5d828596cb8218364a6175132eb4b782fe61202581d2b906ec926dcee4a2cd2302de6ec9354785ea52d5bd5900bda21ea652849adab4030243b676debdc60af83126d32d91c2d34a85341c20682e6d233ab41b8f02f154e6a05e4e9b897c2b319c990c52e3a859123b533d932bbdf76c276c527c2e4b21ceb4d8cd8aa8bb1b56dac6d90260d1b8db10c036bbaa54063abace4ba8ea2241c3da3f77980ddaa92bd2e7628c7629ab617f54c2527174b05a6ae8a8236da3229af186acd0293fea689c65e7716ccb0eb61a892b5e548eeca2475a55ec7d3d32658c78357533c329d62a2b5eda28a6cb492c93f3758e35524f9ac128236578e11276e742c286468aca330a42cf661ab98b783ebbd58643cafff27cf7b71c4685a678db575669c5f1543c3e0735af70bef07a975ec4a819b769132cbcc6379f1637c36f3278f7c7debe2cb1f7c7eadd434c8feb73fdd3bfaf4956223c0f1fcb4fec587792193fd4fee3cc31edc2956278e5f1fdd7cfc59566c1fbd39fc19d8d14999a138ee42707492b171f5c0afa848c877af9e78c7cb22f570ec3f77fb789951c882be4940930cf4f0d1db6fdc5f16528fe3ddaf0eee2fb324e3d8fb1e057942cd851ffef1fb8fc5fcd920f8af3f2e66c9fcffb84b7ff865b7ce875708c9ff60d8f137aa5a1fa900d00700001001010020742877c36a520b152b1337ea1ecd37b0c98ad07289c32fec392e7eebab9f0ac71f7bc8c718cfa75317b2e15702372a9222c4616783ee7b3f0ec6358f8c328eea00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232201a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b72410000d00700001001010020058e23368b919493d6ac61d27f66b829a53893e88ddde857d3b82d913960960d22fa36f397752b98c295e3b31927f740127c0a99e76f8bfeea88f44466b8fbfd00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea990000d0070000100101001f43fe868e263d8134cf705aa85e26ce78ebb058edd558865fa3d240f5cb9e50c2389e9c8276eac800b7233a552045b2e79124c97e5156a0649849cc7f5d09eee600005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232204a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0f0000d0070000100101001f29e82b08ccf15e2187f29fea11ee3f4974f41b51e45b19f353348d8848b86fb71cadd88630456b7a1c60803c7b402487d41fbf18f0b0a13b4cca1f740447938300005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220e0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff5260000d0070000100101002047a8b784c3765b5c63ac52e3d8461b80bc2d3e3f62434f8accb277d9f2487cfd3c0728fcd26b5119a11288e5db46bc5b547877e220971609d1cef8cba443340800005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed32322068dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a2974280000d007000010010100203e701fbafd4149bc95b55a6bfc3b78246f5c2668ccc05ed4059a36ceb38f140b31e3b69e15f2579571e5bde39e034947271599c200e540b3949112bef163074c00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c430000d0070000100101001f0cc7352e60f4f8476783d6d1b48766a111c56fee2c1a552e76a75c92bc17de172f994ffc854c09717c904054819ca7a17379ddecaf531c439b35337ba099b81300005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232208ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a4050000d0070000100101002040965063a83be2d53b36c8d7e0775f503c2caa1407e586314562aace52c272fe60659e196413a6c9db4168470bcabb9a5851121c10c7b665f363f6cd4d1e4bda00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232202652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed250000d0070000100101002074ea7468b2a031c4cd53bf10ec3ac66b0c4b5c8779e045f1ef8d9c7b116be649217ff340107d0163397b99918ee2ce822b66cd6fce7b385af97a04671136e2ee00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d0000d007000010010100204dfb21ca5140582379bc026792c16b4cf97827143a4a9cd99ae70b3e6016cd6316bcbb9f1cb1233f12a0bbcd9debafa64724d0459b5c8d3cb67ceddfb2e3962500005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232204e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d670000d0070000100101002033446a3a94ade71dff3edb786259679487ab701bbc147490b1d4159fecf545fa22fee0698db16bf616465e5cebb985bfc4d9ed1ec4a55e38997dd4b4bbc427eb00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232204fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c20000d0070000100101001f3f67edd35bf731a07f40c638e8812112cd7d1baa39ec7dac4a1b2f0c83ac8bd53689b56dba69a7386e3860a6f8976695ac0bc2b5dacae91080f1d54df2dac0c000005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b44767070000d0070000100101001f1e030564013603d54f9e983b63cd940f8ff09ae038b14813f4021bb0c09ebb640d90cb4f8d57be2809f492a51737b671a5f549d4efa8e7efdaeaa9663c09d1ad00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead450710000d007000010010100205cea642eecf05568ce8c5564e63349eea3b816108914ba2ab5efffbb8ea467265f0b6d474f03ed02a3bf529fd6e55a595cbf8dd1adf4311cb9c51e862f8a535400005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232205443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b40000d0070000100101001f4556076cc86e0840bf69664f1ef8fcd4d91abda313d08e7840d24ba45cb429cf12b7d3a1f64250c19d1b975e7b107853beff70ebfc4c27c44f825dc05cdc9cd600005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e990000d0070000100101001f354d903ad0f2c6cc9d9a377d681ffaa00475d1e559e48074b4c8cce3111d5c172903b2f179ad4d736dda4e7d1b6a859baeab9dde5e5e495ce09733ec4650634400005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb400000d0070000100101001f1766fa716a828da244c9ce52919b7a19acb38dbd110d1bb0039bb2477c17e4465dceecb8330ed5ee9de1330930dfcfa1a5e8149ce8536a82c0093642adf7328200005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232206bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc0000d00700001001010020488923db1c78fa430a3a9eab75f4ee467c7b9a3d3b4eb3bd08e183c82ef79b9102a4d2a7d1ec79c96b404911ae1b10f579bd82a660011c1ca2b872b30ef7dcac00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed32322035c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b000001 +DMLOG APPLIED_TRANSACTION 3 04ba316cf9ddd86690833edc0f4548f8c07f0d66c09dca029b0a1fb96f16c62803000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50100d007000010000000000000000080000000000000000001010000010000000000ea3055302a2f1713925c939a997367c967b457bfc2c580304f9686b1de22fc5946e40616000000000000001600000000000000010000000000ea3055160000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed32322035c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b0000000000000000000004ba316cf9ddd86690833edc0f4548f8c07f0d66c09dca029b0a1fb96f16c62803000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50000000000000000 +DMLOG CREATION_OP ROOT 0 +DMLOG FEATURE_OP PRE_ACTIVATE 0 98c4175db53ed27e7911a1b5adf0e7db0fc96c2cae172cf594dfa9a742ca9e88 {"feature_digest":"98c4175db53ed27e7911a1b5adf0e7db0fc96c2cae172cf594dfa9a742ca9e88","subjective_restrictions":{"enabled":true,"preactivation_required":true,"earliest_allowed_activation_time":"1970-01-01T00:00:00.000"},"description_digest":"01969c44de35999b924095ae7f50081a7f274409fdbccb9fc54fa7836c76089c","dependencies":[],"protocol_feature_type":"builtin","specification":[{"name":"builtin_feature_codename","value":"BLS_PRIMITIVES"}]} +DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304002,"value_ex":55377,"consumed":9568},"cpu_usage":{"last_ordinal":1262304002,"value_ex":244232,"consumed":42101},"ram_usage":180802} +DMLOG APPLIED_TRANSACTION 3 793b276fb55f2f81cbdcfcaf882555ea5dde340f80c16e5dc652ffad52eea87c03000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50100d007000010000000000000000080000000000000000001010000010000000000ea30553a97dc6254ea785e8c6ee5994044fae975bfc8ef1916a24b476a984724cc5cf017000000000000001700000000000000010000000000ea3055170000000000000001010000000000ea30550000000000ea30550000002a9bed3232010000000000ea305500000000a8ed32322098c4175db53ed27e7911a1b5adf0e7db0fc96c2cae172cf594dfa9a742ca9e8800000000000000000000793b276fb55f2f81cbdcfcaf882555ea5dde340f80c16e5dc652ffad52eea87c03000000023b3d4b01000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b50000000000000000 +DMLOG RLIMIT_OP STATE UPD {"average_block_net_usage":{"last_ordinal":2,"value_ex":0,"consumed":0},"average_block_cpu_usage":{"last_ordinal":2,"value_ex":833334,"consumed":100},"pending_net_usage":9568,"pending_cpu_usage":42100,"total_net_weight":0,"total_cpu_weight":0,"total_ram_bytes":0,"virtual_net_limit":1049625,"virtual_cpu_limit":200200} +DMLOG RLIMIT_OP STATE UPD {"average_block_net_usage":{"last_ordinal":3,"value_ex":79733334,"consumed":9568},"average_block_cpu_usage":{"last_ordinal":3,"value_ex":351659723,"consumed":42101},"pending_net_usage":0,"pending_cpu_usage":0,"total_net_weight":0,"total_cpu_weight":0,"total_ram_bytes":0,"virtual_net_limit":1050675,"virtual_cpu_limit":200400} +DMLOG ACCEPTED_BLOCK 3 03000000030000000200000000000000010000000000ea3055000100000001000240e54a7b27e042b80a810153bec1dd166eef95fa69f6c9886ae283363bc2add80100012d5b1b639d6ae94fcdd0536b224644931573d1ccb2a0c548613cd1feea18888b0200000000000000010000000000ea305503000000010000000000ea305502000000000100000001000240e54a7b27e042b80a810153bec1dd166eef95fa69f6c9886ae283363bc2add8010000000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b5023b3d4b0000000000ea305500000000000213588be25132b4167ced6df22b5439e376d5a20284190bb94a43e3e841639eb3a733e9536932b85f63002945d82e25a0ef948f220ba098df51ab2f5d9d5fc55180118b2a44ae7b7ad158b7de8fee6df8ac1c5afd3681c5b11460ac9600000000000000205965a329efe657efedb21975c97dab14e1d8cfbdcd9492177294fcfe876d7c0a1ffb656f523795bea8035bb945520efcb50606d38965fd0fc8c94a2a99f28e510000000029807708239aa7de914d3ed61e9009ab2280bfbc50f1d9769f27f8341ef26198000000000001010ec7e080177b2c02b278d5088611686b49d739925a92d9bfcacd7fc6b74053bd0001023b3d4b0000000000ea305500000000000213588be25132b4167ced6df22b5439e376d5a20284190bb94a43e3e841639eb3a733e9536932b85f63002945d82e25a0ef948f220ba098df51ab2f5d9d5fc55180118b2a44ae7b7ad158b7de8fee6df8ac1c5afd3681c5b11460ac9600000000000000205965a329efe657efedb21975c97dab14e1d8cfbdcd9492177294fcfe876d7c0a1ffb656f523795bea8035bb945520efcb50606d38965fd0fc8c94a2a99f28e511500d0070000fb05010100203b7de491b51d3d74624078bc2c5dc4420985f0350afb6923a5585b5621750c9f126d7cff0efeade2068c7b618fc754b2abb5bff8cdb9bd0ecb4432b72ae1ed380100a82f78daed5c7b8c5ce755ff1ef7357b67e3ebc6d94c3609f9e662d0b8a4659bb8eb2575dbbddbc476694b9cca2dfea3b0bbd99d647776bdbb9e1da70e0adead081045158a7894b6405524a4d21424545aa8cacb0d0815a94891fa20414284ff2a025511a245ad54737ee77cf7ceeccb71f09a87545b9e7be77b9cef7ce79cef3cbf71f44fe94f1bf5d03d9f1951f447e343fdf3d87be873f2879efef473830dea77fff59e7bbef7f440d3bfd197d9f57368d1bfa54767949ab11b9736d48cd9b8840f7a0b372ed11f35136cf0436fe80dfac0b80dbc2afa67f84d6306e6063201ad97a8ff9234d00880f033d54c84469e48cd68b03c8b3ea54dd0909531c1fc52d0b0ed95c70e2dae4f3fd29eed5de8b6a767e77a8b8fcdf6daf32a42d7cd6bdd76d9548e51317aeaedd5f5c5d5e9d9f5f576b7a72c9aa273ed73ebed9e4af025c3b4d595e9f9d9deecf4fae2cfb4558d9b09defcf4409f1a2aa7cead3d2e53ebddf6f90b8b40e6426f41a568ba89e04eaf75171f5b5c6e3f4ac8d519393476dbebab17ba73ede9e5c5738bbd75358c9e70f6e155c24ae17d44a6aeaeadaeb7e7f1327f61aedd5d5737a1d3a1f3e1e5d5b9a5b985d9c595e9b5d9eeecb9768ffae9756e8956e29db9475f6918efa23e77a1db6daff4a67b8be7daea00d316339982ed81b579743afff0f4238b2bf3d38be347558696da34d17361b9b778af3a88ef0707693c3db73adf56868958aed36dcfb5097257d61a2280580ef09890d1fac2ec3d6f1c57af61e4a877bdb74a6445ffcd681aa6a60b6bf3e02dda0ed993275414abb8369444511c0f0d594b9f517c8b1e31237624a07ff4371cd123d60e51efd0adb7da86ff63ab8f46725b10ea353d34145aad7434623774b17959a51baaf8d45f568fb8a6c3d9b5b5e5c7d5eb6a07b42a745a7bfdd83d47c727ee7bd39b87fe66539f0854767bbaa9b5dd3093f2d7a9078655417f5be683f4a5c81ecb752737e3f44d5a9f9cccad539d22ee1417cfe76a9c1a9c29b29e53ef1ad64e4faa62e3c4b0a9dbb45007e81ff5e90e663b4d2fe83d39aca9bdf8cdcb2a33ce1e489d4d8d4ac7b5def8415a6e29a755c64d9d66d262f59651832ba175dc6cd2f3ad0a40313352c533b4f3ffd03ada2854d3601718b7043ccf3b757258611fef0076d96d07d2ecce62649cc0127ae5968b8d4e1e38ddc96ecbb17da75c405b74f67c6e4ed034553cd1c92da19207457c3ed70f0c1b0c21ac685a71b19387d4d78c9c75da192c1c776901daf9131d02648088f62d173b2e62184ec68434c5f29bca465367881c84970c54f4d1c22c80549d0a2430a126fe9ede4b742b469a9637a28be0ed843e6191fd00d024d49de6bd366d0a5a6777d2dc74429b0dde36f5df9e6bec7a5859225a9339fce1c9dc60ae39a894d39e26292146a426345d7a93f272c2484b6b9e2e1154e1a0398c01a6a8778011febd839629d7b3d95d34d54c62415e4c31a2584ca6381a31acea26051d200bf4245168a23feb1ca6d5d2043cd2d9e1eda8f8f61f4e43950da9f42744a85e22fae9c3a08b2e5e0021137ecde82da8ded0adb2d78ef257a75be822622d65756a7949d1bae92fd774c0846b1104fa0872b354c43fcee7e5eb2cceaa08c0b2a62194695a9245a3dc961b6c411509c9112f456fcd80799088f838bb54d8415018cf5c23410b00c783082a10f50e84dded3abb44840118013088481f4a76fd881cda17441ad78fc81dfb8288bb7e440eef0b22adeb47e4ee7d4164ecfa1139ba2f884c5c3f22c7f70591cb6a174cf45e9898014c4c05e33982a10750d17ba2a2050223a0592d1118361ae9778cd51be612eb3957aa3975c4aadc4cb9a78eab14d660aa456f43fc36466f357e9ba03728426c01e32d8f870db33cdef01bc66b7ec378b62d9fc883fbd4017a0b8ae4b1fbd44dfc96d1db30bf35e8ad8e193c2eaec645d5b8b01a17f0fa0d5edf1c57b70aee99c7e5f60a97d10a97db2a5c1abc0b8cbbb9dae36baa3d1eacf69809ce8a9118e10581c42db234bd1d1264d57dea2e2107b5fd4035eece6adc1d6459c844b286602bf4adefd3fe7f92f6da533efd522076fd194daed5619535e0fa38f56e78155bff121a57aefcf1b77ee7d73ffde2d44f929380af57ae7cf6db5fc35720b9b9b9f9fca7fff04f3e72cf43c356be5efe95ef50ef43c3817cddfc230c7ef770e22c7c910f12ba05b9544fd1d3d923f6297dccb263414ecb8f8ed693d42f71e55b1f7e71ea3dbcc4339f7cf1c57ff8e047bef6f98d3ed0bfffbddfa0efef1e8e05ea3c3dc8c59e119833c76c4b409205c8de305a8f539ef639d94705e5437ffbf257805a244096e9419a6541802c1cb3ce03719decded17a94fab537bffde13e10c0fc28808402e4494c08c8c5f6fbdba4fd251e4ed2c9de385a0f531979861ee1b8392de34e1fb3137ed844273b365a0ffcb01e3da271b326c3d68ed9861fd6e8643f365ab77ed83be9118f9b5332ecd4313be98791a20538e3c73d013cc6cd451977f198cdfcb8ac931d1fad6b3fec7df4a88d9bb332ecec313be6878d75b2b78c52f891dd415f9ed190a6d7283eb3194e0bf99b27b324fdb2d131046c8ce4ab19389231e8eea0198a568f24ccc8823c7e4064cec5c507d8f58eb3db9a86d1a0a6039d62ed3cbbc37007e32c240f3f2848d65b2e98526010b5769ab010ae038f30f1b0e277b025f8f92fc012a09310635fd260540df077b6d2bce4647f5eea12572b34fae9bc53d4007b414c1f3719351cc2e45a47da98c714f14094031716fa8220d5eabc4ea926751db1ae09479bbacec3d7e6082462fb1461abca25c5157dde4507b51a2086c978c36344650a3d2378e671fa73468757a36d79743d753d30ed296b52d09ec5612f0283b22d4fd91dd44c795b25e102f218997a4c0750d45614c9842289d0ac0145dae9d3e6886dbd0245a283666f5a0cf7652e3b927edb50e84a24f9b8b911f2f6450ad6157d667654f6725c1e13781095c6095c40a756866653a3bc550e555cd032934211daf1045303a7069d09efb9ea4c8ed96760595ee05e97205a1662d29e4bb22a1c7fa6ae9359cfe89cb9c55d2f6881ee71268c99452f700b562d5b1a1523aec20199181db4bb70e1e346d870f3e0d1c79cac96feaa3511197562c7a6be91227a4a1e93f2382d8fb3c29aa3f218ab38045e819050a478bb8c2816e738036dbe496c7b2b734d58365171658c8f34c2d75d5846ebcdc8eced1c6b0d722c138e3564d24cae847bf4581304060ec559728fe871baa9f138454a891e93cda1abf069c8c125c2790976e1d4a6de7960ee4ebf6775c207e6867108142639236748b4227fcf8884fefb560ebe02cf66fa3cdbd4b229614a764ab856bb1ad78840bb706d53ced910b85613ae65c0d8d5ae81718cc54bb2c31a2ca4eaaf98418892b289d978cc2ec8db647f6dac54cd430309821d9c450e083949b2b45f31bbb673bbb9f7b9f5d2f05e4e35e586844ea48239adfc6095dd46019b2246227596a5a3900f24d5c897ec33dbed18927e2e14b3ff4db5b71e8e2b5d9c94ba38f1eb267d5d9c6c93aaa4b4fd7071f6949a44a4060a93c5252b46af76aa9f17f9a8ed38d5a72be161d1b986537d7a40386604cfb395626a99fbd91010518ab173cd9a77ad2db8572bbef6ec575ffbe030ab7ea44c3397c7d43ab6ec7d8b182e223fcef421e535c0d2a77032e9f85b56ebe8815339b682d93966a4d726348cef82e03b431009d0e9a53c06b221840833428f28fca9af13a231231a6e4174461ef38209a000d1b08f682888f2bc15993a2f324be42e6596e6cd88d6f1d0e22c4fa5fdf440fb99b23d19907119c6f957efacdd4fed792a6a1ab27f2015ce672d957a25426f3763619dfd083b3a2f3e074727ad952a33fd4598347de34ddae92d7af1ecdede06fb1ba52dfb22f46243ccbad8b2c957f040763767c99ee6ec2a0ec8cc80ffb1b6c5b5d8d59c5d456f95562cbc8a15bb8c8481bec479f2cb8a83576477103b2134297833766a03e859f16345c3e5014e2ce144f8fbe347e87338f7d17ff9cc37de40bccf5038390595c4d11069b50772d522cd826f2758303e7b993d600b7e247ed49492c8ee0436d4cac3615d2f87d4113d31a3127ecb3a651878d20f7e6058a7a20b8abb3b790492d3493b816202e9da850e1020c1715cd2e19ac0034c1412e8900b3329c7b818a4a038c326b5442e947a482ee11feb6eff967ecc4af4b0a93df57212ab2306e25629e6b054cca1e742d857cce136e90dbd62862e15511a70ca4eeda2a343d6d1c66ba3ad815acb1c45be8e75370825dac2727c717440afb364676ff3ca3de21e7a1b14e6ad2e40eca2bd1db718648f2a151f5d9be326fa1af179c04a964f23407ad373ff00fdbc66e20a9868a6e24b34d070054ab45329e15f30da6e38613b54129f42944b2cca25c1d2568a599fe40cc08a40086639cbca8bf9c04cb15c21c6dd3f90287bec23b44687a34186a6010df5a3dc6e83a6fb395d55ca871ec8e932b4f4dff50d2261b00709d51e2095b84c7b8084d0ecdfa6bf6e593346bcf1a069a6147c3bae9271dabb19d2f18e2ca7f470d0d4db7989efc2d471029d4b6e48579071e69a73cee2097b75459d7711f21379d4fbfd27096e54c49d664487980c1249ee79d2435ea9f20e12d9526d891c083a7af613b97950aaaa2e5ecadeeb7bcb8de5c949d699d0facebc0b03a983cc81613726c1eee85b728274a564f0835229d2eeb4f5cbd2495adaa14e7857b52a5bc14dd007466aba21a8e469a2b7d124d84a934068120dd224649a18a189014d42170dd0049ed95b0cb248f5bedcb868a9703bd0447291c8da1c40b3e93940be207c54a4a6b886bc7b117510e2401155977b7f1545d441506511065af8da8aa8bb2162b13bfbaa8ba8af0e9143fb8248e3fa11b9635f1071d78fc8e17d41a475fd88dcbd2f888c5d3f2247f7059189eb47e4f8be20b27b11752f4caeb188ba072aba84b05b11f5b7c52f0ff7d1fa243badcfa0a68d5cb2cdfa88ed89c5ba180a3b617822313ce4122f650f55db492aa32ac3c5b925e55d591f52c61c4103346f04d4499660a128307e701712259ca6a0686e2bb738620389fe53f74397cc27502417c677740825f24bab6b48755e104ec1521e88c7b8f1ce61d6e6e46052e81dba402e3489b3cf8fa03f5130266727d7127d87f065450042870b65e4efa896783641cea40b386e534211cd496d89d4789ce65d6a7642602ea55261d877e1a00417a5b0469efa6b46c81821b6fe0b6b62899edd12a79ce47a13416de4108f3b1855443db8d34456556e6d69dc1c433585c2a0f0a4bfcf147074c48d4027e4ea1c9132aceea269dcb2cb0ee54c30d0ed0301b22bf0edfa910ba49183f2e21b12d20588700a0d3bcc63b343a374ba98ce0a914bc8ac629a6cad8684a5810d61c3622925253cf062a7b86bcbd8d82585e3b1a0d551445308dce98108b526112af5d4ab6b75779010321fe9dd61c70f725aa32665158d143697eb10a2b01cc41c82e32d92405471e94a3e90612401c97eca45083c25b8268fb4d1d41e0ce8076632174bd2a67fa5ad2106a2649c079c11d2888b9504c57fc69b03ba4896dcfc1037be2c3b66998e24f0e18f983d667203d9e6e771760b4d8c789c4cfcd873c20fe2dfe94e19df97c5a6b314ac09050981a3ac1d5bd9ad0c0195f7337251b13375c94553fa09faf8d9f7de4e6c232e51b0fa5d4d7e93d4cd82c39c1c3a46b84cf2da25da4ffb1217d21d874a0a071c1712754422ac5c05e864ef1b958188092d5f02909091a01ecd43cf46f60724b28fd9aa7b26c6583e41264cea100a706249b344b44b6622b49296b48eeb94c50a30904f218e9b5c4f844a75c8b130982d4c948a59fa211b0a0b858d14ae8b0ae228c9ee0c4228a4b96bb72004210dc270e5d930600b1c3026c54f683635ab00d6fa688af860cb443a244c1583c0389a4a7e01d9bc3728f5641e4c4d3cf524498b2e363ad80cf5b1f9206340d0ab2081149a08de95e7fc098c40c9b084430c670cf840c2c30f80c1001c72a3194cc61aa744850e3d04b1b03d3ab8d9413ec822bd068f000b0550d7b21ea77848e6d0820405be34e44ba3c3bb979b21d294f9a6ac6c324898105f3eef85321bd08c03a944affa37399518f854a264b612a46b78e9665837e93605c7df919d97b17e9c682fbe3dbc5d7dd9d216f910179773b795c36d3596d57b7a3f85d95244a87095c41ae3ab3cbe7a2fd4522e197c1fc80d02f26553a9bb6d92b5975c9529ea3da1226175581e8e9d003afca4be5a223c8d1dd6b1ca4d86d089879b7c07a5515d1e6079e220f730fc4f674e6e99ea7c4a6fcbec5b315b97b3f59eb3ab0923db26f00ea026b3fed1701dc9cabe6d5492748924e97c0ed7882d6435fae7b86830703b4af160f1a12cd9b407799af2ae171cad3c821f620a5c698a59f511d988b0c5f7a8016e3f291dc2ab0777d1456fbf1dd503b80a996be23700e23d231d6c71ef05b7b3011d3bf7fefb062960728e82342d8b6b900cc5e50dbec311c38292e1586a4afa350f91f328e15902d5b4151ce636bcf6509cd8a85526bf902f5e62d5e00b4f7cc58ebdddca313462bd02c9e921b5ca387a6374204d9fd7261057f07f5de10d68ba6d6a8ec28b4a668ed804fecbeb540c5394c5d81d5f712a95e0a70ced28d8eedc5edb8e1a7e478d6bd851c38f7ba51d855e77e73bb7c585403f322b4766db062503831a25811a7bd801efdd8148311e194556f468346b4cab1ae221176535ef4aa65ff6d6eed590ea1a69b4cfc4317b11a74ca76571b9a9bfb6b2295454fcae08e7607b2565b3aaa404a2baab4a4a807d04be9262717acec8035703032e989c159d754a640147f079ae90f81a37d0872a65dff3ac04ce72a710f181af81841c78579d196a20b6ac8184acb2b8936f32c9302e78707dade56f56a20632263d6b825352ba0e16c569cb65eec0578e41c4c1dab154bf387e0dfaa5635b2e17c0a3adc0700c2faa861597e8700e1ffad5e320f5fa3b9b280b2c81e86e0616488598c1f5dbefe7769ac8451714c7a02d898f57d1edb4a36dea1dc96dafe17d65bcf82a3dd99b868e47bf293ef9d5676f19d0f2b401d6f296b53c59956552f441a5e80df39698a53c4dfd83ec68f9e6aab746f596f937291396399eb1dd6d848574f66d44c0587438c5cd2ca9ec036cf37f0b0de3ebb0c8d80d9a1672b079a95dac8b45a2e2f439ee36e2e48b8db192b550550564771bc377292cdb98a735bb4ffca3a5fdf47ccec8e3b4f77ce450ca314cf8d69fe8047a3f22878e20fcdaff19f79e7434a3c746ebefac0dca7bf7dfbc36328542a6edb820b046600432719855c908c5604614532916a51dc32363fdba353d22d40c25b264e141fc88e82de6f851fa0349af1889da620490914b38808c3880440e860248c3c16513f65ae35786fd00d2ec08206309203d9c12f92a808ca6b80254c19100d29401a447c5226ea72f6500697d00197b3be92355e5d713a3238999b16dc1a2646ac606e245d6be134c3ebc8d41b32bcfd0ec6ed1e3c48a97becfd8ffff8cf51750b65c46aa38fcb211ed36e06ddc30edc657387689ea5ae68c04575f54db8239f95583c21d259e3d51a9c80984574c3ab62bd2debfb351fa2b49df5f09d88a559dc9167f25e0247f69659ca9fc9586f82b6ec05f69f5fd9506dfb13c25f8bc593c83898168ef7819edb16790fea93656c29531b92dc3e9b631e7adb35c01e3727499d6e15008d849b3385d64ef9638319907d92dcef6af04245d64f6d8be210d990cdc472248b8432a9797f8f46523e3e668992de55ca7de35d729a1aa53e9b3b8ea53ba3241e5b634cec1ad82dbf229f257908c2c9ec50b0e635956966141f1157268c47b09e0bdc470e7254625ff212e1ae2bd9832f41c702bb4fca25bfb4b4174e61acb79826461243f15364c32fc34462ea121730a88b0635c868d7c0e5c2e0918c13f3ec1ee2049d102d7fe49ea16fc85002be94fc0ae8acafc3b702f455adcf7b5f2e46906e10294915cc077a9785d5d9574627f8904bb8a21f13edb8a7ed9063b20a15ccd22152117b762a0148b24c4e5c5ad7e469696ab344d799b2b4dffd1a6fc93fef49d8fcc2e2eb7e75d6fd5cd2e2fafcecdf6da6e6df6d1f6ba5a7db8d39eebd197f575e95fecb5bbb3bdd5ee34ded7ddca6acf2daeb87317967b8bd38b2bf3ed8b8a7f0c99def9fe2e0d55ed6e77b5ebf07f5b2cae3c5a4d567cacd310ed8a33e0e9bd73b32b0036476db4baacbb0ed8bdd98797a9e111374bfd0bedae9b5b5de97567e77a8aeb00e9eb77e0786e757ef191c7f744efe581e5fcd06b5cee63cfa9f44df21f4350bb47786176e551225777f1dc6cf771b7d47edcbd7fa1bde22163d7b32b1ebe62cd9ae66bddd5deeadceab2f3ff71488969ffff18e132651a3cdac61cb22ce9dd1756da17d70806ed50684aa83eb278b13d3ffdf0e3bdf63ab05cef752fcc097569ee1f349552ff05ee7357f400d00700008101010100204b21f3cba072cc493e70861540df4677b498b0505a8b8e2a346b85a0c2dd2fc4263c4a7d8629026c4eb594ad96fac2bfe5f8ffebb9c841c353920b7b8ec11abc0100d90778da8d563b8f1c4510eedbf7e37cf209d9e60808402496c0dcdaac4e8ece01090112afe83043ef74ed4e6b677a86ee9edd5b3b2121b049888d842c84c0c1456702eb20b036424242c2e00408800c24fe03d53db3f33a58e860b6bbeaebeaeaaaafaab7f55bff9d1a796df0e5798263c37cc89f2fbe657e1eb8c7cb92e0de5f83c1eded95e4fded2d08150faf5ea5237e69f7855db2d3c199e351e5915a339c0b900d4103681849dff5c09daa3818bc34ec5057f319d54036b6c640752cc1617c024a17515d1a6b2f945c2f48a3ab3d09ca0b7dd68ab9d097078d292cd4267e9c39f089a70faea351378c85563b11c8802bf44c383eccc0cf20cd39e55a9d31df4c766ee487eed4f528174e4425baab412ab2fd44400f1dab73046827567402f6ece195a73495139455b44ee4ead4bb1db3594b2a94b929fa51367179f0f4882adc00722dea6c6edb0798d3452a7fd60d858643ed8c2598c8297bf18227220efe2f948148a1851bbb515c72a47ce34cbbeec655133b0106781de0c9aa059f8f41f3200b19833148090c41870e1c465c528b9b73c1c2798a3a57b5c2c0cfe276de28b9f0b90027552b7e6375c085d35a0691f6ac7a7768c39351b2a4eabb54b8e0dba3486d2b597131b1f0b3553ab68cff9c15a9dec3adc83b0327b5764a645b3bbd7c77b2ce294f6a755cf4a278e473d7c1692b91a74e75d083a9b5d828596cb8218364a6175132eb4b782fe61202581d2b906ec926dcee4a2cd2302de6ec9354785ea52d5bd5900bda21ea652849adab4030243b676debdc60af83126d32d91c2d34a85341c20682e6d233ab41b8f02f154e6a05e4e9b897c2b319c990c52e3a859123b533d932bbdf76c276c527c2e4b21ceb4d8cd8aa8bb1b56dac6d90260d1b8db10c036bbaa54063abace4ba8ea2241c3da3f77980ddaa92bd2e7628c7629ab617f54c2527174b05a6ae8a8236da3229af186acd0293fea689c65e7716ccb0eb61a892b5e548eeca2475a55ec7d3d32658c78357533c329d62a2b5eda28a6cb492c93f3758e35524f9ac128236578e11276e742c286468aca330a42cf661ab98b783ebbd58643cafff27cf7b71c4685a678db575669c5f1543c3e0735af70bef07a975ec4a819b769132cbcc6379f1637c36f3278f7c7debe2cb1f7c7eadd434c8feb73fdd3bfaf4956223c0f1fcb4fec587792193fd4fee3cc31edc2956278e5f1fdd7cfc59566c1fbd39fc19d8d14999a138ee42707492b171f5c0afa848c877af9e78c7cb22f570ec3f77fb789951c882be4940930cf4f0d1db6fdc5f16528fe3ddaf0eee2fb324e3d8fb1e057942cd851ffef1fb8fc5fcd920f8af3f2e66c9fcffb84b7ff865b7ce875708c9ff60d8f137aa5a1fa900d00700001001010020742877c36a520b152b1337ea1ecd37b0c98ad07289c32fec392e7eebab9f0ac71f7bc8c718cfa75317b2e15702372a9222c4616783ee7b3f0ec6358f8c328eea00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232201a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b72410000d00700001001010020058e23368b919493d6ac61d27f66b829a53893e88ddde857d3b82d913960960d22fa36f397752b98c295e3b31927f740127c0a99e76f8bfeea88f44466b8fbfd00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea990000d0070000100101001f43fe868e263d8134cf705aa85e26ce78ebb058edd558865fa3d240f5cb9e50c2389e9c8276eac800b7233a552045b2e79124c97e5156a0649849cc7f5d09eee600005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232204a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0f0000d0070000100101001f29e82b08ccf15e2187f29fea11ee3f4974f41b51e45b19f353348d8848b86fb71cadd88630456b7a1c60803c7b402487d41fbf18f0b0a13b4cca1f740447938300005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220e0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff5260000d0070000100101002047a8b784c3765b5c63ac52e3d8461b80bc2d3e3f62434f8accb277d9f2487cfd3c0728fcd26b5119a11288e5db46bc5b547877e220971609d1cef8cba443340800005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed32322068dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a2974280000d007000010010100203e701fbafd4149bc95b55a6bfc3b78246f5c2668ccc05ed4059a36ceb38f140b31e3b69e15f2579571e5bde39e034947271599c200e540b3949112bef163074c00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c430000d0070000100101001f0cc7352e60f4f8476783d6d1b48766a111c56fee2c1a552e76a75c92bc17de172f994ffc854c09717c904054819ca7a17379ddecaf531c439b35337ba099b81300005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232208ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a4050000d0070000100101002040965063a83be2d53b36c8d7e0775f503c2caa1407e586314562aace52c272fe60659e196413a6c9db4168470bcabb9a5851121c10c7b665f363f6cd4d1e4bda00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232202652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed250000d0070000100101002074ea7468b2a031c4cd53bf10ec3ac66b0c4b5c8779e045f1ef8d9c7b116be649217ff340107d0163397b99918ee2ce822b66cd6fce7b385af97a04671136e2ee00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d0000d007000010010100204dfb21ca5140582379bc026792c16b4cf97827143a4a9cd99ae70b3e6016cd6316bcbb9f1cb1233f12a0bbcd9debafa64724d0459b5c8d3cb67ceddfb2e3962500005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232204e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d670000d0070000100101002033446a3a94ade71dff3edb786259679487ab701bbc147490b1d4159fecf545fa22fee0698db16bf616465e5cebb985bfc4d9ed1ec4a55e38997dd4b4bbc427eb00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232204fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c20000d0070000100101001f3f67edd35bf731a07f40c638e8812112cd7d1baa39ec7dac4a1b2f0c83ac8bd53689b56dba69a7386e3860a6f8976695ac0bc2b5dacae91080f1d54df2dac0c000005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b44767070000d0070000100101001f1e030564013603d54f9e983b63cd940f8ff09ae038b14813f4021bb0c09ebb640d90cb4f8d57be2809f492a51737b671a5f549d4efa8e7efdaeaa9663c09d1ad00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead450710000d007000010010100205cea642eecf05568ce8c5564e63349eea3b816108914ba2ab5efffbb8ea467265f0b6d474f03ed02a3bf529fd6e55a595cbf8dd1adf4311cb9c51e862f8a535400005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232205443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b40000d0070000100101001f4556076cc86e0840bf69664f1ef8fcd4d91abda313d08e7840d24ba45cb429cf12b7d3a1f64250c19d1b975e7b107853beff70ebfc4c27c44f825dc05cdc9cd600005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e990000d0070000100101001f354d903ad0f2c6cc9d9a377d681ffaa00475d1e559e48074b4c8cce3111d5c172903b2f179ad4d736dda4e7d1b6a859baeab9dde5e5e495ce09733ec4650634400005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed323220d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb400000d0070000100101001f1766fa716a828da244c9ce52919b7a19acb38dbd110d1bb0039bb2477c17e4465dceecb8330ed5ee9de1330930dfcfa1a5e8149ce8536a82c0093642adf7328200005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed3232206bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc0000d00700001001010020488923db1c78fa430a3a9eab75f4ee467c7b9a3d3b4eb3bd08e183c82ef79b9102a4d2a7d1ec79c96b404911ae1b10f579bd82a660011c1ca2b872b30ef7dcac00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed32322035c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b0000d0070000100101002031ca6aeda725c01ed6aa6199dd2767930803051d3bc2897956bc9f97f8db5abf3bf243b775b4020f0c96d8ad197d591d11f8a51760c19fdc81134eff06a1941f00005206e10b5e02005132b41600000000010000000000ea30550000002a9bed3232010000000000ea305500000000a8ed32322098c4175db53ed27e7911a1b5adf0e7db0fc96c2cae172cf594dfa9a742ca9e88000001 DMLOG START_BLOCK 4 DMLOG FEATURE_OP ACTIVATE 1a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b7241 {"feature_digest":"1a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b7241","subjective_restrictions":{"enabled":true,"preactivation_required":true,"earliest_allowed_activation_time":"1970-01-01T00:00:00.000"},"description_digest":"f3c3d91c4603cde2397268bfed4e662465293aab10cd9416db0d442b8cec2949","dependencies":[],"protocol_feature_type":"builtin","specification":[{"name":"builtin_feature_codename","value":"ONLY_LINK_TO_EXISTING_PERMISSION"}]} DMLOG FEATURE_OP ACTIVATE ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea99 {"feature_digest":"ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea99","subjective_restrictions":{"enabled":true,"preactivation_required":true,"earliest_allowed_activation_time":"1970-01-01T00:00:00.000"},"description_digest":"9908b3f8413c8474ab2a6be149d3f4f6d0421d37886033f27d4759c47a26d944","dependencies":[],"protocol_feature_type":"builtin","specification":[{"name":"builtin_feature_codename","value":"REPLACE_DEFERRED"}]} @@ -153,19 +157,11 @@ DMLOG APPLIED_TRANSACTION 4 3d5251a1c9a3cd8d7baad33a381b9e09858e0503df1751181fd6 DMLOG CREATION_OP ROOT 0 DMLOG RAM_OP 0 eosio abi update setabi eosio 199629 137 DMLOG DB_OP UPD 0 eosio:eosio eosio eosio abihash eosio 0000000000ea3055d7abd75d188060de8a01ab2672d1cc2cd768fddc56203181b43685cc11f5ce46:0000000000ea3055fc470c7761cfe2530d91ab199fc6326b456e254a57fcc882544eb4c0e488fd39 -<<<<<<< HEAD DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304003,"value_ex":101210,"consumed":7921},"cpu_usage":{"last_ordinal":1262304003,"value_ex":267959,"consumed":4101},"ram_usage":199629} DMLOG APPLIED_TRANSACTION 4 befaff75b7a38d724c06bd3cf84cec04cb9b771d261f3937b82f0f29a6ecd12c04000000033b3d4b010000000446ce40fcba331770d4e40c1a69d054d3a9a5ed89ef08b50cc808e3250100d00700008201000000000000000010040000000000000001010000010000000000ea30552deb8b0eef2f2bfd027d20727a96e4b30eb6ccdc27488670d57bf488395c48fc1a000000000000001a00000000000000010000000000ea30551a0000000000000002020000000000ea30550000000000ea305500000000b863b2c2010000000000ea305500000000a8ed323293120000000000ea305589120e656f73696f3a3a6162692f312e320117626c6f636b5f7369676e696e675f617574686f726974792276617269616e745f626c6f636b5f7369676e696e675f617574686f726974795f763019086162695f686173680002056f776e6572046e616d6504686173680b636865636b73756d32353608616374697661746500010e666561747572655f6469676573740b636865636b73756d32353609617574686f726974790004097468726573686f6c640675696e743332046b6579730c6b65795f7765696768745b5d086163636f756e7473197065726d697373696f6e5f6c6576656c5f7765696768745b5d0577616974730d776169745f7765696768745b5d1a626c6f636b5f7369676e696e675f617574686f726974795f76300002097468726573686f6c640675696e743332046b6579730c6b65795f7765696768745b5d15626c6f636b636861696e5f706172616d65746572730011136d61785f626c6f636b5f6e65745f75736167650675696e7436341a7461726765745f626c6f636b5f6e65745f75736167655f7063740675696e743332196d61785f7472616e73616374696f6e5f6e65745f75736167650675696e7433321e626173655f7065725f7472616e73616374696f6e5f6e65745f75736167650675696e743332106e65745f75736167655f6c65657761790675696e74333223636f6e746578745f667265655f646973636f756e745f6e65745f75736167655f6e756d0675696e74333223636f6e746578745f667265655f646973636f756e745f6e65745f75736167655f64656e0675696e743332136d61785f626c6f636b5f6370755f75736167650675696e7433321a7461726765745f626c6f636b5f6370755f75736167655f7063740675696e743332196d61785f7472616e73616374696f6e5f6370755f75736167650675696e743332196d696e5f7472616e73616374696f6e5f6370755f75736167650675696e743332186d61785f7472616e73616374696f6e5f6c69666574696d650675696e7433321e64656665727265645f7472785f65787069726174696f6e5f77696e646f770675696e743332156d61785f7472616e73616374696f6e5f64656c61790675696e743332166d61785f696e6c696e655f616374696f6e5f73697a650675696e743332176d61785f696e6c696e655f616374696f6e5f64657074680675696e743136136d61785f617574686f726974795f64657074680675696e7431360b63616e63656c64656c617900020e63616e63656c696e675f61757468107065726d697373696f6e5f6c6576656c067472785f69640b636865636b73756d3235360a64656c657465617574680002076163636f756e74046e616d650a7065726d697373696f6e046e616d650a6b65795f7765696768740002036b65790a7075626c69635f6b6579067765696768740675696e743136086c696e6b617574680004076163636f756e74046e616d6504636f6465046e616d650474797065046e616d650b726571756972656d656e74046e616d650a6e65776163636f756e7400040763726561746f72046e616d65046e616d65046e616d65056f776e657209617574686f726974790661637469766509617574686f72697479076f6e6572726f7200020973656e6465725f69640775696e743132380873656e745f747278056279746573107065726d697373696f6e5f6c6576656c0002056163746f72046e616d650a7065726d697373696f6e046e616d65177065726d697373696f6e5f6c6576656c5f77656967687400020a7065726d697373696f6e107065726d697373696f6e5f6c6576656c067765696768740675696e7431361270726f64756365725f617574686f7269747900020d70726f64756365725f6e616d65046e616d6509617574686f7269747917626c6f636b5f7369676e696e675f617574686f726974790c72657161637469766174656400010e666561747572655f6469676573740b636865636b73756d323536077265716175746800010466726f6d046e616d65067365746162690002076163636f756e74046e616d65036162690562797465730a736574616c696d6974730004076163636f756e74046e616d650972616d5f627974657305696e7436340a6e65745f77656967687405696e7436340a6370755f77656967687405696e74363407736574636f64650004076163636f756e74046e616d6506766d747970650575696e743809766d76657273696f6e0575696e743804636f646505627974657309736574706172616d73000106706172616d7315626c6f636b636861696e5f706172616d657465727307736574707269760002076163636f756e74046e616d650769735f707269760575696e74380873657470726f64730001087363686564756c651470726f64756365725f617574686f726974795b5d0a756e6c696e6b617574680003076163636f756e74046e616d6504636f6465046e616d650474797065046e616d650a757064617465617574680004076163636f756e74046e616d650a7065726d697373696f6e046e616d6506706172656e74046e616d65046175746809617574686f726974790b776169745f776569676874000208776169745f7365630675696e743332067765696768740675696e743136100000002a9bed32320861637469766174650000bc892a4585a6410b63616e63656c64656c6179000040cbdaa8aca24a0a64656c65746561757468000000002d6b03a78b086c696e6b617574680000409e9a2264b89a0a6e65776163636f756e7400000000e0d27bd5a4076f6e6572726f7200905436db6564acba0c72657161637469766174656400000000a0656dacba07726571617574680000000000b863b2c206736574616269000000ce4eba68b2c20a736574616c696d6974730000000040258ab2c207736574636f6465000000c0d25c53b3c209736574706172616d730000000060bb5bb3c207736574707269760000000038d15bb3c20873657470726f6473000040cbdac0e9e2d40a756e6c696e6b61757468000040cbdaa86c52d50a757064617465617574680001000000a061d3dc31036936340000086162695f68617368000000012276617269616e745f626c6f636b5f7369676e696e675f617574686f726974795f7630011a626c6f636b5f7369676e696e675f617574686f726974795f76300000000000000000000000befaff75b7a38d724c06bd3cf84cec04cb9b771d261f3937b82f0f29a6ecd12c04000000033b3d4b010000000446ce40fcba331770d4e40c1a69d054d3a9a5ed89ef08b50cc808e325010000000000ea3055890000000000000000000000000000 DMLOG RLIMIT_OP STATE UPD {"average_block_net_usage":{"last_ordinal":3,"value_ex":79733334,"consumed":9568},"average_block_cpu_usage":{"last_ordinal":3,"value_ex":351659723,"consumed":42101},"pending_net_usage":7920,"pending_cpu_usage":4100,"total_net_weight":0,"total_cpu_weight":0,"total_ram_bytes":0,"virtual_net_limit":1050675,"virtual_cpu_limit":200400} DMLOG RLIMIT_OP STATE UPD {"average_block_net_usage":{"last_ordinal":4,"value_ex":145068889,"consumed":8000},"average_block_cpu_usage":{"last_ordinal":4,"value_ex":382895892,"consumed":4449},"pending_net_usage":0,"pending_cpu_usage":0,"total_net_weight":0,"total_cpu_weight":0,"total_ram_bytes":0,"virtual_net_limit":1051726,"virtual_cpu_limit":200600} -DMLOG ACCEPTED_BLOCK 4 04000000040000000300000000000000010000000000ea3055000100000001000240e54a7b27e042b80a810153bec1dd166eef95fa69f6c9886ae283363bc2add8010003000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b52d5b1b639d6ae94fcdd0536b224644931573d1ccb2a0c548613cd1feea18888b832a8006b631c33ec6afc9ab302513af7c26d7d5bd2a3801f269dd2bf1d13b540300000000000000010000000000ea305504000000010000000000ea305503000000000100000001000240e54a7b27e042b80a810153bec1dd166eef95fa69f6c9886ae283363bc2add80100000000000446ce40fcba331770d4e40c1a69d054d3a9a5ed89ef08b50cc808e325033b3d4b0000000000ea30550000000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b5dafd0f0596077e5010e7d7876a42e26a54669cb6ab0f1f073bf87b3d88a3043bc48e1625ffa8c398daca7e3f8bd15d4b2e191b8fa7d72547f72e57668630f3430000000000010000e104131a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b7241ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea994a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0fe0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff52668dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a297428ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c438ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a4052652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed25f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d4e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d674fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c2299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b4476707c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead450715443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b4bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e99d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb406bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc35c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b98c4175db53ed27e7911a1b5adf0e7db0fc96c2cae172cf594dfa9a742ca9e8800206af0063f6484fc2fa8e6fe0264faec9dba3f7efaa4f888c9998ea3fe0520e42a56cb0a715d87a7ad6434f43fd50065329f5230598c84aa372b6a1ed1735aa13e0000000029807708239aa7de914d3ed61e9009ab2280bfbc50f1d9769f27f8341ef26198000000000001140ec7e080177b2c02b278d5088611686b49d739925a92d9bfcacd7fc6b74053bd1a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b72412652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed25299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b447670735c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b4a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0f4e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d674fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c25443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b468dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a2974286bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc8ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a40598c4175db53ed27e7911a1b5adf0e7db0fc96c2cae172cf594dfa9a742ca9e88ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c43bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e99c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead45071d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb40e0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff526ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea99f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d0001033b3d4b0000000000ea30550000000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b5dafd0f0596077e5010e7d7876a42e26a54669cb6ab0f1f073bf87b3d88a3043bc48e1625ffa8c398daca7e3f8bd15d4b2e191b8fa7d72547f72e57668630f3430000000000010000e104131a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b7241ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea994a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0fe0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff52668dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a297428ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c438ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a4052652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed25f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d4e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d674fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c2299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b4476707c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead450715443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b4bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e99d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb406bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc35c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b98c4175db53ed27e7911a1b5adf0e7db0fc96c2cae172cf594dfa9a742ca9e8800206af0063f6484fc2fa8e6fe0264faec9dba3f7efaa4f888c9998ea3fe0520e42a56cb0a715d87a7ad6434f43fd50065329f5230598c84aa372b6a1ed1735aa13e0200d0070000dc06010100201ba2b33dda3b5437782a9c6370a15fc8f11fa60dbea2c8f918f838e0e4c1842114085668fb0e76c2884e12c516aef88770c3d61341505f165c0940a6b50f141b0100af3578daed3c0b8c5c5775f7f33eb3f366ece7609261ed36771e4b3aa64ed90467bd0d69e3b725fe902f69a0f4c77abc3bf6ceecd7b3b3c6aea8c734566a3e9568a12509550b286d4868a81410a2202a272512d0564d2141b82a2dad2a15416953552a1451d2f3b9f7cd9bd9dde03049402a9b78e7befbee39f7def33fe7ded9f09fa2376af1aa0bdebb04fc48fc25be36fe3af8bdef656f7bf8d17c87f8e037aebefa2fefc975fd393cd45717b147de2d5f725888c3aadb158775177f7ba7e147760f0b79fab0d73d7d1abafc2efe409fe60f95fd3e6ddf89c3018251bf3c0df84e3b4c80f6340d94d023bb841861e10560a769795497401899821ef5943fa61b4b27a2d923d3479b4bb3d3cd893d42634fa9b1bcda5c9eaeafae36da1d21b12b9e596bb71b4b9de97663a6d13cd1680b0fbbfdfa91651822b05de6f1d3ab73f5abaf99108a70f7faaee29edca86baeba9afb62dbd76eae341667af9a18e7ee208f69641ad633b7d069be52f8f8ecf55006795c2303482258f032ac777abe714a04d863561b9de9230bcb33f33373f5e6d2f44abd5d5f6c741aed5568cecc376679c7c162637166e5940809e6d8f78229e0b04b11f54a7b796579b5318b8dd9b51918234688aa8e849de66283c9b71dd1d6673a40d0dc684255586937973aabd30bbc9a4b1c8972bb291256e0de6a67b9dd20f645d4d56e1c5f6b424f7dad33274ad8b58517d63cd15c681c83d596b1f345d8d96eac2eafb5671ad30bcdc56667556cc1372fd9781fd38d93622b41aeb41bb4ec7aa7317db451efacb51b2226aaf1b2f9617b73d5bd9d76c367c53666393c2f2f4dcfd63bf5e9d5e6af35c425d40d7867a773ef9818dbf202393db33cdb102fc2fe226c1e49885b273e95a1636d651697857ddb7b949c83b54bbdff06f1e26db1d816c771292ea8f8d2822a5c26652c2bfc5390f643560af8290ad094ee9f2ac882829f82e7cb15592efb5a0a195caabb323d735e445d91fef363d9473822fdfacacac229f1b2914ba44865547addeb7fe1177fe9977ff58dd3b38da3c50fbd5ddee089b8167d590b23e22be331238c7cadb76feacc99ff79e281b3f7fcfdbd5da3e019bbe357f9d0fdd0177feb77dffbc0eb7abdd7b9de0ffdede744affb67b0fbcc571ffec6f92fbc3d87e367ede88f7fe23fefe8f55e0fbddffae3273effc1f77fe1911c8e7d84e3cc139ffec085a95e6fcabd67be7977bef7d5dcfbe16fffc3d7eecbcd7703777fec9b5fcc0fde8fbd1fffeffbde736fbef7008d3dffae6ff78d3d48bdbff7d75f7f22df7b13e3fdbb3f79ef173f919bee16ea7efce18f7cf29eab7bbdb7fa53ef7ce0c2852fbfe39ebec1b7f946f056ce7fe2ee27c5eddebe949e2f7ce123dff88dff10b189067ffcdc70c7a7be3d0382b7f42348457c55d496baab60d2b248c556e84a454dbd039ed3f844225b899a8027ee3dbb2fd146b4d2adad74e5782226a00300551a778cb811c1a12d5b38de4868546504afe53e91760fe0dbf49de7452c23a32325a20929bb2f8539e6137833a14a000c33946a4af4d09fd987bd384d2aae1788377aa5545d589a34624755aa7d1af0c75724a22c5351e535a689baa12c8dda2644494491115180e2fb13910f3a2fecef222e56ecd5e7d2e8165ec857c47c22c78070b0f42f09d844819a31b4bcac85af45fc8a517a34b286af60c5f3f116e8f98a688d89e80305582192b30618e09797a8f9347c0defff11d83f7556556414c014e2ada38676eea505a2b587bdadaa7628005a6f0cad532f07ed65d0a5a1a0e3a1a0b70f055d190a7ae750d06628e8b1a1a06b4341ef1e0a7a7c28e83d43414f0e057ddd50d0e7453fb8dc0c5ce5c05506fe2880cbef0d2e07c0115844df965a76d569b23be3f38926b38373c5adb83025aa5e1a57d1a02968fb60e2f08551ad6aa0d0de02ce436561fca9c25dc633c155429c4dbca9c97367ab3ebcebc2ba8c07efaa5e89ed6f2af7d3da1e60eb0b907b35982607bb570b9c0eed7dab2a70769c3522539ea8d480e9663431a0e94daf011ee7d39df4642b1e8135165abb34401a8d1f1e4ee4edc5c881e603ab0fa206f6114cff7b202c817cc0c3ed3f2578ff1a1410fd00b4a6c02e57e0a3bb57c7308d007489874bd6849068e0c116d1bbddfb6f1ffdf7abc00508f42207697d0011bf32017a8f1bcd1b3fff28bb1d03bc1bc7f7b496780fd3c78bd56b69d8dbfe02878160c4bb12818b888126b556e2631bf6012b4c02d7aeb492d0b68d46b4c0427c42cc46814f480af8e199c27c3c0e84c27e0082bde0a8809f63f71c22d1262db65d7a9c774e636a203373f661421de609043b0e3ba4d09e50b3d00407445c8caf19653c853c8d2c212dd6f8d2c49f507b88943032be03593a751ac82adf0cbf7efdf53b600d48334193665c40fa01e06ee282aea99d89c20f732bc02b7c13c307732b25506598ab204f15d8c0ce1272029a76bdb41d0d362c9e8810d1e1aa7090e286323aee97473c5325f16f288bdebc205707500daa02506a8c57e65ac876501b4321050a83421c0a70000b044a3261aae2272e7627e187099f22df7d36d0234e2f311e505558f618cf297005a0bce06690bb3e29034ceb83f8d73030d80f4107a804ae02175652107bc0f37e5c2374e2c2029238fe0f5407561957133fedb2edf82f1453248f9fbec53b54c6467c45354c65b580bd405d8e8ce693700cc65741a724488e1f5747596803165a2ba301127edc04406bdb0102ec5a356e295c7f48a15b7ae1d3a425810959b8420c433cc53b4c2fef1b84f25f1d013c60328a403e30a6c64b0d8081ed88c09cf8a4d05595b239299111a351ad6a99b6efb31929a1158b4c99ac584456ac04efc08af926422b16b196face8a7dec315a8132251432e560d98af9188cb6c86e46382d7000ad98975931df59313b3d5a2d408153f60c19a9252c0335a81ae15c11528da78c4c115f18ec2922343cd4f88184dae4d4bc88769bbae29ee64b503b90be604219fc40bd02f468b7e0cd4e276b3b139f2c0e880daa968f2f63f88832d532f014a06aa17c65aa3542f359626b1056d02bc058403d082108266525f6300aecf75907287e354174b7d20acc33698101eb5c050b3146961f6daa60367c8a8ca5da172b320d6c41bf4e9d46b21ff0d80ed2af808d6180c610e31de04b46258cbde039ee3d03213da03d3d608bc49a425385aca30978c63f6079d4e96d2d722368de6a14bc7b6896d1eed820db235ea3ff8575a18584ddec994209a8c5096115d60c0a30833e9a413f33832040681f3eaf7b7e1b2803a6815c3ced24d1d789cb38a6a7476fca9cbb4e68b486533568296a8d434b526b125a08ae69dc8bb0753fd882c2896bc5a5a4eb31b45e4cad0ab4b623100cb85684d487e3826c9c9f8df370093cffe45d38f55d9c159e39ffb4b8f32c74546cc757aebf93c2047a7aeaf23bcfe2cbc2397cfcd6567c55c1f6774202aa41fbbbfa4e5af6d9b36759f3609af8799ea6420442a26da31612f2126a21f9e2be344bcea797b3213df7681684a134824d30b920cc901028e228c462f76ae977ad49c6f7f80ba8379f5616811d603c82f4434f3ef8246a61fa2036aaa11b0b4246c3bcf489079f7c391848d06eb0379d2404b31c1cda9184b81cb0e0826231b0a895857817864692bc01ba009451f41a958504f23f89ea2950d361d524f79885063c08c15b14e381f10d6c6ec9cb0dd9f9145ae068aa52634e0e6ec8c3592068e259242b04ca27bc5e81d82ed3378c2ea19ba6c6e7398a21c18f86c623a749535a92863425ec08025c11ef86b721477b3eaa9dc0d57a180db103060c6030604521ae284448705ace3d4b343f12cd0f6c0f67a2800c3b3de88c1e57da739628267d4b7143e4dd612a70610a4b0ebc6a2407a7e3893f9ffa6b0f5503f23a12e27cf089e139f48fb7e36e1451c2f2dc770b54d640a049c0149aac2a11f71931a56f269830edee2f2b8b9ab4b1d48a5f3b4a26907041f0e85b6a12fd7c4b4d20236cca47390119896f17118738e8d9c1d3df5ca698d084f3f1cf59408aa04c782bbd014b8ef21c71f0e5f1072e00b12395404fe39f1f25bf0816ec4fb5420bd6b35f68bce3cb9e633326323326323326f2664cb01913991913991913ffffcc18f8a31de9a72073dc09bcfae9f493d4620315fd7ebfcbe10a95b0bc52c82b7c645e69cb2b69a750d4625e493b19659a9657d0ba1f8c17f34aa20b265e618b792591991ef20afb98576e9c9f8df35c6ea191887a9088ba8f88ba9f883a47449d23a2ce88a87bbca269e2e7799a0a118879852de615b6985710adc42fa59805b873ff8f02821fb68040c53f4641c0971ee13c8119f567527ace8bf4923a085f7f3cf1cab6e650c08a0b3901b2b15c6748cf7887c81d5d51559c85792e0b0324f41c5f3e6a115860180239958c7af912e6259cb1730286de9662592f3d793c2d1cc8e7563a1bcb26fbd552c3ca71d9bc5c97045fe4d2220cde7f846403249f552c13e37d32c11281a2f02c65c01698c6f803733be86f6195a5666b5a842b9f6d63b457c364aca6c6b05e487511c77d12122c378e5194a20e3c13dc6508271d9c7c06380b70e900002d3ca5d0339365ca230bad786a946b2e8584ca29b4bf1257556c51ef69692b7ab6f409b9b7c6a857d3f910c5ca876819773ed6571fbd525020c44ba6c01143a5a7c57120d4d3f278a23a0f9d45d6a4610bb2d0a08a46ed8c3c5eb64112c57c3ec77c0a8225725718176130ec22260f036dfce081cc42084b6f2e73d59579e4452ea60fe6916af3897f6b8e708c07591d40ba9c2513c6b715ddbb555f1651e0c0dc4bf4bc918728bc047a5c2b844b4260bb9a0bc95d88fa6db548bbdc03f7848947f7a6b24c9f869f10059d48092f55fa5de8d29c6f28cc3734161220dfd024b8da0aafd1906c70111bf305a01da40455dd5b8b8d68dd1a3008ef654012269aa7fa0f4c7110c51fa9455ba7203ee250bfc0f54f8cf83d0ac35d44bfd566070f2ba5413440cfcec8e754d1eee08fdbaca24da837b0e41edc50cdee60b1ff8c185030c28372bf8fa127e1e9712a9d4ca2e093025095077b394742dd72855e2e31e85dfab6c4e712b5dcab51f7b9868da5ef9a2d77eed20719ebd5ac4d93396dbace69d31989ea74d390e60d36fee479da3874fe8d541e33e007edfc725e6fc0e5817e67e6088b6e81d1570a482b0de62698548b0371c539c407156cc87339cc661baad80d55bedf0d552cf0f7da906fdd78b27e579057fb6e64ec46c603830ab94115479fca26210156d602a6119d19c4d5027e54aa2344aa1153c0d243fc12b2deb0a3f76b19f5fb3834cb44a9ac9aee5baa60b5d91ba8347b6364167cab76a0e2dbf923e60320d09f0aeb4fc1c536b46d1d1f1aa515b11789f74e91161a3c7f001f04662c1eb55ec5907c33d631cafbb95f2441aedeef81750fb0de1fd01ab1a000043fdcc26a0c92bf9514f0ea4017cbed5ebad04a4610431131172de1575a4944f6d51439e3f7d28319fb5a5ca72c3106cd25c9832d534a55273df79840c5df265144d22e2abd0fc259a41388c88c505a1e99c814e915aa728187f1a2a9ea4a67629acb235ece77fe95a672eb482e87206fa3e920900e00f9546b2327aa23d414940936e7ec55c0559213f5c989fae844b1c614a2346bac61ac73a261ae709204985868f6a31a6bb6af61078a050a3cbaba992be830a1df01ba9bd0567812ed18a291a02319433432a4881344c890080f32a1131882f73dc07d45fbad8f3cd8b2ef00dec77765c6a0b8b80e0c290f32c4674a07b0afc852bb48e5352ceb47f40aa93de21852a03a136cad80a4023d8a9808b88ed0958204974e349f677161683b6931297d7c2389084230b6ac9cf887812e023775af64d58b0934c7041e12d9850558074face678f6036671ad42cb2995e052bf2d6126de60f4909d2b59ffed58093211a698875105130287eb51ff49a2fc79e098bf86e1041eef50b54ea7de5a821214423cc1fe19855063b5cf737834b6fd0e84179aac02ca011a22102c9488110cfc7abba9b436df17eea5eae54210a25091b71060452d30c5f96ac47a00f60d621889c211303b8bd88162c72736928a8c1cdd48e8c5131b61e529274d12456f0b970f25cae65626ef16124a5b06ddca62bb25ab8a765002617bd2f620b1e6dce8c09479142322dc68117c584562cd04ac15ed3487a41445954bda864978290964b88c615581c32a8fc3aa112e95c2042c9c01dbbdc0d9adb0dfeee17a133e3aa50b0a64f7b6b2dd1339bb271d3c995adfa959c1da3d7f50cd34135c56a9b84b1bda6203c1ad7cc44b75dcd06aa329b362947125657c632b909f93140ff2fe55a67a18796bab1d83b19b57f5d855bb436fbe2d35c1a12ad6a909877456d3cf520f8d6ffaaca6cc5b4d327099d5c403b75eeae1a1d524e78f02aaa9eccc5693b206fffef870f4564981dae059f1f311d9daa0144ccfcdceb142fba7dcb1dd26d7ce6e1c4c61149f875cdcb5b38da03114b9b86b67cf0e3a1e0a7afb50d095a1a0770e056d86821e1b0aba3614f4eea1a0c78782de3314f4e450d0d70d05bdeedad966e01779ed6c330ddfe8dad9bb7f588aa090be90052387f00ecff72862b2077d4f6d624c375c8e3fb01c1f97e3b3319da254c95d7549e32adfb0cba290eca2195e2f20bcfd975c7cbcac125ad3ebf319329ee361a483f23b622fb71429727d9c2fb7f01215df2e29e2e596c04474b925a0cb2d454c2020cb33015e6ee10b4198faf65d6e19314524e4888375cb1f41333982fbc269d75d6e51ee728b7257f420788287c12b7a459b47e244015282e7e38c9503edfc65354bb4812b6bda5e59ab708bafac51910410845c21f917a049814b243e5f23937bf51bb83a725be6d3e2563c995dc1fa8cd69e3b51f9a191843e1120defb96f7619ef7853cef43e67d21c7fbf06278ef9b1079ef3b58b7609f2a0896f7e145f13edc80f761c67b9f79cff30dcf7b7b7df5da8c934f4aadfb0fef39d5d41cad419c37b9f8101f830bbab3c05f19303e1eb0fbf680dddd23e07b8a367cada9f12478881282cd61dcc5c3c01dcc2b4ae928c0854e886ebff3888b6ed9500ab4b304ea818bc04a85cbed62caedb6d2e93c7f7fe0bb5cf0d6039be36f03d0e5034ef62813d2f7e3c534102f5824c8d8ed90bc841dae73b7af155b739749c4ba0b2c1e965f140ab5cc59746913c0c0decda5109ec91b10917238c38d71fa034120271b3e4695778cbafb0a01de2b6198529e14d19725152d546eff5c8f30f21a1573fec7bbf670d7dee6bbd61bed5ab30f5cbf6bddbfebd8e5731e17721c46bd314639e094ed9ee3378c0e30f93216084aa55834aa78cb63d3fe134aba9c860ac474ed234d5a894d1d6bad6b949882d695622c95c77750155ea0ec8a9e58f085127733a6a66a341cd25d7902e5fcf88e848aeb78aa2f68d6e81eddbb48bd5e0a51bd5e4029747218b21c4a5b14ba468df399c3334ebfe562a6dfb2f9f44edb43b40dde7a950f41a741e53ffa68a6f22106917e5fc6e465d7f8d72bcb40384613876826424e8607cdc42c64863d59a1c00ccb2868b2f038c6cbc570ebf7abd8930d6c9642404e57d32acdf9824cf2a07c01660101aff607c69ba0d203a8ec6533c884e25f198dfe77bd596285806c1fa60245d2a8480f556de540bf4076caaec0c715c0afe349b083eaef549e202766821d54d2b17319ff960de7dae0f431679515fd3f4af6832d0dcd01a91ab00e2fd47dd81e791bfad205872b549fdd9efbf2852af1a997d7eef1d6551436ce76f84ae146b6d58beba3fda69a8e6ce9d631577fec999aa09bf264150ff22188c0e2944775405745aeb4e835bbef7c71cae3aa93aa0a7be21d71a1879221ba9748e76b92528fbdae4e17f365483c4681be12e52aef7bcc467c747cf29b5c9bf7d6b9b917b2366f0fb843b4e8eb6bf347ece1765f6d1eb396c905accd5baafa48556d2ff32701e1cb95fcf03598b301aada1aab8695155c309495cdfd5cd9dcb1cee87866b44f64828d52d400e9bb87d8b82e4bc51352c4d86f53a3f7fbb2d45f525f5f549f5cec15d5c7b9a8aeb8a84e211d45ff2a2b48abac20adb282b4e28234b7fa4bee931b94dc73a576e20c95daffe8773e3b766b59a6f7c167aed28e2374fadb9fbdef123cb747fec8ce86757689d23cb9d0abad031f6d6d1d39daabad7f5f9b42cab8d6645fe53dbb00edaaeff4ed9a8d8ad1f4151557959754952743deabcae3418d2dc303d222be26b92bf59de8905bf6b3339d775bc9a3ea7189cbea11ddaf85416f6ebd428a5781db464f01c8b900ed56c791a75ba4bd5d4bcbb2c967ee78c973c74b24bbb672aef86c490c6a80e4fd20767b7937ca7d6582a5d35d74f847feda8476c7adc3d98a70bdadd06c2b34db8a70d056a05de0fb1f7c99b9d5f327e18141150cf98b3e035e2b1c74cbf64b1ff06879566b51c97c904c7c595d58bb3ace5fe9c03331d8139fc5d0c5264e2b4576e53cee3d17f8608d9f4b74bb04268a8f2195c7d906dc44f77576090bb1d90c6260063130033d3fb7c84e4ad92574ca1e29597456667be8dc7b87ce3d3b74ee79373eefe6b319bebb0fb8c7f6aa31a3507bed552d11fdabc70710e745cea1a3462b32bbfcbc4509694fd6f80b59a40a052a596401b03ab08163f7dda58c81c8cdd61efa44243bea9d6cd195e4752242ae9788273311a138a39fecd4d52f28d4d52f2bf65a8e1517c50e2517c2ec7ebeb60ba876e563de8df078ebf0b0f1c4af39262a9e1b7d76342389a0afae3a111beba35e5eca72d453eba9a7d653af276eeefb1f0371d0792ae6bc0fbf2593bbe48ca4ae9030e2b7644998e99a204b5c0dcfca21e44bf43c5fee40eccc1de5ce7d576e2d2b5bc42bde482618bf3a836200c46b733c83be0cff144400de906274fe86430003ecb72cc0fce35d109fac2702e35776e8eb6d74b5cd435df0ca744b80bd1187c6907a1fa7c818298733611cee8e8dc5848dd75dfc0cefe297dba3ddccd8e5f53623dc73829f6fd3483e426672c61c32d386b73be7636cba09b1ed4f8263fabaafe92f6c44a78ed69b0b8d59d35936f58585e5997aa76156eac71aab626da97172a531d381978d767bb96d9a4be668f3646376fac8a94e63d5cc2c2fad76da6b339de5b6e8cc35ccf2120fe33f776366ea4b4bcb1d73a401ad059c61b6d9066c0ba784fb49dffa88882e78f609ff3c0ee06bd4174dbdd3692cae7478556f6a376949ab1d83b33496664551d83fc3033861a51d93fd359e6b8d58692f77966796178c1bd35c35b890de5fece13f80a5e09f7e76f30a5cab0fff02f8b77ca405dbc101ab0c00c3db7520c634b6794ea0d8e2da42a739dd5c9a6d9c144c1ffc9b40cda563d978612935032f6046c6bb8ab09dfa9105e8386aeaf07eaed1469277dab091f5932f2ecf368f9eda645e3b811d735113f05f1d6a3b2ececcd5978e0135dacdc57afb94996f9c326f9a6b2c5994b89bfa9245bc294171dffdf43cd6e80811022d0bf06f04fe15e15f24f04fb108d15c3a515f68ce9a13f576b3be847bc2ad3c1ba1045b1b795f4d00d7ff019e55743300d007000082010101002071c6cbdee3f4d6824fb9876d6362d085242ac20ad2e5cff92667c7f9a21e805874361f0f0af17fbbb704e35533a3678c5f59434140ff314085ad604beb1fb0640100e60778da8d563b8f1c4510eedd9d7ddcae7d3a0ecc710e088c482c197c6bb33a99e408480808784487197aa76b775a3bd33374f7ecde424c6048909c1909590881838bce897510589b22216170c023003290f80f54cfccceebb8e53a984755757557d5575f77fb8fdebb0df2f2cfd66d82a3661ee4efab6f9bd703e7685112dcfba7dfbfbdb994dcda5c8740f1e0c60d3ae42feebcd0af6d0dbdc099d88a8f0517639b46da0d24d7f34b532a3915da3e456f4faf6e77d089ed52e5927a3398099096a03e5846d2735c70262af2fb2f0d3ad4d17c4a3590dafa08a88e24d88c8f41e9a2d55ae69a586bda95a0dcc063ad880b7dad6f4d60aecee1c39e011fbb7aff263a75824868b51d82f4b9c2a084edc114bccca439a35cabf3e699c92e9e1e0ea99f61d90bf17cc7a55cd8219518ae06a9c8134ffaf4204d95006d478a8e217632b87e515339065dd5daa1a3d365b6cd642da95026531847d9c5b5feb343aa7002c895561bb96f0f6046e7a9fc3927101a0eb43d926032afe2c415762222ffaca60c446a5a88d809a3d246ca1167da5511575d6cfb98e05506cf543d787c049afb59ca188c404a60687460c341c8258ded665cb060965a5da87a61e065797bda28b9f0b8003b552bfec17281ad935a06a17663f5ce204e4f0eafa2aae750e180172f45eaebc9df128d1b5538b7ccfe392bb64a17a722ee8c39a9b7d346887baf9bcf4efe73ec927a037fba6134f4b863e3672b91a79beae00e26b147abe4d1720206c9979e87c9574fc2fb1197e0c3725981704b26e174476293072919648f8421f22e6fc5ac00b9a01da05e0612fb5081600876cedaf1e6fabb1d946853c9e670ae419d48121210ba4bd7ac2661eb148620f582e5c9bc97d2b319ca80450e6e2aa7a9faf94c98459987731ab19ec3e42d0991ad64c4b6b13415a9592319f8b1ff96028dac5b297b03454966ba46ef711f89af52c835242b3bb669c6b4d4354d9dc4980a4c8b15056df465aa5f71d49afa06094d9398ddb5a93f4502c4ac25ff315c92ad6015754c918ad45ac9c77fb3a75927947c5a09aacd956dc489e34e6c143074d65198241679f0d4c9a2ecdfec46228372e37fa1dc8d4246d356b256b69209618977cbd8e7a5ee158e1852efc47f0a9c9428ca40dac083f8f2677828e7a722f9f6d6e5573ffaea95122f90bdef7eb977f8c56bc55ec77165d2f8fa93bc57c9dee7772eb107778a0d88e3f7471f3efe32eba74fdf1afc0aecf0b88c3c1c77c13f3cce50b6bc3e2c2146c8f7af1fbb478b22a470ec3dfff1d1228306210f1fbdf3e6fd45a1d838defb66fffe222b2b8edd1f509097d004f7f0af3f7f2ad62a0ed87be371b122e6267397fef8db4e830fae1392df37f0d673860b4a6dd5694ffe059b3958df0000 -======= -DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304003,"value_ex":100469,"consumed":7921},"cpu_usage":{"last_ordinal":1262304003,"value_ex":256384,"consumed":4101},"ram_usage":199629} -DMLOG APPLIED_TRANSACTION 4 d276f624b0262b174fe373d5bcb026f4b5c87dd77d794b246b77a75e4d22525504000000033b3d4b01000000044444a224a7e16ae04e24e6640d6a909fb89ca6e5e8c1e5397e1e03ef0100d00700008201000000000000000010040000000000000001010000010000000000ea30552deb8b0eef2f2bfd027d20727a96e4b30eb6ccdc27488670d57bf488395c48fc19000000000000001900000000000000010000000000ea3055190000000000000002020000000000ea30550000000000ea305500000000b863b2c2010000000000ea305500000000a8ed323293120000000000ea305589120e656f73696f3a3a6162692f312e320117626c6f636b5f7369676e696e675f617574686f726974792276617269616e745f626c6f636b5f7369676e696e675f617574686f726974795f763019086162695f686173680002056f776e6572046e616d6504686173680b636865636b73756d32353608616374697661746500010e666561747572655f6469676573740b636865636b73756d32353609617574686f726974790004097468726573686f6c640675696e743332046b6579730c6b65795f7765696768745b5d086163636f756e7473197065726d697373696f6e5f6c6576656c5f7765696768745b5d0577616974730d776169745f7765696768745b5d1a626c6f636b5f7369676e696e675f617574686f726974795f76300002097468726573686f6c640675696e743332046b6579730c6b65795f7765696768745b5d15626c6f636b636861696e5f706172616d65746572730011136d61785f626c6f636b5f6e65745f75736167650675696e7436341a7461726765745f626c6f636b5f6e65745f75736167655f7063740675696e743332196d61785f7472616e73616374696f6e5f6e65745f75736167650675696e7433321e626173655f7065725f7472616e73616374696f6e5f6e65745f75736167650675696e743332106e65745f75736167655f6c65657761790675696e74333223636f6e746578745f667265655f646973636f756e745f6e65745f75736167655f6e756d0675696e74333223636f6e746578745f667265655f646973636f756e745f6e65745f75736167655f64656e0675696e743332136d61785f626c6f636b5f6370755f75736167650675696e7433321a7461726765745f626c6f636b5f6370755f75736167655f7063740675696e743332196d61785f7472616e73616374696f6e5f6370755f75736167650675696e743332196d696e5f7472616e73616374696f6e5f6370755f75736167650675696e743332186d61785f7472616e73616374696f6e5f6c69666574696d650675696e7433321e64656665727265645f7472785f65787069726174696f6e5f77696e646f770675696e743332156d61785f7472616e73616374696f6e5f64656c61790675696e743332166d61785f696e6c696e655f616374696f6e5f73697a650675696e743332176d61785f696e6c696e655f616374696f6e5f64657074680675696e743136136d61785f617574686f726974795f64657074680675696e7431360b63616e63656c64656c617900020e63616e63656c696e675f61757468107065726d697373696f6e5f6c6576656c067472785f69640b636865636b73756d3235360a64656c657465617574680002076163636f756e74046e616d650a7065726d697373696f6e046e616d650a6b65795f7765696768740002036b65790a7075626c69635f6b6579067765696768740675696e743136086c696e6b617574680004076163636f756e74046e616d6504636f6465046e616d650474797065046e616d650b726571756972656d656e74046e616d650a6e65776163636f756e7400040763726561746f72046e616d65046e616d65046e616d65056f776e657209617574686f726974790661637469766509617574686f72697479076f6e6572726f7200020973656e6465725f69640775696e743132380873656e745f747278056279746573107065726d697373696f6e5f6c6576656c0002056163746f72046e616d650a7065726d697373696f6e046e616d65177065726d697373696f6e5f6c6576656c5f77656967687400020a7065726d697373696f6e107065726d697373696f6e5f6c6576656c067765696768740675696e7431361270726f64756365725f617574686f7269747900020d70726f64756365725f6e616d65046e616d6509617574686f7269747917626c6f636b5f7369676e696e675f617574686f726974790c72657161637469766174656400010e666561747572655f6469676573740b636865636b73756d323536077265716175746800010466726f6d046e616d65067365746162690002076163636f756e74046e616d65036162690562797465730a736574616c696d6974730004076163636f756e74046e616d650972616d5f627974657305696e7436340a6e65745f77656967687405696e7436340a6370755f77656967687405696e74363407736574636f64650004076163636f756e74046e616d6506766d747970650575696e743809766d76657273696f6e0575696e743804636f646505627974657309736574706172616d73000106706172616d7315626c6f636b636861696e5f706172616d657465727307736574707269760002076163636f756e74046e616d650769735f707269760575696e74380873657470726f64730001087363686564756c651470726f64756365725f617574686f726974795b5d0a756e6c696e6b617574680003076163636f756e74046e616d6504636f6465046e616d650474797065046e616d650a757064617465617574680004076163636f756e74046e616d650a7065726d697373696f6e046e616d6506706172656e74046e616d65046175746809617574686f726974790b776169745f776569676874000208776169745f7365630675696e743332067765696768740675696e743136100000002a9bed32320861637469766174650000bc892a4585a6410b63616e63656c64656c6179000040cbdaa8aca24a0a64656c65746561757468000000002d6b03a78b086c696e6b617574680000409e9a2264b89a0a6e65776163636f756e7400000000e0d27bd5a4076f6e6572726f7200905436db6564acba0c72657161637469766174656400000000a0656dacba07726571617574680000000000b863b2c206736574616269000000ce4eba68b2c20a736574616c696d6974730000000040258ab2c207736574636f6465000000c0d25c53b3c209736574706172616d730000000060bb5bb3c207736574707269760000000038d15bb3c20873657470726f6473000040cbdac0e9e2d40a756e6c696e6b61757468000040cbdaa86c52d50a757064617465617574680001000000a061d3dc31036936340000086162695f68617368000000012276617269616e745f626c6f636b5f7369676e696e675f617574686f726974795f7630011a626c6f636b5f7369676e696e675f617574686f726974795f76300000000000000000000000d276f624b0262b174fe373d5bcb026f4b5c87dd77d794b246b77a75e4d22525504000000033b3d4b01000000044444a224a7e16ae04e24e6640d6a909fb89ca6e5e8c1e5397e1e03ef010000000000ea3055890000000000000000000000000000 -DMLOG RLIMIT_OP STATE UPD {"average_block_net_usage":{"last_ordinal":3,"value_ex":78666667,"consumed":9440},"average_block_cpu_usage":{"last_ordinal":3,"value_ex":334993056,"consumed":40101},"pending_net_usage":7920,"pending_cpu_usage":4100,"total_net_weight":0,"total_cpu_weight":0,"total_ram_bytes":0,"virtual_net_limit":1050675,"virtual_cpu_limit":200400} -DMLOG RLIMIT_OP STATE UPD {"average_block_net_usage":{"last_ordinal":4,"value_ex":144011111,"consumed":7999},"average_block_cpu_usage":{"last_ordinal":4,"value_ex":366368114,"consumed":4433},"pending_net_usage":0,"pending_cpu_usage":0,"total_net_weight":0,"total_cpu_weight":0,"total_ram_bytes":0,"virtual_net_limit":1051726,"virtual_cpu_limit":200600} -DMLOG ACCEPTED_BLOCK 4 04000000040000000300000000000000010000000000ea3055000100000001000240e54a7b27e042b80a810153bec1dd166eef95fa69f6c9886ae283363bc2add8010003000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cd2d5b1b639d6ae94fcdd0536b224644931573d1ccb2a0c548613cd1feea18888ba1daaeb8ca4a99a2fdb182ebb462ceb26de69d76f024586207a1159226ea43de0300000000000000010000000000ea305504000000010000000000ea305503000000000100000001000240e54a7b27e042b80a810153bec1dd166eef95fa69f6c9886ae283363bc2add8010000000000044444a224a7e16ae04e24e6640d6a909fb89ca6e5e8c1e5397e1e03ef033b3d4b0000000000ea30550000000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cdded9794b7e6d10923376031cef59e6d6d809ee653bcc37297cb644078a507a6bd26c416dc790f2b35815f1d6741bc63e1c235f13e809df666ddea0ba2e5f45c80000000000010000c104121a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b7241ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea994a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0fe0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff52668dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a297428ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c438ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a4052652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed25f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d4e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d674fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c2299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b4476707c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead450715443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b4bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e99d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb406bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc35c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b001f5505dc47adebb683205c6cd618df9385777f5ffb29d307479ace7cc07533ec5d3b9e648ee95c2a1dbea8d971cd9e980c6185867556035db58109f2678ce179e30000000029807708239aa7de914d3ed61e9009ab2280bfbc50f1d9769f27f8341ef26198000000000001130ec7e080177b2c02b278d5088611686b49d739925a92d9bfcacd7fc6b74053bd1a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b72412652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed25299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b447670735c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b4a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0f4e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d674fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c25443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b468dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a2974286bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc8ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a405ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c43bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e99c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead45071d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb40e0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff526ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea99f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d0001033b3d4b0000000000ea30550000000000034b2b890c59dad3c04fd9300057ba6285196dc55f32e988a49d6059cdded9794b7e6d10923376031cef59e6d6d809ee653bcc37297cb644078a507a6bd26c416dc790f2b35815f1d6741bc63e1c235f13e809df666ddea0ba2e5f45c80000000000010000c104121a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b7241ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea994a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0fe0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff52668dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a297428ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c438ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a4052652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed25f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d4e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d674fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c2299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b4476707c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead450715443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b4bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e99d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb406bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc35c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b001f5505dc47adebb683205c6cd618df9385777f5ffb29d307479ace7cc07533ec5d3b9e648ee95c2a1dbea8d971cd9e980c6185867556035db58109f2678ce179e30200d0070000dc060101002026bcc48f2a2332b2fcb39133cc9226405049c824dba512d79415009b403b107d7dade3a3173c6cc9657b7662dd1fd267156e076ac91df0aea1d8172e65d676fe0100b13578daed3c0b90645755f7f33e3dfdba77df862569665773fb31606fdcc8246c66c710cdbe91ec872424c480c10fb3bd33bd3bddf3dd9e9e65d7c2edc56ce1f2b10a1525099602150d0906ab02456128ac4d245504b58c24a108258a965552201acb2a410a89e773efebd73d33614327912a9964a7efbbef9e73ef3dff73eeed09ff317a8b166ffef2e3e705fc48fc25be3efe46f8bdef15ef7ae0e17c87f8c837afbcf22fefcc75fd393cd45717b147de215f765888c3aadb158775177f7ba7e147760f0b79fab0d73d7d1abafc2efe409fe60f95fd3e6ddf89c3018251bf3c0df84e3b4c80f6340d94d023bb841861e10560a769795497401899821ef5b43fa61b4b27a2d923d3479b4bb3d3cd893d42634fa9b1bcda5c9eaeafae36da1d21b12b9e596bb71b4b9de97663a6d13cd1680b0fbbfdfa91651822b05de6f1d3ab73f52baf9a108a70f7faaee09edca8abaeb892fb62dbd76eae341667af9818e7ee208f69641ad633b7d069be5af8f8ecf55006795c2303482258f032ac777abe714a04d863561b9de9230bcb33f33373f5e6d2f44abd5d5f6c741aed5568cecc376679c7c162637166e5940809e6d8f78329e0b08b11f54a7b796579b5318b8dd9b51918234688aa8e849de66283c9b71dd1d6673a40d0dc684255586937973aabd30bbc9a8b1c8972bb291256e0de6a67b9dd20f645d4d56e1c5f6b424f7dad33274ad8b58517d63cd15c681c83d596b1f325d8d96eac2eafb5671ad30bcdc56667556cc1372fdb781fd38d93622b41aeb41bb4ec7aa7317db451efacb51b2226aaf1b2f9617b73d5bd9d76c367c53666393c2f2f4dcfd63bf5e9d5e6af36c445d40d7867a773ef9818dbf202393db33cdb102fc1fe226c1e49885b273e95a1636d651697857ddb7b949c83b54bbdff3af1d26db1d816c771292ea8f8e2822a5c22652c2bfc5390f643560af8290ad094ee9f2ac882829f82e7cb15592efb5a0a195cacbb323d735e445d91fed323d9473822fdfacacac229f18a918ba44865547ae39b7ee1cdbff84bbff296e9d9c6d1e247df2daff3445c8bbea28511f1e5f1981146bec1db3775e6cc7f3f71efd93bffeeaeae51f08cddf16b7ce8beff8bbff9bb1fb8f78dbdde6b5cef47fff6f3a2d7fd33d87de66b0f7cf3fce3efcee1f8593bfa530ffec7adbdde6ba1f7db7ffcc4173ef2a1c71fcae1d84738ce3cf1d90f3f35d5eb4db9f7ccb7eec8f7be967b3ff69dbffffaddb9f9aee3ee4f7eeb8bf9c1fbb1f753ff75f7fbefcaf71ea0b1e77fe73b7d630f52efeffdf5379ec8f7dec078bffc271ff8e283b9e95e4fdd8f3df0f14fdf7965aff7267feabdf73ef5d457de7367dfe09b7d23782be71fbce349718bb72fa5e7a71efff8377ffddf456ca2c11f3f37dcf1a96fcf80e0edfd0852115f11b5a5ee2a98b42c52b115ba525153ef81e7343e91c856a226e0897bcfee4bb411ad746b2b5d399e8809e8004095c61d23ae477068cb168e37121a5519c16bb94fa4dd03f8367def7911cbc8e848896842caeecb618ef904de4ca81200c30ca59a123df467f6612f4e938a6b05e28d5e2d551796268dd851956a9f06fcf12b135196a9a8f21ad3445d5796466d13a224a2c8882840f1fd89c8079d17f67711172bf6ea7369f47a5ec857c57c22c78070b0f42f09d844819a31b4bcac85af45fcaa517a34b286af60c5f3f116e8f9aa688d89e8c305582192b30618e09797a8f9347c1defff21d83f7556556414c014e2ada38676eea505a2b587bdadaa7628005a6f0cad532f07ed65d0a5a1a0e3a1a0b70f055d190a7ae750d06628e8b1a1a06b4341ef1e0a7a7c28e83d43414f0e057dcd50d0e7453fb8dc0c5ce5c05506fe3080cbef0f2e07c0115844df915a76d569b23be3f38926b38373c5adb83025aa5e1a57d1a02968fb60e2f08551ad6aa0d0de02ce436561fca9c23b8c67822b84389b785393e7ce567d78d78575190fde55bd12dbdf54eea7b5ddcbd61720f76a304d0e76af16381ddafb5655e0ec386b44a63c51a901d3cd686240d39b5e033ccea73be9c9563c026b2cb4766980341a3f3c9cc8db8b9103cd07561f440dec2398fef7435802f98087db7f5af0fe352820fa01684d815daec04777af8e611a01e8120f97ac0921d1c0832da277bbeb5f3ff16f57800b10e8450ed2fa00227e7502f41e379a377efe61763b0678378eef692df11ea68f17ab37d0b077fd050e03c1887725021711034d6aadc4c736ec03569804ae5d6925a16d1b8d688185f884988d029f9014f0c33385f9781c0885fd00047bc151013fc7ee3944a24d5a6cbbf438ef9cc6d44066e6ecc3843acc1308761c7648a13da166a1090e88b8185f35ca780a791a59425aacf1c5893fa1f6102961647c2bb274ea349055be0d7efdda9b76c01a90668226cdb880f403c0ddc4055d533b13851fe6268057f826860fe6564aa0ca3057419e2ab0819d25e40434ed7a693b1a6c583c1121a2c355e120c5756574dc97453c5325f1af2b8bdebc205707500daa02506a8c57e65ac876501b4321050a83421c0a70000b044a3261aae2272e7627e187099f26df7d36d0234e2f311e505558f618cf297005a0bce06690bb3e29034ceb83f8d73030d80f4107a804ae02175652107bc0f37e5c2374e2c2029238fe0f5407561957133fedb2edf84f1453248f9fbedd3b54c646fcca6a98ca6a017b81ba1c19cd27e1188caf824e49901c3fae8eb2d0062cb456460324fcb80980d6b60304d8b56adc52b8fe9042b7f4a9cf9296042664e10a310cf114ef30bdb46f10ca7f7504f080c92802f9c0981a2f350006b6230273e293425755cae6a444468c46b5aa65dabecf66a484562c3265b2621159b112bc032be69b08ad58c45aea3b2bf6c9476805ca9450c89483652be66330da22bb19e1b4c001b4625e66c57c67c5ecf468b500054ed93364a496b00cd4a06a84734548359e3232457c61b0a788d0f050e307126a9353f322da6dea8a7b9a2f41ed40fa820965f003f50ad0a3dd82373b9daced4c7cb2382036a85a3ebe8ce123ca54cbc05380aa85f295a9d608cd6789ad415841af006301f5208420989495d8c328b0df671da0f8d504d11d4a2b30cfa40506ac73152cc418597eb4a982d9f01932966a5facc834b005fd06751ac97ec0633b48bf023686011a438c77802f199530f682e7b8f70c84f480f6f4802d126b0a4d15b28e26e019ff80e551a737b7c88da079ab51f0eea15946bb63836c8f788dfe17d685161276b3670a25a016278455583328c00cfa6806fdcc0c8200a17df882eef96da00c980672f1b493445f232ee1989e1ebd2973ee1aa1d11a4ed5a0a5a8350e2d49ad496821b8a6712fc1d63d600b0a27ae161793aec7d07a29b52ad0da8e4030e06a11521f8e0bb2717e36cec325f0fc93efc0a9dfc159e199f3cf88dbcf4247c5767cf5dadb294ca0a7a72fbdfd2cbe2c9cc3c76f6fc557156c7f3724a01ab4bfa76fa7659f3d7b96350fa6895fe0692a442024da366a21212fa216922fee4bb3e47c7a291bd2730f6741184a23d804930bc20c0981228e422c7697967ed79a647c8fbf807af3696511d801c623483ffae47d4fa216a6f761a31abab1206434cc4b9fb8efc9cbc040827683bde9242198e5e0d08e24c4e5800517148b8145ad2cc4bb303492e40dd005a08ca2d7a82c2490ff49544f819a0eab26b9c72c34e04108dea2180f8c6f60734b5e6ec8cea7d0024753951a737270431ece024113cf225921503ee1f50ac47699be617409dd34353ecf510c097e34341e394d9ad29234a429614710e08a7837bc0d39daf351ed04aed6c368881d30600083012b0a7145214282d372ee59a2f991687e607b38130564d8e94167f498d29eb34431e95b8a1b22ef0e53810b535872e0552339381d4ffcf9d45fbbbf1a90d79110e7834f0ccfa17fbc0577a3881296e7be5ba0b206024d02a6d0645589b8cf8a297d1bc18469777f5959d4a48da556fc86513281840b8247df5293e8e75b6a021961533eca09c8487c8b8838c441cf0e9efec632c584269c8f7fce02520465c29be80d587294e788832f8f3f7001881da9047a1afffc28f945b0607faa155ab09efd42e31d5ff23c9b3191993191993191376382cd98c8cc98c8cc98f8ff67c6c01fed483f0399e34ee0d54fa79fa6161ba8e8f7fb5d0e57a884e595425ee123f34a5b5e493b85a216f34adac928d3b4bc82d63d60bc9857125d30f10a5bcc2b89ccf49057d8c7bc72e3fc6c9ce7720b8d44d48344d47d44d4fd44d43922ea1c11754644dde3154d13bfc0d3548840cc2b6c31afb0c5bc8268257e39c52cc09d7b7e1410fcb005042afe310a02bef410e709cca83f93d2735ea497d441f8fae38957b6358702565cc809908de53a437ac63b44eee89555c55998e7b2304042cff1a5a316810586219053c9a8972f615ec2193b2760e86d2996f5d293c7d3c2817c6ea5b3b16cb25f2b35ac1c97cdcb7549f0052e2dc2e0fd47483640f2a8629918ef930996081485e72803b6c034c61f98db417f0bab2c355bd3225cf96c1ba3bd1a2663353586f542aa8b38ee939060b9718ca21475e0d9e02e4138e9e0e4b3c059808b070068e129859e992c531e5968c553a35c732924544ea1fd95b8aa628b7acf485bd1b3a54fc8bd3546bd9ace8728563e44cbb8fd91befae8e58202215e32058e182a3d238e03a19e91c713d5b9ff2cb2260d5b90850655346a67e4f1b20d9228e6f339e653102c91bbc2b80883611731791868e3070f641642587a6399abaecc232f72317d308f549b4ffc9b7284633cc8ea00d2e52c9930beade8dea1fab2880207e65ea2e78d3c44e125d0e36a215c1202dbd55c48ee42d46fab45dae51eb8274c3cba379465fa0cfc8428e8444a78a9d2ef4197e67c4361bea1b19000f98626c1d556788d8664838bd8982f00ed2025a8eade5a6c44ebd68041782f039230d13cd57f608a8328fe482dda3a05f11187fa05ae7f62c4ef5118ee22faad363b7840290da2017a76463eaf8a762b7fdc6c156d42ddc6927b704335bb95c5fe736240c1080fcafd3e869e84a7c7a8743289824f0a40551eece51c0975cb157ab9c4a077e99b139f4bd472af46dde71a3696be6bb6dcb94b1f64ac57b2364de6b4e91aa74d6724aad30d439a37d8f893e769e3d0f9375279cc80ff6be797f37a032e0ff43b334758740b8cbe5c405a693037c1a45a1c882bce21dea760439ecb6136db50c56ea8f2836ea86281bfdf867cebc693f5bb82bcda77236337321e1854c80daa38fa54360909b0b216308de8cc20ae16f0a3521d21528d9802961ee29791f5861d7d48cba8dfc7a159264a65d574df5205abcdde40a5d91b23b3e05bb50315dfce1f311f0081fe54587f0a2eb6a16debf8d028ad88bd48bc778ab4d0e0f903f8203063f1a8f52a86e49bb18e51decffd220972f57e0fac7b80f5fe80d688050520f8e116566390fcada4805707ba586ef7d285563282188a88b96809bfd24a22b2afa6c819bf971eccd8d7e23a658931682e491e6c9952aa3ae9b947042afe368922927651e97d10ce229d40446684d2f2c844a648af50950b3c8c174d55573a13d35c1ef172bef3af34955b47723904791b4d07817400c8a75a1b39511da1a6a04cb03967af02ae929ca84f4ed447278a35a610a559630d639d130d73859324c0c442b31fd558b37d1d3b502c50e0d1d58d5c418709fd0ed0dd84b6c29368c7108d041dc918a29121459c204286447890099dc010bcef01ee2bda6f7de4c1967d07f03ebe2b3306c5c57560487990213e533a807d4596da452aaf61593fa25748ed11c79002d599606b052415e851c444c07584ae1424b874a2f93c8b0b43db498b49e9e3eb49441082b165e5c43f0c7411b8a97b25ab5e4ca03926f090c82e2cc03a786235c7b31f308b6b155a4ea90497fa6d0933f106a387ec5cc9fa6fc74a908930c53c8c2a9810385c8bfa4f12e5cf03c7fc350c27f07887aa753af5d61294a010e209f6cf28841aab7d9ec3a3b1ed7720bcd06415500ed0108160a1448c60e0d7db4da5b5f9be702f552f178210858abc85002b6a8129ce5723d603b06f10c348148e80d959c40e143b3eb1915464e4e846422f9ed8082b4f396992287a5bb87c285136b73279b79050da32e85616db2d5955b4831208db93b6078935e74607a6cca31811e1468be0c32a126b2660ad68a73924a528aa5cd2364cc24b4920c3650cab0a1c56791c568d70a9142660e10cd8ee05ce6e85fd760fd79bf0d1295d5020bbb795ed9ec8d93de9e0c9d4fa4ecd0ad6eef9836aa699e0b24ac55ddad0161b086ee5235eaae386561b4d9915a38c2b29e31b5b81fcbca47890f7af32d5c3c85b5bed188cddbcaac7aeda1d7af36da9090e55b14e4d38a4b39a7e967a687cd3673565de6a9281cbac261eb8f5520f0fad26397f14504d6567b69a9435f8f7c487a3774a0ad406cf8a5f88c8d606a5607a6e748e15da3fe58eed36b97676fd600aa3f83ce4c2ae9d6d048da1c8855d3b7b6ed0f150d0db8782ae0c05bd7328683314f4d850d0b5a1a0770f053d3e14f49ea1a0278782be6628e875d7ce3603bfc06b679b69f846d7cedef7c3520485f4852c183984f778be4711933de87b7a1363bae172fc81e5f8b81c9f8de914a54aeeaa4b1a57f9865d16856417cdf07a01e1edbfe4e2e36595d09a5e9fcf90f11c0f231d94df117bb9a54891eb637cb98597a8f87649112fb70426a2cb2d015d6e29620201599e09f0720b5f08c2d4b7ef72cb88292221471cac5bfe089ac911dc174ebbee728b72975b94bba207c1133c0c5ed12bda3c12270a90123c1f67ac1c68e72fab59a20d5c59d3f6ca5a855b7c658d8a248020e40ac93f034d0a5c22f1f91a99dcab6fe3eac8cd994f8b5bf1647605eb735a7bee44e5874612fa448078ef5bde8779de17f2bc0f99f7851cefc30be1bd6f42e4bdef60dd827daa2058de8717c4fb7003de8719ef7de63dcf373cefedf5d5ab334e3e29b5ee3fbce7545373b40671dee4e2fd7c0c2ee8ce027f65c0f878c0eedb0376778f80ef29daf0b5a6c693e07e4a08368771170f037730af28a5a300173a21bafdee432eba654329d0ce12a8072e022b152eb78b29b7db4aa7f3fcfd81ef71c15b0f6c8ebf0d40970f38d9a34c48df8317d340bc60912063b740f21276b8ceddbe5a6ccd5d2611eb2eb078587e5128d43267d1a54d00037b37974278266f4044cae10c37c6e90f04819c6cf81855de3aeaee2b0478af84614a7952445f9154b450b9fd733dc2c8ab54ccf91fefdac35d7b9bef5a6fb46bcd3e70fdae75ffae6397cf795cc87118f5c618e58053b67b8e6f1b1d60f2252c10944ab16854f196c7a6fd279474390d1588e9da479ab4129b3ad65a57293105adcbc5582a8fefa02abc40d9153db1e00b25ee664c4dd56838a4bbf204caf9f11d0915d7f1545fd0acd19dba77917abd14a27abd8852e8e430643994b62874951ae73387679d7ecb854cbf65f3e99db687681bbcf52a1f824e83ca7fe2e14ce5430c22fdbe8cc9cbaef1af579681708c260ed14c849c0c0f9a8959c80c7bb24281199651d064e1718c978be1d6ef57b1271bd82c85809caea6559af34599e43ef922cc02025eed0f8c3741a50750d9cb669009c5bf3c1afdcf7ab3c40a01d93e4c058aa45191eeafdaca817e91ec945d818f2b805fc7936007d5dfa93c414ecc043ba8a463e732feeb379c6b83d3c79c5556f4ff28d90fb6343407a46ac03abc50f7317be46de84b171cae507d767beecb17aac4a75e5ebbc75b5751d838dbe12b851bd9562fae8ff69b6a3ab2a55bc75cfdb1676a826eca93553cc88720028b531ed5015d15b9d2a2d7ecbef3c5298fab4eaa2aec8977c4851e4a86e85e229daf494a3df6ba3a5dcc9721f11805fa4a94ab7cf0111bf1d1f1c96f706dde5be7e65eccdabc3de00ed1a2afafcd1fb187db7db579cc5a2617b0366fa9ea2355b5bdcc9f04842f57f2c3d760ce06a86a6bac1a565670c1505636f7736573c73aa3e399d13e9109364a5103a4ef1e62e3ba2c154f481163bf4d8d3ee4cb527f497d7d517d72b157541fe7a2bae2a23a857414fdabac20adb282b4ca0ad28a0bd2dcea2fb94f6e5072cf95da8933546affa3df7e74eca6b24cef86cf5ca51d47e8f4b71ebdfb223cb747fec8ce86757689d23cb9d0abad031f6d6d1d39daabadff409b42cab8d6645fe53dbb00edaaeff4ed9a8d8ad1f4151557959754952743deabcae3418d2dc303d222be26b92bf59de8905bf6b3339df759c9a3ea7189cbea11ddaf85416f6bbd4a8ad780db464f01c8b900ed56c791a75ba4bd5d4bcbb2c967ee78c973c74b24bbb672aef86c490c6a80e4fd20767b7937ca7d6582a5d35d74f807feda8476c7adc3d98a70bdadd06c2b34db8a70d056a05de0fb1f7c99b9d5f327e18141150cf98b3e035e2b1c74cbf64b1ff06879566b51c97c904c7c595d58bb3ace5fe9c03331d8139fc5d0c5264e2b4576e53cee3d17f8608d9f4b74bb04268a8f2195c7d906dc40f77576090bb1d90c6260063130033d3fbfc84e4ad92574ca1e29597456667be8dc7b87ce3d3b74ee79373eefe6b319bebb0fb8c7f6aa31a3507bed552d11fd8bc70710e745cea1a3462b32bbfcbc4509694fd6f80b59a40a052a596401b03ab08163f7dda58c81c8cdd61efa44243bea9d6cd195e4752242ae9788273311a138a39fecd4d52f28d4d52f2bf65a8e1517c50e2517c2ec7ea1b60ba876e563de8df078ebf0b0f1c4af39262a9e1b7d6e342389a0afae3a111beba35e5eca72d453eba9a7d653af276eeefb1f0371d0792ae67c10bf2593bbe48ca4ae9030e2b7644998e99a204b5c0dcfca21e44bf43c5fee40eccc1de5ce7d576e2a2b5bc42b5e4f2618bf3a836200c46b733c83be0cff144400de906274fe86430003ecb72cc0fce35d109fac2702e35776e8eb6d74b5cd435df0ca744b80bd1187c6907a1fa7c818298733611cee8e8dc5848dd75dfc0cefe2cbecd16e66ecf27a9b11ee79c1cfb769241f213339630e9969c3db9df33136dd84d8f627c1317dc3d7f41736a25347ebcd85c6ace92c9bfac2c2f24cbdd3302bf5638d55b1b6d438b9d298e9c0cb46bbbddc36cd2573b479b2313b7de454a7b16a669697563bedb599ce725b74e61a66798987f19fbb3133f5a5a5e58e39d280d602ce30db6c03b68553c2fda4ef7c48444f79f609ff3c0ee06bd4174dbdd3692cae7478556f6d376949ab1d83b33496664551d83fc3033861a51d93fd359eab8d58692f77966796178c1bd35c35b890de5fece13f80a5e09f7e6ef30a5cab0fff02f8b77ca405dbc101ab0c00c3db7520c634b6794ea0d8e2da42a739dd5c9a6d9c144c1ffc9b40cda563d978612935032f6046c6bb8ab09dfa9105e8386aeaf07eaed1469277dab091f5932f2ecf368f9eda645e3b811d734113f05f1d6a3b2ececcd5978e0135dacdc57afb94996f9c326f9d6b2c5994b89bfa9245bc294171dffdf43cd6e80811022d0bf06f04fe15e15f24f04fb108d15c3a515f68ce9a13f576b3be847bc2ad3c17a1045b1b795f4b00d7ff02b86d754e00d007000082010101001f5be06ae972efdca372f145881855ab035fc9b761243d0042d6d39703ea6e94a86cd3b37db4b18cdc3f21d6403bc80f91005cf01ed88a02858ec4a7b9fe9ba77f0100e60778da8d56bd6f1c45149ffb3edf25966308c6292882682205e24bb0ac54a6a0a1a0e0a340262c733bef6e47b73bbb9999bdf3414d116890e88284228420852ba7890c85752d121209690205d081c4ffc09bd9bdddbd353e3cc57ebcf7e6cdbcf77eef37d3faa3fb418dbcf7f4f131c151310ff2f7b577cdeba17b385b10dcffa7d7fb627d2eb9b3be0aa1e2e1cd9bb4cf5fd97ab957d9e8fba13b72141f0a2e860e8db5174aaea797c754722ab4738ade195fdb6ca313c7a3ca23d546381120eb8206503792aeeb813b5271d07b75bb4d5dcdc75403a9ac0e80ea5882c3f810942e5aad64ae497d457b129417faac1973a1aff7ea2398aa73f87026c0879edebb854edd30165a6d462003ae3028e1f830063f33694c28d7eabc7966b24ba78743aa6758f6a29def7a940b27a212c3d52015b9f04c40f7d35409d04eace810ac93ed1b97349543d065ad13b93a5d66d34cd6920a653285712cbab8de7ba14f154e00b9d46a2df7ed034ce83495bfe88642c3be7606124ce6954d5c6127220ece6aca40a4a68588dd285ed8c862c4997659c465179b01267899c1f3650f3e1f80e641963206039012181aed3bb01f7149addd840b164e52ab8b652f0cfc2c6fcf1925173e17e0a46ac53f9a2fb07152cb20d29e556f6ddbf4e4f02aaaba2e152ef87629525d4dfee6685c2bc3b969f6cf59b1553a38157167cc49b5953682edbd4e3e3bf9cfb14baa35fce94471dfe7ae839fcd449e6eaa8d3b18598ff5058f753764907ce969947c7525dc8eb98400e6cb0a845b3209a7bb129b3c4cc9207b240c917779d3b202e48256887a194aec43058221d8396bd9cdf576da28d1a6928dfe54833a912424207497ae594ec2c6290c41aa05cb93795f48cf7a244316bbb8a99ca6aae7336116651ece69c47a0e93372744b694115bc6d254a4521fc830b0fe9b0a34b26ea9ec35142599e918bdcf0324be52215790ac1c6bd3b0b4d4314d9dc4980a4c8b15052df465aa5f72d41c0706090d93989d9571304602c4ac25ff162ec956b08ada52a4229566f2f1dfec69d689241f97826a71e51871e2b86d8d4286ceda0a93c4621f9e3d5994bd5b9d586450aefd2f943b71c468da4af5a5ad644298e3bd6eecf352770b470ca9b6ed9f0237258a4520ade1417ce54b3c94f35391fc70e7caeb9f7cfbda022f90dd1f9fde3ff8fa8d62afe3b83aaa7df759deab64f7abbb97d9c3bbc506c4f1fba38f9f7c93f5d3e7ef6cff0aece068117938ee41707094a16c7e7d98438c909fde3cf20e674548e1d87de9d3c359060d428e1fbdfff68359a1d8383efc7eefc12c2b2b8e9d9f519097d00477fcd79fbf146b6503f6df7a52ac88b9c9dca38f7fdbaaf1ed1b84e4f70dbcf59ce182525976da937f01d36959fa0001 ->>>>>>> d243f8569d5f8baf55bfb787a481530998a15d93 +DMLOG ACCEPTED_BLOCK 4 04000000040000000300000000000000010000000000ea3055000100000001000240e54a7b27e042b80a810153bec1dd166eef95fa69f6c9886ae283363bc2add8010003000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b52d5b1b639d6ae94fcdd0536b224644931573d1ccb2a0c548613cd1feea18888b832a8006b631c33ec6afc9ab302513af7c26d7d5bd2a3801f269dd2bf1d13b540300000000000000010000000000ea305504000000010000000000ea305503000000000100000001000240e54a7b27e042b80a810153bec1dd166eef95fa69f6c9886ae283363bc2add80100000000000446ce40fcba331770d4e40c1a69d054d3a9a5ed89ef08b50cc808e325033b3d4b0000000000ea30550000000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b5dafd0f0596077e5010e7d7876a42e26a54669cb6ab0f1f073bf87b3d88a3043bc48e1625ffa8c398daca7e3f8bd15d4b2e191b8fa7d72547f72e57668630f3430000000000010000e104131a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b7241ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea994a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0fe0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff52668dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a297428ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c438ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a4052652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed25f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d4e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d674fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c2299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b4476707c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead450715443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b4bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e99d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb406bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc35c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b98c4175db53ed27e7911a1b5adf0e7db0fc96c2cae172cf594dfa9a742ca9e8800206af0063f6484fc2fa8e6fe0264faec9dba3f7efaa4f888c9998ea3fe0520e42a56cb0a715d87a7ad6434f43fd50065329f5230598c84aa372b6a1ed1735aa13e0000000029807708239aa7de914d3ed61e9009ab2280bfbc50f1d9769f27f8341ef26198000000000001140ec7e080177b2c02b278d5088611686b49d739925a92d9bfcacd7fc6b74053bd1a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b72412652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed25299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b447670735c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b4a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0f4e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d674fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c25443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b468dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a2974286bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc8ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a40598c4175db53ed27e7911a1b5adf0e7db0fc96c2cae172cf594dfa9a742ca9e88ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c43bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e99c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead45071d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb40e0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff526ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea99f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d0001033b3d4b0000000000ea30550000000000037b325d753bd9049355de4d8a48eee75fa3672264fa488e7f3cb464b5dafd0f0596077e5010e7d7876a42e26a54669cb6ab0f1f073bf87b3d88a3043bc48e1625ffa8c398daca7e3f8bd15d4b2e191b8fa7d72547f72e57668630f3430000000000010000e104131a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b7241ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea994a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0fe0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff52668dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a297428ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c438ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a4052652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed25f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d4e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d674fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c2299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b4476707c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead450715443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b4bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e99d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb406bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc35c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b98c4175db53ed27e7911a1b5adf0e7db0fc96c2cae172cf594dfa9a742ca9e8800206af0063f6484fc2fa8e6fe0264faec9dba3f7efaa4f888c9998ea3fe0520e42a56cb0a715d87a7ad6434f43fd50065329f5230598c84aa372b6a1ed1735aa13e0200d0070000dc06010100201ba2b33dda3b5437782a9c6370a15fc8f11fa60dbea2c8f918f838e0e4c1842114085668fb0e76c2884e12c516aef88770c3d61341505f165c0940a6b50f141b0100af3578daed3c0b8c5c5775f7f33eb3f366ece7609261ed36771e4b3aa64ed90467bd0d69e3b725fe902f69a0f4c77abc3bf6ceecd7b3b3c6aea8c734566a3e9568a12509550b286d4868a81410a2202a272512d0564d2141b82a2dad2a15416953552a1451d2f3b9f7cd9bd9dde03049402a9b78e7befbee39f7def33fe7ded9f09fa2376af1aa0bdebb04fc48fc25be36fe3af8bdef656f7bf8d17c87f8e037aebefa2fefc975fd393cd45717b147de2d5f725888c3aadb158775177f7ba7e147760f0b79fab0d73d7d1abafc2efe409fe60f95fd3e6ddf89c3018251bf3c0df84e3b4c80f6340d94d023bb841861e10560a769795497401899821ef5943fa61b4b27a2d923d3479b4bb3d3cd893d42634fa9b1bcda5c9eaeafae36da1d21b12b9e596bb71b4b9de97663a6d13cd1680b0fbbfdfa91651822b05de6f1d3ab73f5abaf99108a70f7faaee29edca86baeba9afb62dbd76eae341667af9a18e7ee208f69641ad633b7d069be52f8f8ecf55006795c2303482258f032ac777abe714a04d863561b9de9230bcb33f33373f5e6d2f44abd5d5f6c741aed5568cecc376679c7c162637166e5940809e6d8f78229e0b04b11f54a7b796579b5318b8dd9b51918234688aa8e849de66283c9b71dd1d6673a40d0dc684255586937973aabd30bbc9a4b1c8972bb291256e0de6a67b9dd20f645d4d56e1c5f6b424f7dad33274ad8b58517d63cd15c681c83d596b1f345d8d96eac2eafb5671ad30bcdc56667556cc1372fd9781fd38d93622b41aeb41bb4ec7aa7317db451efacb51b2226aaf1b2f9617b73d5bd9d76c367c53666393c2f2f4dcfd63bf5e9d5e6af35c425d40d7867a773ef9818dbf202393db33cdb102fc2fe226c1e49885b273e95a1636d651697857ddb7b949c83b54bbdff06f1e26db1d816c771292ea8f8d2822a5c26652c2bfc5390f643560af8290ad094ee9f2ac882829f82e7cb15592efb5a0a195caabb323d735e445d91fef363d9473822fdfacacac229f1b2914ba44865547addeb7fe1177fe9977ff58dd3b38da3c50fbd5ddee089b8167d590b23e22be331238c7cadb76feacc99ff79e281b3f7fcfdbd5da3e019bbe357f9d0fdd0177feb77dffbc0eb7abdd7b9de0ffdede744affb67b0fbcc571ffec6f92fbc3d87e367ede88f7fe23fefe8f55e0fbddffae3273effc1f77fe1911c8e7d84e3cc139ffec085a95e6fcabd67be7977bef7d5dcfbe16fffc3d7eecbcd7703777fec9b5fcc0fde8fbd1fffeffbde736fbef7008d3dffae6ff78d3d48bdbff7d75f7f22df7b13e3fdbb3f79ef173f919bee16ea7efce18f7cf29eab7bbdb7fa53ef7ce0c2852fbfe39ebec1b7f946f056ce7fe2ee27c5eddebe949e2f7ce123dff88dff10b189067ffcdc70c7a7be3d0382b7f42348457c55d496baab60d2b248c556e84a454dbd039ed3f844225b899a8027ee3dbb2fd146b4d2adad74e5782226a00300551a778cb811c1a12d5b38de4868546504afe53e91760fe0dbf49de7452c23a32325a20929bb2f8539e6137833a14a000c33946a4af4d09fd987bd384d2aae1788377aa5545d589a34624755aa7d1af0c75724a22c5351e535a689baa12c8dda2644494491115180e2fb13910f3a2fecef222e56ecd5e7d2e8165ec857c47c22c78070b0f42f09d844819a31b4bcac85af45fc8a517a34b286af60c5f3f116e8f98a688d89e80305582192b30618e09797a8f9347c0defff11d83f7556556414c014e2ada38676eea505a2b587bdadaa7628005a6f0cad532f07ed65d0a5a1a0e3a1a0b70f055d190a7ae750d06628e8b1a1a06b4341ef1e0a7a7c28e83d43414f0e057ddd50d0e7453fb8dc0c5ce5c05506fe2880cbef0d2e07c0115844df965a76d569b23be3f38926b38373c5adb83025aa5e1a57d1a02968fb60e2f08551ad6aa0d0de02ce436561fca9c25dc633c155429c4dbca9c97367ab3ebcebc2ba8c07efaa5e89ed6f2af7d3da1e60eb0b907b35982607bb570b9c0eed7dab2a70769c3522539ea8d480e9663431a0e94daf011ee7d39df4642b1e8135165abb34401a8d1f1e4ee4edc5c881e603ab0fa206f6114cff7b202c817cc0c3ed3f2578ff1a1410fd00b4a6c02e57e0a3bb57c7308d007489874bd6849068e0c116d1bbddfb6f1ffdf7abc00508f42207697d0011bf32017a8f1bcd1b3fff28bb1d03bc1bc7f7b496780fd3c78bd56b69d8dbfe02878160c4bb12818b888126b556e2631bf6012b4c02d7aeb492d0b68d46b4c0427c42cc46814f480af8e199c27c3c0e84c27e0082bde0a8809f63f71c22d1262db65d7a9c774e636a203373f661421de609043b0e3ba4d09e50b3d00407445c8caf19653c853c8d2c212dd6f8d2c49f507b88943032be03593a751ac82adf0cbf7efdf53b600d48334193665c40fa01e06ee282aea99d89c20f732bc02b7c13c307732b25506598ab204f15d8c0ce1272029a76bdb41d0d362c9e8810d1e1aa7090e286323aee97473c5325f16f288bdebc205707500daa02506a8c57e65ac876501b4321050a83421c0a70000b044a3261aae2272e7627e187099f22df7d36d0234e2f311e505558f618cf297005a0bce06690bb3e29034ceb83f8d73030d80f4107a804ae02175652107bc0f37e5c2374e2c2029238fe0f5407561957133fedb2edf82f1453248f9fbec53b54c6467c45354c65b580bd405d8e8ce693700cc65741a724488e1f5747596803165a2ba301127edc04406bdb0102ec5a356e295c7f48a15b7ae1d3a425810959b8420c433cc53b4c2fef1b84f25f1d013c60328a403e30a6c64b0d8081ed88c09cf8a4d05595b239299111a351ad6a99b6efb31929a1158b4c99ac584456ac04efc08af926422b16b196face8a7dec315a8132251432e560d98af9188cb6c86e46382d7000ad98975931df59313b3d5a2d408153f60c19a9252c0335a81ae15c11528da78c4c115f18ec2922343cd4f88184dae4d4bc88769bbae29ee64b503b90be604219fc40bd02f468b7e0cd4e276b3b139f2c0e880daa968f2f63f88832d532f014a06aa17c65aa3542f359626b1056d02bc058403d082108266525f6300aecf75907287e354174b7d20acc33698101eb5c050b3146961f6daa60367c8a8ca5da172b320d6c41bf4e9d46b21ff0d80ed2af808d6180c610e31de04b46258cbde039ee3d03213da03d3d608bc49a425385aca30978c63f6079d4e96d2d722368de6a14bc7b6896d1eed820db235ea3ff8575a18584ddec994209a8c5096115d60c0a30833e9a413f33832040681f3eaf7b7e1b2803a6815c3ced24d1d789cb38a6a7476fca9cbb4e68b486533568296a8d434b526b125a08ae69dc8bb0753fd882c2896bc5a5a4eb31b45e4cad0ab4b623100cb85684d487e3826c9c9f8df370093cffe45d38f55d9c159e39ffb4b8f32c74546cc757aebf93c2047a7aeaf23bcfe2cbc2397cfcd6567c55c1f6774202aa41fbbbfa4e5af6d9b36759f3609af8799ea6420442a26da31612f2126a21f9e2be344bcea797b3213df7681684a134824d30b920cc901028e228c462f76ae977ad49c6f7f80ba8379f5616811d603c82f4434f3ef8246a61fa2036aaa11b0b4246c3bcf489079f7c391848d06eb0379d2404b31c1cda9184b81cb0e0826231b0a895857817864692bc01ba009451f41a958504f23f89ea2950d361d524f79885063c08c15b14e381f10d6c6ec9cb0dd9f9145ae068aa52634e0e6ec8c3592068e259242b04ca27bc5e81d82ed3378c2ea19ba6c6e7398a21c18f86c623a749535a92863425ec08025c11ef86b721477b3eaa9dc0d57a180db103060c6030604521ae284448705ace3d4b343f12cd0f6c0f67a2800c3b3de88c1e57da739628267d4b7143e4dd612a70610a4b0ebc6a2407a7e3893f9ffa6b0f5503f23a12e27cf089e139f48fb7e36e1451c2f2dc770b54d640a049c0149aac2a11f71931a56f269830edee2f2b8b9ab4b1d48a5f3b4a26907041f0e85b6a12fd7c4b4d20236cca47390119896f17118738e8d9c1d3df5ca698d084f3f1cf59408aa04c782bbd014b8ef21c71f0e5f1072e00b12395404fe39f1f25bf0816ec4fb5420bd6b35f68bce3cb9e633326323326323326f2664cb01913991913991913ffffcc18f8a31de9a72073dc09bcfae9f493d4620315fd7ebfcbe10a95b0bc52c82b7c645e69cb2b69a750d4625e493b19659a9657d0ba1f8c17f34aa20b265e618b792591991ef20afb98576e9c9f8df35c6ea191887a9088ba8f88ba9f883a47449d23a2ce88a87bbca269e2e7799a0a118879852de615b6985710adc42fa59805b873ff8f02821fb68040c53f4641c0971ee13c8119f567527ace8bf4923a085f7f3cf1cab6e650c08a0b3901b2b15c6748cf7887c81d5d51559c85792e0b0324f41c5f3e6a115860180239958c7af912e6259cb1730286de9662592f3d793c2d1cc8e7563a1bcb26fbd552c3ca71d9bc5c97045fe4d2220cde7f846403249f552c13e37d32c11281a2f02c65c01698c6f803733be86f6195a5666b5a842b9f6d63b457c364aca6c6b05e487511c77d12122c378e5194a20e3c13dc6508271d9c7c06380b70e900002d3ca5d0339365ca230bad786a946b2e8584ca29b4bf1257556c51ef69692b7ab6f409b9b7c6a857d3f910c5ca876819773ed6571fbd525020c44ba6c01143a5a7c57120d4d3f278a23a0f9d45d6a4610bb2d0a08a46ed8c3c5eb64112c57c3ec77c0a8225725718176130ec22260f036dfce081cc42084b6f2e73d59579e4452ea60fe6916af3897f6b8e708c07591d40ba9c2513c6b715ddbb555f1651e0c0dc4bf4bc918728bc047a5c2b844b4260bb9a0bc95d88fa6db548bbdc03f7848947f7a6b24c9f869f10059d48092f55fa5de8d29c6f28cc3734161220dfd024b8da0aafd1906c70111bf305a01da40455dd5b8b8d68dd1a3008ef654012269aa7fa0f4c7110c51fa9455ba7203ee250bfc0f54f8cf83d0ac35d44bfd566070f2ba5413440cfcec8e754d1eee08fdbaca24da837b0e41edc50cdee60b1ff8c185030c28372bf8fa127e1e9712a9d4ca2e093025095077b394742dd72855e2e31e85dfab6c4e712b5dcab51f7b9868da5ef9a2d77eed20719ebd5ac4d93396dbace69d31989ea74d390e60d36fee479da3874fe8d541e33e007edfc725e6fc0e5817e67e6088b6e81d1570a482b0de62698548b0371c539c407156cc87339cc661baad80d55bedf0d552cf0f7da906fdd78b27e579057fb6e64ec46c603830ab94115479fca26210156d602a6119d19c4d5027e54aa2344aa1153c0d243fc12b2deb0a3f76b19f5fb3834cb44a9ac9aee5baa60b5d91ba8347b6364167cab76a0e2dbf923e60320d09f0aeb4fc1c536b46d1d1f1aa515b11789f74e91161a3c7f001f04662c1eb55ec5907c33d631cafbb95f2441aedeef81750fb0de1fd01ab1a000043fdcc26a0c92bf9514f0ea4017cbed5ebad04a4610431131172de1575a4944f6d51439e3f7d28319fb5a5ca72c3106cd25c9832d534a55273df79840c5df265144d22e2abd0fc259a41388c88c505a1e99c814e915aa728187f1a2a9ea4a67629acb235ece77fe95a672eb482e87206fa3e920900e00f9546b2327aa23d414940936e7ec55c0559213f5c989fae844b1c614a2346bac61ac73a261ae709204985868f6a31a6bb6af61078a050a3cbaba992be830a1df01ba9bd0567812ed18a291a02319433432a4881344c890080f32a1131882f73dc07d45fbad8f3cd8b2ef00dec77765c6a0b8b80e0c290f32c4674a07b0afc852bb48e5352ceb47f40aa93de21852a03a136cad80a4023d8a9808b88ed0958204974e349f677161683b6931297d7c2389084230b6ac9cf887812e023775af64d58b0934c7041e12d9850558074face678f6036671ad42cb2995e052bf2d6126de60f4909d2b59ffed58093211a698875105130287eb51ff49a2fc79e098bf86e1041eef50b54ea7de5a821214423cc1fe19855063b5cf737834b6fd0e84179aac02ca011a22102c9488110cfc7abba9b436df17eea5eae54210a25091b71060452d30c5f96ac47a00f60d621889c211303b8bd88162c72736928a8c1cdd48e8c5131b61e529274d12456f0b970f25cae65626ef16124a5b06ddca62bb25ab8a765002617bd2f620b1e6dce8c09479142322dc68117c584562cd04ac15ed3487a41445954bda864978290964b88c615581c32a8fc3aa112e95c2042c9c01dbbdc0d9adb0dfeee17a133e3aa50b0a64f7b6b2dd1339bb271d3c995adfa959c1da3d7f50cd34135c56a9b84b1bda6203c1ad7cc44b75dcd06aa329b362947125657c632b909f93140ff2fe55a67a18796bab1d83b19b57f5d855bb436fbe2d35c1a12ad6a909877456d3cf520f8d6ffaaca6cc5b4d327099d5c403b75eeae1a1d524e78f02aaa9eccc5693b206fffef870f4564981dae059f1f311d9daa0144ccfcdceb142fba7dcb1dd26d7ce6e1c4c61149f875cdcb5b38da03114b9b86b67cf0e3a1e0a7afb50d095a1a0770e056d86821e1b0aba3614f4eea1a0c78782de3314f4e450d0d70d05bdeedad966e01779ed6c330ddfe8dad9bb7f588aa090be90052387f00ecff72862b2077d4f6d624c375c8e3fb01c1f97e3b3319da254c95d7549e32adfb0cba290eca2195e2f20bcfd975c7cbcac125ad3ebf319329ee361a483f23b622fb71429727d9c2fb7f01215df2e29e2e596c04474b925a0cb2d454c2020cb33015e6ee10b4198faf65d6e19314524e4888375cb1f41333982fbc269d75d6e51ee728b7257f420788287c12b7a459b47e244015282e7e38c9503edfc65354bb4812b6bda5e59ab708bafac51910410845c21f917a049814b243e5f23937bf51bb83a725be6d3e2563c995dc1fa8cd69e3b51f9a191843e1120defb96f7619ef7853cef43e67d21c7fbf06278ef9b1079ef3b58b7609f2a0896f7e145f13edc80f761c67b9f79cff30dcf7b7b7df5da8c934f4aadfb0fef39d5d41cad419c37b9f8101f830bbab3c05f19303e1eb0fbf680dddd23e07b8a367cada9f12478881282cd61dcc5c3c01dcc2b4ae928c0854e886ebff3888b6ed9500ab4b304ea818bc04a85cbed62caedb6d2e93c7f7fe0bb5cf0d6039be36f03d0e5034ef62813d2f7e3c534102f5824c8d8ed90bc841dae73b7af155b739749c4ba0b2c1e965f140ab5cc59746913c0c0decda5109ec91b10917238c38d71fa034120271b3e4695778cbafb0a01de2b6198529e14d19725152d546eff5c8f30f21a1573fec7bbf670d7dee6bbd61bed5ab30f5cbf6bddbfebd8e5731e17721c46bd314639e094ed9ee3378c0e30f93216084aa55834aa78cb63d3fe134aba9c860ac474ed234d5a894d1d6bad6b949882d695622c95c77750155ea0ec8a9e58f085127733a6a66a341cd25d7902e5fcf88e848aeb78aa2f68d6e81eddbb48bd5e0a51bd5e4029747218b21c4a5b14ba468df399c3334ebfe562a6dfb2f9f44edb43b40dde7a950f41a741e53ffa68a6f22106917e5fc6e465d7f8d72bcb40384613876826424e8607cdc42c64863d59a1c00ccb2868b2f038c6cbc570ebf7abd8930d6c9642404e57d32acdf9824cf2a07c01660101aff607c69ba0d203a8ec6533c884e25f198dfe77bd596285806c1fa60245d2a8480f556de540bf4076caaec0c715c0afe349b083eaef549e202766821d54d2b17319ff960de7dae0f431679515fd3f4af6832d0dcd01a91ab00e2fd47dd81e791bfad205872b549fdd9efbf2852af1a997d7eef1d6551436ce76f84ae146b6d58beba3fda69a8e6ce9d631577fec999aa09bf264150ff22188c0e2944775405745aeb4e835bbef7c71cae3aa93aa0a7be21d71a1879221ba9748e76b92528fbdae4e17f365483c4681be12e52aef7bcc467c747cf29b5c9bf7d6b9b917b2366f0fb843b4e8eb6bf347ece1765f6d1eb396c905accd5baafa48556d2ff32701e1cb95fcf03598b301aada1aab8695155c309495cdfd5cd9dcb1cee87866b44f64828d52d400e9bb87d8b82e4bc51352c4d86f53a3f7fbb2d45f525f5f549f5cec15d5c7b9a8aeb8a84e211d45ff2a2b48abac20adb282b4e28234b7fa4bee931b94dc73a576e20c95daffe8773e3b766b59a6f7c167aed28e2374fadb9fbdef123cb747fec8ce86757689d23cb9d0abad031f6d6d1d39daabad7f5f9b42cab8d6645fe53dbb00edaaeff4ed9a8d8ad1f4151557959754952743deabcae3418d2dc303d222be26b92bf59de8905bf6b3339d775bc9a3ea7189cbea11ddaf85416f6ebd428a5781db464f01c8b900ed56c791a75ba4bd5d4bcbb2c967ee78c973c74b24bbb672aef86c490c6a80e4fd20767b7937ca7d6582a5d35d74f847feda8476c7adc3d98a70bdadd06c2b34db8a70d056a05de0fb1f7c99b9d5f327e18141150cf98b3e035e2b1c74cbf64b1ff06879566b51c97c904c7c595d58bb3ace5fe9c03331d8139fc5d0c5264e2b4576e53cee3d17f8608d9f4b74bb04268a8f2195c7d906dc44f77576090bb1d90c6260063130033d3fb7c84e4ad92574ca1e29597456667be8dc7b87ce3d3b74ee79373eefe6b319bebb0fb8c7f6aa31a3507bed552d11fdabc70710e745cea1a3462b32bbfcbc4509694fd6f80b59a40a052a596401b03ab08163f7dda58c81c8cdd61efa44243bea9d6cd195e4752242ae9788273311a138a39fecd4d52f28d4d52f2bf65a8e1517c50e2517c2ec7ebeb60ba876e563de8df078ebf0b0f1c4af39262a9e1b7d76342389a0afae3a111beba35e5eca72d453eba9a7d653af276eeefb1f0371d0792ae6bc0fbf2593bbe48ca4ae9030e2b7644998e99a204b5c0dcfca21e44bf43c5fee40eccc1de5ce7d576e2d2b5bc42bde482618bf3a836200c46b733c83be0cff144400de906274fe86430003ecb72cc0fce35d109fac2702e35776e8eb6d74b5cd435df0ca744b80bd1187c6907a1fa7c818298733611cee8e8dc5848dd75dfc0cefe297dba3ddccd8e5f53623dc73829f6fd3483e426672c61c32d386b73be7636cba09b1ed4f8263fabaafe92f6c44a78ed69b0b8d59d35936f58585e5997aa76156eac71aab626da97172a531d381978d767bb96d9a4be668f3646376fac8a94e63d5cc2c2fad76da6b339de5b6e8cc35ccf2120fe33f776366ea4b4bcb1d73a401ad059c61b6d9066c0ba784fb49dffa88882e78f609ff3c0ee06bd4174dbdd3692cae7478556f6a376949ab1d83b33496664551d83fc3033861a51d93fd359e6b8d58692f77966796178c1bd35c35b890de5fece13f80a5e09f7e76f30a5cab0fff02f8b77ca405dbc101ab0c00c3db7520c634b6794ea0d8e2da42a739dd5c9a6d9c144c1ffc9b40cda563d978612935032f6046c6bb8ab09dfa9105e8386aeaf07eaed1469277dab091f5932f2ecf368f9eda645e3b811d735113f05f1d6a3b2ececcd5978e0135dacdc57afb94996f9c326f9a6b2c5994b89bfa9245bc294171dffdf43cd6e80811022d0bf06f04fe15e15f24f04fb108d15c3a515f68ce9a13f576b3be847bc2ad3c1ba1045b1b795f4d00d7ff019e55743300d007000082010101002071c6cbdee3f4d6824fb9876d6362d085242ac20ad2e5cff92667c7f9a21e805874361f0f0af17fbbb704e35533a3678c5f59434140ff314085ad604beb1fb0640100e60778da8d563b8f1c4510eedd9d7ddcae7d3a0ecc710e088c482c197c6bb33a99e408480808784487197aa76b775a3bd33374f7ecde424c6048909c1909590881838bce897510589b22216170c023003290f80f54cfccceebb8e53a984755757557d5575f77fb8fdebb0df2f2cfd66d82a3661ee4efab6f9bd703e7685112dcfba7dfbfbdb994dcda5c8740f1e0c60d3ae42feebcd0af6d0dbdc099d88a8f0517639b46da0d24d7f34b532a3915da3e456f4faf6e77d089ed52e5927a3398099096a03e5846d2735c70262af2fb2f0d3ad4d17c4a3590dafa08a88e24d88c8f41e9a2d55ae69a586bda95a0dcc063ad880b7dad6f4d60aecee1c39e011fbb7aff263a75824868b51d82f4b9c2a084edc114bccca439a35cabf3e699c92e9e1e0ea99f61d90bf17cc7a55cd8219518ae06a9c8134ffaf4204d95006d478a8e217632b87e515339065dd5daa1a3d365b6cd642da95026531847d9c5b5feb343aa7002c895561bb96f0f6046e7a9fc3927101a0eb43d926032afe2c415762222ffaca60c446a5a88d809a3d246ca1167da5511575d6cfb98e05506cf543d787c049afb59ca188c404a60687460c341c8258ded665cb060965a5da87a61e065797bda28b9f0b8003b552bfec17281ad935a06a17663f5ce204e4f0eafa2aae750e180172f45eaebc9df128d1b5538b7ccfe392bb64a17a722ee8c39a9b7d346887baf9bcf4efe73ec927a037fba6134f4b863e3672b91a79beae00e26b147abe4d1720206c9979e87c9574fc2fb1197e0c3725981704b26e174476293072919648f8421f22e6fc5ac00b9a01da05e0612fb5081600876cedaf1e6fabb1d946853c9e670ae419d48121210ba4bd7ac2661eb148620f582e5c9bc97d2b319ca80450e6e2aa7a9faf94c98459987731ab19ec3e42d0991ad64c4b6b13415a9592319f8b1ff96028dac5b297b03454966ba46ef711f89af52c835242b3bb669c6b4d4354d9dc4980a4c8b15056df465aa5f71d49afa06094d9398ddb5a93f4502c4ac25ff315c92ad6015754c918ad45ac9c77fb3a75927947c5a09aacd956dc489e34e6c143074d65198241679f0d4c9a2ecdfec46228372e37fa1dc8d4246d356b256b69209618977cbd8e7a5ee158e1852efc47f0a9c9428ca40dac083f8f2677828e7a722f9f6d6e5573ffaea95122f90bdef7eb977f8c56bc55ec77165d2f8fa93bc57c9dee7772eb107778a0d88e3f7471f3efe32eba74fdf1afc0aecf0b88c3c1c77c13f3cce50b6bc3e2c2146c8f7af1fbb478b22a470ec3dfff1d1228306210f1fbdf3e6fd45a1d838defb66fffe222b2b8edd1f509097d004f7f0af3f7f2ad62a0ed87be371b122e6267397fef8db4e830fae1392df37f0d673860b4a6dd5694ffe059b3958df0001 DMLOG START_BLOCK 5 DMLOG CREATION_OP ROOT 0 DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"eosio","net_usage":{"last_ordinal":1262304004,"value_ex":101209,"consumed":1},"cpu_usage":{"last_ordinal":1262304004,"value_ex":268536,"consumed":101},"ram_usage":199629} @@ -183,14 +179,7 @@ DMLOG CREATION_OP ROOT 0 DMLOG PERM_OP INS 0 11 {"usage_id":10,"parent":10,"owner":"alice","name":"test1","last_updated":"2020-01-01T00:00:02.000","auth":{"threshold":1,"keys":[],"accounts":[{"permission":{"actor":"eosio","permission":"active"},"weight":1}],"waits":[]}} DMLOG RAM_OP 0 11 auth add updateauth_create alice 3108 320 DMLOG RLIMIT_OP ACCOUNT_USAGE UPD {"owner":"alice","net_usage":{"last_ordinal":1262304004,"value_ex":834,"consumed":144},"cpu_usage":{"last_ordinal":1262304004,"value_ex":11575,"consumed":2000},"ram_usage":3108} -<<<<<<< HEAD DMLOG APPLIED_TRANSACTION 5 530de341efeac006a43329e4748583c9ef216a164c70c7b46a8e93042c45cd8a05000000043b3d4b010000000551fa877e4307b47a58bb19e36497ab2df3119c5c9cc1b9d80c307b5f0100d007000012000000000000000090000000000000000001010000010000000000ea3055f3d881d2f7fbf2f7cb6081aff84e7aca1dd3914a0948ef4fc9422e734e8d4d571d000000000000001d00000000000000010000000000855c34010000000000000002020000000000ea30550000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c34000000008090b1ca00000000a8ed32320100000000010000000000ea305500000000a8ed323201000000000000000000000000530de341efeac006a43329e4748583c9ef216a164c70c7b46a8e93042c45cd8a05000000043b3d4b010000000551fa877e4307b47a58bb19e36497ab2df3119c5c9cc1b9d80c307b5f010000000000855c34400100000000000000000000000000 DMLOG RLIMIT_OP STATE UPD {"average_block_net_usage":{"last_ordinal":4,"value_ex":145068889,"consumed":8000},"average_block_cpu_usage":{"last_ordinal":4,"value_ex":382895892,"consumed":4449},"pending_net_usage":376,"pending_cpu_usage":4100,"total_net_weight":0,"total_cpu_weight":0,"total_ram_bytes":0,"virtual_net_limit":1051726,"virtual_cpu_limit":200600} DMLOG RLIMIT_OP STATE UPD {"average_block_net_usage":{"last_ordinal":5,"value_ex":146993315,"consumed":520},"average_block_cpu_usage":{"last_ordinal":5,"value_ex":413871759,"consumed":4480},"pending_net_usage":0,"pending_cpu_usage":0,"total_net_weight":0,"total_cpu_weight":0,"total_ram_bytes":0,"virtual_net_limit":1052778,"virtual_cpu_limit":200800} -DMLOG ACCEPTED_BLOCK 5 05000000050000000400000000000000010000000000ea3055000100000001000240e54a7b27e042b80a810153bec1dd166eef95fa69f6c9886ae283363bc2add8010001b2cd0fd8d0aeb0983cf5b79b35e97f42f204914726c831b95c1ff896ca7cc1f70400000000000000010000000000ea305505000000010000000000ea305504000000000100000001000240e54a7b27e042b80a810153bec1dd166eef95fa69f6c9886ae283363bc2add80100000000000551fa877e4307b47a58bb19e36497ab2df3119c5c9cc1b9d80c307b5f043b3d4b0000000000ea305500000000000446ce40fcba331770d4e40c1a69d054d3a9a5ed89ef08b50cc808e32529e6fd108fe2b5c29c60c4d10b3bcd6dd68fbbaeb8eda2417ea361750429ed07182c0649523b9bcbb941da3c9ba69b7fdd2a061be2e8e19bd532c4532c674074000000000000001f64905c5f3f6b6fea6be1479d459f26f49dabe66f6452d029b4aac534bdae794a5bc74c010be03a9ac8bcd1af835910bff6619dcc993a6b3cda9ef986372bcf900000000029807708239aa7de914d3ed61e9009ab2280bfbc50f1d9769f27f8341ef26198000000000001140ec7e080177b2c02b278d5088611686b49d739925a92d9bfcacd7fc6b74053bd1a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b72412652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed25299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b447670735c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b4a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0f4e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d674fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c25443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b468dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a2974286bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc8ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a40598c4175db53ed27e7911a1b5adf0e7db0fc96c2cae172cf594dfa9a742ca9e88ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c43bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e99c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead45071d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb40e0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff526ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea99f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d0001043b3d4b0000000000ea305500000000000446ce40fcba331770d4e40c1a69d054d3a9a5ed89ef08b50cc808e32529e6fd108fe2b5c29c60c4d10b3bcd6dd68fbbaeb8eda2417ea361750429ed07182c0649523b9bcbb941da3c9ba69b7fdd2a061be2e8e19bd532c4532c674074000000000000001f64905c5f3f6b6fea6be1479d459f26f49dabe66f6452d029b4aac534bdae794a5bc74c010be03a9ac8bcd1af835910bff6619dcc993a6b3cda9ef986372bcf900200d00700001d0101001f281f9a1a1c1db3802dcc9722bc82373b1b7e5e02ee3c23555be869da51384317257214aaabf8797fe97ff3d5c7366353d197575f7ad7dc07b8f6b48f251b39ce0000bd0107e10b5e0400ba33177000000000010000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed32328a010000000000ea30550000000000855c3401000000010002bb30f6894f29bb6fca635b1df728ad77e48fdd6123ce5e4455b0f71e072e7df80100010000000000855c3400804a1401ea305501000001000000010003ebcf44b45a71d4f225768f602d1e2e2b25ef779ee9897fe744bf1a16e85423d50100010000000000855c3400804a1401ea30550100000000d0070000120101001f111f9dacd4b0ca94c80782ea19e40bccd1d211a4ef502ce83a27752116ccd86f1063361a90577bd5654df73be79ba08d45a08d786975c9b93ef6f249558beca000006307e10b5e0400ba33177000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c34000000008090b1ca00000000a8ed32320100000000010000000000ea305500000000a8ed3232010000000000 -======= -DMLOG APPLIED_TRANSACTION 5 6cdc68c8257e32da2f6cd8c4f6e6bb7798a47e7da6ac14a7cea45da9cd70c81c05000000043b3d4b010000000596867aec674ebb58c23ffcafefab5119fdbdbb08736a63fbdc64e7510100d007000012000000000000000090000000000000000001010000010000000000ea3055f3d881d2f7fbf2f7cb6081aff84e7aca1dd3914a0948ef4fc9422e734e8d4d571c000000000000001c00000000000000010000000000855c34010000000000000002020000000000ea30550000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c34000000008090b1ca00000000a8ed32320100000000010000000000ea305500000000a8ed3232010000000000000000000000006cdc68c8257e32da2f6cd8c4f6e6bb7798a47e7da6ac14a7cea45da9cd70c81c05000000043b3d4b010000000596867aec674ebb58c23ffcafefab5119fdbdbb08736a63fbdc64e751010000000000855c34400100000000000000000000000000 -DMLOG RLIMIT_OP STATE UPD {"average_block_net_usage":{"last_ordinal":4,"value_ex":144011111,"consumed":7999},"average_block_cpu_usage":{"last_ordinal":4,"value_ex":366368114,"consumed":4433},"pending_net_usage":376,"pending_cpu_usage":4100,"total_net_weight":0,"total_cpu_weight":0,"total_ram_bytes":0,"virtual_net_limit":1051726,"virtual_cpu_limit":200600} -DMLOG RLIMIT_OP STATE UPD {"average_block_net_usage":{"last_ordinal":5,"value_ex":145944352,"consumed":519},"average_block_cpu_usage":{"last_ordinal":5,"value_ex":397481713,"consumed":4464},"pending_net_usage":0,"pending_cpu_usage":0,"total_net_weight":0,"total_cpu_weight":0,"total_ram_bytes":0,"virtual_net_limit":1052778,"virtual_cpu_limit":200800} -DMLOG ACCEPTED_BLOCK 5 05000000050000000400000000000000010000000000ea3055000100000001000240e54a7b27e042b80a810153bec1dd166eef95fa69f6c9886ae283363bc2add80100018b5b706080c8d5ec9456986e611761b17ec82e672f8176e581625f54535c32150400000000000000010000000000ea305505000000010000000000ea305504000000000100000001000240e54a7b27e042b80a810153bec1dd166eef95fa69f6c9886ae283363bc2add80100000000000596867aec674ebb58c23ffcafefab5119fdbdbb08736a63fbdc64e751043b3d4b0000000000ea30550000000000044444a224a7e16ae04e24e6640d6a909fb89ca6e5e8c1e5397e1e03ef08a40bd5b3162bbbe3fb5d540dabc705bada65dd0a276381665c9ed73d4afa451bb28b302f397e60628e8e3a7d3ecb23a8a0bf20f606dd26b93b61511cb87673000000000000001f69207fd55ddaddad96457d633a97f216211989106548974158e1cf70d1f8e5e5262d674a40041040cf394ae3496bb3852b67e15d9c771dfb4a818f6166f590a90000000029807708239aa7de914d3ed61e9009ab2280bfbc50f1d9769f27f8341ef26198000000000001130ec7e080177b2c02b278d5088611686b49d739925a92d9bfcacd7fc6b74053bd1a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b72412652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed25299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b447670735c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b4a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0f4e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d674fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c25443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b468dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a2974286bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc8ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a405ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c43bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e99c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead45071d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb40e0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff526ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea99f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d0001043b3d4b0000000000ea30550000000000044444a224a7e16ae04e24e6640d6a909fb89ca6e5e8c1e5397e1e03ef08a40bd5b3162bbbe3fb5d540dabc705bada65dd0a276381665c9ed73d4afa451bb28b302f397e60628e8e3a7d3ecb23a8a0bf20f606dd26b93b61511cb87673000000000000001f69207fd55ddaddad96457d633a97f216211989106548974158e1cf70d1f8e5e5262d674a40041040cf394ae3496bb3852b67e15d9c771dfb4a818f6166f590a90200d00700001d0101001f55be758d9f4e3d253e069c66875beafbffe405c897ee2da2dd4577b2953a3379758676fd8906c5c3eb7043a30dc8d939af3eef5e73bf7f57f253e854f803dd810000bd0107e10b5e0400a7e16ae000000000010000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed32328a010000000000ea30550000000000855c3401000000010002bb30f6894f29bb6fca635b1df728ad77e48fdd6123ce5e4455b0f71e072e7df80100010000000000855c3400804a1401ea305501000001000000010003ebcf44b45a71d4f225768f602d1e2e2b25ef779ee9897fe744bf1a16e85423d50100010000000000855c3400804a1401ea30550100000000d0070000120101001f504584a3e50ad7d75a7ffd3254fbd363824a5269d57a1d3443644067e42117515242fb12efe17be14590b398489b951a8823f8b5aed4d7de11be3a971498ddb100006307e10b5e0400a7e16ae000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c34000000008090b1ca00000000a8ed32320100000000010000000000ea305500000000a8ed3232010000000001 ->>>>>>> d243f8569d5f8baf55bfb787a481530998a15d93 +DMLOG ACCEPTED_BLOCK 5 05000000050000000400000000000000010000000000ea3055000100000001000240e54a7b27e042b80a810153bec1dd166eef95fa69f6c9886ae283363bc2add8010001b2cd0fd8d0aeb0983cf5b79b35e97f42f204914726c831b95c1ff896ca7cc1f70400000000000000010000000000ea305505000000010000000000ea305504000000000100000001000240e54a7b27e042b80a810153bec1dd166eef95fa69f6c9886ae283363bc2add80100000000000551fa877e4307b47a58bb19e36497ab2df3119c5c9cc1b9d80c307b5f043b3d4b0000000000ea305500000000000446ce40fcba331770d4e40c1a69d054d3a9a5ed89ef08b50cc808e32529e6fd108fe2b5c29c60c4d10b3bcd6dd68fbbaeb8eda2417ea361750429ed07182c0649523b9bcbb941da3c9ba69b7fdd2a061be2e8e19bd532c4532c674074000000000000001f64905c5f3f6b6fea6be1479d459f26f49dabe66f6452d029b4aac534bdae794a5bc74c010be03a9ac8bcd1af835910bff6619dcc993a6b3cda9ef986372bcf900000000029807708239aa7de914d3ed61e9009ab2280bfbc50f1d9769f27f8341ef26198000000000001140ec7e080177b2c02b278d5088611686b49d739925a92d9bfcacd7fc6b74053bd1a99a59d87e06e09ec5b028a9cbb7749b4a5ad8819004365d02dc4379a8b72412652f5f96006294109b3dd0bbde63693f55324af452b799ee137a81a905eed25299dcb6af692324b899b39f16d5a530a33062804e41f09dc97e9f156b447670735c2186cc36f7bb4aeaf4487b36e57039ccf45a9136aa856a5d569ecca55ef2b4a90c00d55454dc5b059055ca213579c6ea856967712a56017487886a4d4cc0f4e7bf348da00a945489b2a681749eb56f5de00b900014e137ddae39f48f69d674fca8bd82bbd181e714e283f83e1b45d95ca5af40fb89ad3977b653c448f78c25443fcf88330c586bc0e5f3dee10e7f63c76c00249c87fe4fbf7f38c082006b468dcaa34c0517d19666e6b33add67351d8c5f69e999ca1e37931bc410a2974286bcb40a24e49c26d0a60513b6aeb8551d264e4717f306b81a37a5afb3b47cedc8ba52fe7a3956c5cd3a656a3174b931d3bb2abb45578befc59f283ecd816a40598c4175db53ed27e7911a1b5adf0e7db0fc96c2cae172cf594dfa9a742ca9e88ad9e3d8f650687709fd68f4b90b41f7d825a365b02c23a636cef88ac2ac00c43bcd2a26394b36614fd4894241d3c451ab0f6fd110958c3423073621a70826e99c3a6138c5061cf291310887c0b5c71fcaffeab90d5deb50d3b9e687cead45071d528b9f6e9693f45ed277af93474fd473ce7d831dae2180cca35d907bd10cb40e0fb64b1085cc5538970158d05a009c24e276fb94e1a0bf6a528b48fbc4ff526ef43112c6543b88db2283a2e077278c315ae2c84719a8b25f25cc88565fbea99f0af56d2c5a48d60a4a5b5c903edfb7db3a736a94ed589d0b797df33ff9d3e1d0001043b3d4b0000000000ea305500000000000446ce40fcba331770d4e40c1a69d054d3a9a5ed89ef08b50cc808e32529e6fd108fe2b5c29c60c4d10b3bcd6dd68fbbaeb8eda2417ea361750429ed07182c0649523b9bcbb941da3c9ba69b7fdd2a061be2e8e19bd532c4532c674074000000000000001f64905c5f3f6b6fea6be1479d459f26f49dabe66f6452d029b4aac534bdae794a5bc74c010be03a9ac8bcd1af835910bff6619dcc993a6b3cda9ef986372bcf900200d00700001d0101001f281f9a1a1c1db3802dcc9722bc82373b1b7e5e02ee3c23555be869da51384317257214aaabf8797fe97ff3d5c7366353d197575f7ad7dc07b8f6b48f251b39ce0000bd0107e10b5e0400ba33177000000000010000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed32328a010000000000ea30550000000000855c3401000000010002bb30f6894f29bb6fca635b1df728ad77e48fdd6123ce5e4455b0f71e072e7df80100010000000000855c3400804a1401ea305501000001000000010003ebcf44b45a71d4f225768f602d1e2e2b25ef779ee9897fe744bf1a16e85423d50100010000000000855c3400804a1401ea30550100000000d0070000120101001f111f9dacd4b0ca94c80782ea19e40bccd1d211a4ef502ce83a27752116ccd86f1063361a90577bd5654df73be79ba08d45a08d786975c9b93ef6f249558beca000006307e10b5e0400ba33177000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c34000000008090b1ca00000000a8ed32320100000000010000000000ea305500000000a8ed3232010000000001 From 181c182dd85bc2feedf7f31931f0505befce1979 Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Sun, 30 Jul 2023 16:43:15 -0400 Subject: [PATCH 25/79] update bls12-381 to Antelope fork; fix libtester install --- .gitmodules | 2 +- CMakeModules/EosioTesterBuild.cmake.in | 2 +- libraries/chain/controller.cpp | 3 +- libraries/chain/webassembly/crypto.cpp | 56 ++++++++++++------------ libraries/libfc/CMakeLists.txt | 3 ++ libraries/libfc/libraries/bls12-381 | 2 +- libraries/libfc/test/crypto/test_bls.cpp | 14 +++--- 7 files changed, 42 insertions(+), 40 deletions(-) diff --git a/.gitmodules b/.gitmodules index 859e7637d8..e4ca16a9fe 100644 --- a/.gitmodules +++ b/.gitmodules @@ -33,7 +33,7 @@ url = https://github.com/AntelopeIO/CLI11.git [submodule "libraries/libfc/libraries/bls12-381"] path = libraries/libfc/libraries/bls12-381 - url = https://github.com/mschoenebeck/bls12-381.git + url = https://github.com/AntelopeIO/bls12-381 [submodule "libraries/boost"] path = libraries/boost url = https://github.com/boostorg/boost.git diff --git a/CMakeModules/EosioTesterBuild.cmake.in b/CMakeModules/EosioTesterBuild.cmake.in index 1ef5d2d695..209f0ec985 100644 --- a/CMakeModules/EosioTesterBuild.cmake.in +++ b/CMakeModules/EosioTesterBuild.cmake.in @@ -42,7 +42,7 @@ find_library(libchain eosio_chain @CMAKE_BINARY_DIR@/libraries/chain NO_DEFAULT_ find_library(libfc fc @CMAKE_BINARY_DIR@/libraries/libfc NO_DEFAULT_PATH) find_library(libsecp256k1 secp256k1 @CMAKE_BINARY_DIR@/libraries/libfc/secp256k1 NO_DEFAULT_PATH) find_library(libbn256 bn256 @CMAKE_BINARY_DIR@/libraries/libfc/libraries/bn256/src NO_DEFAULT_PATH) -find_library(libbls12-381 bls12-381 @CMAKE_BINARY_DIR@/libraries/libfc/libraries/bls12-381/src NO_DEFAULT_PATH) +find_library(libbls12-381 bls12-381 @CMAKE_BINARY_DIR@/libraries/libfc/libraries/bls12-381 NO_DEFAULT_PATH) find_library(libwasm WASM @CMAKE_BINARY_DIR@/libraries/wasm-jit/Source/WASM NO_DEFAULT_PATH) find_library(libwast WAST @CMAKE_BINARY_DIR@/libraries/wasm-jit/Source/WAST NO_DEFAULT_PATH) diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index 5fb35a78d7..be604bffb6 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include @@ -340,7 +340,6 @@ struct controller_impl { set_activation_handler(); set_activation_handler(); set_activation_handler(); - bls12_381::init(); self.irreversible_block.connect([this](const block_state_ptr& bsp) { wasm_if_collect.current_lib(bsp->block_num); diff --git a/libraries/chain/webassembly/crypto.cpp b/libraries/chain/webassembly/crypto.cpp index b2a05b5e1e..aab88890f6 100644 --- a/libraries/chain/webassembly/crypto.cpp +++ b/libraries/chain/webassembly/crypto.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include namespace { uint32_t ceil_log2(uint32_t n) @@ -255,12 +255,12 @@ namespace eosio { namespace chain { namespace webassembly { { if(op1.size() != 144 || op2.size() != 144 || result.size() != 144) return return_code::failure; - std::optional a = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(op1.data()), 144}, false, true); - std::optional b = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(op2.data()), 144}, false, true); + std::optional a = bls12_381::g1::fromJacobianBytesLE(std::span((uint8_t*)op1.data(), 144), false, true); + std::optional b = bls12_381::g1::fromJacobianBytesLE(std::span((uint8_t*)op2.data(), 144), false, true); if(!a.has_value() || !b.has_value()) return return_code::failure; bls12_381::g1 c = a.value().add(b.value()); - c.toJacobianBytesLE({reinterpret_cast(result.data()), 144}, true); + c.toJacobianBytesLE(std::span((uint8_t*)result.data(), 144), true); return return_code::success; } @@ -268,12 +268,12 @@ namespace eosio { namespace chain { namespace webassembly { { if(op1.size() != 288 || op2.size() != 288 || result.size() != 288) return return_code::failure; - std::optional a = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(op1.data()), 288}, false, true); - std::optional b = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(op2.data()), 288}, false, true); + std::optional a = bls12_381::g2::fromJacobianBytesLE(std::span((uint8_t*)op1.data(), 288), false, true); + std::optional b = bls12_381::g2::fromJacobianBytesLE(std::span((uint8_t*)op2.data(), 288), false, true); if(!a.has_value() || !b.has_value()) return return_code::failure; bls12_381::g2 c = a.value().add(b.value()); - c.toJacobianBytesLE({reinterpret_cast(result.data()), 288}, true); + c.toJacobianBytesLE(std::span((uint8_t*)result.data(), 288), true); return return_code::success; } @@ -281,12 +281,12 @@ namespace eosio { namespace chain { namespace webassembly { { if(point.size() != 144 || scalar.size() != 32 || result.size() != 144) return return_code::failure; - std::optional a = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(point.data()), 144}, false, true); + std::optional a = bls12_381::g1::fromJacobianBytesLE(std::span((uint8_t*)point.data(), 144), false, true); if(!a.has_value()) return return_code::failure; - std::array b = bls12_381::scalar::fromBytesLE<4>({reinterpret_cast(scalar.data()), 32}); + std::array b = bls12_381::scalar::fromBytesLE<4>(std::span((uint8_t*)scalar.data(), 32)); bls12_381::g1 c = a.value().mulScalar(b); - c.toJacobianBytesLE({reinterpret_cast(result.data()), 144}, true); + c.toJacobianBytesLE(std::span((uint8_t*)result.data(), 144), true); return return_code::success; } @@ -294,12 +294,12 @@ namespace eosio { namespace chain { namespace webassembly { { if(point.size() != 288 || scalar.size() != 32 || result.size() != 288) return return_code::failure; - std::optional a = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(point.data()), 288}, false, true); + std::optional a = bls12_381::g2::fromJacobianBytesLE(std::span((uint8_t*)point.data(), 288), false, true); if(!a.has_value()) return return_code::failure; - std::array b = bls12_381::scalar::fromBytesLE<4>({reinterpret_cast(scalar.data()), 32}); + std::array b = bls12_381::scalar::fromBytesLE<4>(std::span((uint8_t*)scalar.data(), 32)); bls12_381::g2 c = a.value().mulScalar(b); - c.toJacobianBytesLE({reinterpret_cast(result.data()), 288}, true); + c.toJacobianBytesLE(std::span((uint8_t*)result.data(), 288), true); return return_code::success; } @@ -313,17 +313,17 @@ namespace eosio { namespace chain { namespace webassembly { sv.reserve(n); for(uint32_t i = 0; i < n; i++) { - std::optional p = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(points.data() + i*144), 144}, false, true); + std::optional p = bls12_381::g1::fromJacobianBytesLE(std::span((uint8_t*)points.data() + i*144, 144), false, true); if(!p.has_value()) return return_code::failure; - std::array s = bls12_381::scalar::fromBytesLE<4>({reinterpret_cast(scalars.data() + i*32), 32}); + std::array s = bls12_381::scalar::fromBytesLE<4>(std::span((uint8_t*)scalars.data() + i*32, 32)); pv.push_back(p.value()); sv.push_back(s); if(i%10 == 0) context.trx_context.checktime(); } bls12_381::g1 r = bls12_381::g1::multiExp(pv, sv, [this](){ context.trx_context.checktime(); }).value(); // accessing value is safe - r.toJacobianBytesLE({reinterpret_cast(result.data()), 144}, true); + r.toJacobianBytesLE(std::span((uint8_t*)result.data(), 144), true); return return_code::success; } @@ -337,17 +337,17 @@ namespace eosio { namespace chain { namespace webassembly { sv.reserve(n); for(uint32_t i = 0; i < n; i++) { - std::optional p = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(points.data() + i*288), 288}, false, true); + std::optional p = bls12_381::g2::fromJacobianBytesLE(std::span((uint8_t*)points.data() + i*288, 288), false, true); if(!p.has_value()) return return_code::failure; - std::array s = bls12_381::scalar::fromBytesLE<4>({reinterpret_cast(scalars.data() + i*32), 32}); + std::array s = bls12_381::scalar::fromBytesLE<4>(std::span((uint8_t*)scalars.data() + i*32, 32)); pv.push_back(p.value()); sv.push_back(s); if(i%6 == 0) context.trx_context.checktime(); } bls12_381::g2 r = bls12_381::g2::multiExp(pv, sv, [this](){ context.trx_context.checktime(); }).value(); // accessing value is safe - r.toJacobianBytesLE({reinterpret_cast(result.data()), 288}, true); + r.toJacobianBytesLE(std::span((uint8_t*)result.data(), 288), true); return return_code::success; } @@ -359,8 +359,8 @@ namespace eosio { namespace chain { namespace webassembly { v.reserve(n); for(uint32_t i = 0; i < n; i++) { - std::optional p_g1 = bls12_381::g1::fromJacobianBytesLE({reinterpret_cast(g1_points.data() + i*144), 144}, true, true); - std::optional p_g2 = bls12_381::g2::fromJacobianBytesLE({reinterpret_cast(g2_points.data() + i*288), 288}, true, true); + std::optional p_g1 = bls12_381::g1::fromJacobianBytesLE(std::span((uint8_t*)g1_points.data() + i*144, 144), true, true); + std::optional p_g2 = bls12_381::g2::fromJacobianBytesLE(std::span((uint8_t*)g2_points.data() + i*288, 288), true, true); if(!p_g1.has_value() || !p_g2.has_value()) return return_code::failure; bls12_381::pairing::add_pair(v, p_g1.value(), p_g2.value()); @@ -368,7 +368,7 @@ namespace eosio { namespace chain { namespace webassembly { context.trx_context.checktime(); } bls12_381::fp12 r = bls12_381::pairing::calculate(v, [this](){ context.trx_context.checktime(); }); - r.toBytesLE({reinterpret_cast(result.data()), 576}, true); + r.toBytesLE(std::span((uint8_t*)result.data(), 576), true); return return_code::success; } @@ -376,11 +376,11 @@ namespace eosio { namespace chain { namespace webassembly { { if(e.size() != 48 || result.size() != 144) return return_code::failure; - std::optional a = bls12_381::fp::fromBytesLE({reinterpret_cast(e.data()), 48}, true, true); + std::optional a = bls12_381::fp::fromBytesLE(std::span((uint8_t*)e.data(), 48), true, true); if(!a.has_value()) return return_code::failure; bls12_381::g1 c = bls12_381::g1::mapToCurve(a.value()); - c.toJacobianBytesLE({reinterpret_cast(result.data()), 144}, true); + c.toJacobianBytesLE(std::span((uint8_t*)result.data(), 144), true); return return_code::success; } @@ -388,11 +388,11 @@ namespace eosio { namespace chain { namespace webassembly { { if(e.size() != 96 || result.size() != 288) return return_code::failure; - std::optional a = bls12_381::fp2::fromBytesLE({reinterpret_cast(e.data()), 96}, true, true); + std::optional a = bls12_381::fp2::fromBytesLE(std::span((uint8_t*)e.data(), 96), true, true); if(!a.has_value()) return return_code::failure; bls12_381::g2 c = bls12_381::g2::mapToCurve(a.value()); - c.toJacobianBytesLE({reinterpret_cast(result.data()), 288}, true); + c.toJacobianBytesLE(std::span((uint8_t*)result.data(), 288), true); return return_code::success; } @@ -400,9 +400,9 @@ namespace eosio { namespace chain { namespace webassembly { { if(s.size() != 64 || result.size() != 48) return return_code::failure; - std::array k = bls12_381::scalar::fromBytesLE<8>({reinterpret_cast(s.data()), 64}); + std::array k = bls12_381::scalar::fromBytesLE<8>(std::span((uint8_t*)s.data(), 64)); bls12_381::fp e = bls12_381::fp::modPrime<8>(k); - e.toBytesLE({reinterpret_cast(result.data()), 48}, true); + e.toBytesLE(std::span((uint8_t*)result.data(), 48), true); return return_code::success; } diff --git a/libraries/libfc/CMakeLists.txt b/libraries/libfc/CMakeLists.txt index d6291d5130..3975f2bd4d 100644 --- a/libraries/libfc/CMakeLists.txt +++ b/libraries/libfc/CMakeLists.txt @@ -126,3 +126,6 @@ install(TARGETS fc LIBRARY DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR} COMPONENT dev EXCLUDE_FROM_ALL ARCHIVE DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR} COMPONENT dev EXCLUDE_FROM_ALL) install(DIRECTORY include/fc DESTINATION ${CMAKE_INSTALL_FULL_INCLUDEDIR} COMPONENT dev EXCLUDE_FROM_ALL) + +install(TARGETS bls12-381 ARCHIVE DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}" COMPONENT dev EXCLUDE_FROM_ALL + PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_FULL_INCLUDEDIR}/bls12-381" COMPONENT dev EXCLUDE_FROM_ALL) diff --git a/libraries/libfc/libraries/bls12-381 b/libraries/libfc/libraries/bls12-381 index 82a137ecdc..e8ee0c20dd 160000 --- a/libraries/libfc/libraries/bls12-381 +++ b/libraries/libfc/libraries/bls12-381 @@ -1 +1 @@ -Subproject commit 82a137ecdc010563a78673ddabf014dd0ec6ae77 +Subproject commit e8ee0c20ddaa482395a05ea59c7dc0b277051c37 diff --git a/libraries/libfc/test/crypto/test_bls.cpp b/libraries/libfc/test/crypto/test_bls.cpp index 8d5fbbf538..569c2c4e91 100644 --- a/libraries/libfc/test/crypto/test_bls.cpp +++ b/libraries/libfc/test/crypto/test_bls.cpp @@ -1,6 +1,6 @@ #include -#include +#include #include using namespace std; @@ -33,13 +33,13 @@ BOOST_AUTO_TEST_CASE(bls_serialization_test) try { g1 pk = public_key(sk); g2 signature = sign(sk, message_1); - string pk_string = bytesToHex<144>(pk.toJacobianBytesBE()); - string signature_string = bytesToHex<288>(signature.toJacobianBytesBE()); - cout << pk_string << std::endl; - cout << signature_string << std::endl; + const array pk_string = pk.toJacobianBytesBE(); + const array signature_string = signature.toJacobianBytesBE(); + cout << bytesToHex<144>(pk_string) << std::endl; + cout << bytesToHex<288>(signature_string) << std::endl; - g1 pk2 = g1::fromJacobianBytesBE(hexToBytes(pk_string)).value(); - g2 signature2 = g2::fromJacobianBytesBE(hexToBytes(signature_string)).value(); + g1 pk2 = g1::fromJacobianBytesBE(pk_string).value(); + g2 signature2 = g2::fromJacobianBytesBE(signature_string).value(); bool ok = verify(pk2, message_1, signature2); BOOST_CHECK_EQUAL(ok, true); } FC_LOG_AND_RETHROW(); From 429e311be1693154c170784e283604ff17487616 Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Mon, 31 Jul 2023 15:48:50 -0400 Subject: [PATCH 26/79] install bls12-381 LICENSE --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index a6532b4292..1521e0ec1f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -225,6 +225,7 @@ configure_file(libraries/libfc/include/fc/crypto/webauthn_json/license.txt licen configure_file(libraries/eos-vm/LICENSE licenses/leap/LICENSE.eos-vm COPYONLY) configure_file(libraries/prometheus/prometheus-cpp/LICENSE licenses/leap/LICENSE.prom COPYONLY) configure_file(programs/cleos/LICENSE.CLI11 licenses/leap/LICENSE.CLI11 COPYONLY) +configure_file(libraries/libfc/libraries/bls12-381/LICENSE licenses/leap/LICENSE.bls12-381 COPYONLY) install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/licenses/leap" DESTINATION "${CMAKE_INSTALL_FULL_DATAROOTDIR}/licenses/" COMPONENT base) From 9fa13cd8b64e25b558669703b5a41e2660e1664c Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Tue, 1 Aug 2023 14:13:43 -0400 Subject: [PATCH 27/79] add BLS unit test for host functions with n=0 --- unittests/bls_primitives_tests.cpp | 45 ++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/unittests/bls_primitives_tests.cpp b/unittests/bls_primitives_tests.cpp index 08846766de..71cac24697 100644 --- a/unittests/bls_primitives_tests.cpp +++ b/unittests/bls_primitives_tests.cpp @@ -506,6 +506,51 @@ BOOST_AUTO_TEST_CASE( bls_testg2map ) { try { } FC_LOG_AND_RETHROW() } +BOOST_AUTO_TEST_CASE( bls_empty ) { try { + tester c( setup_policy::preactivate_feature_and_new_bios ); + + const auto& tester1_account = account_name("tester1"); + c.create_accounts( {tester1_account} ); + c.produce_block(); + + const auto& pfm = c.control->get_protocol_feature_manager(); + const auto& d = pfm.get_builtin_digest( builtin_protocol_feature_t::bls_primitives ); + BOOST_REQUIRE( d ); + c.preactivate_protocol_features( {*d} ); + c.produce_block(); + + c.set_code( tester1_account, test_contracts::bls_primitives_test_wasm() ); + c.set_abi( tester1_account, test_contracts::bls_primitives_test_abi().data() ); + c.produce_block(); + + //expected return is g1::zero(), which is x=0, y=1, z=0. 1 here means fp::R1 + c.push_action( tester1_account, "testg1exp"_n, tester1_account, mutable_variant_object() + ("points", std::vector()) + ("scalars", std::vector()) + ("num", 0) + ("res", hex2bin("000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FDFF02000000097602000CC40B00F4EBBA58C7535798485F455752705358CE776DEC56A2971A075C93E480FAC35EF615000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")) + ("expected_error", (int32_t)return_code::success) + ); + + //expected return is g2::zero(), which is x=0, y=1, z=0. 1 here means fb2::one(), {fp::R1, 0} + c.push_action( tester1_account, "testg2exp"_n, tester1_account, mutable_variant_object() + ("points", std::vector()) + ("scalars", std::vector()) + ("num", 0) + ("res", hex2bin("000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FDFF02000000097602000CC40B00F4EBBA58C7535798485F455752705358CE776DEC56A2971A075C93E480FAC35EF615000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")) + ("expected_error", (int32_t)return_code::success) + ); + + //expected return is fp12::one(), which is {fp6::one(), fp6::zero()}, which is {{fp2::one(), fp2::zero(), fp2::zero()}, {fp2::zero(), fp2::zero(), fp2::zero()}} + c.push_action( tester1_account, "testpairing"_n, tester1_account, mutable_variant_object() + ("g1_points", std::vector()) + ("g2_points", std::vector()) + ("num", 0) + ("res", hex2bin("FDFF02000000097602000CC40B00F4EBBA58C7535798485F455752705358CE776DEC56A2971A075C93E480FAC35EF615000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")) + ("expected_error", (int32_t)return_code::success) + ); + +} FC_LOG_AND_RETHROW() } BOOST_AUTO_TEST_SUITE_END() From 79c981718aee2417a64cffecc6c74dd61a2e78ba Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Wed, 2 Aug 2023 17:03:39 -0500 Subject: [PATCH 28/79] Add per peer prometheus metrics and a TUI to view them. --- plugins/chain_plugin/chain_plugin.cpp | 9 - .../eosio/chain_plugin/chain_plugin.hpp | 9 + .../include/eosio/net_plugin/net_plugin.hpp | 53 +++ plugins/net_plugin/net_plugin.cpp | 56 ++- .../prometheus_plugin/prometheus_plugin.hpp | 3 +- plugins/prometheus_plugin/metrics.hpp | 103 ++++- .../prometheus_plugin/prometheus_plugin.cpp | 2 + programs/CMakeLists.txt | 1 + programs/net-util/CMakeLists.txt | 1 + programs/net-util/net-util.py | 360 ++++++++++++++++++ tests/cluster_launcher.py | 11 +- 11 files changed, 564 insertions(+), 44 deletions(-) create mode 100644 programs/net-util/CMakeLists.txt create mode 100755 programs/net-util/net-util.py diff --git a/plugins/chain_plugin/chain_plugin.cpp b/plugins/chain_plugin/chain_plugin.cpp index 6073a8637d..c3db9e8961 100644 --- a/plugins/chain_plugin/chain_plugin.cpp +++ b/plugins/chain_plugin/chain_plugin.cpp @@ -1296,15 +1296,6 @@ namespace chain_apis { const string read_only::KEYi64 = "i64"; -template -std::string itoh(I n, size_t hlen = sizeof(I)<<1) { - static const char* digits = "0123456789abcdef"; - std::string r(hlen, '0'); - for(size_t i = 0, j = (hlen - 1) * 4 ; i < hlen; ++i, j -= 4) - r[i] = digits[(n>>j) & 0x0f]; - return r; -} - read_only::get_info_results read_only::get_info(const read_only::get_info_params&, const fc::time_point&) const { const auto& rm = db.get_resource_limits_manager(); diff --git a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp index 6f2233a362..77eb431bda 100644 --- a/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp +++ b/plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp @@ -950,6 +950,15 @@ class read_write : public api_base { } }; + template + std::string itoh(I n, size_t hlen = sizeof(I)<<1) { + static const char* digits = "0123456789abcdef"; + std::string r(hlen, '0'); + for(size_t i = 0, j = (hlen - 1) * 4 ; i < hlen; ++i, j -= 4) + r[i] = digits[(n>>j) & 0x0f]; + return r; + } + } // namespace chain_apis class chain_plugin : public plugin { diff --git a/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp b/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp index 5d5d12ef40..06555c63fc 100644 --- a/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp +++ b/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp @@ -39,9 +39,62 @@ namespace eosio { std::optional status( const string& endpoint )const; vector connections()const; + struct p2p_per_connection_metrics { + p2p_per_connection_metrics(size_t count) { + addresses.reserve(count); + ports.reserve(count); + accepting_blocks.reserve(count); + last_received_blocks.reserve(count); + first_available_blocks.reserve(count); + last_available_blocks.reserve(count); + unique_first_block_counts.reserve(count); + latencies.reserve(count); + bytes_received.reserve(count); + bytes_sent.reserve(count); + connection_start_times.reserve(count); + } + p2p_per_connection_metrics(p2p_per_connection_metrics&& metrics) + : addresses{std::move(metrics.addresses)} + , ports{std::move(metrics.ports)} + , accepting_blocks{std::move(metrics.accepting_blocks)} + , last_received_blocks{std::move(metrics.last_received_blocks)} + , first_available_blocks{std::move(metrics.first_available_blocks)} + , last_available_blocks{std::move(metrics.last_available_blocks)} + , unique_first_block_counts{std::move(metrics.unique_first_block_counts)} + , latencies{std::move(metrics.latencies)} + , bytes_received{std::move(metrics.bytes_received)} + , bytes_sent{std::move(metrics.bytes_sent)} + , connection_start_times{std::move(metrics.connection_start_times)} + {} + p2p_per_connection_metrics(const p2p_per_connection_metrics&) = delete; + p2p_per_connection_metrics& operator=(const p2p_per_connection_metrics&) = delete; + std::vector addresses; + std::vector ports; + std::vector accepting_blocks; + std::vector last_received_blocks; + std::vector first_available_blocks; + std::vector last_available_blocks; + std::vector unique_first_block_counts; + std::vector latencies; + std::vector bytes_received; + std::vector bytes_sent; + std::vector connection_start_times; + }; struct p2p_connections_metrics { + p2p_connections_metrics(std::size_t peers, std::size_t clients, p2p_per_connection_metrics&& statistics) + : num_peers{peers} + , num_clients{clients} + , stats{std::move(statistics)} + {} + p2p_connections_metrics(p2p_connections_metrics&& statistics) + : num_peers{std::move(statistics.num_peers)} + , num_clients{std::move(statistics.num_clients)} + , stats{std::move(statistics.stats)} + {} + p2p_connections_metrics(const p2p_connections_metrics&) = delete; std::size_t num_peers = 0; std::size_t num_clients = 0; + p2p_per_connection_metrics stats; }; void register_update_p2p_connection_metrics(std::function&&); diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index 1328e1195a..c0b0b2deb6 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -790,6 +790,12 @@ namespace eosio { bool is_blocks_only_connection()const { return connection_type == blocks_only; } bool is_transactions_connection() const { return connection_type != blocks_only; } // thread safe, atomic bool is_blocks_connection() const { return connection_type != transactions_only; } // thread safe, atomic + uint32_t get_peer_start_block_num() const { return peer_start_block_num.load(); } + uint32_t get_peer_head_block_num() const { return peer_head_block_num.load(); } + uint32_t get_last_received_blk_num() const { return last_received_blk_num.load(); } + uint32_t get_unique_blocks_rcvd_count() const { return unique_blocks_rcvd_count.load(); } + size_t get_bytes_received() const { return bytes_received.load(); } + size_t get_bytes_sent() const { return bytes_sent.load(); } void set_heartbeat_timeout(std::chrono::milliseconds msec) { hb_timeout = msec; } @@ -819,6 +825,10 @@ namespace eosio { std::atomic connection_type{both}; std::atomic peer_start_block_num{0}; std::atomic peer_head_block_num{0}; + std::atomic last_received_blk_num{0}; + std::atomic unique_blocks_rcvd_count{0}; + std::atomic bytes_received{0}; + std::atomic bytes_sent{0}; public: boost::asio::io_context::strand strand; @@ -836,6 +846,9 @@ namespace eosio { string log_remote_endpoint_port; string local_endpoint_ip; string local_endpoint_port; + bool remote_endpoint_ipv4; + uint32_t remote_endpoint_ip_integer; + uint32_t remote_endpoint_port; // kept in sync with last_handshake_recv.last_irreversible_block_num, only accessed from connection strand uint32_t peer_lib_num = 0; @@ -876,6 +889,8 @@ namespace eosio { fc::time_point last_close GUARDED_BY(conn_mtx); string remote_endpoint_ip GUARDED_BY(conn_mtx); + std::chrono::nanoseconds construction_time{0}; + connection_status get_status()const; /** \name Peer Timestamps @@ -941,10 +956,11 @@ namespace eosio { void send_time(const time_message& msg); /** \brief Read system time and convert to a 64 bit integer. * - * There are only two calls on this routine in the program. One - * when a packet arrives from the network and the other when a - * packet is placed on the send queue. Calls the kernel time of - * day routine and converts to a (at least) 64 bit integer. + * There are four calls to this routine in the program. One + * when a packet arrives from the network, one when a packet + * is placed on the send queue, and one during construction. + * Calls the kernel time of day routine and converts to + * a (at least) 64 bit integer. */ static std::chrono::nanoseconds get_time() { return std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()); @@ -1155,7 +1171,8 @@ namespace eosio { connection_id( ++my_impl->current_connection_id ), response_expected_timer( my_impl->thread_pool.get_executor() ), last_handshake_recv(), - last_handshake_sent() + last_handshake_sent(), + construction_time(get_time()) { my_impl->mark_bp_connection(this); fc_ilog( logger, "created connection ${c} to ${n}", ("c", connection_id)("n", endpoint) ); @@ -1169,7 +1186,8 @@ namespace eosio { connection_id( ++my_impl->current_connection_id ), response_expected_timer( my_impl->thread_pool.get_executor() ), last_handshake_recv(), - last_handshake_sent() + last_handshake_sent(), + construction_time(get_time()) { update_endpoints(); fc_dlog( logger, "new connection object created for peer ${address}:${port} from listener ${addr}", ("address", log_remote_endpoint_ip)("port", log_remote_endpoint_port)("addr", listen_address) ); @@ -1181,6 +1199,9 @@ namespace eosio { boost::system::error_code ec2; auto rep = socket->remote_endpoint(ec); auto lep = socket->local_endpoint(ec2); + remote_endpoint_ipv4 = ec ? false : rep.address().is_v4(); + remote_endpoint_ip_integer = remote_endpoint_ipv4 ? rep.address().to_v4().to_uint() : 0; + remote_endpoint_port = ec ? 0 : rep.port(); log_remote_endpoint_ip = ec ? unknown : rep.address().to_string(); log_remote_endpoint_port = ec ? unknown : std::to_string(rep.port()); local_endpoint_ip = ec2 ? unknown : lep.address().to_string(); @@ -1517,6 +1538,7 @@ namespace eosio { void connection::queue_write(const std::shared_ptr>& buff, std::function callback, bool to_sync_queue) { + bytes_sent += buff->size(); if( !buffer_queue.add_write_queue( buff, std::move(callback), to_sync_queue )) { peer_wlog( this, "write_queue full ${s} bytes, giving up on connection", ("s", buffer_queue.write_queue_size()) ); close(); @@ -2867,6 +2889,7 @@ namespace eosio { // called from connection strand bool connection::process_next_message( uint32_t message_length ) { + bytes_received += message_length; try { latest_msg_time = std::chrono::system_clock::now(); @@ -2906,7 +2929,7 @@ namespace eosio { fc::raw::unpack( peek_ds, bh ); const block_id_type blk_id = bh.calculate_id(); - const uint32_t blk_num = block_header::num_from_id(blk_id); + const uint32_t blk_num = last_received_blk_num = block_header::num_from_id(blk_id); // don't add_peer_block because we have not validated this block header yet if( my_impl->dispatcher->have_block( blk_id ) ) { peer_dlog( this, "canceling wait, already received block ${num}, id ${id}...", @@ -2941,6 +2964,7 @@ namespace eosio { my_impl->sync_master->sync_recv_block(shared_from_this(), blk_id, blk_num, false); } + ++unique_blocks_rcvd_count; auto ds = pending_message_buffer.create_datastream(); fc::raw::unpack( ds, which ); shared_ptr ptr = std::make_shared(); @@ -4400,6 +4424,7 @@ namespace eosio { auto it = (from ? connections.find(from) : connections.begin()); if (it == connections.end()) it = connections.begin(); size_t num_rm = 0, num_clients = 0, num_peers = 0, num_bp_peers = 0; + net_plugin::p2p_per_connection_metrics per_connection(max_client_count); while (it != connections.end()) { if (fc::time_point::now() >= max_time) { connection_wptr wit = *it; @@ -4417,6 +4442,21 @@ namespace eosio { } else { ++num_peers; } + if((*it)->remote_endpoint_ipv4) { + per_connection.addresses.push_back((*it)->remote_endpoint_ip_integer); + per_connection.ports.push_back((*it)->remote_endpoint_port); + per_connection.accepting_blocks.push_back((*it)->is_blocks_connection()); + per_connection.last_received_blocks.push_back((*it)->get_last_received_blk_num()); + per_connection.first_available_blocks.push_back((*it)->get_peer_start_block_num()); + per_connection.last_available_blocks.push_back((*it)->get_peer_head_block_num()); + per_connection.bytes_received.push_back((*it)->get_bytes_received()); + per_connection.bytes_sent.push_back((*it)->get_bytes_sent()); + per_connection.connection_start_times.push_back((*it)->construction_time); + per_connection.unique_first_block_counts.push_back((*it)->get_unique_blocks_rcvd_count()); + per_connection.latencies.push_back((*it)->get_peer_ping_time_ns()); + } + else + fc_wlog(logger, "socket remote endpoint is not IPv4"); if (!(*it)->socket_is_open() && (*it)->state() != connection::connection_state::connecting) { if (!(*it)->incoming()) { @@ -4438,7 +4478,7 @@ namespace eosio { g.unlock(); if (update_p2p_connection_metrics) { - update_p2p_connection_metrics({.num_peers = num_peers, .num_clients = num_clients}); + update_p2p_connection_metrics({num_peers, num_clients, std::move(per_connection)}); } if( num_clients > 0 || num_peers > 0 ) { diff --git a/plugins/prometheus_plugin/include/eosio/prometheus_plugin/prometheus_plugin.hpp b/plugins/prometheus_plugin/include/eosio/prometheus_plugin/prometheus_plugin.hpp index 7d771f556f..0413bd57c1 100644 --- a/plugins/prometheus_plugin/include/eosio/prometheus_plugin/prometheus_plugin.hpp +++ b/plugins/prometheus_plugin/include/eosio/prometheus_plugin/prometheus_plugin.hpp @@ -2,6 +2,7 @@ #include #include +#include namespace eosio { @@ -12,7 +13,7 @@ namespace eosio { prometheus_plugin(); ~prometheus_plugin() override; - APPBASE_PLUGIN_REQUIRES((http_plugin)) + APPBASE_PLUGIN_REQUIRES((http_plugin)(chain_plugin)) void set_program_options(options_description&, options_description& cfg) override; diff --git a/plugins/prometheus_plugin/metrics.hpp b/plugins/prometheus_plugin/metrics.hpp index de697ec7c3..8d4b0aff77 100644 --- a/plugins/prometheus_plugin/metrics.hpp +++ b/plugins/prometheus_plugin/metrics.hpp @@ -5,9 +5,10 @@ #include #include +#include #include #include - +#include namespace eosio::metrics { struct catalog_type { @@ -26,6 +27,9 @@ struct catalog_type { } prometheus::Registry registry; + // nodeos + prometheus::Family& info; + prometheus::Info info_details; // http plugin prometheus::Family& http_request_counts; @@ -34,6 +38,16 @@ struct catalog_type { Gauge& num_peers; Gauge& num_clients; + std::vector addresses; + std::vector> accepting_blocks_gauges; + std::vector> last_received_blocks_gauges; + std::vector> first_available_blocks_gauges; + std::vector> last_available_blocks_gauges; + std::vector> unique_first_block_counts_gauges; + std::vector> latency_gauges; + std::vector> bytes_received_gauges; + std::vector> bytes_sent_gauges; + std::vector> connection_start_time_gauges; // net plugin failed p2p connection Counter& failed_p2p_connections; @@ -70,36 +84,38 @@ struct catalog_type { catalog_type() - : http_request_counts(family("http_requests_total", "number of HTTP requests")) - , p2p_connections(family("p2p_connections", "current number of connected p2p connections")) + : info(family("nodeos", "static information about the server")) + , http_request_counts(family("nodeos_http_requests_total", "number of HTTP requests")) + , p2p_connections(family("nodeos_p2p_connections", "current number of connected p2p connections")) , num_peers(p2p_connections.Add({{"direction", "out"}})) , num_clients(p2p_connections.Add({{"direction", "in"}})) , failed_p2p_connections( - build("failed_p2p_connections", "total number of failed out-going p2p connections")) - , dropped_trxs_total(build("dropped_trxs_total", "total number of dropped transactions by net plugin")) - , cpu_usage_us(family("cpu_usage_us_total", "total cpu usage in microseconds for blocks")) - , net_usage_us(family("net_usage_us_total", "total net usage in microseconds for blocks")) - , last_irreversible(build("last_irreversible", "last irreversible block number")) - , head_block_num(build("head_block_num", "head block number")) - , unapplied_transactions_total(build("unapplied_transactions_total", + build("nodeos_failed_p2p_connections", "total number of failed out-going p2p connections")) + , dropped_trxs_total(build("nodeos_dropped_trxs_total", "total number of dropped transactions by net plugin")) + , cpu_usage_us(family("nodeos_cpu_usage_us_total", "total cpu usage in microseconds for blocks")) + , net_usage_us(family("nodeos_net_usage_us_total", "total net usage in microseconds for blocks")) + , last_irreversible(build("nodeos_last_irreversible", "last irreversible block number")) + , head_block_num(build("nodeos_head_block_num", "head block number")) + , unapplied_transactions_total(build("nodeos_unapplied_transactions_total", "total number of unapplied transactions from produced blocks")) - , blacklisted_transactions_total(build("blacklisted_transactions_total", + , blacklisted_transactions_total(build("nodeos_blacklisted_transactions_total", "total number of blacklisted transactions from produced blocks")) , subjective_bill_account_size_total(build( - "subjective_bill_account_size_total", "total number of subjective bill account size from produced blocks")) + "nodeos_subjective_bill_account_size_total", "total number of subjective bill account size from produced blocks")) , scheduled_trxs_total( - build("scheduled_trxs_total", "total number of scheduled transactions from produced blocks")) - , trxs_produced_total(build("trxs_produced_total", "number of transactions produced")) + build("nodeos_scheduled_trxs_total", "total number of scheduled transactions from produced blocks")) + , trxs_produced_total(build("nodeos_trxs_produced_total", "number of transactions produced")) , cpu_usage_us_produced_block(cpu_usage_us.Add({{"block_type", "produced"}})) , net_usage_us_produced_block(net_usage_us.Add({{"block_type", "produced"}})) - , blocks_produced(build("blocks_produced", "number of blocks produced")) - , trxs_incoming_total(build("trxs_incoming_total", "number of incoming transactions")) + , blocks_produced(build("nodeos_blocks_produced", "number of blocks produced")) + , trxs_incoming_total(build("nodeos_trxs_incoming_total", "number of incoming transactions")) , cpu_usage_us_incoming_block(cpu_usage_us.Add({{"block_type", "incoming"}})) , net_usage_us_incoming_block(net_usage_us.Add({{"block_type", "incoming"}})) - , blocks_incoming(build("blocks_incoming", "number of incoming blocks")) - , bytes_transferred(build("exposer_transferred_bytes_total", + , blocks_incoming(build("nodeos_blocks_incoming", "number of incoming blocks")) + , bytes_transferred(build("nodeos_exposer_transferred_bytes_total", "total number of bytes for responses to prometheus scape requests")) - , num_scrapes(build("exposer_scrapes_total", "total number of prometheus scape requests received")) {} + , num_scrapes(build("nodeos_exposer_scrapes_total", "total number of prometheus scape requests received")) + {} std::string report() { const prometheus::TextSerializer serializer; @@ -116,6 +132,42 @@ struct catalog_type { void update(const net_plugin::p2p_connections_metrics& metrics) { num_peers.Set(metrics.num_peers); num_clients.Set(metrics.num_clients); + dlog("Adding metrics for ${i} connections", ("i", metrics.stats.addresses.size())); + for(size_t i = 0; i < metrics.stats.addresses.size(); ++i) { + auto addr = boost::asio::ip::address_v4(metrics.stats.addresses[i]).to_string(); + std::replace(addr.begin(), addr.end(), '.', '_'); + addr.insert(0, 1, '_'); + addr.append("__"); + addr.append(to_string(metrics.stats.ports[i])); + addresses.push_back(addr); + auto& accepting_blocks = p2p_connections.Add({{addr, "accepting_blocks"}}); + accepting_blocks.Set(metrics.stats.accepting_blocks[i]); + accepting_blocks_gauges.push_back(accepting_blocks); + auto& last_received_block = p2p_connections.Add({{addr, "last_received_block"}}); + last_received_block.Set(metrics.stats.last_received_blocks[i]); + last_received_blocks_gauges.push_back(last_received_block); + auto& first_available_block = p2p_connections.Add({{addr, "first_available_block"}}); + first_available_block.Set(metrics.stats.first_available_blocks[i]); + first_available_blocks_gauges.push_back(first_available_block); + auto& last_available_block = p2p_connections.Add({{addr, "last_available_block"}}); + last_available_block.Set(metrics.stats.last_available_blocks[i]); + last_available_blocks_gauges.push_back(last_available_block); + auto& unique_first_block_count = p2p_connections.Add({{addr, "unique_first_block_count"}}); + unique_first_block_count.Set(metrics.stats.unique_first_block_counts[i]); + unique_first_block_counts_gauges.push_back(unique_first_block_count); + auto& latency = p2p_connections.Add({{addr, "latency"}}); + latency.Set(metrics.stats.latencies[i]); + latency_gauges.push_back(latency); + auto& bytes_received = p2p_connections.Add({{addr, "bytes_received"}}); + bytes_received.Set(metrics.stats.bytes_received[i]); + bytes_received_gauges.push_back(bytes_received); + auto& bytes_sent = p2p_connections.Add({{addr, "bytes_sent"}}); + bytes_sent.Set(metrics.stats.bytes_sent[i]); + bytes_sent_gauges.push_back(bytes_sent); + auto& connection_start_time = p2p_connections.Add({{addr, "connection_start_time"}}); + connection_start_time.Set(metrics.stats.connection_start_times[i].count()); + connection_start_time_gauges.push_back(connection_start_time); + } } void update(const producer_plugin::produced_block_metrics& metrics) { @@ -142,6 +194,15 @@ struct catalog_type { head_block_num.Set(metrics.head_block_num); } + void late_initialize() { + info_details = info.Add({ + {"server_version", chain_apis::itoh(static_cast(app().version()))}, + {"chain_id", app().get_plugin().get_chain_id()}, + {"server_version_string", app().version_string()}, + {"server_full_version_string", app().full_version_string()}, + {"earliest_available_block_num", to_string(app().get_plugin().chain().earliest_available_block_num())} + }); + } void register_update_handlers(boost::asio::io_context::strand& strand) { auto& http = app().get_plugin(); http.register_update_metrics( @@ -149,8 +210,8 @@ struct catalog_type { auto& net = app().get_plugin(); - net.register_update_p2p_connection_metrics([&strand, this](net_plugin::p2p_connections_metrics metrics) { - strand.post([metrics, this]() { update(metrics); }); + net.register_update_p2p_connection_metrics([&strand, this](net_plugin::p2p_connections_metrics&& metrics) { + boost::asio::post(strand, [metrics = std::move(metrics), this]() mutable { update(std::move(metrics)); }); }); net.register_increment_failed_p2p_connections([this]() { diff --git a/plugins/prometheus_plugin/prometheus_plugin.cpp b/plugins/prometheus_plugin/prometheus_plugin.cpp index 869df66c4d..c7a6d10863 100644 --- a/plugins/prometheus_plugin/prometheus_plugin.cpp +++ b/plugins/prometheus_plugin/prometheus_plugin.cpp @@ -73,6 +73,8 @@ namespace eosio { elog("Prometheus exception ${e}", ("e", e)); } ); + my->_catalog.late_initialize(); + ilog("Prometheus plugin started."); } diff --git a/programs/CMakeLists.txt b/programs/CMakeLists.txt index 9dda023946..270a78d40c 100644 --- a/programs/CMakeLists.txt +++ b/programs/CMakeLists.txt @@ -2,3 +2,4 @@ add_subdirectory( nodeos ) add_subdirectory( cleos ) add_subdirectory( keosd ) add_subdirectory( leap-util ) +add_subdirectory( net-util ) diff --git a/programs/net-util/CMakeLists.txt b/programs/net-util/CMakeLists.txt new file mode 100644 index 0000000000..5e8639daec --- /dev/null +++ b/programs/net-util/CMakeLists.txt @@ -0,0 +1 @@ +configure_file(net-util.py net-util.py COPYONLY) diff --git a/programs/net-util/net-util.py b/programs/net-util/net-util.py new file mode 100755 index 0000000000..e193bfb912 --- /dev/null +++ b/programs/net-util/net-util.py @@ -0,0 +1,360 @@ +#!/usr/bin/env python3 + +import argparse +import logging +import pathlib +import requests +import sys +import time + +import urwid +import urwid.curses_display + +from prometheus_client.parser import text_string_to_metric_families +from urwid.canvas import apply_text_layout +from urwid.widget import WidgetError + +logging.TRACE = 5 +logging._levelToName[logging.TRACE] = 'TRACE' +logging._nameToLevel['TRACE'] = logging.TRACE +assert logging.TRACE < logging.DEBUG, 'Logging TRACE level expected to be lower than DEBUG' + +logger = logging.getLogger(__name__) + +def replacement_render(self, size, focus=False): + """ + Render contents with wrapping and alignment. Return canvas. + + See :meth:`Widget.render` for parameter details. + + >>> Text(u"important things").render((18,)).text # ... = b in Python 3 + [...'important things '] + >>> Text(u"important things").render((11,)).text + [...'important ', ...'things '] + """ + maxcol = size[0] + text, attr = self.get_text() + #assert isinstance(text, unicode) + trans = self.get_line_translation( maxcol, (text,attr) ) + return apply_text_layout(text, attr, trans, maxcol) + +def replacement_rows(self, size, focus=False): + """ + Return the number of rows the rendered text requires. + + See :meth:`Widget.rows` for parameter details. + + >>> Text(u"important things").rows((18,)) + 1 + >>> Text(u"important things").rows((11,)) + 2 + """ + maxcol = size[0] + return len(self.get_line_translation(maxcol)) + +def validate_size(widget, size, canv): + """ + Raise a WidgetError if a canv does not match size size. + """ + if (size and size[1:] != (0,) and size[0] != canv.cols()) or \ + (len(size)>1 and size[1] < canv.rows()): + raise WidgetError("Widget %r rendered (%d x %d) canvas" + " when passed size %r!" % (widget, canv.cols(), + canv.rows(), size)) + +#urwid.Text.render = replacement_render +#urwid.Text.rows = replacement_rows +#urwid.widget.validate_size = validate_size + +def humanReadableBytesPerSecond(bytes: int, telco:bool = False): + power = 10**3 if telco else 2**10 + n = 0 + labels = {0: '', 1: 'K', 2: 'M', 3: 'G', 4: 'T'} if telco else {0: '', 1: 'Ki', 2: 'Mi', 3: 'Gi', 4: 'Ti'} + while bytes > power: + bytes /= power + n += 1 + return f'{"~0" if bytes < 0.01 else format(bytes, ".2f")} {labels[n]}B/s' + +class TextSimpleFocusListWalker(urwid.SimpleFocusListWalker): + def __contains__(self, text): + for element in self: + if text == element.text: + return True + return False + def index(self, text): + '''Emulation of list index() method unfortunately much slower than the real thing but our lists are short''' + for i, e in enumerate(self): + if e.text == text: + return i + + +class ColumnedListPile(urwid.Pile): + def __init__(self, widget_list, focus_item=None): + super().__init__(widget_list, focus_item) + self.allColumns = [] + def setAllColumns(self, columns): + self.allColumns = columns + def render(self, size, focus=False): + super().render(size, focus) + maxrows = 0 + for pile in self.allColumns: + _, rows = pile.contents[0][0].pack() + if rows > maxrows: + maxrows = rows + for pile in self.allColumns: + _, rows = pile.contents[0][0].pack() + if rows < maxrows: + text = pile.contents[0][0].text + pile.contents[0][0].text = (maxrows - rows)*'\n'+text + + +def readMetrics(): + response = requests.get('http://localhost:8888/v1/prometheus/metrics', timeout=10) + if response.status_code == 404: + print(f'Prometheus metrics URL returned 404: {response.url}') + raise urwid.ExitMainLoop() + return response + +class netUtil: + def __init__(self): + self.prometheusMetrics = { + ('nodeos_info', 'server_version_string'): 'Nodeos Vers:', + 'nodeos_head_block_num': 'Head Block Num:', + 'nodeos_last_irreversible': 'LIB:', + ('nodeos_p2p_connections','in'): 'Inbound P2P Connections:', + ('nodeos_p2p_connections','out'): 'Outbound P2P Connections:', + 'nodeos_blocks_incoming_total': 'Total Incoming Blocks:', + 'nodeos_trxs_incoming_total': 'Total Incoming Trxs:', + 'nodeos_blocks_produced_total': 'Blocks Produced:', + 'nodeos_trxs_produced_total': 'Trxs Produced:', + 'nodeos_scheduled_trxs_total': 'Scheduled Trxs:', + 'nodeos_blacklisted_transactions_total': 'Blacklisted Trxs:', + 'nodeos_unapplied_transactions_total': 'Unapplied Trxs:', + 'nodeos_dropped_trxs_total': 'Dropped Trxs:', + 'nodeos_failed_p2p_connections_total': 'Failed P2P Connections:', + 'nodeos_http_requests_total': 'HTTP Requests:', + } + self.ignoredPrometheusMetrics = [ + 'nodeos_exposer_scrapes_total', + 'nodeos_exposer_transferred_bytes_total', + 'nodeos_subjective_bill_account_size_total', + 'nodeos_net_usage_us_total', + 'nodeos_cpu_usage_us_total', + ] + self.leftFieldLabels = [ + 'Host:', + 'Head Block Num:', + 'Inbound P2P Connections:', + 'Failed P2P Connections:', + 'Total Incoming Blocks:', + 'Blocks Produced:', + 'Scheduled Trxs:', + 'Unapplied Trxs:', + 'HTTP Requests:', + ] + self.rightFieldLabels = [ + 'Nodeos Vers:', + 'LIB:', + 'Outbound P2P Connections:', + 'Total Incoming Trxs:', + 'Trxs Produced:', + 'Blacklisted Trxs:', + 'Dropped Trxs:', + ] + self.peerMetricConversions = { + 'hostname': lambda x: x[1:].replace('__', ':').replace('_', '.'), + 'accepting_blocks': lambda x: 'True' if x else 'False', + 'latency': lambda x: format(int(x)/1000000, '.2f') + ' ms', + 'bandwidth': lambda x: str(int(x)) + ' B/s', + 'last_received_block': lambda x: str(int(x)), + 'first_available_block': lambda x: str(int(x)), + 'last_available_block': lambda x: str(int(x)), + 'unique_first_block_count': lambda x: str(int(x)), + } + self.peerColumns = [ + ('\n\nHostname', 'hostnameLW'), + ('\n\nLatency', 'latencyLW'), + ('\nSend\nRate', 'sendBandwidthLW'), + ('\nRcv\nRate', 'receiveBandwidthLW'), + ('Last\nRcvd\nBlock', 'lastReceivedBlockLW'), + ('Unique\nFirst\nBlks', 'uniqueFirstBlockCountLW'), + ('First\nAvail\nBlk', 'firstAvailableBlockLW'), + ('Last\nAvail\nBlk', 'lastAvailableBlockLW'), + ('\nAcpt\nBlks', 'acceptingBlocksLW') + ] + self.fields = {k:v for k, v in zip(self.leftFieldLabels, [e[:1].lower() + e[1:-1].replace(' ', '') + 'Text' for e in self.leftFieldLabels])} + self.fields.update({self.rightFieldLabels[0]: self.rightFieldLabels[0][:1].lower() + self.rightFieldLabels[0][1:-1].replace(' ', '') + 'Button'}) + self.fields.update({k:v for k, v in zip(self.rightFieldLabels[1:], [e[:1].lower() + e[1:-1].replace(' ', '') + 'Text' for e in self.rightFieldLabels[1:]])}) + + parser = argparse.ArgumentParser(description='Terminal UI for monitoring and managing nodeos P2P connections') + parser.add_argument('--log-level', choices=[logging._nameToLevel.keys()] + [k.lower() for k in logging._nameToLevel.keys()], help='Logging level', default='debug') + self.args = parser.parse_args() + + def createUrwidUI(self): + Button = urwid.Button + Text = urwid.Text + Filler = urwid.Filler + Columns = urwid.Columns + Divider = urwid.Divider + Padding = urwid.Padding + Pile = urwid.Pile + Placeholder = urwid.WidgetPlaceholder + + def packLabeledText(labelTxt: str, defaultValue=''): + label = Text(('bold', labelTxt), align='right') + text = Text(defaultValue) + attrName = labelTxt[:1].lower() + labelTxt[1:-1].replace(' ', '') + 'Text' if labelTxt else '' + if attrName: + setattr(self, attrName, text) + minwidth = max([len(x) for x in self.leftFieldLabels + self.rightFieldLabels]) + return Columns([(minwidth, Filler(label, valign='top')), Filler(text, valign='top')], 1) + + def packLabeledButton(labelTxt: str, defaultValue='', callback: callable = None): + label = Text(('bold', labelTxt), align='right') + button = Button(defaultValue, callback) + attrName = labelTxt[:1].lower() + labelTxt[1:-1].replace(' ', '') + 'Button' if labelTxt else '' + if attrName: + setattr(self, attrName, button) + return Columns([Filler(label, valign='top'), Filler(button, valign='top')], 1) + + widgets = [packLabeledText(labelTxt, 'not connected' if labelTxt == 'Host:' else '0'*11 if labelTxt == 'Head Block Num:' else '') for labelTxt in self.leftFieldLabels] + # At least one child of a Pile must have weight 1 or the app will crash on mouse click in the Pile. + leftColumn = Pile([(1, widget) for widget in widgets[:-1]] + [('weight', 1, widgets[-1])]) + + widgets = [packLabeledButton(self.rightFieldLabels[0], callback=self.onVersionClick)] + widgets.extend([packLabeledText(labelTxt) for labelTxt in self.rightFieldLabels[1:]]) + widgets.insert(3, Filler(Divider())) + rightColumn = Pile([(1, widget) for widget in widgets[:-1]] + [('weight', 1, widgets[-1])]) + + self.errorText = Text(('error', '')) + self.errorBox = urwid.LineBox(self.errorText, 'Error:', 'left', 'error') + + def packLabeledList(labelTxt: str, attrName: str): + label = Text(('bold', labelTxt)) + listWalker = TextSimpleFocusListWalker([]) + setattr(listWalker, 'name', attrName) + setattr(self, attrName, listWalker) + return Pile([('pack', label), ('weight', 1, urwid.ListBox(listWalker))]) + + self.peerListPiles = [] + for colName, attrName in self.peerColumns: + self.peerListPiles.append(packLabeledList(colName, attrName)) + + #for pile in self.peerListPiles: + # pile.setAllColumns(self.peerListPiles) + + def focus_changed(new_focus): + logger.info('focus changed') + for pile in self.peerListPiles[:-1]: + pile.contents[-1][0].body.set_focus(new_focus) + + self.peerListPiles[0].contents[-1][0].body.set_focus_changed_callback(focus_changed) + + self.peerLineBox = urwid.LineBox(Columns([('weight', 2, self.peerListPiles[0])]+self.peerListPiles[1:], + dividechars=1, focus_column=0), + 'Peers:', 'left') + + #, Filler(Placeholder(self.errorText), valign='bottom') + return Pile([Columns([leftColumn, rightColumn]), ('weight', 4, self.peerLineBox)]) + + def onVersionClick(self, button): + logger.info('Button clicked') + + def update(self, mainLoop, userData=None): + try: + response = readMetrics() + except requests.ConnectionError as e: + self.errorText.set_text(str(e)) + mainLoop.widget.contents[-1][0].original_widget = self.errorBox + else: + self.errorText.set_text('') + self.hostText.set_text('localhost:8888') + class bandwidthStats(): + def __init__(self, bytesReceived=0, bytesSent=0, connectionStarted=0): + self.bytesReceived = 0 + self.bytesSent = 0 + self.connectionStarted = 0 + mainLoop.widget.contents[-1][0].original_widget = self.errorText + for family in text_string_to_metric_families(response.text): + bandwidths = {} + for sample in family.samples: + if sample.name in self.prometheusMetrics: + fieldName = self.fields.get(self.prometheusMetrics[sample.name]) + field = getattr(self, fieldName) + field.set_text(str(int(sample.value))) + elif sample.name == 'nodeos_p2p_connections': + if 'direction' in sample.labels: + fieldName = self.fields.get(self.prometheusMetrics[(sample.name, sample.labels['direction'])]) + field = getattr(self, fieldName) + field.set_text(str(int(sample.value))) + else: + hostLabel = next(iter(sample.labels)) + fieldName = sample.labels[hostLabel] + host = hostLabel[1:].replace('__', ':').replace('_', '.') + listwalker = getattr(self, 'hostnameLW') + if host not in listwalker: + startOffset = endOffset = len(listwalker) + listwalker.append(urwid.Text(host)) + else: + startOffset = listwalker.index(host) + endOffset = startOffset + 1 + if fieldName == 'bytes_received': + bytesReceived = int(sample.value) + stats = bandwidths.get(host, bandwidthStats()) + stats.bytesReceived = bytesReceived + bandwidths[host] = stats + elif fieldName == 'bytes_sent': + bytesSent = int(sample.value) + stats = bandwidths.get(host, bandwidthStats()) + stats.bytesSent = bytesSent + bandwidths[host] = stats + elif fieldName == 'connection_start_time': + connectionStarted = int(sample.value) + stats = bandwidths.get(host, bandwidthStats()) + stats.connectionStarted = connectionStarted + bandwidths[host] = stats + logger.info(f'length of bandwidth is {len(bandwidths)}') + else: + listwalker = getattr(self, fieldName[:1] + fieldName.replace('_', ' ').title().replace(' ', '')[1:] + 'LW') + listwalker[startOffset:endOffset] = [urwid.Text(self.peerMetricConversions[fieldName](sample.value))] + elif sample.name == 'nodeos_info': + fieldName = self.fields.get(self.prometheusMetrics[(sample.name, 'server_version_string')]) + field = getattr(self, fieldName) + field.set_label(sample.labels['server_version_string']) + else: + if sample.name not in self.ignoredPrometheusMetrics: + logger.warning(f'Received unhandled Prometheus metric {sample.name}') + else: + if sample.name == 'nodeos_p2p_connections': + now = time.time_ns() + hostListwalker = getattr(self, 'hostnameLW') + for host, stats in bandwidths.items(): + startOffset = hostListwalker.index(host) + endOffset = startOffset + 1 + connected_seconds = (now - stats.connectionStarted)/1000000000 + listwalker = getattr(self, 'receiveBandwidthLW') + bps = stats.bytesReceived/connected_seconds + listwalker[startOffset:endOffset] = [urwid.Text(humanReadableBytesPerSecond(bps))] + listwalker = getattr(self, 'sendBandwidthLW') + bps = stats.bytesSent/connected_seconds + listwalker[startOffset:endOffset] = [urwid.Text(humanReadableBytesPerSecond(bps))] + mainLoop.set_alarm_in(0.5, self.update) + +def exitOnQ(key): + if key in ('q', 'Q'): + raise urwid.ExitMainLoop() + +if __name__ == '__main__': + inst = netUtil() + exePath = pathlib.Path(sys.argv[0]) + loggingLevel = getattr(logging, inst.args.log_level.upper(), None) + if not isinstance(loggingLevel, int): + raise ValueError(f'Invalid log leve: {inst.args.log_level}') + logging.basicConfig(filename=exePath.stem + '.log', filemode='w', level=loggingLevel) + logger.info(f'Starting {sys.argv[0]}') + palette = [('error', 'yellow,bold', 'default'), + ('bold', 'default,bold', 'default'), + ('dim', 'dark gray', 'default'),] + loop = urwid.MainLoop(inst.createUrwidUI(), palette, screen=urwid.curses_display.Screen(), unhandled_input=exitOnQ, event_loop=None, pop_ups=True) + loop.set_alarm_in(0.5, inst.update) + loop.run() diff --git a/tests/cluster_launcher.py b/tests/cluster_launcher.py index d4db91c72e..4a0d450daa 100755 --- a/tests/cluster_launcher.py +++ b/tests/cluster_launcher.py @@ -17,15 +17,16 @@ appArgs = AppArgs() appArgs.add(flag="--plugin",action='append',type=str,help="Run nodes with additional plugins") -args=TestHelper.parse_args({"-p","-n","-d","-s","--keep-logs" - ,"--dump-error-details","-v" - ,"--leave-running","--unshared"}, +args=TestHelper.parse_args({"-p","-n","-d","-s","--keep-logs","--prod-count" + ,"--dump-error-details","-v","--leave-running" + ,"--unshared"}, applicationSpecificArgs=appArgs) pnodes=args.p delay=args.d topo=args.s debug=args.v -total_nodes=pnodes +prod_count = args.prod_count +total_nodes=args.n if args.n > 0 else pnodes dumpErrorDetails=args.dump_error_details Utils.Debug=debug @@ -46,7 +47,7 @@ extraNodeosArgs = ''.join([i+j for i,j in zip([' --plugin '] * len(args.plugin), args.plugin)]) else: extraNodeosArgs = '' - if cluster.launch(pnodes=pnodes, totalNodes=total_nodes, topo=topo, delay=delay, + if cluster.launch(pnodes=pnodes, totalNodes=total_nodes, prodCount=prod_count, topo=topo, delay=delay, extraNodeosArgs=extraNodeosArgs) is False: errorExit("Failed to stand up eos cluster.") From 727a0c5520b066cc21525f3aca0247146453e485 Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Wed, 2 Aug 2023 17:42:34 -0500 Subject: [PATCH 29/79] Remove debug log statement. --- programs/net-util/net-util.py | 1 - 1 file changed, 1 deletion(-) diff --git a/programs/net-util/net-util.py b/programs/net-util/net-util.py index e193bfb912..3f4358b1bc 100755 --- a/programs/net-util/net-util.py +++ b/programs/net-util/net-util.py @@ -313,7 +313,6 @@ def __init__(self, bytesReceived=0, bytesSent=0, connectionStarted=0): stats = bandwidths.get(host, bandwidthStats()) stats.connectionStarted = connectionStarted bandwidths[host] = stats - logger.info(f'length of bandwidth is {len(bandwidths)}') else: listwalker = getattr(self, fieldName[:1] + fieldName.replace('_', ' ').title().replace(' ', '')[1:] + 'LW') listwalker[startOffset:endOffset] = [urwid.Text(self.peerMetricConversions[fieldName](sample.value))] From fbb0cec9b127e4fc65a74e60b1a3432f8c83d7e3 Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Wed, 2 Aug 2023 18:36:08 -0500 Subject: [PATCH 30/79] Add net-util command line support for host and port. Add custom logging level TRACE via the mechanism provided rather than reaching into the library's internal data structures. Actually use the logging level command line argument. --- programs/net-util/net-util.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/programs/net-util/net-util.py b/programs/net-util/net-util.py index 3f4358b1bc..0692817112 100755 --- a/programs/net-util/net-util.py +++ b/programs/net-util/net-util.py @@ -15,9 +15,9 @@ from urwid.widget import WidgetError logging.TRACE = 5 -logging._levelToName[logging.TRACE] = 'TRACE' -logging._nameToLevel['TRACE'] = logging.TRACE +logging.addLevelName(5, 'TRACE') assert logging.TRACE < logging.DEBUG, 'Logging TRACE level expected to be lower than DEBUG' +assert logging.getLevelName('TRACE') < logging.getLevelName('DEBUG'), 'Logging TRACE level expected to be lower than DEBUG' logger = logging.getLogger(__name__) @@ -108,10 +108,10 @@ def render(self, size, focus=False): pile.contents[0][0].text = (maxrows - rows)*'\n'+text -def readMetrics(): - response = requests.get('http://localhost:8888/v1/prometheus/metrics', timeout=10) +def readMetrics(host: str, port: str): + response = requests.get(f'http://{host}:{port}/v1/prometheus/metrics', timeout=10) if response.status_code == 404: - print(f'Prometheus metrics URL returned 404: {response.url}') + logger.warn(f'Prometheus metrics URL returned 404: {response.url}') raise urwid.ExitMainLoop() return response @@ -186,9 +186,13 @@ def __init__(self): self.fields.update({self.rightFieldLabels[0]: self.rightFieldLabels[0][:1].lower() + self.rightFieldLabels[0][1:-1].replace(' ', '') + 'Button'}) self.fields.update({k:v for k, v in zip(self.rightFieldLabels[1:], [e[:1].lower() + e[1:-1].replace(' ', '') + 'Text' for e in self.rightFieldLabels[1:]])}) - parser = argparse.ArgumentParser(description='Terminal UI for monitoring and managing nodeos P2P connections') + parser = argparse.ArgumentParser(description='Terminal UI for monitoring and managing nodeos P2P connections', + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument('--host', help='hostname or IP address to connect to', default='localhost') + parser.add_argument('-p', '--port', help='port number to connect to', default='8888') parser.add_argument('--log-level', choices=[logging._nameToLevel.keys()] + [k.lower() for k in logging._nameToLevel.keys()], help='Logging level', default='debug') self.args = parser.parse_args() + logger.setLevel(logging.getLevelName(self.args.log_level.upper())) def createUrwidUI(self): Button = urwid.Button @@ -262,13 +266,13 @@ def onVersionClick(self, button): def update(self, mainLoop, userData=None): try: - response = readMetrics() + response = readMetrics(self.args.host, self.args.port) except requests.ConnectionError as e: self.errorText.set_text(str(e)) mainLoop.widget.contents[-1][0].original_widget = self.errorBox else: self.errorText.set_text('') - self.hostText.set_text('localhost:8888') + self.hostText.set_text(f'{self.args.host}:{self.args.port}') class bandwidthStats(): def __init__(self, bytesReceived=0, bytesSent=0, connectionStarted=0): self.bytesReceived = 0 From 86c6ced9b1c06486ac94aa14dbab12ad7a3d27e4 Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Wed, 2 Aug 2023 19:41:01 -0500 Subject: [PATCH 31/79] Update prometheus metric names in plugin_http_api_test. --- tests/plugin_http_api_test.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/plugin_http_api_test.py b/tests/plugin_http_api_test.py index c903173ff6..0f49f458ee 100755 --- a/tests/plugin_http_api_test.py +++ b/tests/plugin_http_api_test.py @@ -1451,12 +1451,12 @@ def test_prometheusApi(self) : ret_text = self.nodeos.processUrllibRequest(resource, command, returnType = ReturnType.raw, method="GET", endpoint=endpoint).decode() # filter out all empty lines or lines starting with '#' data_lines = filter(lambda line: len(line) > 0 and line[0]!='#', ret_text.split('\n')) - # converting each line into a key value pair and then construct a dictionay out of all the pairs + # convert each line into a key value pair and then construct a dictionay out of all the pairs metrics = dict(map(lambda line: tuple(line.split(' ')), data_lines)) - self.assertTrue(int(metrics["head_block_num"]) > 1) - self.assertTrue(int(metrics["blocks_produced"]) > 1) - self.assertTrue(int(metrics["last_irreversible"]) > 1) + self.assertTrue(int(metrics["nodeos_head_block_num"]) > 1) + self.assertTrue(int(metrics["nodeos_blocks_produced"]) > 1) + self.assertTrue(int(metrics["nodeos_last_irreversible"]) > 1) ret = self.nodeos.processUrllibRequest(resource, "m", returnType = ReturnType.raw, method="GET", silentErrors= True, endpoint=endpoint) self.assertTrue(ret == 404) From ed9eee6ef8f85f88b6b58cb55d83c5187747cf16 Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Thu, 3 Aug 2023 14:44:07 -0500 Subject: [PATCH 32/79] Make p2p_per_connection_metrics constructor explicit. --- plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp b/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp index 06555c63fc..7c14f5a8e6 100644 --- a/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp +++ b/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp @@ -40,7 +40,7 @@ namespace eosio { vector connections()const; struct p2p_per_connection_metrics { - p2p_per_connection_metrics(size_t count) { + explicit p2p_per_connection_metrics(size_t count) { addresses.reserve(count); ports.reserve(count); accepting_blocks.reserve(count); From a30d7c71a55ddb2f7e11257a704e6a7ffcc67682 Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Thu, 3 Aug 2023 14:46:44 -0500 Subject: [PATCH 33/79] Count unique received blocks in process_signed_block Update endpoints in both constructors and when a connection is established. --- plugins/net_plugin/net_plugin.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index c0b0b2deb6..41d3fe20b4 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -1175,6 +1175,7 @@ namespace eosio { construction_time(get_time()) { my_impl->mark_bp_connection(this); + update_endpoints(); fc_ilog( logger, "created connection ${c} to ${n}", ("c", connection_id)("n", endpoint) ); } @@ -2686,6 +2687,7 @@ namespace eosio { boost::asio::bind_executor( strand, [resolver, c = shared_from_this(), socket=socket]( const boost::system::error_code& err, const tcp::endpoint& endpoint ) { if( !err && socket->is_open() && socket == c->socket ) { + c->update_endpoints(); if( c->start_session() ) { c->send_handshake(); c->send_time(); @@ -2964,7 +2966,6 @@ namespace eosio { my_impl->sync_master->sync_recv_block(shared_from_this(), blk_id, blk_num, false); } - ++unique_blocks_rcvd_count; auto ds = pending_message_buffer.create_datastream(); fc::raw::unpack( ds, which ); shared_ptr ptr = std::make_shared(); @@ -3663,6 +3664,7 @@ namespace eosio { } if( accepted ) { + ++unique_blocks_rcvd_count; boost::asio::post( my_impl->thread_pool.get_executor(), [dispatcher = my_impl->dispatcher.get(), c, blk_id, blk_num]() { fc_dlog( logger, "accepted signed_block : #${n} ${id}...", ("n", blk_num)("id", blk_id.str().substr(8,16)) ); dispatcher->add_peer_block( blk_id, c->connection_id ); From 51c5f153663560dbd656fb45ecca6464d51c7798 Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Thu, 3 Aug 2023 14:53:48 -0500 Subject: [PATCH 34/79] Rename construction_time to connection_time and update every connect --- plugins/net_plugin/net_plugin.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index 41d3fe20b4..d523fc68b8 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -846,9 +846,9 @@ namespace eosio { string log_remote_endpoint_port; string local_endpoint_ip; string local_endpoint_port; - bool remote_endpoint_ipv4; - uint32_t remote_endpoint_ip_integer; - uint32_t remote_endpoint_port; + bool remote_endpoint_ipv4{false}; + uint32_t remote_endpoint_ip_integer{0}; + uint32_t remote_endpoint_port{0}; // kept in sync with last_handshake_recv.last_irreversible_block_num, only accessed from connection strand uint32_t peer_lib_num = 0; @@ -889,7 +889,7 @@ namespace eosio { fc::time_point last_close GUARDED_BY(conn_mtx); string remote_endpoint_ip GUARDED_BY(conn_mtx); - std::chrono::nanoseconds construction_time{0}; + std::chrono::nanoseconds connection_time{0}; connection_status get_status()const; @@ -956,9 +956,9 @@ namespace eosio { void send_time(const time_message& msg); /** \brief Read system time and convert to a 64 bit integer. * - * There are four calls to this routine in the program. One + * There are three calls to this routine in the program. One * when a packet arrives from the network, one when a packet - * is placed on the send queue, and one during construction. + * is placed on the send queue, and one during connect. * Calls the kernel time of day routine and converts to * a (at least) 64 bit integer. */ @@ -1171,8 +1171,7 @@ namespace eosio { connection_id( ++my_impl->current_connection_id ), response_expected_timer( my_impl->thread_pool.get_executor() ), last_handshake_recv(), - last_handshake_sent(), - construction_time(get_time()) + last_handshake_sent() { my_impl->mark_bp_connection(this); update_endpoints(); @@ -1187,8 +1186,7 @@ namespace eosio { connection_id( ++my_impl->current_connection_id ), response_expected_timer( my_impl->thread_pool.get_executor() ), last_handshake_recv(), - last_handshake_sent(), - construction_time(get_time()) + last_handshake_sent() { update_endpoints(); fc_dlog( logger, "new connection object created for peer ${address}:${port} from listener ${addr}", ("address", log_remote_endpoint_ip)("port", log_remote_endpoint_port)("addr", listen_address) ); @@ -2688,6 +2686,7 @@ namespace eosio { [resolver, c = shared_from_this(), socket=socket]( const boost::system::error_code& err, const tcp::endpoint& endpoint ) { if( !err && socket->is_open() && socket == c->socket ) { c->update_endpoints(); + c->connection_time = get_time(); if( c->start_session() ) { c->send_handshake(); c->send_time(); @@ -4453,7 +4452,7 @@ namespace eosio { per_connection.last_available_blocks.push_back((*it)->get_peer_head_block_num()); per_connection.bytes_received.push_back((*it)->get_bytes_received()); per_connection.bytes_sent.push_back((*it)->get_bytes_sent()); - per_connection.connection_start_times.push_back((*it)->construction_time); + per_connection.connection_start_times.push_back((*it)->connection_time); per_connection.unique_first_block_counts.push_back((*it)->get_unique_blocks_rcvd_count()); per_connection.latencies.push_back((*it)->get_peer_ping_time_ns()); } From d511095e7e90d27fa8caedae064c36d19cfcf3b6 Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Thu, 3 Aug 2023 14:54:54 -0500 Subject: [PATCH 35/79] Make prometheus endpoint URL a variable at the top of the script. Remove redundant logging level setup. Fix typo. --- programs/net-util/net-util.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/programs/net-util/net-util.py b/programs/net-util/net-util.py index 0692817112..94f164c5f5 100755 --- a/programs/net-util/net-util.py +++ b/programs/net-util/net-util.py @@ -19,6 +19,8 @@ assert logging.TRACE < logging.DEBUG, 'Logging TRACE level expected to be lower than DEBUG' assert logging.getLevelName('TRACE') < logging.getLevelName('DEBUG'), 'Logging TRACE level expected to be lower than DEBUG' +PROMETHEUS_URL = '/v1/prometheus/metrics' + logger = logging.getLogger(__name__) def replacement_render(self, size, focus=False): @@ -109,7 +111,7 @@ def render(self, size, focus=False): def readMetrics(host: str, port: str): - response = requests.get(f'http://{host}:{port}/v1/prometheus/metrics', timeout=10) + response = requests.get(f'http://{host}:{port}{PROMETHEUS_URL}', timeout=10) if response.status_code == 404: logger.warn(f'Prometheus metrics URL returned 404: {response.url}') raise urwid.ExitMainLoop() @@ -192,7 +194,6 @@ def __init__(self): parser.add_argument('-p', '--port', help='port number to connect to', default='8888') parser.add_argument('--log-level', choices=[logging._nameToLevel.keys()] + [k.lower() for k in logging._nameToLevel.keys()], help='Logging level', default='debug') self.args = parser.parse_args() - logger.setLevel(logging.getLevelName(self.args.log_level.upper())) def createUrwidUI(self): Button = urwid.Button @@ -352,7 +353,7 @@ def exitOnQ(key): exePath = pathlib.Path(sys.argv[0]) loggingLevel = getattr(logging, inst.args.log_level.upper(), None) if not isinstance(loggingLevel, int): - raise ValueError(f'Invalid log leve: {inst.args.log_level}') + raise ValueError(f'Invalid log level: {inst.args.log_level}') logging.basicConfig(filename=exePath.stem + '.log', filemode='w', level=loggingLevel) logger.info(f'Starting {sys.argv[0]}') palette = [('error', 'yellow,bold', 'default'), From ef80f6907ca7d8eeb2c0ec2a2c6648c098689a94 Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Thu, 3 Aug 2023 15:00:12 -0500 Subject: [PATCH 36/79] Reserve enough space only for current connection count. --- plugins/net_plugin/net_plugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index d523fc68b8..cb47407585 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -4425,7 +4425,7 @@ namespace eosio { auto it = (from ? connections.find(from) : connections.begin()); if (it == connections.end()) it = connections.begin(); size_t num_rm = 0, num_clients = 0, num_peers = 0, num_bp_peers = 0; - net_plugin::p2p_per_connection_metrics per_connection(max_client_count); + net_plugin::p2p_per_connection_metrics per_connection(connections.size()); while (it != connections.end()) { if (fc::time_point::now() >= max_time) { connection_wptr wit = *it; From 507efb7a4cceb4869ea136619ffbdab0c4b9ea9e Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Thu, 3 Aug 2023 15:03:51 -0500 Subject: [PATCH 37/79] Rename late_initialize to update_prometheus_info. Remove stray debug log statement. --- plugins/prometheus_plugin/metrics.hpp | 3 +-- plugins/prometheus_plugin/prometheus_plugin.cpp | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/prometheus_plugin/metrics.hpp b/plugins/prometheus_plugin/metrics.hpp index 8d4b0aff77..e216353789 100644 --- a/plugins/prometheus_plugin/metrics.hpp +++ b/plugins/prometheus_plugin/metrics.hpp @@ -132,7 +132,6 @@ struct catalog_type { void update(const net_plugin::p2p_connections_metrics& metrics) { num_peers.Set(metrics.num_peers); num_clients.Set(metrics.num_clients); - dlog("Adding metrics for ${i} connections", ("i", metrics.stats.addresses.size())); for(size_t i = 0; i < metrics.stats.addresses.size(); ++i) { auto addr = boost::asio::ip::address_v4(metrics.stats.addresses[i]).to_string(); std::replace(addr.begin(), addr.end(), '.', '_'); @@ -194,7 +193,7 @@ struct catalog_type { head_block_num.Set(metrics.head_block_num); } - void late_initialize() { + void update_prometheus_info() { info_details = info.Add({ {"server_version", chain_apis::itoh(static_cast(app().version()))}, {"chain_id", app().get_plugin().get_chain_id()}, diff --git a/plugins/prometheus_plugin/prometheus_plugin.cpp b/plugins/prometheus_plugin/prometheus_plugin.cpp index c7a6d10863..2f14e5eba3 100644 --- a/plugins/prometheus_plugin/prometheus_plugin.cpp +++ b/plugins/prometheus_plugin/prometheus_plugin.cpp @@ -73,7 +73,7 @@ namespace eosio { elog("Prometheus exception ${e}", ("e", e)); } ); - my->_catalog.late_initialize(); + my->_catalog.update_prometheus_info(); ilog("Prometheus plugin started."); } From 1e14aa0a4ecb7fabd4c303834e4ac3ee464631f8 Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Thu, 3 Aug 2023 16:02:02 -0500 Subject: [PATCH 38/79] Change default host from localhost to 127.0.0.1. --- programs/net-util/net-util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/net-util/net-util.py b/programs/net-util/net-util.py index 94f164c5f5..45435e1966 100755 --- a/programs/net-util/net-util.py +++ b/programs/net-util/net-util.py @@ -190,7 +190,7 @@ def __init__(self): parser = argparse.ArgumentParser(description='Terminal UI for monitoring and managing nodeos P2P connections', formatter_class=argparse.ArgumentDefaultsHelpFormatter) - parser.add_argument('--host', help='hostname or IP address to connect to', default='localhost') + parser.add_argument('--host', help='hostname or IP address to connect to', default='127.0.0.1') parser.add_argument('-p', '--port', help='port number to connect to', default='8888') parser.add_argument('--log-level', choices=[logging._nameToLevel.keys()] + [k.lower() for k in logging._nameToLevel.keys()], help='Logging level', default='debug') self.args = parser.parse_args() From 850a336aab2c35000eccf7776f966b6731013c3c Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Thu, 3 Aug 2023 16:10:14 -0500 Subject: [PATCH 39/79] Check for non-200 status codes rather than only 404. --- programs/net-util/net-util.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/programs/net-util/net-util.py b/programs/net-util/net-util.py index 45435e1966..fc89ddc0a5 100755 --- a/programs/net-util/net-util.py +++ b/programs/net-util/net-util.py @@ -112,8 +112,8 @@ def render(self, size, focus=False): def readMetrics(host: str, port: str): response = requests.get(f'http://{host}:{port}{PROMETHEUS_URL}', timeout=10) - if response.status_code == 404: - logger.warn(f'Prometheus metrics URL returned 404: {response.url}') + if response.status_code != 200: + logger.fatal(f'Prometheus metrics URL returned {response.status_code}: {response.url}') raise urwid.ExitMainLoop() return response From 7420c726b2e7f6ab2d7da3e70d698a6d82d99f07 Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Thu, 3 Aug 2023 17:04:44 -0500 Subject: [PATCH 40/79] Add reported p2p_address to Prometheus metrics per peer. --- .../include/eosio/net_plugin/net_plugin.hpp | 3 +++ plugins/net_plugin/net_plugin.cpp | 1 + plugins/prometheus_plugin/metrics.hpp | 4 ++++ programs/net-util/net-util.py | 17 ++++++++++++----- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp b/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp index 7c14f5a8e6..f9162ffa1a 100644 --- a/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp +++ b/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp @@ -52,6 +52,7 @@ namespace eosio { bytes_received.reserve(count); bytes_sent.reserve(count); connection_start_times.reserve(count); + log_p2p_addresses.reserve(count); } p2p_per_connection_metrics(p2p_per_connection_metrics&& metrics) : addresses{std::move(metrics.addresses)} @@ -65,6 +66,7 @@ namespace eosio { , bytes_received{std::move(metrics.bytes_received)} , bytes_sent{std::move(metrics.bytes_sent)} , connection_start_times{std::move(metrics.connection_start_times)} + , log_p2p_addresses{std::move(metrics.log_p2p_addresses)} {} p2p_per_connection_metrics(const p2p_per_connection_metrics&) = delete; p2p_per_connection_metrics& operator=(const p2p_per_connection_metrics&) = delete; @@ -79,6 +81,7 @@ namespace eosio { std::vector bytes_received; std::vector bytes_sent; std::vector connection_start_times; + std::vector log_p2p_addresses; }; struct p2p_connections_metrics { p2p_connections_metrics(std::size_t peers, std::size_t clients, p2p_per_connection_metrics&& statistics) diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index cb47407585..45956f084d 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -4455,6 +4455,7 @@ namespace eosio { per_connection.connection_start_times.push_back((*it)->connection_time); per_connection.unique_first_block_counts.push_back((*it)->get_unique_blocks_rcvd_count()); per_connection.latencies.push_back((*it)->get_peer_ping_time_ns()); + per_connection.log_p2p_addresses.push_back((*it)->log_p2p_address); } else fc_wlog(logger, "socket remote endpoint is not IPv4"); diff --git a/plugins/prometheus_plugin/metrics.hpp b/plugins/prometheus_plugin/metrics.hpp index e216353789..727070b7e3 100644 --- a/plugins/prometheus_plugin/metrics.hpp +++ b/plugins/prometheus_plugin/metrics.hpp @@ -48,6 +48,7 @@ struct catalog_type { std::vector> bytes_received_gauges; std::vector> bytes_sent_gauges; std::vector> connection_start_time_gauges; + std::vector> log_p2p_address_gauges; // net plugin failed p2p connection Counter& failed_p2p_connections; @@ -166,6 +167,9 @@ struct catalog_type { auto& connection_start_time = p2p_connections.Add({{addr, "connection_start_time"}}); connection_start_time.Set(metrics.stats.connection_start_times[i].count()); connection_start_time_gauges.push_back(connection_start_time); + auto& log_p2p_address = p2p_connections.Add({{addr, metrics.stats.log_p2p_addresses[i]}}); + log_p2p_address.Set(0); // Empty gauge; we only want the label + log_p2p_address_gauges.push_back(log_p2p_address); } } diff --git a/programs/net-util/net-util.py b/programs/net-util/net-util.py index fc89ddc0a5..6729f07024 100755 --- a/programs/net-util/net-util.py +++ b/programs/net-util/net-util.py @@ -174,6 +174,7 @@ def __init__(self): 'unique_first_block_count': lambda x: str(int(x)), } self.peerColumns = [ + ('\n\nIP Address', 'ipAddressLW'), ('\n\nHostname', 'hostnameLW'), ('\n\nLatency', 'latencyLW'), ('\nSend\nRate', 'sendBandwidthLW'), @@ -255,7 +256,8 @@ def focus_changed(new_focus): self.peerListPiles[0].contents[-1][0].body.set_focus_changed_callback(focus_changed) - self.peerLineBox = urwid.LineBox(Columns([('weight', 2, self.peerListPiles[0])]+self.peerListPiles[1:], + self.peerLineBox = urwid.LineBox(Columns([('weight', 1, self.peerListPiles[0]), + ('weight', 2, self.peerListPiles[1])]+self.peerListPiles[2:], dividechars=1, focus_column=0), 'Peers:', 'left') @@ -296,7 +298,7 @@ def __init__(self, bytesReceived=0, bytesSent=0, connectionStarted=0): hostLabel = next(iter(sample.labels)) fieldName = sample.labels[hostLabel] host = hostLabel[1:].replace('__', ':').replace('_', '.') - listwalker = getattr(self, 'hostnameLW') + listwalker = getattr(self, 'ipAddressLW') if host not in listwalker: startOffset = endOffset = len(listwalker) listwalker.append(urwid.Text(host)) @@ -319,8 +321,13 @@ def __init__(self, bytesReceived=0, bytesSent=0, connectionStarted=0): stats.connectionStarted = connectionStarted bandwidths[host] = stats else: - listwalker = getattr(self, fieldName[:1] + fieldName.replace('_', ' ').title().replace(' ', '')[1:] + 'LW') - listwalker[startOffset:endOffset] = [urwid.Text(self.peerMetricConversions[fieldName](sample.value))] + attrname = fieldName[:1] + fieldName.replace('_', ' ').title().replace(' ', '')[1:] + 'LW' + if hasattr(self, attrname): + listwalker = getattr(self, attrname) + listwalker[startOffset:endOffset] = [urwid.Text(self.peerMetricConversions[fieldName](sample.value))] + else: + listwalker = getattr(self, 'hostnameLW') + listwalker[startOffset:endOffset] = [urwid.Text(fieldName.replace('_', '.'))] elif sample.name == 'nodeos_info': fieldName = self.fields.get(self.prometheusMetrics[(sample.name, 'server_version_string')]) field = getattr(self, fieldName) @@ -331,7 +338,7 @@ def __init__(self, bytesReceived=0, bytesSent=0, connectionStarted=0): else: if sample.name == 'nodeos_p2p_connections': now = time.time_ns() - hostListwalker = getattr(self, 'hostnameLW') + hostListwalker = getattr(self, 'ipAddressLW') for host, stats in bandwidths.items(): startOffset = hostListwalker.index(host) endOffset = startOffset + 1 From c33ea2e92b23648976003f0c00a3d823785b2baf Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Fri, 4 Aug 2023 17:44:23 -0400 Subject: [PATCH 41/79] restore const for what was previously const --- libraries/chain/webassembly/crypto.cpp | 30 +++++++++++++------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/libraries/chain/webassembly/crypto.cpp b/libraries/chain/webassembly/crypto.cpp index aab88890f6..035bece57e 100644 --- a/libraries/chain/webassembly/crypto.cpp +++ b/libraries/chain/webassembly/crypto.cpp @@ -255,8 +255,8 @@ namespace eosio { namespace chain { namespace webassembly { { if(op1.size() != 144 || op2.size() != 144 || result.size() != 144) return return_code::failure; - std::optional a = bls12_381::g1::fromJacobianBytesLE(std::span((uint8_t*)op1.data(), 144), false, true); - std::optional b = bls12_381::g1::fromJacobianBytesLE(std::span((uint8_t*)op2.data(), 144), false, true); + std::optional a = bls12_381::g1::fromJacobianBytesLE(std::span((const uint8_t*)op1.data(), 144), false, true); + std::optional b = bls12_381::g1::fromJacobianBytesLE(std::span((const uint8_t*)op2.data(), 144), false, true); if(!a.has_value() || !b.has_value()) return return_code::failure; bls12_381::g1 c = a.value().add(b.value()); @@ -268,8 +268,8 @@ namespace eosio { namespace chain { namespace webassembly { { if(op1.size() != 288 || op2.size() != 288 || result.size() != 288) return return_code::failure; - std::optional a = bls12_381::g2::fromJacobianBytesLE(std::span((uint8_t*)op1.data(), 288), false, true); - std::optional b = bls12_381::g2::fromJacobianBytesLE(std::span((uint8_t*)op2.data(), 288), false, true); + std::optional a = bls12_381::g2::fromJacobianBytesLE(std::span((const uint8_t*)op1.data(), 288), false, true); + std::optional b = bls12_381::g2::fromJacobianBytesLE(std::span((const uint8_t*)op2.data(), 288), false, true); if(!a.has_value() || !b.has_value()) return return_code::failure; bls12_381::g2 c = a.value().add(b.value()); @@ -281,7 +281,7 @@ namespace eosio { namespace chain { namespace webassembly { { if(point.size() != 144 || scalar.size() != 32 || result.size() != 144) return return_code::failure; - std::optional a = bls12_381::g1::fromJacobianBytesLE(std::span((uint8_t*)point.data(), 144), false, true); + std::optional a = bls12_381::g1::fromJacobianBytesLE(std::span((const uint8_t*)point.data(), 144), false, true); if(!a.has_value()) return return_code::failure; std::array b = bls12_381::scalar::fromBytesLE<4>(std::span((uint8_t*)scalar.data(), 32)); @@ -294,7 +294,7 @@ namespace eosio { namespace chain { namespace webassembly { { if(point.size() != 288 || scalar.size() != 32 || result.size() != 288) return return_code::failure; - std::optional a = bls12_381::g2::fromJacobianBytesLE(std::span((uint8_t*)point.data(), 288), false, true); + std::optional a = bls12_381::g2::fromJacobianBytesLE(std::span((const uint8_t*)point.data(), 288), false, true); if(!a.has_value()) return return_code::failure; std::array b = bls12_381::scalar::fromBytesLE<4>(std::span((uint8_t*)scalar.data(), 32)); @@ -313,10 +313,10 @@ namespace eosio { namespace chain { namespace webassembly { sv.reserve(n); for(uint32_t i = 0; i < n; i++) { - std::optional p = bls12_381::g1::fromJacobianBytesLE(std::span((uint8_t*)points.data() + i*144, 144), false, true); + std::optional p = bls12_381::g1::fromJacobianBytesLE(std::span((const uint8_t*)points.data() + i*144, 144), false, true); if(!p.has_value()) return return_code::failure; - std::array s = bls12_381::scalar::fromBytesLE<4>(std::span((uint8_t*)scalars.data() + i*32, 32)); + std::array s = bls12_381::scalar::fromBytesLE<4>(std::span((const uint8_t*)scalars.data() + i*32, 32)); pv.push_back(p.value()); sv.push_back(s); if(i%10 == 0) @@ -337,10 +337,10 @@ namespace eosio { namespace chain { namespace webassembly { sv.reserve(n); for(uint32_t i = 0; i < n; i++) { - std::optional p = bls12_381::g2::fromJacobianBytesLE(std::span((uint8_t*)points.data() + i*288, 288), false, true); + std::optional p = bls12_381::g2::fromJacobianBytesLE(std::span((const uint8_t*)points.data() + i*288, 288), false, true); if(!p.has_value()) return return_code::failure; - std::array s = bls12_381::scalar::fromBytesLE<4>(std::span((uint8_t*)scalars.data() + i*32, 32)); + std::array s = bls12_381::scalar::fromBytesLE<4>(std::span((const uint8_t*)scalars.data() + i*32, 32)); pv.push_back(p.value()); sv.push_back(s); if(i%6 == 0) @@ -359,8 +359,8 @@ namespace eosio { namespace chain { namespace webassembly { v.reserve(n); for(uint32_t i = 0; i < n; i++) { - std::optional p_g1 = bls12_381::g1::fromJacobianBytesLE(std::span((uint8_t*)g1_points.data() + i*144, 144), true, true); - std::optional p_g2 = bls12_381::g2::fromJacobianBytesLE(std::span((uint8_t*)g2_points.data() + i*288, 288), true, true); + std::optional p_g1 = bls12_381::g1::fromJacobianBytesLE(std::span((const uint8_t*)g1_points.data() + i*144, 144), true, true); + std::optional p_g2 = bls12_381::g2::fromJacobianBytesLE(std::span((const uint8_t*)g2_points.data() + i*288, 288), true, true); if(!p_g1.has_value() || !p_g2.has_value()) return return_code::failure; bls12_381::pairing::add_pair(v, p_g1.value(), p_g2.value()); @@ -376,7 +376,7 @@ namespace eosio { namespace chain { namespace webassembly { { if(e.size() != 48 || result.size() != 144) return return_code::failure; - std::optional a = bls12_381::fp::fromBytesLE(std::span((uint8_t*)e.data(), 48), true, true); + std::optional a = bls12_381::fp::fromBytesLE(std::span((const uint8_t*)e.data(), 48), true, true); if(!a.has_value()) return return_code::failure; bls12_381::g1 c = bls12_381::g1::mapToCurve(a.value()); @@ -388,7 +388,7 @@ namespace eosio { namespace chain { namespace webassembly { { if(e.size() != 96 || result.size() != 288) return return_code::failure; - std::optional a = bls12_381::fp2::fromBytesLE(std::span((uint8_t*)e.data(), 96), true, true); + std::optional a = bls12_381::fp2::fromBytesLE(std::span((const uint8_t*)e.data(), 96), true, true); if(!a.has_value()) return return_code::failure; bls12_381::g2 c = bls12_381::g2::mapToCurve(a.value()); @@ -400,7 +400,7 @@ namespace eosio { namespace chain { namespace webassembly { { if(s.size() != 64 || result.size() != 48) return return_code::failure; - std::array k = bls12_381::scalar::fromBytesLE<8>(std::span((uint8_t*)s.data(), 64)); + std::array k = bls12_381::scalar::fromBytesLE<8>(std::span((const uint8_t*)s.data(), 64)); bls12_381::fp e = bls12_381::fp::modPrime<8>(k); e.toBytesLE(std::span((uint8_t*)result.data(), 48), true); return return_code::success; From 2774deac6894f64860eec9bcacdf358ced7079cf Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Fri, 4 Aug 2023 17:27:55 -0500 Subject: [PATCH 42/79] Add refresh interval argument and default to the max possible. Add error overlay when there's a problem connecting. Also log errors to the log file. --- programs/net-util/net-util.py | 55 ++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/programs/net-util/net-util.py b/programs/net-util/net-util.py index 6729f07024..e47843f006 100755 --- a/programs/net-util/net-util.py +++ b/programs/net-util/net-util.py @@ -77,6 +77,7 @@ def humanReadableBytesPerSecond(bytes: int, telco:bool = False): n += 1 return f'{"~0" if bytes < 0.01 else format(bytes, ".2f")} {labels[n]}B/s' + class TextSimpleFocusListWalker(urwid.SimpleFocusListWalker): def __contains__(self, text): for element in self: @@ -193,11 +194,14 @@ def __init__(self): formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('--host', help='hostname or IP address to connect to', default='127.0.0.1') parser.add_argument('-p', '--port', help='port number to connect to', default='8888') + parser.add_argument('--refresh-interval', help='refresh interval in seconds (max 25.5)', default='25.5') parser.add_argument('--log-level', choices=[logging._nameToLevel.keys()] + [k.lower() for k in logging._nameToLevel.keys()], help='Logging level', default='debug') self.args = parser.parse_args() def createUrwidUI(self): + AttrMap = urwid.AttrMap Button = urwid.Button + LineBox = urwid.LineBox Text = urwid.Text Filler = urwid.Filler Columns = urwid.Columns @@ -217,7 +221,7 @@ def packLabeledText(labelTxt: str, defaultValue=''): def packLabeledButton(labelTxt: str, defaultValue='', callback: callable = None): label = Text(('bold', labelTxt), align='right') - button = Button(defaultValue, callback) + button = AttrMap(Button(defaultValue, callback), None, focus_map='reversed') attrName = labelTxt[:1].lower() + labelTxt[1:-1].replace(' ', '') + 'Button' if labelTxt else '' if attrName: setattr(self, attrName, button) @@ -232,9 +236,6 @@ def packLabeledButton(labelTxt: str, defaultValue='', callback: callable = None) widgets.insert(3, Filler(Divider())) rightColumn = Pile([(1, widget) for widget in widgets[:-1]] + [('weight', 1, widgets[-1])]) - self.errorText = Text(('error', '')) - self.errorBox = urwid.LineBox(self.errorText, 'Error:', 'left', 'error') - def packLabeledList(labelTxt: str, attrName: str): label = Text(('bold', labelTxt)) listWalker = TextSimpleFocusListWalker([]) @@ -256,26 +257,36 @@ def focus_changed(new_focus): self.peerListPiles[0].contents[-1][0].body.set_focus_changed_callback(focus_changed) - self.peerLineBox = urwid.LineBox(Columns([('weight', 1, self.peerListPiles[0]), - ('weight', 2, self.peerListPiles[1])]+self.peerListPiles[2:], - dividechars=1, focus_column=0), - 'Peers:', 'left') + columnedList = Columns([('weight', 1, self.peerListPiles[0]), + ('weight', 2, self.peerListPiles[1])]+self.peerListPiles[2:], + dividechars=1, focus_column=0) + self.peerLineBox = urwid.LineBox(columnedList, 'Peers:', 'left') + + self.mainView = Pile([Columns([leftColumn, rightColumn]), ('weight', 4, self.peerLineBox)]) + + self.errorText = Text(('error', '')) + self.errorBox = LineBox(Filler(self.errorText), 'Error:', 'left', 'error') + self.errorOverlay = urwid.Overlay(self.errorBox, self.mainView, 'center', ('relative', 80), 'middle', ('relative', 80), min_width=24, min_height=8) + + return self.mainView - #, Filler(Placeholder(self.errorText), valign='bottom') - return Pile([Columns([leftColumn, rightColumn]), ('weight', 4, self.peerLineBox)]) def onVersionClick(self, button): logger.info('Button clicked') def update(self, mainLoop, userData=None): + AttrMap = urwid.AttrMap + Text = urwid.Text try: + self.hostText.set_text(f'{self.args.host}:{self.args.port}') response = readMetrics(self.args.host, self.args.port) except requests.ConnectionError as e: + logger.error(str(e)) self.errorText.set_text(str(e)) - mainLoop.widget.contents[-1][0].original_widget = self.errorBox + mainLoop.widget = self.errorOverlay else: self.errorText.set_text('') - self.hostText.set_text(f'{self.args.host}:{self.args.port}') + mainLoop.widget = self.mainView class bandwidthStats(): def __init__(self, bytesReceived=0, bytesSent=0, connectionStarted=0): self.bytesReceived = 0 @@ -301,7 +312,7 @@ def __init__(self, bytesReceived=0, bytesSent=0, connectionStarted=0): listwalker = getattr(self, 'ipAddressLW') if host not in listwalker: startOffset = endOffset = len(listwalker) - listwalker.append(urwid.Text(host)) + listwalker.append(Text(host)) else: startOffset = listwalker.index(host) endOffset = startOffset + 1 @@ -324,14 +335,14 @@ def __init__(self, bytesReceived=0, bytesSent=0, connectionStarted=0): attrname = fieldName[:1] + fieldName.replace('_', ' ').title().replace(' ', '')[1:] + 'LW' if hasattr(self, attrname): listwalker = getattr(self, attrname) - listwalker[startOffset:endOffset] = [urwid.Text(self.peerMetricConversions[fieldName](sample.value))] + listwalker[startOffset:endOffset] = [AttrMap(Text(self.peerMetricConversions[fieldName](sample.value)), None, 'reversed')] else: listwalker = getattr(self, 'hostnameLW') - listwalker[startOffset:endOffset] = [urwid.Text(fieldName.replace('_', '.'))] + listwalker[startOffset:endOffset] = [AttrMap(Text(fieldName.replace('_', '.')), None, 'reversed')] elif sample.name == 'nodeos_info': fieldName = self.fields.get(self.prometheusMetrics[(sample.name, 'server_version_string')]) field = getattr(self, fieldName) - field.set_label(sample.labels['server_version_string']) + field.original_widget.set_label(sample.labels['server_version_string']) else: if sample.name not in self.ignoredPrometheusMetrics: logger.warning(f'Received unhandled Prometheus metric {sample.name}') @@ -345,11 +356,11 @@ def __init__(self, bytesReceived=0, bytesSent=0, connectionStarted=0): connected_seconds = (now - stats.connectionStarted)/1000000000 listwalker = getattr(self, 'receiveBandwidthLW') bps = stats.bytesReceived/connected_seconds - listwalker[startOffset:endOffset] = [urwid.Text(humanReadableBytesPerSecond(bps))] + listwalker[startOffset:endOffset] = [Text(humanReadableBytesPerSecond(bps))] listwalker = getattr(self, 'sendBandwidthLW') bps = stats.bytesSent/connected_seconds - listwalker[startOffset:endOffset] = [urwid.Text(humanReadableBytesPerSecond(bps))] - mainLoop.set_alarm_in(0.5, self.update) + listwalker[startOffset:endOffset] = [Text(humanReadableBytesPerSecond(bps))] + mainLoop.set_alarm_in(float(self.args.refresh_interval), self.update) def exitOnQ(key): if key in ('q', 'Q'): @@ -365,7 +376,9 @@ def exitOnQ(key): logger.info(f'Starting {sys.argv[0]}') palette = [('error', 'yellow,bold', 'default'), ('bold', 'default,bold', 'default'), - ('dim', 'dark gray', 'default'),] + ('dim', 'dark gray', 'default'), + ('reversed', 'standout', ''), + ] loop = urwid.MainLoop(inst.createUrwidUI(), palette, screen=urwid.curses_display.Screen(), unhandled_input=exitOnQ, event_loop=None, pop_ups=True) - loop.set_alarm_in(0.5, inst.update) + inst.update(loop) loop.run() From df3554d37551dbe536a682e0c9cf2966e07a18e5 Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Fri, 4 Aug 2023 19:25:47 -0500 Subject: [PATCH 43/79] Add support for last data received and sent timestamps on peers. Remove obsolete comment regarding IPv6. --- .../include/eosio/net_plugin/net_plugin.hpp | 6 ++++++ plugins/net_plugin/net_plugin.cpp | 14 +++++++++++--- plugins/prometheus_plugin/metrics.hpp | 8 ++++++++ programs/net-util/net-util.py | 6 +++++- 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp b/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp index f9162ffa1a..af86a32026 100644 --- a/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp +++ b/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp @@ -50,7 +50,9 @@ namespace eosio { unique_first_block_counts.reserve(count); latencies.reserve(count); bytes_received.reserve(count); + last_bytes_received.reserve(count); bytes_sent.reserve(count); + last_bytes_sent.reserve(count); connection_start_times.reserve(count); log_p2p_addresses.reserve(count); } @@ -64,7 +66,9 @@ namespace eosio { , unique_first_block_counts{std::move(metrics.unique_first_block_counts)} , latencies{std::move(metrics.latencies)} , bytes_received{std::move(metrics.bytes_received)} + , last_bytes_received(std::move(metrics.last_bytes_received)) , bytes_sent{std::move(metrics.bytes_sent)} + , last_bytes_sent(std::move(metrics.last_bytes_sent)) , connection_start_times{std::move(metrics.connection_start_times)} , log_p2p_addresses{std::move(metrics.log_p2p_addresses)} {} @@ -79,7 +83,9 @@ namespace eosio { std::vector unique_first_block_counts; std::vector latencies; std::vector bytes_received; + std::vector last_bytes_received; std::vector bytes_sent; + std::vector last_bytes_sent; std::vector connection_start_times; std::vector log_p2p_addresses; }; diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index 45956f084d..99cf478ef2 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -795,7 +795,9 @@ namespace eosio { uint32_t get_last_received_blk_num() const { return last_received_blk_num.load(); } uint32_t get_unique_blocks_rcvd_count() const { return unique_blocks_rcvd_count.load(); } size_t get_bytes_received() const { return bytes_received.load(); } + time_t get_last_bytes_received() const { return last_bytes_received.load(); } size_t get_bytes_sent() const { return bytes_sent.load(); } + time_t get_last_bytes_sent() const { return last_bytes_sent.load(); } void set_heartbeat_timeout(std::chrono::milliseconds msec) { hb_timeout = msec; } @@ -828,7 +830,9 @@ namespace eosio { std::atomic last_received_blk_num{0}; std::atomic unique_blocks_rcvd_count{0}; std::atomic bytes_received{0}; + std::atomic last_bytes_received{0}; std::atomic bytes_sent{0}; + std::atomic last_bytes_sent{0}; public: boost::asio::io_context::strand strand; @@ -956,9 +960,10 @@ namespace eosio { void send_time(const time_message& msg); /** \brief Read system time and convert to a 64 bit integer. * - * There are three calls to this routine in the program. One + * There are five calls to this routine in the program. One * when a packet arrives from the network, one when a packet - * is placed on the send queue, and one during connect. + * is placed on the send queue, one during connect, and + * one each when data is counted as received or sent. * Calls the kernel time of day routine and converts to * a (at least) 64 bit integer. */ @@ -1538,6 +1543,7 @@ namespace eosio { std::function callback, bool to_sync_queue) { bytes_sent += buff->size(); + last_bytes_sent = get_time().count(); if( !buffer_queue.add_write_queue( buff, std::move(callback), to_sync_queue )) { peer_wlog( this, "write_queue full ${s} bytes, giving up on connection", ("s", buffer_queue.write_queue_size()) ); close(); @@ -2658,7 +2664,6 @@ namespace eosio { auto resolver = std::make_shared( my_impl->thread_pool.get_executor() ); connection_wptr weak_conn = c; - // Note: need to add support for IPv6 too resolver->async_resolve(host, port, boost::asio::bind_executor( c->strand, [resolver, weak_conn, host = host, port = port]( const boost::system::error_code& err, const tcp::resolver::results_type& endpoints ) { auto c = weak_conn.lock(); @@ -2891,6 +2896,7 @@ namespace eosio { // called from connection strand bool connection::process_next_message( uint32_t message_length ) { bytes_received += message_length; + last_bytes_received = get_time().count(); try { latest_msg_time = std::chrono::system_clock::now(); @@ -4451,7 +4457,9 @@ namespace eosio { per_connection.first_available_blocks.push_back((*it)->get_peer_start_block_num()); per_connection.last_available_blocks.push_back((*it)->get_peer_head_block_num()); per_connection.bytes_received.push_back((*it)->get_bytes_received()); + per_connection.last_bytes_received.push_back((*it)->get_last_bytes_received()); per_connection.bytes_sent.push_back((*it)->get_bytes_sent()); + per_connection.last_bytes_sent.push_back((*it)->get_last_bytes_sent()); per_connection.connection_start_times.push_back((*it)->connection_time); per_connection.unique_first_block_counts.push_back((*it)->get_unique_blocks_rcvd_count()); per_connection.latencies.push_back((*it)->get_peer_ping_time_ns()); diff --git a/plugins/prometheus_plugin/metrics.hpp b/plugins/prometheus_plugin/metrics.hpp index 727070b7e3..706747f63f 100644 --- a/plugins/prometheus_plugin/metrics.hpp +++ b/plugins/prometheus_plugin/metrics.hpp @@ -46,7 +46,9 @@ struct catalog_type { std::vector> unique_first_block_counts_gauges; std::vector> latency_gauges; std::vector> bytes_received_gauges; + std::vector> last_bytes_received_gauges; std::vector> bytes_sent_gauges; + std::vector> last_bytes_sent_gauges; std::vector> connection_start_time_gauges; std::vector> log_p2p_address_gauges; @@ -161,9 +163,15 @@ struct catalog_type { auto& bytes_received = p2p_connections.Add({{addr, "bytes_received"}}); bytes_received.Set(metrics.stats.bytes_received[i]); bytes_received_gauges.push_back(bytes_received); + auto& last_bytes_received = p2p_connections.Add({{addr, "last_bytes_received"}}); + last_bytes_received.Set(metrics.stats.last_bytes_received[i]); + last_bytes_received_gauges.push_back(last_bytes_received); auto& bytes_sent = p2p_connections.Add({{addr, "bytes_sent"}}); bytes_sent.Set(metrics.stats.bytes_sent[i]); bytes_sent_gauges.push_back(bytes_sent); + auto& last_bytes_sent = p2p_connections.Add({{addr, "last_bytes_sent"}}); + last_bytes_sent.Set(metrics.stats.last_bytes_sent[i]); + last_bytes_sent_gauges.push_back(last_bytes_sent); auto& connection_start_time = p2p_connections.Add({{addr, "connection_start_time"}}); connection_start_time.Set(metrics.stats.connection_start_times[i].count()); connection_start_time_gauges.push_back(connection_start_time); diff --git a/programs/net-util/net-util.py b/programs/net-util/net-util.py index e47843f006..90fd84f59a 100755 --- a/programs/net-util/net-util.py +++ b/programs/net-util/net-util.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 import argparse +import datetime import logging import pathlib import requests @@ -168,18 +169,21 @@ def __init__(self): 'hostname': lambda x: x[1:].replace('__', ':').replace('_', '.'), 'accepting_blocks': lambda x: 'True' if x else 'False', 'latency': lambda x: format(int(x)/1000000, '.2f') + ' ms', - 'bandwidth': lambda x: str(int(x)) + ' B/s', 'last_received_block': lambda x: str(int(x)), 'first_available_block': lambda x: str(int(x)), 'last_available_block': lambda x: str(int(x)), 'unique_first_block_count': lambda x: str(int(x)), + 'last_bytes_received': lambda x: str(datetime.timedelta(microseconds=(time.time_ns() - int(x))/1000)), + 'last_bytes_sent': lambda x: str(datetime.timedelta(microseconds=(time.time_ns() - int(x))/1000)), } self.peerColumns = [ ('\n\nIP Address', 'ipAddressLW'), ('\n\nHostname', 'hostnameLW'), ('\n\nLatency', 'latencyLW'), ('\nSend\nRate', 'sendBandwidthLW'), + ('Last\nSent\nTime', 'lastBytesSentLW'), ('\nRcv\nRate', 'receiveBandwidthLW'), + ('Last\nRcv\nTime', 'lastBytesReceivedLW'), ('Last\nRcvd\nBlock', 'lastReceivedBlockLW'), ('Unique\nFirst\nBlks', 'uniqueFirstBlockCountLW'), ('First\nAvail\nBlk', 'firstAvailableBlockLW'), From dc4adfaed0f9bcfde852a6f95822127e3cddf4cd Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Sat, 5 Aug 2023 13:18:18 -0500 Subject: [PATCH 44/79] GH-1432 Refactor producer_watermarks, calculate_producer_wake_up_time, calculate_next_block_slot into block_timing_util --- .../producer_plugin/block_timing_util.hpp | 128 ++++++++++++++++-- plugins/producer_plugin/producer_plugin.cpp | 128 +++--------------- 2 files changed, 133 insertions(+), 123 deletions(-) diff --git a/plugins/producer_plugin/include/eosio/producer_plugin/block_timing_util.hpp b/plugins/producer_plugin/include/eosio/producer_plugin/block_timing_util.hpp index 8238e55fae..602032cc4e 100644 --- a/plugins/producer_plugin/include/eosio/producer_plugin/block_timing_util.hpp +++ b/plugins/producer_plugin/include/eosio/producer_plugin/block_timing_util.hpp @@ -1,6 +1,7 @@ #pragma once #include #include +#include namespace eosio { @@ -8,6 +9,32 @@ enum class pending_block_mode { producing, speculating }; namespace block_timing_util { + // Store watermarks + class producer_watermarks { + public: + void consider_new_watermark(chain::account_name producer, uint32_t block_num, chain::block_timestamp_type timestamp) { + auto itr = _producer_watermarks.find(producer); + if (itr != _producer_watermarks.end()) { + itr->second.first = std::max(itr->second.first, block_num); + itr->second.second = std::max(itr->second.second, timestamp); + } else { + _producer_watermarks.emplace(producer, std::make_pair(block_num, timestamp)); + } + } + + using producer_watermark = std::pair; + std::optional get_watermark(chain::account_name producer) const { + auto itr = _producer_watermarks.find(producer); + + if (itr == _producer_watermarks.end()) + return {}; + + return itr->second; + } + private: + std::map _producer_watermarks; + }; + // Calculate when a producer can start producing a given block represented by its block_time // // In the past, a producer would always start a block `config::block_interval_us` ahead of its block time. However, @@ -25,22 +52,95 @@ namespace block_timing_util { fc::microseconds(cpu_effort_us * production_round_index); } - inline fc::time_point calculate_block_deadline(uint32_t cpu_effort_us, pending_block_mode mode, chain::block_timestamp_type block_time) { - const auto hard_deadline = - block_time.to_time_point() - fc::microseconds(chain::config::block_interval_us - cpu_effort_us); - if (mode == pending_block_mode::producing) { - auto estimated_deadline = production_round_block_start_time(cpu_effort_us, block_time) + fc::microseconds(cpu_effort_us); - auto now = fc::time_point::now(); - if (estimated_deadline > now) { - return estimated_deadline; - } else { - // This could only happen when the producer stop producing and then comes back alive in the middle of its own - // production round. In this case, we just use the hard deadline. - return std::min(hard_deadline, now + fc::microseconds(cpu_effort_us)); + inline fc::time_point calculate_producing_block_deadline(uint32_t cpu_effort_us, chain::block_timestamp_type block_time) { + auto estimated_deadline = production_round_block_start_time(cpu_effort_us, block_time) + fc::microseconds(cpu_effort_us); + auto now = fc::time_point::now(); + if (estimated_deadline > now) { + return estimated_deadline; + } else { + // This could only happen when the producer stop producing and then comes back alive in the middle of its own + // production round. In this case, we just use the hard deadline. + const auto hard_deadline = block_time.to_time_point() - fc::microseconds(chain::config::block_interval_us - cpu_effort_us); + return std::min(hard_deadline, now + fc::microseconds(cpu_effort_us)); + } + } + + inline uint32_t calculate_next_block_slot(const chain::account_name& producer_name, uint32_t current_block_slot, uint32_t block_num, + const std::vector& active_schedule, const producer_watermarks& prod_watermarks) { + // determine if this producer is in the active schedule and if so, where + auto itr = + std::find_if(active_schedule.begin(), active_schedule.end(), [&](const auto& asp) { return asp.producer_name == producer_name; }); + if (itr == active_schedule.end()) { + // this producer is not in the active producer set + return UINT32_MAX; + } + + size_t producer_index = itr - active_schedule.begin(); + uint32_t minimum_offset = 1; // must at least be the "next" block + + // account for a watermark in the future which is disqualifying this producer for now + // this is conservative assuming no blocks are dropped. If blocks are dropped the watermark will + // disqualify this producer for longer but it is assumed they will wake up, determine that they + // are disqualified for longer due to skipped blocks and re-calculate their next block with better + // information then + auto current_watermark = prod_watermarks.get_watermark(producer_name); + if (current_watermark) { + const auto watermark = *current_watermark; + if (watermark.first > block_num) { + // if I have a watermark block number then I need to wait until after that watermark + minimum_offset = watermark.first - block_num + 1; } + if (watermark.second.slot > current_block_slot) { + // if I have a watermark block timestamp then I need to wait until after that watermark timestamp + minimum_offset = std::max(minimum_offset, watermark.second.slot - current_block_slot + 1); + } + } + + // this producers next opportunity to produce is the next time its slot arrives after or at the calculated minimum + uint32_t minimum_slot = current_block_slot + minimum_offset; + size_t minimum_slot_producer_index = + (minimum_slot % (active_schedule.size() * chain::config::producer_repetitions)) / chain::config::producer_repetitions; + if (producer_index == minimum_slot_producer_index) { + // this is the producer for the minimum slot, go with that + return minimum_slot; } else { - return hard_deadline; + // calculate how many rounds are between the minimum producer and the producer in question + size_t producer_distance = producer_index - minimum_slot_producer_index; + // check for unsigned underflow + if (producer_distance > producer_index) { + producer_distance += active_schedule.size(); + } + + // align the minimum slot to the first of its set of reps + uint32_t first_minimum_producer_slot = minimum_slot - (minimum_slot % chain::config::producer_repetitions); + + // offset the aligned minimum to the *earliest* next set of slots for this producer + uint32_t next_block_slot = first_minimum_producer_slot + (producer_distance * chain::config::producer_repetitions); + return next_block_slot; } } -}; + + // Return the *next* block start time according to its block time slot. + // Returns empty optional if no producers are in the active_schedule. + // block_num is only used for watermark minimum offset. + inline std::optional calculate_producer_wake_up_time(uint32_t cpu_effort_us, uint32_t block_num, + const chain::block_timestamp_type& ref_block_time, + const std::set& producers, + const std::vector& active_schedule, + const producer_watermarks& prod_watermarks) { + auto ref_block_slot = ref_block_time.slot; + // if we have any producers then we should at least set a timer for our next available slot + uint32_t wake_up_slot = UINT32_MAX; + for (const auto& p : producers) { + auto next_producer_block_slot = calculate_next_block_slot(p, ref_block_slot, block_num, active_schedule, prod_watermarks); + wake_up_slot = std::min(next_producer_block_slot, wake_up_slot); + } + if (wake_up_slot == UINT32_MAX) { + return {}; + } + + return production_round_block_start_time(cpu_effort_us, chain::block_timestamp_type(wake_up_slot)); + } + +} // namespace block_timing_util } // namespace eosio \ No newline at end of file diff --git a/plugins/producer_plugin/producer_plugin.cpp b/plugins/producer_plugin/producer_plugin.cpp index dd0b944b0a..0056ace507 100644 --- a/plugins/producer_plugin/producer_plugin.cpp +++ b/plugins/producer_plugin/producer_plugin.cpp @@ -382,7 +382,6 @@ class producer_plugin_impl : public std::enable_shared_from_this()) , _ro_timer(io) {} - uint32_t calculate_next_block_slot(const account_name& producer_name, uint32_t current_block_slot) const; void schedule_production_loop(); void schedule_maybe_produce_block(bool exhausted); void produce_block(); @@ -513,8 +512,7 @@ class producer_plugin_impl : public std::enable_shared_from_this _signature_providers; std::set _producers; boost::asio::deadline_timer _timer; - using producer_watermark = std::pair; - std::map _producer_watermarks; + block_timing_util::producer_watermarks _producer_watermarks; pending_block_mode _pending_block_mode = pending_block_mode::speculating; unapplied_transaction_queue _unapplied_transactions; size_t _thread_pool_size = config::default_controller_thread_pool_size; @@ -634,25 +632,6 @@ class producer_plugin_impl : public std::enable_shared_from_this next); - void consider_new_watermark(account_name producer, uint32_t block_num, block_timestamp_type timestamp) { - auto itr = _producer_watermarks.find(producer); - if (itr != _producer_watermarks.end()) { - itr->second.first = std::max(itr->second.first, block_num); - itr->second.second = std::max(itr->second.second, timestamp); - } else if (_producers.count(producer) > 0) { - _producer_watermarks.emplace(producer, std::make_pair(block_num, timestamp)); - } - } - - std::optional get_watermark(account_name producer) const { - auto itr = _producer_watermarks.find(producer); - - if (itr == _producer_watermarks.end()) - return {}; - - return itr->second; - } - void on_block(const block_state_ptr& bsp) { auto& chain = chain_plug->chain(); auto before = _unapplied_transactions.size(); @@ -663,7 +642,10 @@ class producer_plugin_impl : public std::enable_shared_from_thisheader.producer, bsp->block_num, bsp->block->timestamp); } + void on_block_header(const block_state_ptr& bsp) { + if (_producers.contains(bsp->header.producer)) + _producer_watermarks.consider_new_watermark(bsp->header.producer, bsp->block_num, bsp->block->timestamp); + } void on_irreversible_block(const signed_block_ptr& lib) { const chain::controller& chain = chain_plug->chain(); @@ -999,7 +981,6 @@ class producer_plugin_impl : public std::enable_shared_from_this& weak_this, std::optional wake_up_time); - std::optional calculate_producer_wake_up_time( const block_timestamp_type& ref_block_time ) const; bool in_producing_mode() const { return _pending_block_mode == pending_block_mode::producing; } bool in_speculating_mode() const { return _pending_block_mode == pending_block_mode::speculating; } @@ -1811,69 +1792,6 @@ producer_plugin::get_unapplied_transactions_result producer_plugin::get_unapplie return result; } - -uint32_t producer_plugin_impl::calculate_next_block_slot(const account_name& producer_name, uint32_t current_block_slot) const { - chain::controller& chain = chain_plug->chain(); - const auto& hbs = chain.head_block_state(); - const auto& active_schedule = hbs->active_schedule.producers; - - // determine if this producer is in the active schedule and if so, where - auto itr = - std::find_if(active_schedule.begin(), active_schedule.end(), [&](const auto& asp) { return asp.producer_name == producer_name; }); - if (itr == active_schedule.end()) { - // this producer is not in the active producer set - return UINT32_MAX; - } - - size_t producer_index = itr - active_schedule.begin(); - uint32_t minimum_offset = 1; // must at least be the "next" block - - // account for a watermark in the future which is disqualifying this producer for now - // this is conservative assuming no blocks are dropped. If blocks are dropped the watermark will - // disqualify this producer for longer but it is assumed they will wake up, determine that they - // are disqualified for longer due to skipped blocks and re-calculate their next block with better - // information then - auto current_watermark = get_watermark(producer_name); - if (current_watermark) { - const auto watermark = *current_watermark; - auto block_num = chain.head_block_state()->block_num; - if (chain.is_building_block()) { - ++block_num; - } - if (watermark.first > block_num) { - // if I have a watermark block number then I need to wait until after that watermark - minimum_offset = watermark.first - block_num + 1; - } - if (watermark.second.slot > current_block_slot) { - // if I have a watermark block timestamp then I need to wait until after that watermark timestamp - minimum_offset = std::max(minimum_offset, watermark.second.slot - current_block_slot + 1); - } - } - - // this producers next opportunity to produce is the next time its slot arrives after or at the calculated minimum - uint32_t minimum_slot = current_block_slot + minimum_offset; - size_t minimum_slot_producer_index = - (minimum_slot % (active_schedule.size() * config::producer_repetitions)) / config::producer_repetitions; - if (producer_index == minimum_slot_producer_index) { - // this is the producer for the minimum slot, go with that - return minimum_slot; - } else { - // calculate how many rounds are between the minimum producer and the producer in question - size_t producer_distance = producer_index - minimum_slot_producer_index; - // check for unsigned underflow - if (producer_distance > producer_index) { - producer_distance += active_schedule.size(); - } - - // align the minimum slot to the first of its set of reps - uint32_t first_minimum_producer_slot = minimum_slot - (minimum_slot % config::producer_repetitions); - - // offset the aligned minimum to the *earliest* next set of slots for this producer - uint32_t next_block_slot = first_minimum_producer_slot + (producer_distance * config::producer_repetitions); - return next_block_slot; - } -} - block_timestamp_type producer_plugin_impl::calculate_pending_block_time() const { const chain::controller& chain = chain_plug->chain(); const fc::time_point now = fc::time_point::now(); @@ -1912,7 +1830,7 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() { // Not our turn const auto& scheduled_producer = hbs->get_scheduled_producer(block_time); - const auto current_watermark = get_watermark(scheduled_producer.producer_name); + const auto current_watermark = _producer_watermarks.get_watermark(scheduled_producer.producer_name); size_t num_relevant_signatures = 0; scheduled_producer.for_each_key([&](const public_key_type& key) { @@ -2668,8 +2586,12 @@ void producer_plugin_impl::schedule_production_loop() { })); } else if (result == start_block_result::waiting_for_block) { if (!_producers.empty() && !production_disabled_by_policy()) { + chain::controller& chain = chain_plug->chain(); fc_dlog(_log, "Waiting till another block is received and scheduling Speculative/Production Change"); - schedule_delayed_production_loop(weak_from_this(), calculate_producer_wake_up_time(calculate_pending_block_time())); + auto wake_time = block_timing_util::calculate_producer_wake_up_time(_cpu_effort_us, chain.head_block_num(), calculate_pending_block_time(), + _producers, chain.head_block_state()->active_schedule.producers, + _producer_watermarks); + schedule_delayed_production_loop(weak_from_this(), wake_time); } else { fc_tlog(_log, "Waiting till another block is received"); // nothing to do until more blocks arrive @@ -2685,7 +2607,10 @@ void producer_plugin_impl::schedule_production_loop() { chain::controller& chain = chain_plug->chain(); fc_dlog(_log, "Speculative Block Created; Scheduling Speculative/Production Change"); EOS_ASSERT(chain.is_building_block(), missing_pending_block_state, "speculating without pending_block_state"); - schedule_delayed_production_loop(weak_from_this(), calculate_producer_wake_up_time(chain.pending_block_timestamp())); + auto wake_time = block_timing_util::calculate_producer_wake_up_time(_cpu_effort_us, chain.pending_block_num(), chain.pending_block_timestamp(), + _producers, chain.head_block_state()->active_schedule.producers, + _producer_watermarks); + schedule_delayed_production_loop(weak_from_this(), wake_time); } else { fc_dlog(_log, "Speculative Block Created"); } @@ -2696,9 +2621,10 @@ void producer_plugin_impl::schedule_production_loop() { void producer_plugin_impl::schedule_maybe_produce_block(bool exhausted) { chain::controller& chain = chain_plug->chain(); + assert(in_producing_mode()); // we succeeded but block may be exhausted static const boost::posix_time::ptime epoch(boost::gregorian::date(1970, 1, 1)); - auto deadline = block_timing_util::calculate_block_deadline(_cpu_effort_us, _pending_block_mode, chain.pending_block_time()); + auto deadline = block_timing_util::calculate_producing_block_deadline(_cpu_effort_us, chain.pending_block_time()); if (!exhausted && deadline > fc::time_point::now()) { // ship this block off no later than its deadline @@ -2728,24 +2654,6 @@ void producer_plugin_impl::schedule_maybe_produce_block(bool exhausted) { })); } - - -std::optional producer_plugin_impl::calculate_producer_wake_up_time(const block_timestamp_type& ref_block_time) const { - auto ref_block_slot = ref_block_time.slot; - // if we have any producers then we should at least set a timer for our next available slot - uint32_t wake_up_slot = UINT32_MAX; - for (const auto& p : _producers) { - auto next_producer_block_slot = calculate_next_block_slot(p, ref_block_slot); - wake_up_slot = std::min(next_producer_block_slot, wake_up_slot); - } - if (wake_up_slot == UINT32_MAX) { - fc_dlog(_log, "Not Scheduling Speculative/Production, no local producers had valid wake up times"); - return {}; - } - - return block_timing_util::production_round_block_start_time(_cpu_effort_us, block_timestamp_type(wake_up_slot)); -} - void producer_plugin_impl::schedule_delayed_production_loop(const std::weak_ptr& weak_this, std::optional wake_up_time) { if (wake_up_time) { @@ -2759,6 +2667,8 @@ void producer_plugin_impl::schedule_delayed_production_loop(const std::weak_ptr< self->schedule_production_loop(); } })); + } else { + fc_dlog(_log, "Not Scheduling Speculative/Production, no local producers had valid wake up times"); } } From 2bb1e0d0b55b6749caba0e5cb6d083fcf89363f6 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Sat, 5 Aug 2023 13:19:06 -0500 Subject: [PATCH 45/79] GH-1432 Add some initial tests for calculate_producer_wake_up_time --- .../test/test_block_timing_util.cpp | 133 +++++++++++++++--- 1 file changed, 114 insertions(+), 19 deletions(-) diff --git a/plugins/producer_plugin/test/test_block_timing_util.cpp b/plugins/producer_plugin/test/test_block_timing_util.cpp index c2d1e43e78..a6d0f2216d 100644 --- a/plugins/producer_plugin/test/test_block_timing_util.cpp +++ b/plugins/producer_plugin/test/test_block_timing_util.cpp @@ -4,6 +4,7 @@ namespace fc { std::ostream& boost_test_print_type(std::ostream& os, const time_point& t) { return os << t.to_iso_string(); } +std::ostream& boost_test_print_type(std::ostream& os, const std::optional& t) { return os << (t ? t->to_iso_string() : "null"); } } // namespace fc static_assert(eosio::chain::config::block_interval_ms == 500); @@ -34,17 +35,6 @@ BOOST_AUTO_TEST_CASE(test_calculate_block_deadline) { { // Scenario 1: - // In speculating mode, the deadline of a block will always be ahead of its block_time by 100 ms, - // These deadlines are referred as hard deadlines. - for (int i = 0; i < eosio::chain::config::producer_repetitions; ++i) { - auto block_time = eosio::chain::block_timestamp_type(production_round_1st_block_slot + i); - auto expected_deadline = block_time.to_time_point() - fc::milliseconds(100); - BOOST_CHECK_EQUAL(calculate_block_deadline(cpu_effort_us, eosio::pending_block_mode::speculating, block_time), - expected_deadline); - } - } - { - // Scenario 2: // In producing mode, the deadline of a block will be ahead of its block_time from 100, 200, 300, ...ms, // depending on the its index to the starting block of a production round. These deadlines are referred // as optimized deadlines. @@ -52,31 +42,31 @@ BOOST_AUTO_TEST_CASE(test_calculate_block_deadline) { for (int i = 0; i < eosio::chain::config::producer_repetitions; ++i) { auto block_time = eosio::chain::block_timestamp_type(production_round_1st_block_slot + i); auto expected_deadline = block_time.to_time_point() - fc::milliseconds((i + 1) * 100); - BOOST_CHECK_EQUAL(calculate_block_deadline(cpu_effort_us, eosio::pending_block_mode::producing, block_time), + BOOST_CHECK_EQUAL(calculate_producing_block_deadline(cpu_effort_us, block_time), expected_deadline); fc::mock_time_traits::set_now(expected_deadline); } } { - // Scenario 3: + // Scenario 2: // In producing mode and it is already too late to meet the optimized deadlines, // the returned deadline can never be later than the hard deadlines. auto second_block_time = eosio::chain::block_timestamp_type(production_round_1st_block_slot + 1); fc::mock_time_traits::set_now(second_block_time.to_time_point() - fc::milliseconds(200)); auto second_block_hard_deadline = second_block_time.to_time_point() - fc::milliseconds(100); - BOOST_CHECK_EQUAL(calculate_block_deadline(cpu_effort_us, eosio::pending_block_mode::producing, second_block_time), + BOOST_CHECK_EQUAL(calculate_producing_block_deadline(cpu_effort_us, second_block_time), second_block_hard_deadline); // use previous deadline as now fc::mock_time_traits::set_now(second_block_hard_deadline); auto third_block_time = eosio::chain::block_timestamp_type(production_round_1st_block_slot + 2); - BOOST_CHECK_EQUAL(calculate_block_deadline(cpu_effort_us, eosio::pending_block_mode::producing, third_block_time), + BOOST_CHECK_EQUAL(calculate_producing_block_deadline(cpu_effort_us, third_block_time), third_block_time.to_time_point() - fc::milliseconds(300)); // use previous deadline as now fc::mock_time_traits::set_now(third_block_time.to_time_point() - fc::milliseconds(300)); auto forth_block_time = eosio::chain::block_timestamp_type(production_round_1st_block_slot + 3); - BOOST_CHECK_EQUAL(calculate_block_deadline(cpu_effort_us, eosio::pending_block_mode::producing, forth_block_time), + BOOST_CHECK_EQUAL(calculate_producing_block_deadline(cpu_effort_us, forth_block_time), forth_block_time.to_time_point() - fc::milliseconds(400)); /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -84,23 +74,128 @@ BOOST_AUTO_TEST_CASE(test_calculate_block_deadline) { auto seventh_block_time = eosio::chain::block_timestamp_type(production_round_1st_block_slot + 6); fc::mock_time_traits::set_now(seventh_block_time.to_time_point() - fc::milliseconds(500)); - BOOST_CHECK_EQUAL(calculate_block_deadline(cpu_effort_us, eosio::pending_block_mode::producing, seventh_block_time), + BOOST_CHECK_EQUAL(calculate_producing_block_deadline(cpu_effort_us, seventh_block_time), seventh_block_time.to_time_point() - fc::milliseconds(100)); // use previous deadline as now fc::mock_time_traits::set_now(seventh_block_time.to_time_point() - fc::milliseconds(100)); auto eighth_block_time = eosio::chain::block_timestamp_type(production_round_1st_block_slot + 7); - BOOST_CHECK_EQUAL(calculate_block_deadline(cpu_effort_us, eosio::pending_block_mode::producing, eighth_block_time), + BOOST_CHECK_EQUAL(calculate_producing_block_deadline(cpu_effort_us, eighth_block_time), eighth_block_time.to_time_point() - fc::milliseconds(200)); // use previous deadline as now fc::mock_time_traits::set_now(eighth_block_time.to_time_point() - fc::milliseconds(200)); auto ninth_block_time = eosio::chain::block_timestamp_type(production_round_1st_block_slot + 8); - BOOST_CHECK_EQUAL(calculate_block_deadline(cpu_effort_us, eosio::pending_block_mode::producing, ninth_block_time), + BOOST_CHECK_EQUAL(calculate_producing_block_deadline(cpu_effort_us, ninth_block_time), ninth_block_time.to_time_point() - fc::milliseconds(300)); } } +BOOST_AUTO_TEST_CASE(test_calculate_producer_wake_up_time) { + using namespace eosio; + using namespace eosio::chain; + using namespace eosio::chain::literals; + using namespace eosio::block_timing_util; + + producer_watermarks empty_watermarks; + // use full cpu effort for these tests since calculate_producing_block_deadline is tested above + constexpr uint32_t full_cpu_effort = eosio::chain::config::block_interval_us; + +// std::optional calculate_producer_wake_up_time(uint32_t cpu_effort_us, uint32_t block_num, +// const chain::block_timestamp_type& ref_block_time, +// const std::set& producers, +// const std::vector& active_schedule, +// const producer_watermarks& prod_watermarks); + + // no producers + BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, chain::block_timestamp_type{}, {}, {}, empty_watermarks), std::optional{}); + { // producers not in active_schedule + std::set producers{"p1"_n, "p2"_n}; + std::vector active_schedule{{"active1"_n}, {"active2"_n}}; + BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, chain::block_timestamp_type{}, producers, active_schedule, empty_watermarks), std::optional{}); + } + { // Only producer in active_schedule + std::set producers{"p1"_n, "p2"_n}; + std::vector active_schedule{{"p1"_n}}; + const uint32_t prod_round_1st_block_slot = 100 * active_schedule.size() * eosio::chain::config::producer_repetitions - 1; + for (uint32_t i = 0; i < static_cast(config::producer_repetitions * active_schedule.size() * 3); ++i) { // 3 rounds to test boundaries + block_timestamp_type block_timestamp(prod_round_1st_block_slot + i); + auto block_time = block_timestamp.to_time_point(); + BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp, producers, active_schedule, empty_watermarks), block_time); + } + } + { // Only producers in active_schedule + std::set producers{"p1"_n, "p2"_n, "p3"_n}; + std::vector active_schedule{{"p1"_n}, {"p2"_n}}; + const uint32_t prod_round_1st_block_slot = 100 * active_schedule.size() * eosio::chain::config::producer_repetitions - 1; + for (uint32_t i = 0; i < static_cast(config::producer_repetitions * active_schedule.size() * 3); ++i) { // 3 rounds to test boundaries + block_timestamp_type block_timestamp(prod_round_1st_block_slot + i); + auto block_time = block_timestamp.to_time_point(); + BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp, producers, active_schedule, empty_watermarks), block_time); + } + } + { // Only producers in active_schedule 21 + std::set producers = { + "inita"_n, "initb"_n, "initc"_n, "initd"_n, "inite"_n, "initf"_n, "initg"_n, "p1"_n, + "inith"_n, "initi"_n, "initj"_n, "initk"_n, "initl"_n, "initm"_n, "initn"_n, + "inito"_n, "initp"_n, "initq"_n, "initr"_n, "inits"_n, "initt"_n, "initu"_n, "p2"_n + }; + std::vector active_schedule{ + {"inita"_n}, {"initb"_n}, {"initc"_n}, {"initd"_n}, {"inite"_n}, {"initf"_n}, {"initg"_n}, + {"inith"_n}, {"initi"_n}, {"initj"_n}, {"initk"_n}, {"initl"_n}, {"initm"_n}, {"initn"_n}, + {"inito"_n}, {"initp"_n}, {"initq"_n}, {"initr"_n}, {"inits"_n}, {"initt"_n}, {"initu"_n} + }; + const uint32_t prod_round_1st_block_slot = 100 * active_schedule.size() * eosio::chain::config::producer_repetitions - 1; + for (uint32_t i = 0; i < static_cast(config::producer_repetitions * active_schedule.size() * 3); ++i) { // 3 rounds to test boundaries + block_timestamp_type block_timestamp(prod_round_1st_block_slot + i); + auto block_time = block_timestamp.to_time_point(); + BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp, producers, active_schedule, empty_watermarks), block_time); + } + } + { // One of many producers + std::vector active_schedule{ // 21 + {"inita"_n}, {"initb"_n}, {"initc"_n}, {"initd"_n}, {"inite"_n}, {"initf"_n}, {"initg"_n}, + {"inith"_n}, {"initi"_n}, {"initj"_n}, {"initk"_n}, {"initl"_n}, {"initm"_n}, {"initn"_n}, + {"inito"_n}, {"initp"_n}, {"initq"_n}, {"initr"_n}, {"inits"_n}, {"initt"_n}, {"initu"_n} + }; + const uint32_t prod_round_1st_block_slot = 100 * active_schedule.size() * eosio::chain::config::producer_repetitions - 1; // block production time + + // initb is second in the schedule, so it will produce config::producer_repetitions after + std::set producers = { "initb"_n }; + block_timestamp_type block_timestamp(prod_round_1st_block_slot); + auto expected_block_time = block_timestamp_type(prod_round_1st_block_slot + config::producer_repetitions).to_time_point(); + BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp_type{block_timestamp.slot-1}, producers, active_schedule, empty_watermarks), expected_block_time); // same + BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp_type{block_timestamp.slot+config::producer_repetitions-1}, producers, active_schedule, empty_watermarks), expected_block_time); // same + BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp_type{block_timestamp.slot+config::producer_repetitions-2}, producers, active_schedule, empty_watermarks), expected_block_time); // same + BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp_type{block_timestamp.slot+config::producer_repetitions-3}, producers, active_schedule, empty_watermarks), expected_block_time); // same + // current which gives same expected + BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp_type{block_timestamp.slot+config::producer_repetitions}, producers, active_schedule, empty_watermarks), expected_block_time); + expected_block_time += fc::microseconds(config::block_interval_us); + BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp_type{block_timestamp.slot+config::producer_repetitions+1}, producers, active_schedule, empty_watermarks), expected_block_time); + + producers = std::set{ "inita"_n }; + // inita is first in the schedule, prod_round_1st_block_slot is block time of the first block, so will return the next block time as that is when current should be produced + block_timestamp = block_timestamp_type{prod_round_1st_block_slot}; + expected_block_time = block_timestamp.to_time_point(); + BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp_type{block_timestamp.slot-1}, producers, active_schedule, empty_watermarks), expected_block_time); // same + BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp_type{block_timestamp.slot-2}, producers, active_schedule, empty_watermarks), expected_block_time); // same + BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp_type{block_timestamp.slot-3}, producers, active_schedule, empty_watermarks), expected_block_time); // same + for (size_t i = 0; i < config::producer_repetitions; ++i) { + expected_block_time = block_timestamp_type(prod_round_1st_block_slot+i).to_time_point(); + BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp, producers, active_schedule, empty_watermarks), expected_block_time); + block_timestamp = block_timestamp.next(); + } + expected_block_time = block_timestamp.to_time_point(); + BOOST_CHECK_NE(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp, producers, active_schedule, empty_watermarks), expected_block_time); // end of round, so not the next + // initc + producers = std::set{ "initc"_n }; + block_timestamp = block_timestamp_type(prod_round_1st_block_slot); + expected_block_time = block_timestamp_type(prod_round_1st_block_slot + 2*config::producer_repetitions).to_time_point(); + BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp, producers, active_schedule, empty_watermarks), expected_block_time); + } + +} + BOOST_AUTO_TEST_SUITE_END() From 7a3801ada8a56d9672d3b75c913995ceab2d1918 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Sat, 5 Aug 2023 13:20:12 -0500 Subject: [PATCH 46/79] GH-1432 Set _pending_block_deadline according to if we are producing or can produce. --- plugins/producer_plugin/producer_plugin.cpp | 33 ++++++++++++++------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/plugins/producer_plugin/producer_plugin.cpp b/plugins/producer_plugin/producer_plugin.cpp index 0056ace507..ff0be4ec6f 100644 --- a/plugins/producer_plugin/producer_plugin.cpp +++ b/plugins/producer_plugin/producer_plugin.cpp @@ -1884,19 +1884,32 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() { return start_block_result::waiting_for_block; } - _pending_block_deadline = block_timing_util::calculate_block_deadline(_cpu_effort_us, _pending_block_mode, block_time); - auto preprocess_deadline = _pending_block_deadline; - uint32_t production_round_index = block_timestamp_type(block_time).slot % chain::config::producer_repetitions; - if (production_round_index == 0) { - // first block of our round, wait for block production window - const auto start_block_time = block_time.to_time_point() - fc::microseconds(config::block_interval_us); - if (now < start_block_time) { - fc_dlog(_log, "Not starting block until ${bt}", ("bt", start_block_time)); - schedule_delayed_production_loop(weak_from_this(), start_block_time); - return start_block_result::waiting_for_production; + if (in_producing_mode()) { + uint32_t production_round_index = block_timestamp_type(block_time).slot % chain::config::producer_repetitions; + if (production_round_index == 0) { + // first block of our round, wait for block production window + const auto start_block_time = block_time.to_time_point() - fc::microseconds(config::block_interval_us); + if (now < start_block_time) { + fc_dlog(_log, "Not starting block until ${bt}", ("bt", start_block_time)); + schedule_delayed_production_loop(weak_from_this(), start_block_time); + return start_block_result::waiting_for_production; + } } + + _pending_block_deadline = block_timing_util::calculate_producing_block_deadline(_cpu_effort_us, block_time); + } else if (!_producers.empty()) { + // head_block_time because we need to wake up not to produce a block but to start block production + auto wake_time = block_timing_util::calculate_producer_wake_up_time(config::block_interval_us, chain.head_block_num(), chain.head_block_time(), + _producers, chain.head_block_state()->active_schedule.producers, + _producer_watermarks); + + _pending_block_deadline = wake_time ? *wake_time - fc::microseconds(config::block_interval_us) : fc::time_point::maximum(); + } else { + _pending_block_deadline = fc::time_point::maximum(); } + const auto& preprocess_deadline = _pending_block_deadline; + fc_dlog(_log, "Starting block #${n} at ${time} producer ${p}", ("n", pending_block_num)("time", now)("p", scheduled_producer.producer_name)); try { From e2247daa537d267a00c60facaca03c80510ddcf1 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Mon, 7 Aug 2023 11:11:50 -0500 Subject: [PATCH 47/79] GH-1432 Add additional tests including watermark --- .../test/test_block_timing_util.cpp | 65 ++++++++++++++++--- 1 file changed, 56 insertions(+), 9 deletions(-) diff --git a/plugins/producer_plugin/test/test_block_timing_util.cpp b/plugins/producer_plugin/test/test_block_timing_util.cpp index a6d0f2216d..66a7f273f8 100644 --- a/plugins/producer_plugin/test/test_block_timing_util.cpp +++ b/plugins/producer_plugin/test/test_block_timing_util.cpp @@ -100,15 +100,9 @@ BOOST_AUTO_TEST_CASE(test_calculate_producer_wake_up_time) { using namespace eosio::block_timing_util; producer_watermarks empty_watermarks; - // use full cpu effort for these tests since calculate_producing_block_deadline is tested above + // use full cpu effort for most of these tests since calculate_producing_block_deadline is tested above constexpr uint32_t full_cpu_effort = eosio::chain::config::block_interval_us; -// std::optional calculate_producer_wake_up_time(uint32_t cpu_effort_us, uint32_t block_num, -// const chain::block_timestamp_type& ref_block_time, -// const std::set& producers, -// const std::vector& active_schedule, -// const producer_watermarks& prod_watermarks); - // no producers BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, chain::block_timestamp_type{}, {}, {}, empty_watermarks), std::optional{}); { // producers not in active_schedule @@ -160,7 +154,7 @@ BOOST_AUTO_TEST_CASE(test_calculate_producer_wake_up_time) { {"inith"_n}, {"initi"_n}, {"initj"_n}, {"initk"_n}, {"initl"_n}, {"initm"_n}, {"initn"_n}, {"inito"_n}, {"initp"_n}, {"initq"_n}, {"initr"_n}, {"inits"_n}, {"initt"_n}, {"initu"_n} }; - const uint32_t prod_round_1st_block_slot = 100 * active_schedule.size() * eosio::chain::config::producer_repetitions - 1; // block production time + const uint32_t prod_round_1st_block_slot = 100 * active_schedule.size() * eosio::chain::config::producer_repetitions - 1; // initb is second in the schedule, so it will produce config::producer_repetitions after std::set producers = { "initb"_n }; @@ -175,8 +169,8 @@ BOOST_AUTO_TEST_CASE(test_calculate_producer_wake_up_time) { expected_block_time += fc::microseconds(config::block_interval_us); BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp_type{block_timestamp.slot+config::producer_repetitions+1}, producers, active_schedule, empty_watermarks), expected_block_time); - producers = std::set{ "inita"_n }; // inita is first in the schedule, prod_round_1st_block_slot is block time of the first block, so will return the next block time as that is when current should be produced + producers = std::set{ "inita"_n }; block_timestamp = block_timestamp_type{prod_round_1st_block_slot}; expected_block_time = block_timestamp.to_time_point(); BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp_type{block_timestamp.slot-1}, producers, active_schedule, empty_watermarks), expected_block_time); // same @@ -189,11 +183,64 @@ BOOST_AUTO_TEST_CASE(test_calculate_producer_wake_up_time) { } expected_block_time = block_timestamp.to_time_point(); BOOST_CHECK_NE(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp, producers, active_schedule, empty_watermarks), expected_block_time); // end of round, so not the next + // initc producers = std::set{ "initc"_n }; block_timestamp = block_timestamp_type(prod_round_1st_block_slot); expected_block_time = block_timestamp_type(prod_round_1st_block_slot + 2*config::producer_repetitions).to_time_point(); BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp, producers, active_schedule, empty_watermarks), expected_block_time); + + // inith, initk + producers = std::set{ "inith"_n, "initk"_n }; + block_timestamp = block_timestamp_type(prod_round_1st_block_slot); + expected_block_time = block_timestamp_type(prod_round_1st_block_slot + 7*config::producer_repetitions).to_time_point(); + BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp, producers, active_schedule, empty_watermarks), expected_block_time); + block_timestamp = block_timestamp_type(prod_round_1st_block_slot + 8*config::producer_repetitions); + expected_block_time = block_timestamp_type(prod_round_1st_block_slot + 10*config::producer_repetitions).to_time_point(); + BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp, producers, active_schedule, empty_watermarks), expected_block_time); + + // cpu_effort at 50%, initc + constexpr uint32_t half_cpu_effort = eosio::chain::config::block_interval_us / 2u; + producers = std::set{ "initc"_n }; + block_timestamp = block_timestamp_type(prod_round_1st_block_slot); + expected_block_time = block_timestamp_type(prod_round_1st_block_slot + 2*config::producer_repetitions).to_time_point(); + // first in round is not affected by cpu effort + BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(half_cpu_effort, 2, block_timestamp, producers, active_schedule, empty_watermarks), expected_block_time); + block_timestamp = block_timestamp_type(prod_round_1st_block_slot + 2*config::producer_repetitions + 1); + // second in round is 50% sooner + expected_block_time = block_timestamp.to_time_point(); + expected_block_time -= fc::microseconds(half_cpu_effort); + BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(half_cpu_effort, 2, block_timestamp, producers, active_schedule, empty_watermarks), expected_block_time); + // third in round is 2*50% sooner + block_timestamp = block_timestamp_type(prod_round_1st_block_slot + 2*config::producer_repetitions + 2); + // second in round is 50% sooner + expected_block_time = block_timestamp.to_time_point(); + expected_block_time -= fc::microseconds(2*half_cpu_effort); + BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(half_cpu_effort, 2, block_timestamp, producers, active_schedule, empty_watermarks), expected_block_time); + } + { // test watermark + std::vector active_schedule{ // 21 + {"inita"_n}, {"initb"_n}, {"initc"_n}, {"initd"_n}, {"inite"_n}, {"initf"_n}, {"initg"_n}, + {"inith"_n}, {"initi"_n}, {"initj"_n}, {"initk"_n}, {"initl"_n}, {"initm"_n}, {"initn"_n}, + {"inito"_n}, {"initp"_n}, {"initq"_n}, {"initr"_n}, {"inits"_n}, {"initt"_n}, {"initu"_n} + }; + const uint32_t prod_round_1st_block_slot = 100 * active_schedule.size() * eosio::chain::config::producer_repetitions - 1; // block production time + + producer_watermarks prod_watermarks; + std::set producers; + block_timestamp_type block_timestamp(prod_round_1st_block_slot); + // initc + producers = std::set{ "initc"_n }; + auto expected_block_time = block_timestamp_type(prod_round_1st_block_slot + 2*config::producer_repetitions).to_time_point(); // without watermark + BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp, producers, active_schedule, empty_watermarks), expected_block_time); + // watermark at first block + prod_watermarks.consider_new_watermark("initc"_n, 2, block_timestamp_type((prod_round_1st_block_slot + 2*config::producer_repetitions + 1))); // +1 since watermark is in block production time + expected_block_time = block_timestamp_type(prod_round_1st_block_slot + 2*config::producer_repetitions + 1).to_time_point(); // with watermark, wait until next + BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp, producers, active_schedule, prod_watermarks), expected_block_time); + // watermark at first 2 blocks + prod_watermarks.consider_new_watermark("initc"_n, 2, block_timestamp_type((prod_round_1st_block_slot + 2*config::producer_repetitions + 1 + 1))); + expected_block_time = block_timestamp_type(prod_round_1st_block_slot + 2*config::producer_repetitions + 2).to_time_point(); // with watermark, wait until next + BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp, producers, active_schedule, prod_watermarks), expected_block_time); } } From 6dcb96ebd354f3e57245cff431686ec0b0339e32 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Mon, 7 Aug 2023 11:12:36 -0500 Subject: [PATCH 48/79] GH-1432 Wake up time is start block time already. --- plugins/producer_plugin/producer_plugin.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/producer_plugin/producer_plugin.cpp b/plugins/producer_plugin/producer_plugin.cpp index ff0be4ec6f..9167d30bda 100644 --- a/plugins/producer_plugin/producer_plugin.cpp +++ b/plugins/producer_plugin/producer_plugin.cpp @@ -1898,12 +1898,11 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() { _pending_block_deadline = block_timing_util::calculate_producing_block_deadline(_cpu_effort_us, block_time); } else if (!_producers.empty()) { - // head_block_time because we need to wake up not to produce a block but to start block production + // cpu effort percent doesn't matter for the first block of the round, use max (block_interval_us) for cpu effort auto wake_time = block_timing_util::calculate_producer_wake_up_time(config::block_interval_us, chain.head_block_num(), chain.head_block_time(), _producers, chain.head_block_state()->active_schedule.producers, _producer_watermarks); - - _pending_block_deadline = wake_time ? *wake_time - fc::microseconds(config::block_interval_us) : fc::time_point::maximum(); + _pending_block_deadline = wake_time ? *wake_time : fc::time_point::maximum(); } else { _pending_block_deadline = fc::time_point::maximum(); } From 7c8ebe474e1301423545f34a772d0aebcd8f2511 Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Tue, 8 Aug 2023 16:07:45 -0500 Subject: [PATCH 49/79] Support IPv6 addresses. Add support for node info overlay showing all identifying information. Add missing reversed attribute for focus in some peer list columns. --- .../include/eosio/net_plugin/net_plugin.hpp | 2 +- plugins/net_plugin/net_plugin.cpp | 48 ++++---- plugins/prometheus_plugin/metrics.hpp | 9 +- programs/net-util/net-util.py | 114 +++++++++++++----- 4 files changed, 119 insertions(+), 54 deletions(-) diff --git a/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp b/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp index af86a32026..95c64c1b50 100644 --- a/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp +++ b/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp @@ -74,7 +74,7 @@ namespace eosio { {} p2p_per_connection_metrics(const p2p_per_connection_metrics&) = delete; p2p_per_connection_metrics& operator=(const p2p_per_connection_metrics&) = delete; - std::vector addresses; + std::vector addresses; std::vector ports; std::vector accepting_blocks; std::vector last_received_blocks; diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index 99cf478ef2..d4cdf2c7bd 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -850,8 +850,7 @@ namespace eosio { string log_remote_endpoint_port; string local_endpoint_ip; string local_endpoint_port; - bool remote_endpoint_ipv4{false}; - uint32_t remote_endpoint_ip_integer{0}; + boost::asio::ip::address_v6::bytes_type remote_endpoint_ip_array; uint32_t remote_endpoint_port{0}; // kept in sync with last_handshake_recv.last_irreversible_block_num, only accessed from connection strand uint32_t peer_lib_num = 0; @@ -1203,8 +1202,17 @@ namespace eosio { boost::system::error_code ec2; auto rep = socket->remote_endpoint(ec); auto lep = socket->local_endpoint(ec2); - remote_endpoint_ipv4 = ec ? false : rep.address().is_v4(); - remote_endpoint_ip_integer = remote_endpoint_ipv4 ? rep.address().to_v4().to_uint() : 0; + if(!ec) { + if(rep.address().is_v4()) { + remote_endpoint_ip_array = make_address_v6(boost::asio::ip::v4_mapped, rep.address().to_v4()).to_bytes(); + } + else { + remote_endpoint_ip_array = rep.address().to_v6().to_bytes(); + } + } + else { + remote_endpoint_ip_array = boost::asio::ip::address_v6().to_bytes(); + } remote_endpoint_port = ec ? 0 : rep.port(); log_remote_endpoint_ip = ec ? unknown : rep.address().to_string(); log_remote_endpoint_port = ec ? unknown : std::to_string(rep.port()); @@ -4449,24 +4457,20 @@ namespace eosio { } else { ++num_peers; } - if((*it)->remote_endpoint_ipv4) { - per_connection.addresses.push_back((*it)->remote_endpoint_ip_integer); - per_connection.ports.push_back((*it)->remote_endpoint_port); - per_connection.accepting_blocks.push_back((*it)->is_blocks_connection()); - per_connection.last_received_blocks.push_back((*it)->get_last_received_blk_num()); - per_connection.first_available_blocks.push_back((*it)->get_peer_start_block_num()); - per_connection.last_available_blocks.push_back((*it)->get_peer_head_block_num()); - per_connection.bytes_received.push_back((*it)->get_bytes_received()); - per_connection.last_bytes_received.push_back((*it)->get_last_bytes_received()); - per_connection.bytes_sent.push_back((*it)->get_bytes_sent()); - per_connection.last_bytes_sent.push_back((*it)->get_last_bytes_sent()); - per_connection.connection_start_times.push_back((*it)->connection_time); - per_connection.unique_first_block_counts.push_back((*it)->get_unique_blocks_rcvd_count()); - per_connection.latencies.push_back((*it)->get_peer_ping_time_ns()); - per_connection.log_p2p_addresses.push_back((*it)->log_p2p_address); - } - else - fc_wlog(logger, "socket remote endpoint is not IPv4"); + per_connection.addresses.push_back((*it)->remote_endpoint_ip_array); + per_connection.ports.push_back((*it)->remote_endpoint_port); + per_connection.accepting_blocks.push_back((*it)->is_blocks_connection()); + per_connection.last_received_blocks.push_back((*it)->get_last_received_blk_num()); + per_connection.first_available_blocks.push_back((*it)->get_peer_start_block_num()); + per_connection.last_available_blocks.push_back((*it)->get_peer_head_block_num()); + per_connection.bytes_received.push_back((*it)->get_bytes_received()); + per_connection.last_bytes_received.push_back((*it)->get_last_bytes_received()); + per_connection.bytes_sent.push_back((*it)->get_bytes_sent()); + per_connection.last_bytes_sent.push_back((*it)->get_last_bytes_sent()); + per_connection.connection_start_times.push_back((*it)->connection_time); + per_connection.unique_first_block_counts.push_back((*it)->get_unique_blocks_rcvd_count()); + per_connection.latencies.push_back((*it)->get_peer_ping_time_ns()); + per_connection.log_p2p_addresses.push_back((*it)->log_p2p_address); if (!(*it)->socket_is_open() && (*it)->state() != connection::connection_state::connecting) { if (!(*it)->incoming()) { diff --git a/plugins/prometheus_plugin/metrics.hpp b/plugins/prometheus_plugin/metrics.hpp index 706747f63f..cd6a6fd942 100644 --- a/plugins/prometheus_plugin/metrics.hpp +++ b/plugins/prometheus_plugin/metrics.hpp @@ -136,10 +136,11 @@ struct catalog_type { num_peers.Set(metrics.num_peers); num_clients.Set(metrics.num_clients); for(size_t i = 0; i < metrics.stats.addresses.size(); ++i) { - auto addr = boost::asio::ip::address_v4(metrics.stats.addresses[i]).to_string(); - std::replace(addr.begin(), addr.end(), '.', '_'); - addr.insert(0, 1, '_'); - addr.append("__"); + auto addr = boost::asio::ip::make_address_v6(metrics.stats.addresses[i]).to_string(); + boost::replace_all(addr, ":", "_COLON_"); + boost::replace_all(addr, ".", "_DOT_"); + addr.insert(0, "ip_"); + addr.append("_"); addr.append(to_string(metrics.stats.ports[i])); addresses.push_back(addr); auto& accepting_blocks = p2p_connections.Add({{addr, "accepting_blocks"}}); diff --git a/programs/net-util/net-util.py b/programs/net-util/net-util.py index 90fd84f59a..fa050162c9 100755 --- a/programs/net-util/net-util.py +++ b/programs/net-util/net-util.py @@ -2,6 +2,7 @@ import argparse import datetime +import ipaddress import logging import pathlib import requests @@ -82,13 +83,21 @@ def humanReadableBytesPerSecond(bytes: int, telco:bool = False): class TextSimpleFocusListWalker(urwid.SimpleFocusListWalker): def __contains__(self, text): for element in self: - if text == element.text: + if type(element) is urwid.AttrMap: + val = element.original_widget.text + else: + val = element.text + if text == val: return True return False def index(self, text): '''Emulation of list index() method unfortunately much slower than the real thing but our lists are short''' for i, e in enumerate(self): - if e.text == text: + if type(e) is urwid.AttrMap: + val = e.original_widget.text + else: + val = e.text + if val == text: return i @@ -122,7 +131,11 @@ def readMetrics(host: str, port: str): class netUtil: def __init__(self): self.prometheusMetrics = { - ('nodeos_info', 'server_version_string'): 'Nodeos Vers:', + ('nodeos_info', 'server_version'): 'Nodeos Version ID:', + ('nodeos_info', 'chain_id'): 'Chain ID:', + ('nodeos_info', 'server_version_string'): 'Nodeos Version:', + ('nodeos_info', 'server_full_version_string'): 'Nodeos Full Version:', + ('nodeos_info', 'earliest_available_block_num'): 'Earliest Available Block:', 'nodeos_head_block_num': 'Head Block Num:', 'nodeos_last_irreversible': 'LIB:', ('nodeos_p2p_connections','in'): 'Inbound P2P Connections:', @@ -157,7 +170,7 @@ def __init__(self): 'HTTP Requests:', ] self.rightFieldLabels = [ - 'Nodeos Vers:', + 'Nodeos Version:', 'LIB:', 'Outbound P2P Connections:', 'Total Incoming Trxs:', @@ -176,6 +189,12 @@ def __init__(self): 'last_bytes_received': lambda x: str(datetime.timedelta(microseconds=(time.time_ns() - int(x))/1000)), 'last_bytes_sent': lambda x: str(datetime.timedelta(microseconds=(time.time_ns() - int(x))/1000)), } + self.infoFieldLabels = [ + 'Nodeos Version ID:', + 'Chain ID:', + 'Nodeos Full Version:', + 'Earliest Available Block:', + ] self.peerColumns = [ ('\n\nIP Address', 'ipAddressLW'), ('\n\nHostname', 'hostnameLW'), @@ -190,9 +209,12 @@ def __init__(self): ('Last\nAvail\nBlk', 'lastAvailableBlockLW'), ('\nAcpt\nBlks', 'acceptingBlocksLW') ] - self.fields = {k:v for k, v in zip(self.leftFieldLabels, [e[:1].lower() + e[1:-1].replace(' ', '') + 'Text' for e in self.leftFieldLabels])} - self.fields.update({self.rightFieldLabels[0]: self.rightFieldLabels[0][:1].lower() + self.rightFieldLabels[0][1:-1].replace(' ', '') + 'Button'}) - self.fields.update({k:v for k, v in zip(self.rightFieldLabels[1:], [e[:1].lower() + e[1:-1].replace(' ', '') + 'Text' for e in self.rightFieldLabels[1:]])}) + def labelToAttrName(label: str, fieldType='Text'): + return label[:1].lower() + label[1:-1].replace(' ', '') + fieldType + self.fields = {k:v for k, v in zip(self.leftFieldLabels, [labelToAttrName(e) for e in self.leftFieldLabels])} + self.fields.update({self.rightFieldLabels[0]: labelToAttrName(self.rightFieldLabels[0], 'Button')}) + self.fields.update({k:v for k, v in zip(self.rightFieldLabels[1:], [labelToAttrName(e) for e in self.rightFieldLabels[1:]])}) + self.fields.update({k:v for k, v in zip(self.infoFieldLabels, [labelToAttrName(e) for e in self.infoFieldLabels])}) parser = argparse.ArgumentParser(description='Terminal UI for monitoring and managing nodeos P2P connections', formatter_class=argparse.ArgumentDefaultsHelpFormatter) @@ -202,7 +224,26 @@ def __init__(self): parser.add_argument('--log-level', choices=[logging._nameToLevel.keys()] + [k.lower() for k in logging._nameToLevel.keys()], help='Logging level', default='debug') self.args = parser.parse_args() - def createUrwidUI(self): + @staticmethod + def unmanglePrometheusHostLabel(hostLabel: str) -> (ipaddress.ip_address, str): + '''Remove mangling required to fit an IPv6 address and port into a Prometheus label. + + Prometheus labels may contain only underscore and alphanumeric characters and must begin with + an alphabetic character. This method unmangles according to the following table: + 'ip_' prefix removed + '_DOT_' -> '.' + '_COLON_' -> ':' + + @hostLabel - Prometheus label to convert + + @returns - instance of 'ip_address', string representation of port number + ''' + host = hostLabel[len('ip_'):].replace('_DOT_', '.').replace('_COLON_', ':') + addr = ipaddress.ip_address(host[:host.rfind('_')]) + port = host[host.rfind('_')+1:] + return addr, port + + def createUrwidUI(self, mainLoop): AttrMap = urwid.AttrMap Button = urwid.Button LineBox = urwid.LineBox @@ -223,9 +264,9 @@ def packLabeledText(labelTxt: str, defaultValue=''): minwidth = max([len(x) for x in self.leftFieldLabels + self.rightFieldLabels]) return Columns([(minwidth, Filler(label, valign='top')), Filler(text, valign='top')], 1) - def packLabeledButton(labelTxt: str, defaultValue='', callback: callable = None): + def packLabeledButton(labelTxt: str, defaultValue='', callback: callable=None, userData=None): label = Text(('bold', labelTxt), align='right') - button = AttrMap(Button(defaultValue, callback), None, focus_map='reversed') + button = AttrMap(Button(defaultValue, callback, userData), None, focus_map='reversed') attrName = labelTxt[:1].lower() + labelTxt[1:-1].replace(' ', '') + 'Button' if labelTxt else '' if attrName: setattr(self, attrName, button) @@ -235,7 +276,7 @@ def packLabeledButton(labelTxt: str, defaultValue='', callback: callable = None) # At least one child of a Pile must have weight 1 or the app will crash on mouse click in the Pile. leftColumn = Pile([(1, widget) for widget in widgets[:-1]] + [('weight', 1, widgets[-1])]) - widgets = [packLabeledButton(self.rightFieldLabels[0], callback=self.onVersionClick)] + widgets = [packLabeledButton(self.rightFieldLabels[0], callback=self.onVersionClick, userData=mainLoop)] widgets.extend([packLabeledText(labelTxt) for labelTxt in self.rightFieldLabels[1:]]) widgets.insert(3, Filler(Divider())) rightColumn = Pile([(1, widget) for widget in widgets[:-1]] + [('weight', 1, widgets[-1])]) @@ -268,15 +309,27 @@ def focus_changed(new_focus): self.mainView = Pile([Columns([leftColumn, rightColumn]), ('weight', 4, self.peerLineBox)]) - self.errorText = Text(('error', '')) - self.errorBox = LineBox(Filler(self.errorText), 'Error:', 'left', 'error') - self.errorOverlay = urwid.Overlay(self.errorBox, self.mainView, 'center', ('relative', 80), 'middle', ('relative', 80), min_width=24, min_height=8) + self.errorText = Text('') + self.errorBox = LineBox(Pile([('weight', 4, Filler(self.errorText, 'top', 'flow')), Padding(Filler(Divider('\u2500'))), Filler(Padding(Button(('reversed', 'Close'), self.onDismissOverlay, mainLoop), 'center', len('< Close >')))]), 'Error:', 'left', 'error') + self.errorOverlay = urwid.Overlay(self.errorBox, self.mainView, 'center', ('relative', 80), + 'middle', ('relative', 80), min_width=24, min_height=8) + + widgets = [packLabeledText(labelTxt) for labelTxt in self.infoFieldLabels] + widgets.append(Filler(Divider('\u2500'))) + widgets.append(Padding(Button(('reversed', 'Close'), self.onDismissOverlay, mainLoop), 'center', len('< Close >'))) + infoColumn = Filler(Pile([(1, widget) for widget in widgets[:-1]] + [('weight', 1, widgets[-1])])) + self.infoBox = LineBox(infoColumn, 'Server Information:', 'left') + self.infoOverlay = urwid.Overlay(self.infoBox, self.mainView, 'center', ('relative', 50), + 'middle', ('relative', 25), min_width=28, min_height=8) return self.mainView - def onVersionClick(self, button): - logger.info('Button clicked') + def onVersionClick(self, button, mainLoop): + mainLoop.widget = self.infoOverlay + + def onDismissOverlay(self, button, mainLoop): + mainLoop.widget = self.mainView def update(self, mainLoop, userData=None): AttrMap = urwid.AttrMap @@ -284,19 +337,19 @@ def update(self, mainLoop, userData=None): try: self.hostText.set_text(f'{self.args.host}:{self.args.port}') response = readMetrics(self.args.host, self.args.port) - except requests.ConnectionError as e: + except (requests.ConnectionError, requests.ReadTimeout) as e: logger.error(str(e)) self.errorText.set_text(str(e)) mainLoop.widget = self.errorOverlay else: self.errorText.set_text('') - mainLoop.widget = self.mainView + if mainLoop.widget is self.errorOverlay: + mainLoop.widget = self.mainView class bandwidthStats(): def __init__(self, bytesReceived=0, bytesSent=0, connectionStarted=0): self.bytesReceived = 0 self.bytesSent = 0 self.connectionStarted = 0 - mainLoop.widget.contents[-1][0].original_widget = self.errorText for family in text_string_to_metric_families(response.text): bandwidths = {} for sample in family.samples: @@ -312,11 +365,12 @@ def __init__(self, bytesReceived=0, bytesSent=0, connectionStarted=0): else: hostLabel = next(iter(sample.labels)) fieldName = sample.labels[hostLabel] - host = hostLabel[1:].replace('__', ':').replace('_', '.') + addr, port = self.unmanglePrometheusHostLabel(hostLabel) + host = f'{str(addr.ipv4_mapped) if addr.ipv4_mapped else str(addr)}:{port}' listwalker = getattr(self, 'ipAddressLW') if host not in listwalker: startOffset = endOffset = len(listwalker) - listwalker.append(Text(host)) + listwalker.append(AttrMap(Text(host), None, 'reversed')) else: startOffset = listwalker.index(host) endOffset = startOffset + 1 @@ -344,9 +398,13 @@ def __init__(self, bytesReceived=0, bytesSent=0, connectionStarted=0): listwalker = getattr(self, 'hostnameLW') listwalker[startOffset:endOffset] = [AttrMap(Text(fieldName.replace('_', '.')), None, 'reversed')] elif sample.name == 'nodeos_info': - fieldName = self.fields.get(self.prometheusMetrics[(sample.name, 'server_version_string')]) - field = getattr(self, fieldName) - field.original_widget.set_label(sample.labels['server_version_string']) + for infoLabel, infoValue in sample.labels.items(): + fieldName = self.fields.get(self.prometheusMetrics[(sample.name, infoLabel)]) + field = getattr(self, fieldName) + if type(field) is AttrMap: + field.original_widget.set_label(infoValue) + else: + field.set_text(infoValue) else: if sample.name not in self.ignoredPrometheusMetrics: logger.warning(f'Received unhandled Prometheus metric {sample.name}') @@ -360,10 +418,10 @@ def __init__(self, bytesReceived=0, bytesSent=0, connectionStarted=0): connected_seconds = (now - stats.connectionStarted)/1000000000 listwalker = getattr(self, 'receiveBandwidthLW') bps = stats.bytesReceived/connected_seconds - listwalker[startOffset:endOffset] = [Text(humanReadableBytesPerSecond(bps))] + listwalker[startOffset:endOffset] = [AttrMap(Text(humanReadableBytesPerSecond(bps)), None, 'reversed')] listwalker = getattr(self, 'sendBandwidthLW') bps = stats.bytesSent/connected_seconds - listwalker[startOffset:endOffset] = [Text(humanReadableBytesPerSecond(bps))] + listwalker[startOffset:endOffset] = [AttrMap(Text(humanReadableBytesPerSecond(bps)), None, 'reversed')] mainLoop.set_alarm_in(float(self.args.refresh_interval), self.update) def exitOnQ(key): @@ -383,6 +441,8 @@ def exitOnQ(key): ('dim', 'dark gray', 'default'), ('reversed', 'standout', ''), ] - loop = urwid.MainLoop(inst.createUrwidUI(), palette, screen=urwid.curses_display.Screen(), unhandled_input=exitOnQ, event_loop=None, pop_ups=True) + loop = urwid.MainLoop(urwid.Divider(), palette, screen=urwid.curses_display.Screen(), unhandled_input=exitOnQ, event_loop=None, pop_ups=True) + ui = inst.createUrwidUI(loop) + loop.widget = ui inst.update(loop) loop.run() From fb00ebc013fbd1959a6673374e56628636e98c76 Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Wed, 9 Aug 2023 18:46:53 -0500 Subject: [PATCH 50/79] Convert peer metrics from struct of vectors to vector of structs. --- .../include/eosio/net_plugin/net_plugin.hpp | 63 ++++++------------- plugins/net_plugin/net_plugin.cpp | 33 +++++----- plugins/prometheus_plugin/metrics.hpp | 62 +++++++----------- 3 files changed, 61 insertions(+), 97 deletions(-) diff --git a/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp b/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp index 95c64c1b50..48b234e34e 100644 --- a/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp +++ b/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp @@ -40,54 +40,31 @@ namespace eosio { vector connections()const; struct p2p_per_connection_metrics { + struct connection_metric { + boost::asio::ip::address_v6::bytes_type address; + unsigned short port; + bool accepting_blocks; + uint32_t last_received_block; + uint32_t first_available_block; + uint32_t last_available_block; + size_t unique_first_block_count; + uint64_t latency; + size_t bytes_received; + time_t last_bytes_received; + size_t bytes_sent; + time_t last_bytes_sent; + std::chrono::nanoseconds connection_start_time; + std::string log_p2p_address; + }; explicit p2p_per_connection_metrics(size_t count) { - addresses.reserve(count); - ports.reserve(count); - accepting_blocks.reserve(count); - last_received_blocks.reserve(count); - first_available_blocks.reserve(count); - last_available_blocks.reserve(count); - unique_first_block_counts.reserve(count); - latencies.reserve(count); - bytes_received.reserve(count); - last_bytes_received.reserve(count); - bytes_sent.reserve(count); - last_bytes_sent.reserve(count); - connection_start_times.reserve(count); - log_p2p_addresses.reserve(count); + peers.reserve(count); } - p2p_per_connection_metrics(p2p_per_connection_metrics&& metrics) - : addresses{std::move(metrics.addresses)} - , ports{std::move(metrics.ports)} - , accepting_blocks{std::move(metrics.accepting_blocks)} - , last_received_blocks{std::move(metrics.last_received_blocks)} - , first_available_blocks{std::move(metrics.first_available_blocks)} - , last_available_blocks{std::move(metrics.last_available_blocks)} - , unique_first_block_counts{std::move(metrics.unique_first_block_counts)} - , latencies{std::move(metrics.latencies)} - , bytes_received{std::move(metrics.bytes_received)} - , last_bytes_received(std::move(metrics.last_bytes_received)) - , bytes_sent{std::move(metrics.bytes_sent)} - , last_bytes_sent(std::move(metrics.last_bytes_sent)) - , connection_start_times{std::move(metrics.connection_start_times)} - , log_p2p_addresses{std::move(metrics.log_p2p_addresses)} + p2p_per_connection_metrics(p2p_per_connection_metrics&& other) + : peers{std::move(other.peers)} {} p2p_per_connection_metrics(const p2p_per_connection_metrics&) = delete; p2p_per_connection_metrics& operator=(const p2p_per_connection_metrics&) = delete; - std::vector addresses; - std::vector ports; - std::vector accepting_blocks; - std::vector last_received_blocks; - std::vector first_available_blocks; - std::vector last_available_blocks; - std::vector unique_first_block_counts; - std::vector latencies; - std::vector bytes_received; - std::vector last_bytes_received; - std::vector bytes_sent; - std::vector last_bytes_sent; - std::vector connection_start_times; - std::vector log_p2p_addresses; + std::vector peers; }; struct p2p_connections_metrics { p2p_connections_metrics(std::size_t peers, std::size_t clients, p2p_per_connection_metrics&& statistics) diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index d4cdf2c7bd..23ea72f62a 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -851,7 +851,7 @@ namespace eosio { string local_endpoint_ip; string local_endpoint_port; boost::asio::ip::address_v6::bytes_type remote_endpoint_ip_array; - uint32_t remote_endpoint_port{0}; + boost::asio::ip::port_type remote_endpoint_port{0}; // kept in sync with last_handshake_recv.last_irreversible_block_num, only accessed from connection strand uint32_t peer_lib_num = 0; @@ -4457,20 +4457,23 @@ namespace eosio { } else { ++num_peers; } - per_connection.addresses.push_back((*it)->remote_endpoint_ip_array); - per_connection.ports.push_back((*it)->remote_endpoint_port); - per_connection.accepting_blocks.push_back((*it)->is_blocks_connection()); - per_connection.last_received_blocks.push_back((*it)->get_last_received_blk_num()); - per_connection.first_available_blocks.push_back((*it)->get_peer_start_block_num()); - per_connection.last_available_blocks.push_back((*it)->get_peer_head_block_num()); - per_connection.bytes_received.push_back((*it)->get_bytes_received()); - per_connection.last_bytes_received.push_back((*it)->get_last_bytes_received()); - per_connection.bytes_sent.push_back((*it)->get_bytes_sent()); - per_connection.last_bytes_sent.push_back((*it)->get_last_bytes_sent()); - per_connection.connection_start_times.push_back((*it)->connection_time); - per_connection.unique_first_block_counts.push_back((*it)->get_unique_blocks_rcvd_count()); - per_connection.latencies.push_back((*it)->get_peer_ping_time_ns()); - per_connection.log_p2p_addresses.push_back((*it)->log_p2p_address); + net_plugin::p2p_per_connection_metrics::connection_metric metrics{ + .address = (*it)->remote_endpoint_ip_array + , .port = (*it)->remote_endpoint_port + , .accepting_blocks = (*it)->is_blocks_connection() + , .last_received_block = (*it)->get_last_received_blk_num() + , .first_available_block = (*it)->get_peer_start_block_num() + , .last_available_block = (*it)->get_peer_head_block_num() + , .unique_first_block_count = (*it)->get_unique_blocks_rcvd_count() + , .latency = (*it)->get_peer_ping_time_ns() + , .bytes_received = (*it)->get_bytes_received() + , .last_bytes_received = (*it)->get_last_bytes_received() + , .bytes_sent = (*it)->get_bytes_sent() + , .last_bytes_sent = (*it)->get_last_bytes_sent() + , .connection_start_time = (*it)->connection_time + , .log_p2p_address = (*it)->log_p2p_address + }; + per_connection.peers.push_back(metrics); if (!(*it)->socket_is_open() && (*it)->state() != connection::connection_state::connecting) { if (!(*it)->incoming()) { diff --git a/plugins/prometheus_plugin/metrics.hpp b/plugins/prometheus_plugin/metrics.hpp index cd6a6fd942..f613dea545 100644 --- a/plugins/prometheus_plugin/metrics.hpp +++ b/plugins/prometheus_plugin/metrics.hpp @@ -135,50 +135,34 @@ struct catalog_type { void update(const net_plugin::p2p_connections_metrics& metrics) { num_peers.Set(metrics.num_peers); num_clients.Set(metrics.num_clients); - for(size_t i = 0; i < metrics.stats.addresses.size(); ++i) { - auto addr = boost::asio::ip::make_address_v6(metrics.stats.addresses[i]).to_string(); + for(size_t i = 0; i < metrics.stats.peers.size(); ++i) { + auto addr = boost::asio::ip::make_address_v6(metrics.stats.peers[i].address).to_string(); boost::replace_all(addr, ":", "_COLON_"); boost::replace_all(addr, ".", "_DOT_"); addr.insert(0, "ip_"); addr.append("_"); - addr.append(to_string(metrics.stats.ports[i])); + addr.append(to_string(metrics.stats.peers[i].port)); addresses.push_back(addr); - auto& accepting_blocks = p2p_connections.Add({{addr, "accepting_blocks"}}); - accepting_blocks.Set(metrics.stats.accepting_blocks[i]); - accepting_blocks_gauges.push_back(accepting_blocks); - auto& last_received_block = p2p_connections.Add({{addr, "last_received_block"}}); - last_received_block.Set(metrics.stats.last_received_blocks[i]); - last_received_blocks_gauges.push_back(last_received_block); - auto& first_available_block = p2p_connections.Add({{addr, "first_available_block"}}); - first_available_block.Set(metrics.stats.first_available_blocks[i]); - first_available_blocks_gauges.push_back(first_available_block); - auto& last_available_block = p2p_connections.Add({{addr, "last_available_block"}}); - last_available_block.Set(metrics.stats.last_available_blocks[i]); - last_available_blocks_gauges.push_back(last_available_block); - auto& unique_first_block_count = p2p_connections.Add({{addr, "unique_first_block_count"}}); - unique_first_block_count.Set(metrics.stats.unique_first_block_counts[i]); - unique_first_block_counts_gauges.push_back(unique_first_block_count); - auto& latency = p2p_connections.Add({{addr, "latency"}}); - latency.Set(metrics.stats.latencies[i]); - latency_gauges.push_back(latency); - auto& bytes_received = p2p_connections.Add({{addr, "bytes_received"}}); - bytes_received.Set(metrics.stats.bytes_received[i]); - bytes_received_gauges.push_back(bytes_received); - auto& last_bytes_received = p2p_connections.Add({{addr, "last_bytes_received"}}); - last_bytes_received.Set(metrics.stats.last_bytes_received[i]); - last_bytes_received_gauges.push_back(last_bytes_received); - auto& bytes_sent = p2p_connections.Add({{addr, "bytes_sent"}}); - bytes_sent.Set(metrics.stats.bytes_sent[i]); - bytes_sent_gauges.push_back(bytes_sent); - auto& last_bytes_sent = p2p_connections.Add({{addr, "last_bytes_sent"}}); - last_bytes_sent.Set(metrics.stats.last_bytes_sent[i]); - last_bytes_sent_gauges.push_back(last_bytes_sent); - auto& connection_start_time = p2p_connections.Add({{addr, "connection_start_time"}}); - connection_start_time.Set(metrics.stats.connection_start_times[i].count()); - connection_start_time_gauges.push_back(connection_start_time); - auto& log_p2p_address = p2p_connections.Add({{addr, metrics.stats.log_p2p_addresses[i]}}); - log_p2p_address.Set(0); // Empty gauge; we only want the label - log_p2p_address_gauges.push_back(log_p2p_address); + auto add_and_set_gauge = [&](std::string label_value, + std::vector>& gauges, + auto value) { + auto& gauge = p2p_connections.Add({{addr, label_value}}); + gauge.Set(value); + gauges.push_back(gauge); + }; + auto& peer = metrics.stats.peers[i]; + add_and_set_gauge("accepting_blocks", accepting_blocks_gauges, peer.accepting_blocks); + add_and_set_gauge("last_received_block", last_received_blocks_gauges, peer.last_received_block); + add_and_set_gauge("first_available_block", first_available_blocks_gauges, peer.first_available_block); + add_and_set_gauge("last_available_block", last_available_blocks_gauges, peer.last_available_block); + add_and_set_gauge("unique_first_block_count", unique_first_block_counts_gauges, peer.unique_first_block_count); + add_and_set_gauge("latency", latency_gauges, peer.latency); + add_and_set_gauge("bytes_received", bytes_received_gauges, peer.bytes_received); + add_and_set_gauge("last_bytes_received", last_bytes_received_gauges, peer.last_bytes_received); + add_and_set_gauge("bytes_sent", bytes_sent_gauges, peer.bytes_sent); + add_and_set_gauge("last_bytes_sent", last_bytes_sent_gauges, peer.last_bytes_sent); + add_and_set_gauge("connection_start_time", connection_start_time_gauges, peer.connection_start_time.count()); + add_and_set_gauge(peer.log_p2p_address, log_p2p_address_gauges, 0); // Empty gauge; we only want the label } } From 98e1e3997409d6bd6d2db40113f6b20db0dba130 Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Thu, 10 Aug 2023 14:56:55 -0500 Subject: [PATCH 51/79] Default initialization and const correctness. --- .../include/eosio/net_plugin/net_plugin.hpp | 24 +++++++++---------- plugins/prometheus_plugin/metrics.hpp | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp b/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp index 48b234e34e..d9f68ffe7f 100644 --- a/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp +++ b/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp @@ -42,18 +42,18 @@ namespace eosio { struct p2p_per_connection_metrics { struct connection_metric { boost::asio::ip::address_v6::bytes_type address; - unsigned short port; - bool accepting_blocks; - uint32_t last_received_block; - uint32_t first_available_block; - uint32_t last_available_block; - size_t unique_first_block_count; - uint64_t latency; - size_t bytes_received; - time_t last_bytes_received; - size_t bytes_sent; - time_t last_bytes_sent; - std::chrono::nanoseconds connection_start_time; + unsigned short port{0}; + bool accepting_blocks{false}; + uint32_t last_received_block{0}; + uint32_t first_available_block{0}; + uint32_t last_available_block{0}; + size_t unique_first_block_count{0}; + uint64_t latency{0}; + size_t bytes_received{0}; + time_t last_bytes_received{0}; + size_t bytes_sent{0}; + time_t last_bytes_sent{0}; + std::chrono::nanoseconds connection_start_time{0}; std::string log_p2p_address; }; explicit p2p_per_connection_metrics(size_t count) { diff --git a/plugins/prometheus_plugin/metrics.hpp b/plugins/prometheus_plugin/metrics.hpp index f613dea545..35ffcf7fb9 100644 --- a/plugins/prometheus_plugin/metrics.hpp +++ b/plugins/prometheus_plugin/metrics.hpp @@ -143,9 +143,9 @@ struct catalog_type { addr.append("_"); addr.append(to_string(metrics.stats.peers[i].port)); addresses.push_back(addr); - auto add_and_set_gauge = [&](std::string label_value, + auto add_and_set_gauge = [&](const std::string& label_value, std::vector>& gauges, - auto value) { + const auto& value) { auto& gauge = p2p_connections.Add({{addr, label_value}}); gauge.Set(value); gauges.push_back(gauge); From a90602c34f020ac9b8210e140e5e2fbf56f8a36a Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Thu, 10 Aug 2023 15:59:47 -0400 Subject: [PATCH 52/79] bump bls12-381 submod to main HEAD --- libraries/libfc/libraries/bls12-381 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/libfc/libraries/bls12-381 b/libraries/libfc/libraries/bls12-381 index e8ee0c20dd..a24734c86c 160000 --- a/libraries/libfc/libraries/bls12-381 +++ b/libraries/libfc/libraries/bls12-381 @@ -1 +1 @@ -Subproject commit e8ee0c20ddaa482395a05ea59c7dc0b277051c37 +Subproject commit a24734c86cb61aa4e498181203d1fe054d9e99a0 From 690d12e7ce9b3dcc0c2cdd56242b2f8992797cf6 Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Thu, 10 Aug 2023 15:51:19 -0500 Subject: [PATCH 53/79] Thread safety and collect connection time for inbound connections --- plugins/net_plugin/net_plugin.cpp | 38 +++++++++++++++++-------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index 23ea72f62a..4d2533a32d 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -798,6 +798,7 @@ namespace eosio { time_t get_last_bytes_received() const { return last_bytes_received.load(); } size_t get_bytes_sent() const { return bytes_sent.load(); } time_t get_last_bytes_sent() const { return last_bytes_sent.load(); } + boost::asio::ip::port_type get_remote_endpoint_port() const { return remote_endpoint_port.load(); } void set_heartbeat_timeout(std::chrono::milliseconds msec) { hb_timeout = msec; } @@ -833,6 +834,7 @@ namespace eosio { std::atomic last_bytes_received{0}; std::atomic bytes_sent{0}; std::atomic last_bytes_sent{0}; + std::atomic remote_endpoint_port{0}; public: boost::asio::io_context::strand strand; @@ -850,8 +852,6 @@ namespace eosio { string log_remote_endpoint_port; string local_endpoint_ip; string local_endpoint_port; - boost::asio::ip::address_v6::bytes_type remote_endpoint_ip_array; - boost::asio::ip::port_type remote_endpoint_port{0}; // kept in sync with last_handshake_recv.last_irreversible_block_num, only accessed from connection strand uint32_t peer_lib_num = 0; @@ -891,6 +891,7 @@ namespace eosio { uint32_t fork_head_num GUARDED_BY(conn_mtx) {0}; fc::time_point last_close GUARDED_BY(conn_mtx); string remote_endpoint_ip GUARDED_BY(conn_mtx); + boost::asio::ip::address_v6::bytes_type remote_endpoint_ip_array GUARDED_BY(conn_mtx); std::chrono::nanoseconds connection_time{0}; @@ -961,7 +962,7 @@ namespace eosio { * * There are five calls to this routine in the program. One * when a packet arrives from the network, one when a packet - * is placed on the send queue, one during connect, and + * is placed on the send queue, one during start session, and * one each when data is counted as received or sent. * Calls the kernel time of day routine and converts to * a (at least) 64 bit integer. @@ -1202,6 +1203,13 @@ namespace eosio { boost::system::error_code ec2; auto rep = socket->remote_endpoint(ec); auto lep = socket->local_endpoint(ec2); + remote_endpoint_port = ec ? 0 : rep.port(); + log_remote_endpoint_ip = ec ? unknown : rep.address().to_string(); + log_remote_endpoint_port = ec ? unknown : std::to_string(rep.port()); + local_endpoint_ip = ec2 ? unknown : lep.address().to_string(); + local_endpoint_port = ec2 ? unknown : std::to_string(lep.port()); + fc::lock_guard g_conn( conn_mtx ); + remote_endpoint_ip = log_remote_endpoint_ip; if(!ec) { if(rep.address().is_v4()) { remote_endpoint_ip_array = make_address_v6(boost::asio::ip::v4_mapped, rep.address().to_v4()).to_bytes(); @@ -1213,13 +1221,6 @@ namespace eosio { else { remote_endpoint_ip_array = boost::asio::ip::address_v6().to_bytes(); } - remote_endpoint_port = ec ? 0 : rep.port(); - log_remote_endpoint_ip = ec ? unknown : rep.address().to_string(); - log_remote_endpoint_port = ec ? unknown : std::to_string(rep.port()); - local_endpoint_ip = ec2 ? unknown : lep.address().to_string(); - local_endpoint_port = ec2 ? unknown : std::to_string(lep.port()); - fc::lock_guard g_conn( conn_mtx ); - remote_endpoint_ip = log_remote_endpoint_ip; } // called from connection strand @@ -1266,19 +1267,19 @@ namespace eosio { connection_status connection::get_status()const { connection_status stat; - stat.peer = peer_addr; - stat.remote_ip = log_remote_endpoint_ip; - stat.remote_port = log_remote_endpoint_port; stat.connecting = state() == connection_state::connecting; stat.syncing = peer_syncing_from_us; stat.is_bp_peer = is_bp_connection; stat.is_socket_open = socket_is_open(); fc::lock_guard g( conn_mtx ); + stat.peer = peer_addr; + stat.remote_ip = log_remote_endpoint_ip; + stat.remote_port = log_remote_endpoint_port; stat.last_handshake = last_handshake_recv; return stat; } - // called from connection stand + // called from connection strand bool connection::start_session() { verify_strand_in_this_thread( strand, __func__, __LINE__ ); @@ -1292,6 +1293,7 @@ namespace eosio { } else { peer_dlog( this, "connected" ); socket_open = true; + connection_time = get_time(); start_read_message(); return true; } @@ -2699,7 +2701,6 @@ namespace eosio { [resolver, c = shared_from_this(), socket=socket]( const boost::system::error_code& err, const tcp::endpoint& endpoint ) { if( !err && socket->is_open() && socket == c->socket ) { c->update_endpoints(); - c->connection_time = get_time(); if( c->start_session() ) { c->send_handshake(); c->send_time(); @@ -4457,9 +4458,12 @@ namespace eosio { } else { ++num_peers; } + (*it)->conn_mtx.lock(); + boost::asio::ip::address_v6::bytes_type addr = (*it)->remote_endpoint_ip_array; + (*it)->conn_mtx.unlock(); net_plugin::p2p_per_connection_metrics::connection_metric metrics{ - .address = (*it)->remote_endpoint_ip_array - , .port = (*it)->remote_endpoint_port + .address = addr + , .port = (*it)->get_remote_endpoint_port() , .accepting_blocks = (*it)->is_blocks_connection() , .last_received_block = (*it)->get_last_received_blk_num() , .first_available_block = (*it)->get_peer_start_block_num() From ae874273ae2b9d2bf87dfc46c40aa488e17e13f1 Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Thu, 10 Aug 2023 16:52:14 -0500 Subject: [PATCH 54/79] Retain chrono nanoseconds until the last possible moment. Collect Prometheus metrics for each peer only if the update method exists. Rename a method for consistency. Rename a variable for cosmetic reasons. --- .../include/eosio/net_plugin/net_plugin.hpp | 4 +- plugins/net_plugin/net_plugin.cpp | 66 ++++++++++--------- plugins/prometheus_plugin/metrics.hpp | 4 +- 3 files changed, 39 insertions(+), 35 deletions(-) diff --git a/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp b/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp index d9f68ffe7f..e326db6fd0 100644 --- a/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp +++ b/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp @@ -50,9 +50,9 @@ namespace eosio { size_t unique_first_block_count{0}; uint64_t latency{0}; size_t bytes_received{0}; - time_t last_bytes_received{0}; + std::chrono::nanoseconds last_bytes_received{0}; size_t bytes_sent{0}; - time_t last_bytes_sent{0}; + std::chrono::nanoseconds last_bytes_sent{0}; std::chrono::nanoseconds connection_start_time{0}; std::string log_p2p_address; }; diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index 4d2533a32d..dd7d591ef0 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -42,6 +42,8 @@ using namespace eosio::chain::plugin_interface; +using namespace std::chrono_literals; + namespace boost { /// @brief Overload for boost::lexical_cast to convert vector of strings to string @@ -792,12 +794,12 @@ namespace eosio { bool is_blocks_connection() const { return connection_type != transactions_only; } // thread safe, atomic uint32_t get_peer_start_block_num() const { return peer_start_block_num.load(); } uint32_t get_peer_head_block_num() const { return peer_head_block_num.load(); } - uint32_t get_last_received_blk_num() const { return last_received_blk_num.load(); } + uint32_t get_last_received_block_num() const { return last_received_block_num.load(); } uint32_t get_unique_blocks_rcvd_count() const { return unique_blocks_rcvd_count.load(); } size_t get_bytes_received() const { return bytes_received.load(); } - time_t get_last_bytes_received() const { return last_bytes_received.load(); } + std::chrono::nanoseconds get_last_bytes_received() const { return last_bytes_received.load(); } size_t get_bytes_sent() const { return bytes_sent.load(); } - time_t get_last_bytes_sent() const { return last_bytes_sent.load(); } + std::chrono::nanoseconds get_last_bytes_sent() const { return last_bytes_sent.load(); } boost::asio::ip::port_type get_remote_endpoint_port() const { return remote_endpoint_port.load(); } void set_heartbeat_timeout(std::chrono::milliseconds msec) { hb_timeout = msec; @@ -828,12 +830,12 @@ namespace eosio { std::atomic connection_type{both}; std::atomic peer_start_block_num{0}; std::atomic peer_head_block_num{0}; - std::atomic last_received_blk_num{0}; + std::atomic last_received_block_num{0}; std::atomic unique_blocks_rcvd_count{0}; std::atomic bytes_received{0}; - std::atomic last_bytes_received{0}; + std::atomic last_bytes_received{0ns}; std::atomic bytes_sent{0}; - std::atomic last_bytes_sent{0}; + std::atomic last_bytes_sent{0ns}; std::atomic remote_endpoint_port{0}; public: @@ -893,7 +895,7 @@ namespace eosio { string remote_endpoint_ip GUARDED_BY(conn_mtx); boost::asio::ip::address_v6::bytes_type remote_endpoint_ip_array GUARDED_BY(conn_mtx); - std::chrono::nanoseconds connection_time{0}; + std::chrono::nanoseconds connection_start_time{0}; connection_status get_status()const; @@ -1293,7 +1295,7 @@ namespace eosio { } else { peer_dlog( this, "connected" ); socket_open = true; - connection_time = get_time(); + connection_start_time = get_time(); start_read_message(); return true; } @@ -1553,7 +1555,7 @@ namespace eosio { std::function callback, bool to_sync_queue) { bytes_sent += buff->size(); - last_bytes_sent = get_time().count(); + last_bytes_sent = get_time(); if( !buffer_queue.add_write_queue( buff, std::move(callback), to_sync_queue )) { peer_wlog( this, "write_queue full ${s} bytes, giving up on connection", ("s", buffer_queue.write_queue_size()) ); close(); @@ -2905,7 +2907,7 @@ namespace eosio { // called from connection strand bool connection::process_next_message( uint32_t message_length ) { bytes_received += message_length; - last_bytes_received = get_time().count(); + last_bytes_received = get_time(); try { latest_msg_time = std::chrono::system_clock::now(); @@ -2945,7 +2947,7 @@ namespace eosio { fc::raw::unpack( peek_ds, bh ); const block_id_type blk_id = bh.calculate_id(); - const uint32_t blk_num = last_received_blk_num = block_header::num_from_id(blk_id); + const uint32_t blk_num = last_received_block_num = block_header::num_from_id(blk_id); // don't add_peer_block because we have not validated this block header yet if( my_impl->dispatcher->have_block( blk_id ) ) { peer_dlog( this, "canceling wait, already received block ${num}, id ${id}...", @@ -4458,26 +4460,28 @@ namespace eosio { } else { ++num_peers; } - (*it)->conn_mtx.lock(); - boost::asio::ip::address_v6::bytes_type addr = (*it)->remote_endpoint_ip_array; - (*it)->conn_mtx.unlock(); - net_plugin::p2p_per_connection_metrics::connection_metric metrics{ - .address = addr - , .port = (*it)->get_remote_endpoint_port() - , .accepting_blocks = (*it)->is_blocks_connection() - , .last_received_block = (*it)->get_last_received_blk_num() - , .first_available_block = (*it)->get_peer_start_block_num() - , .last_available_block = (*it)->get_peer_head_block_num() - , .unique_first_block_count = (*it)->get_unique_blocks_rcvd_count() - , .latency = (*it)->get_peer_ping_time_ns() - , .bytes_received = (*it)->get_bytes_received() - , .last_bytes_received = (*it)->get_last_bytes_received() - , .bytes_sent = (*it)->get_bytes_sent() - , .last_bytes_sent = (*it)->get_last_bytes_sent() - , .connection_start_time = (*it)->connection_time - , .log_p2p_address = (*it)->log_p2p_address - }; - per_connection.peers.push_back(metrics); + if (update_p2p_connection_metrics) { + std::unique_lock g_conn((*it)->conn_mtx); + boost::asio::ip::address_v6::bytes_type addr = (*it)->remote_endpoint_ip_array; + g_conn.unlock(); + net_plugin::p2p_per_connection_metrics::connection_metric metrics{ + .address = addr + , .port = (*it)->get_remote_endpoint_port() + , .accepting_blocks = (*it)->is_blocks_connection() + , .last_received_block = (*it)->get_last_received_block_num() + , .first_available_block = (*it)->get_peer_start_block_num() + , .last_available_block = (*it)->get_peer_head_block_num() + , .unique_first_block_count = (*it)->get_unique_blocks_rcvd_count() + , .latency = (*it)->get_peer_ping_time_ns() + , .bytes_received = (*it)->get_bytes_received() + , .last_bytes_received = (*it)->get_last_bytes_received() + , .bytes_sent = (*it)->get_bytes_sent() + , .last_bytes_sent = (*it)->get_last_bytes_sent() + , .connection_start_time = (*it)->connection_start_time + , .log_p2p_address = (*it)->log_p2p_address + }; + per_connection.peers.push_back(metrics); + } if (!(*it)->socket_is_open() && (*it)->state() != connection::connection_state::connecting) { if (!(*it)->incoming()) { diff --git a/plugins/prometheus_plugin/metrics.hpp b/plugins/prometheus_plugin/metrics.hpp index 35ffcf7fb9..79139b7055 100644 --- a/plugins/prometheus_plugin/metrics.hpp +++ b/plugins/prometheus_plugin/metrics.hpp @@ -158,9 +158,9 @@ struct catalog_type { add_and_set_gauge("unique_first_block_count", unique_first_block_counts_gauges, peer.unique_first_block_count); add_and_set_gauge("latency", latency_gauges, peer.latency); add_and_set_gauge("bytes_received", bytes_received_gauges, peer.bytes_received); - add_and_set_gauge("last_bytes_received", last_bytes_received_gauges, peer.last_bytes_received); + add_and_set_gauge("last_bytes_received", last_bytes_received_gauges, peer.last_bytes_received.count()); add_and_set_gauge("bytes_sent", bytes_sent_gauges, peer.bytes_sent); - add_and_set_gauge("last_bytes_sent", last_bytes_sent_gauges, peer.last_bytes_sent); + add_and_set_gauge("last_bytes_sent", last_bytes_sent_gauges, peer.last_bytes_sent.count()); add_and_set_gauge("connection_start_time", connection_start_time_gauges, peer.connection_start_time.count()); add_and_set_gauge(peer.log_p2p_address, log_p2p_address_gauges, 0); // Empty gauge; we only want the label } From 639faf260567141fcf790d90b8669b5590432781 Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Thu, 10 Aug 2023 17:30:18 -0500 Subject: [PATCH 55/79] Relocate net-util to tools. --- programs/CMakeLists.txt | 1 - programs/net-util/CMakeLists.txt | 1 - tools/CMakeLists.txt | 1 + {programs/net-util => tools}/net-util.py | 0 4 files changed, 1 insertion(+), 2 deletions(-) delete mode 100644 programs/net-util/CMakeLists.txt rename {programs/net-util => tools}/net-util.py (100%) diff --git a/programs/CMakeLists.txt b/programs/CMakeLists.txt index 270a78d40c..9dda023946 100644 --- a/programs/CMakeLists.txt +++ b/programs/CMakeLists.txt @@ -2,4 +2,3 @@ add_subdirectory( nodeos ) add_subdirectory( cleos ) add_subdirectory( keosd ) add_subdirectory( leap-util ) -add_subdirectory( net-util ) diff --git a/programs/net-util/CMakeLists.txt b/programs/net-util/CMakeLists.txt deleted file mode 100644 index 5e8639daec..0000000000 --- a/programs/net-util/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -configure_file(net-util.py net-util.py COPYONLY) diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 550b754358..0ae91eef60 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -1,3 +1,4 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/llvm-gcov.sh ${CMAKE_CURRENT_BINARY_DIR}/llvm-gcov.sh COPYONLY) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/ctestwrapper.sh ${CMAKE_CURRENT_BINARY_DIR}/ctestwrapper.sh COPYONLY) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/validate_reflection.py ${CMAKE_CURRENT_BINARY_DIR}/validate_reflection.py COPYONLY) +configure_file(net-util.py net-util.py COPYONLY) diff --git a/programs/net-util/net-util.py b/tools/net-util.py similarity index 100% rename from programs/net-util/net-util.py rename to tools/net-util.py From 3510074827528853689b11d9902fbe5040151e37 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Fri, 11 Aug 2023 10:05:42 -0500 Subject: [PATCH 56/79] GH-1432 Refactor calculate_next_block_slot to not require active_schedule --- .../producer_plugin/block_timing_util.hpp | 100 +++++++++--------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/plugins/producer_plugin/include/eosio/producer_plugin/block_timing_util.hpp b/plugins/producer_plugin/include/eosio/producer_plugin/block_timing_util.hpp index 602032cc4e..e39cf3d9ec 100644 --- a/plugins/producer_plugin/include/eosio/producer_plugin/block_timing_util.hpp +++ b/plugins/producer_plugin/include/eosio/producer_plugin/block_timing_util.hpp @@ -65,58 +65,51 @@ namespace block_timing_util { } } - inline uint32_t calculate_next_block_slot(const chain::account_name& producer_name, uint32_t current_block_slot, uint32_t block_num, - const std::vector& active_schedule, const producer_watermarks& prod_watermarks) { - // determine if this producer is in the active schedule and if so, where - auto itr = - std::find_if(active_schedule.begin(), active_schedule.end(), [&](const auto& asp) { return asp.producer_name == producer_name; }); - if (itr == active_schedule.end()) { - // this producer is not in the active producer set - return UINT32_MAX; - } - - size_t producer_index = itr - active_schedule.begin(); - uint32_t minimum_offset = 1; // must at least be the "next" block - - // account for a watermark in the future which is disqualifying this producer for now - // this is conservative assuming no blocks are dropped. If blocks are dropped the watermark will - // disqualify this producer for longer but it is assumed they will wake up, determine that they - // are disqualified for longer due to skipped blocks and re-calculate their next block with better - // information then - auto current_watermark = prod_watermarks.get_watermark(producer_name); - if (current_watermark) { - const auto watermark = *current_watermark; - if (watermark.first > block_num) { - // if I have a watermark block number then I need to wait until after that watermark - minimum_offset = watermark.first - block_num + 1; - } - if (watermark.second.slot > current_block_slot) { - // if I have a watermark block timestamp then I need to wait until after that watermark timestamp - minimum_offset = std::max(minimum_offset, watermark.second.slot - current_block_slot + 1); + namespace detail { + inline uint32_t calculate_next_block_slot(const chain::account_name& producer_name, uint32_t current_block_slot, uint32_t block_num, + size_t producer_index, size_t active_schedule_size, const producer_watermarks& prod_watermarks) { + uint32_t minimum_offset = 1; // must at least be the "next" block + + // account for a watermark in the future which is disqualifying this producer for now + // this is conservative assuming no blocks are dropped. If blocks are dropped the watermark will + // disqualify this producer for longer but it is assumed they will wake up, determine that they + // are disqualified for longer due to skipped blocks and re-calculate their next block with better + // information then + auto current_watermark = prod_watermarks.get_watermark(producer_name); + if (current_watermark) { + const auto watermark = *current_watermark; + if (watermark.first > block_num) { + // if I have a watermark block number then I need to wait until after that watermark + minimum_offset = watermark.first - block_num + 1; + } + if (watermark.second.slot > current_block_slot) { + // if I have a watermark block timestamp then I need to wait until after that watermark timestamp + minimum_offset = std::max(minimum_offset, watermark.second.slot - current_block_slot + 1); + } } - } - // this producers next opportunity to produce is the next time its slot arrives after or at the calculated minimum - uint32_t minimum_slot = current_block_slot + minimum_offset; - size_t minimum_slot_producer_index = - (minimum_slot % (active_schedule.size() * chain::config::producer_repetitions)) / chain::config::producer_repetitions; - if (producer_index == minimum_slot_producer_index) { - // this is the producer for the minimum slot, go with that - return minimum_slot; - } else { - // calculate how many rounds are between the minimum producer and the producer in question - size_t producer_distance = producer_index - minimum_slot_producer_index; - // check for unsigned underflow - if (producer_distance > producer_index) { - producer_distance += active_schedule.size(); + // this producers next opportunity to produce is the next time its slot arrives after or at the calculated minimum + uint32_t minimum_slot = current_block_slot + minimum_offset; + size_t minimum_slot_producer_index = + (minimum_slot % (active_schedule_size * chain::config::producer_repetitions)) / chain::config::producer_repetitions; + if (producer_index == minimum_slot_producer_index) { + // this is the producer for the minimum slot, go with that + return minimum_slot; + } else { + // calculate how many rounds are between the minimum producer and the producer in question + size_t producer_distance = producer_index - minimum_slot_producer_index; + // check for unsigned underflow + if (producer_distance > producer_index) { + producer_distance += active_schedule_size; + } + + // align the minimum slot to the first of its set of reps + uint32_t first_minimum_producer_slot = minimum_slot - (minimum_slot % chain::config::producer_repetitions); + + // offset the aligned minimum to the *earliest* next set of slots for this producer + uint32_t next_block_slot = first_minimum_producer_slot + (producer_distance * chain::config::producer_repetitions); + return next_block_slot; } - - // align the minimum slot to the first of its set of reps - uint32_t first_minimum_producer_slot = minimum_slot - (minimum_slot % chain::config::producer_repetitions); - - // offset the aligned minimum to the *earliest* next set of slots for this producer - uint32_t next_block_slot = first_minimum_producer_slot + (producer_distance * chain::config::producer_repetitions); - return next_block_slot; } } @@ -132,7 +125,14 @@ namespace block_timing_util { // if we have any producers then we should at least set a timer for our next available slot uint32_t wake_up_slot = UINT32_MAX; for (const auto& p : producers) { - auto next_producer_block_slot = calculate_next_block_slot(p, ref_block_slot, block_num, active_schedule, prod_watermarks); + // determine if this producer is in the active schedule and if so, where + auto itr = std::find_if(active_schedule.begin(), active_schedule.end(), [&](const auto& asp) { return asp.producer_name == p; }); + if (itr == active_schedule.end()) { + continue; + } + size_t producer_index = itr - active_schedule.begin(); + + auto next_producer_block_slot = detail::calculate_next_block_slot(p, ref_block_slot, block_num, producer_index, active_schedule.size(), prod_watermarks); wake_up_slot = std::min(next_producer_block_slot, wake_up_slot); } if (wake_up_slot == UINT32_MAX) { From c34ae35882fcf3b888e92defd28f9cc5185b53d9 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Fri, 11 Aug 2023 10:26:29 -0500 Subject: [PATCH 57/79] GH-1432 Set speculative deadline of 5secs instead of maximum to correspond to existing limit of 5secs on speculative execution on stale state. --- plugins/producer_plugin/producer_plugin.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/producer_plugin/producer_plugin.cpp b/plugins/producer_plugin/producer_plugin.cpp index 9167d30bda..e0d158c231 100644 --- a/plugins/producer_plugin/producer_plugin.cpp +++ b/plugins/producer_plugin/producer_plugin.cpp @@ -1904,7 +1904,8 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() { _producer_watermarks); _pending_block_deadline = wake_time ? *wake_time : fc::time_point::maximum(); } else { - _pending_block_deadline = fc::time_point::maximum(); + // set a deadline of 5 seconds to avoid speculatively executing trx on too old of state + _pending_block_deadline = chain.head_block_time() + fc::seconds(5); } const auto& preprocess_deadline = _pending_block_deadline; From c7bca0e33f8e2e4ceb25506d504e29ce55affa17 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Fri, 11 Aug 2023 12:20:02 -0500 Subject: [PATCH 58/79] GH-1432 Add additional comments --- .../producer_plugin/block_timing_util.hpp | 2 ++ .../test/test_block_timing_util.cpp | 33 +++++++++++-------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/plugins/producer_plugin/include/eosio/producer_plugin/block_timing_util.hpp b/plugins/producer_plugin/include/eosio/producer_plugin/block_timing_util.hpp index e39cf3d9ec..f046d9449c 100644 --- a/plugins/producer_plugin/include/eosio/producer_plugin/block_timing_util.hpp +++ b/plugins/producer_plugin/include/eosio/producer_plugin/block_timing_util.hpp @@ -10,6 +10,8 @@ enum class pending_block_mode { producing, speculating }; namespace block_timing_util { // Store watermarks + // Watermarks are recorded times that the specified producer has produced. + // Used by calculate_producer_wake_up_time to skip over already produced blocks avoiding duplicate production. class producer_watermarks { public: void consider_new_watermark(chain::account_name producer, uint32_t block_num, chain::block_timestamp_type timestamp) { diff --git a/plugins/producer_plugin/test/test_block_timing_util.cpp b/plugins/producer_plugin/test/test_block_timing_util.cpp index 66a7f273f8..652ed626af 100644 --- a/plugins/producer_plugin/test/test_block_timing_util.cpp +++ b/plugins/producer_plugin/test/test_block_timing_util.cpp @@ -103,14 +103,15 @@ BOOST_AUTO_TEST_CASE(test_calculate_producer_wake_up_time) { // use full cpu effort for most of these tests since calculate_producing_block_deadline is tested above constexpr uint32_t full_cpu_effort = eosio::chain::config::block_interval_us; - // no producers - BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, chain::block_timestamp_type{}, {}, {}, empty_watermarks), std::optional{}); + { // no producers + BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, chain::block_timestamp_type{}, {}, {}, empty_watermarks), std::optional{}); + } { // producers not in active_schedule std::set producers{"p1"_n, "p2"_n}; std::vector active_schedule{{"active1"_n}, {"active2"_n}}; BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, chain::block_timestamp_type{}, producers, active_schedule, empty_watermarks), std::optional{}); } - { // Only producer in active_schedule + { // Only one producer in active_schedule, we should produce every block std::set producers{"p1"_n, "p2"_n}; std::vector active_schedule{{"p1"_n}}; const uint32_t prod_round_1st_block_slot = 100 * active_schedule.size() * eosio::chain::config::producer_repetitions - 1; @@ -120,7 +121,7 @@ BOOST_AUTO_TEST_CASE(test_calculate_producer_wake_up_time) { BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp, producers, active_schedule, empty_watermarks), block_time); } } - { // Only producers in active_schedule + { // We have all producers in active_schedule configured, we should produce every block std::set producers{"p1"_n, "p2"_n, "p3"_n}; std::vector active_schedule{{"p1"_n}, {"p2"_n}}; const uint32_t prod_round_1st_block_slot = 100 * active_schedule.size() * eosio::chain::config::producer_repetitions - 1; @@ -130,7 +131,7 @@ BOOST_AUTO_TEST_CASE(test_calculate_producer_wake_up_time) { BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp, producers, active_schedule, empty_watermarks), block_time); } } - { // Only producers in active_schedule 21 + { // We have all producers in active_schedule in active_schedule of 21 (plus a couple of extra producers configured), we should produce every block std::set producers = { "inita"_n, "initb"_n, "initc"_n, "initd"_n, "inite"_n, "initf"_n, "initg"_n, "p1"_n, "inith"_n, "initi"_n, "initj"_n, "initk"_n, "initl"_n, "initm"_n, "initn"_n, @@ -148,7 +149,7 @@ BOOST_AUTO_TEST_CASE(test_calculate_producer_wake_up_time) { BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp, producers, active_schedule, empty_watermarks), block_time); } } - { // One of many producers + { // Tests for when we only have a subset of all active producers, we do not produce all blocks, only produce blocks for our round std::vector active_schedule{ // 21 {"inita"_n}, {"initb"_n}, {"initc"_n}, {"initd"_n}, {"inite"_n}, {"initf"_n}, {"initg"_n}, {"inith"_n}, {"initi"_n}, {"initj"_n}, {"initk"_n}, {"initl"_n}, {"initm"_n}, {"initn"_n}, @@ -156,7 +157,7 @@ BOOST_AUTO_TEST_CASE(test_calculate_producer_wake_up_time) { }; const uint32_t prod_round_1st_block_slot = 100 * active_schedule.size() * eosio::chain::config::producer_repetitions - 1; - // initb is second in the schedule, so it will produce config::producer_repetitions after + // initb is second in the schedule, so it will produce config::producer_repetitions after start, verify its block times std::set producers = { "initb"_n }; block_timestamp_type block_timestamp(prod_round_1st_block_slot); auto expected_block_time = block_timestamp_type(prod_round_1st_block_slot + config::producer_repetitions).to_time_point(); @@ -184,18 +185,22 @@ BOOST_AUTO_TEST_CASE(test_calculate_producer_wake_up_time) { expected_block_time = block_timestamp.to_time_point(); BOOST_CHECK_NE(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp, producers, active_schedule, empty_watermarks), expected_block_time); // end of round, so not the next - // initc + // initc is third in the schedule, verify its wake-up time is as expected producers = std::set{ "initc"_n }; block_timestamp = block_timestamp_type(prod_round_1st_block_slot); + // expect 2*producer_repetitions since we expect wake-up time to be after the first two rounds expected_block_time = block_timestamp_type(prod_round_1st_block_slot + 2*config::producer_repetitions).to_time_point(); BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp, producers, active_schedule, empty_watermarks), expected_block_time); - // inith, initk + // inith, initk - configured for 2 of the 21 producers. inith is 8th in schedule, initk is 11th in schedule producers = std::set{ "inith"_n, "initk"_n }; block_timestamp = block_timestamp_type(prod_round_1st_block_slot); + // expect to produce after 7 rounds since inith is 8th expected_block_time = block_timestamp_type(prod_round_1st_block_slot + 7*config::producer_repetitions).to_time_point(); BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp, producers, active_schedule, empty_watermarks), expected_block_time); - block_timestamp = block_timestamp_type(prod_round_1st_block_slot + 8*config::producer_repetitions); + // give it a time after inith otherwise would return inith time + block_timestamp = block_timestamp_type(prod_round_1st_block_slot + 8*config::producer_repetitions); // after inith round + // expect to produce after 10 rounds since inith is 11th expected_block_time = block_timestamp_type(prod_round_1st_block_slot + 10*config::producer_repetitions).to_time_point(); BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp, producers, active_schedule, empty_watermarks), expected_block_time); @@ -224,20 +229,20 @@ BOOST_AUTO_TEST_CASE(test_calculate_producer_wake_up_time) { {"inith"_n}, {"initi"_n}, {"initj"_n}, {"initk"_n}, {"initl"_n}, {"initm"_n}, {"initn"_n}, {"inito"_n}, {"initp"_n}, {"initq"_n}, {"initr"_n}, {"inits"_n}, {"initt"_n}, {"initu"_n} }; - const uint32_t prod_round_1st_block_slot = 100 * active_schedule.size() * eosio::chain::config::producer_repetitions - 1; // block production time + const uint32_t prod_round_1st_block_slot = 100 * active_schedule.size() * eosio::chain::config::producer_repetitions - 1; producer_watermarks prod_watermarks; std::set producers; block_timestamp_type block_timestamp(prod_round_1st_block_slot); - // initc + // initc, with no watermarks producers = std::set{ "initc"_n }; auto expected_block_time = block_timestamp_type(prod_round_1st_block_slot + 2*config::producer_repetitions).to_time_point(); // without watermark BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp, producers, active_schedule, empty_watermarks), expected_block_time); - // watermark at first block + // add watermark at first block, first block should not be allowed, wake-up time should be after first block of initc prod_watermarks.consider_new_watermark("initc"_n, 2, block_timestamp_type((prod_round_1st_block_slot + 2*config::producer_repetitions + 1))); // +1 since watermark is in block production time expected_block_time = block_timestamp_type(prod_round_1st_block_slot + 2*config::producer_repetitions + 1).to_time_point(); // with watermark, wait until next BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp, producers, active_schedule, prod_watermarks), expected_block_time); - // watermark at first 2 blocks + // add watermark at first 2 blocks, first & second block should not be allowed, wake-up time should be after second block of initc prod_watermarks.consider_new_watermark("initc"_n, 2, block_timestamp_type((prod_round_1st_block_slot + 2*config::producer_repetitions + 1 + 1))); expected_block_time = block_timestamp_type(prod_round_1st_block_slot + 2*config::producer_repetitions + 2).to_time_point(); // with watermark, wait until next BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp, producers, active_schedule, prod_watermarks), expected_block_time); From 9ff857c274a06d049e3b462a0724494690f0603e Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Fri, 11 Aug 2023 14:00:30 -0500 Subject: [PATCH 59/79] Move accounting of bytes written to peer to async_write's completion token. --- plugins/net_plugin/net_plugin.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index dd7d591ef0..297a1dca58 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -1554,8 +1554,6 @@ namespace eosio { void connection::queue_write(const std::shared_ptr>& buff, std::function callback, bool to_sync_queue) { - bytes_sent += buff->size(); - last_bytes_sent = get_time(); if( !buffer_queue.add_write_queue( buff, std::move(callback), to_sync_queue )) { peer_wlog( this, "write_queue full ${s} bytes, giving up on connection", ("s", buffer_queue.write_queue_size()) ); close(); @@ -1601,6 +1599,8 @@ namespace eosio { c->close(); return; } + c->bytes_sent += w; + c->last_bytes_sent = c->get_time(); c->buffer_queue.out_callback( ec, w ); From 6abba1a1badda1aa6658a47957e83752f7104f0f Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Sun, 13 Aug 2023 18:55:23 -0500 Subject: [PATCH 60/79] Use connection ID as per peer Prometheus metric key. Remove some unused and commented code. WIP multicolumned list in net-util. --- .../include/eosio/net_plugin/net_plugin.hpp | 1 + plugins/net_plugin/net_plugin.cpp | 3 +- plugins/prometheus_plugin/metrics.hpp | 16 +-- tools/net-util.py | 122 ++++++------------ 4 files changed, 46 insertions(+), 96 deletions(-) diff --git a/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp b/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp index e326db6fd0..d0c482e5b1 100644 --- a/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp +++ b/plugins/net_plugin/include/eosio/net_plugin/net_plugin.hpp @@ -41,6 +41,7 @@ namespace eosio { struct p2p_per_connection_metrics { struct connection_metric { + uint32_t connection_id{0}; boost::asio::ip::address_v6::bytes_type address; unsigned short port{0}; bool accepting_blocks{false}; diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index 297a1dca58..beaa367e3a 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -4465,7 +4465,8 @@ namespace eosio { boost::asio::ip::address_v6::bytes_type addr = (*it)->remote_endpoint_ip_array; g_conn.unlock(); net_plugin::p2p_per_connection_metrics::connection_metric metrics{ - .address = addr + .connection_id = (*it)->connection_id + , .address = addr , .port = (*it)->get_remote_endpoint_port() , .accepting_blocks = (*it)->is_blocks_connection() , .last_received_block = (*it)->get_last_received_block_num() diff --git a/plugins/prometheus_plugin/metrics.hpp b/plugins/prometheus_plugin/metrics.hpp index 79139b7055..627ad11739 100644 --- a/plugins/prometheus_plugin/metrics.hpp +++ b/plugins/prometheus_plugin/metrics.hpp @@ -38,7 +38,8 @@ struct catalog_type { Gauge& num_peers; Gauge& num_clients; - std::vector addresses; + std::vector> address_gauges; + std::vector> port_gauges; std::vector> accepting_blocks_gauges; std::vector> last_received_blocks_gauges; std::vector> first_available_blocks_gauges; @@ -136,21 +137,18 @@ struct catalog_type { num_peers.Set(metrics.num_peers); num_clients.Set(metrics.num_clients); for(size_t i = 0; i < metrics.stats.peers.size(); ++i) { - auto addr = boost::asio::ip::make_address_v6(metrics.stats.peers[i].address).to_string(); - boost::replace_all(addr, ":", "_COLON_"); - boost::replace_all(addr, ".", "_DOT_"); - addr.insert(0, "ip_"); - addr.append("_"); - addr.append(to_string(metrics.stats.peers[i].port)); - addresses.push_back(addr); + std::string label{"connid_" + to_string(metrics.stats.peers[i].connection_id)}; auto add_and_set_gauge = [&](const std::string& label_value, std::vector>& gauges, const auto& value) { - auto& gauge = p2p_connections.Add({{addr, label_value}}); + auto& gauge = p2p_connections.Add({{label, label_value}}); gauge.Set(value); gauges.push_back(gauge); }; auto& peer = metrics.stats.peers[i]; + auto addr = std::string("addr_") + boost::asio::ip::make_address_v6(peer.address).to_string(); + add_and_set_gauge(addr, address_gauges, 0); // Empty gauge; ipv6 address can't be transmitted as a double + add_and_set_gauge("port", port_gauges, peer.port); add_and_set_gauge("accepting_blocks", accepting_blocks_gauges, peer.accepting_blocks); add_and_set_gauge("last_received_block", last_received_blocks_gauges, peer.last_received_block); add_and_set_gauge("first_available_block", first_available_blocks_gauges, peer.first_available_block); diff --git a/tools/net-util.py b/tools/net-util.py index fa050162c9..32a651f27d 100755 --- a/tools/net-util.py +++ b/tools/net-util.py @@ -9,6 +9,9 @@ import sys import time +from types import MethodType +from typing import Callable + import urwid import urwid.curses_display @@ -25,51 +28,6 @@ logger = logging.getLogger(__name__) -def replacement_render(self, size, focus=False): - """ - Render contents with wrapping and alignment. Return canvas. - - See :meth:`Widget.render` for parameter details. - - >>> Text(u"important things").render((18,)).text # ... = b in Python 3 - [...'important things '] - >>> Text(u"important things").render((11,)).text - [...'important ', ...'things '] - """ - maxcol = size[0] - text, attr = self.get_text() - #assert isinstance(text, unicode) - trans = self.get_line_translation( maxcol, (text,attr) ) - return apply_text_layout(text, attr, trans, maxcol) - -def replacement_rows(self, size, focus=False): - """ - Return the number of rows the rendered text requires. - - See :meth:`Widget.rows` for parameter details. - - >>> Text(u"important things").rows((18,)) - 1 - >>> Text(u"important things").rows((11,)) - 2 - """ - maxcol = size[0] - return len(self.get_line_translation(maxcol)) - -def validate_size(widget, size, canv): - """ - Raise a WidgetError if a canv does not match size size. - """ - if (size and size[1:] != (0,) and size[0] != canv.cols()) or \ - (len(size)>1 and size[1] < canv.rows()): - raise WidgetError("Widget %r rendered (%d x %d) canvas" - " when passed size %r!" % (widget, canv.cols(), - canv.rows(), size)) - -#urwid.Text.render = replacement_render -#urwid.Text.rows = replacement_rows -#urwid.widget.validate_size = validate_size - def humanReadableBytesPerSecond(bytes: int, telco:bool = False): power = 10**3 if telco else 2**10 n = 0 @@ -180,6 +138,7 @@ def __init__(self): ] self.peerMetricConversions = { 'hostname': lambda x: x[1:].replace('__', ':').replace('_', '.'), + 'port': lambda x: str(int(x)), 'accepting_blocks': lambda x: 'True' if x else 'False', 'latency': lambda x: format(int(x)/1000000, '.2f') + ' ms', 'last_received_block': lambda x: str(int(x)), @@ -196,7 +155,9 @@ def __init__(self): 'Earliest Available Block:', ] self.peerColumns = [ + ('Connection ID', 'connectionIDLW'), ('\n\nIP Address', 'ipAddressLW'), + ('\n\nPort', 'portLW'), ('\n\nHostname', 'hostnameLW'), ('\n\nLatency', 'latencyLW'), ('\nSend\nRate', 'sendBandwidthLW'), @@ -224,25 +185,6 @@ def labelToAttrName(label: str, fieldType='Text'): parser.add_argument('--log-level', choices=[logging._nameToLevel.keys()] + [k.lower() for k in logging._nameToLevel.keys()], help='Logging level', default='debug') self.args = parser.parse_args() - @staticmethod - def unmanglePrometheusHostLabel(hostLabel: str) -> (ipaddress.ip_address, str): - '''Remove mangling required to fit an IPv6 address and port into a Prometheus label. - - Prometheus labels may contain only underscore and alphanumeric characters and must begin with - an alphabetic character. This method unmangles according to the following table: - 'ip_' prefix removed - '_DOT_' -> '.' - '_COLON_' -> ':' - - @hostLabel - Prometheus label to convert - - @returns - instance of 'ip_address', string representation of port number - ''' - host = hostLabel[len('ip_'):].replace('_DOT_', '.').replace('_COLON_', ':') - addr = ipaddress.ip_address(host[:host.rfind('_')]) - port = host[host.rfind('_')+1:] - return addr, port - def createUrwidUI(self, mainLoop): AttrMap = urwid.AttrMap Button = urwid.Button @@ -281,28 +223,33 @@ def packLabeledButton(labelTxt: str, defaultValue='', callback: callable=None, u widgets.insert(3, Filler(Divider())) rightColumn = Pile([(1, widget) for widget in widgets[:-1]] + [('weight', 1, widgets[-1])]) - def packLabeledList(labelTxt: str, attrName: str): + def packLabeledList(labelTxt: str, attrName: str, focusChangedCallback: Callable): label = Text(('bold', labelTxt)) listWalker = TextSimpleFocusListWalker([]) + #listWalker.set_focus_changed_callback(focusChangedCallback) + #listWalker._focus_changed = MethodType(focusChangedCallback, listWalker) setattr(listWalker, 'name', attrName) setattr(self, attrName, listWalker) - return Pile([('pack', label), ('weight', 1, urwid.ListBox(listWalker))]) + return Pile([('pack', label), ('weight', 1, urwid.ListBox(listWalker))]), listWalker + + def focus_changed(self, new_focus): + logger.info(f'focus changed to {new_focus}') + for listWalker in self.columns: + logger.info(f'listwalker {id(listWalker)} self {id(self)}') + if listWalker is not self: + listWalker.set_focus(new_focus) self.peerListPiles = [] + listWalkers = [] for colName, attrName in self.peerColumns: - self.peerListPiles.append(packLabeledList(colName, attrName)) + p, l = packLabeledList(colName, attrName, focus_changed) + self.peerListPiles.append(p) + listWalkers.append(l) - #for pile in self.peerListPiles: - # pile.setAllColumns(self.peerListPiles) - - def focus_changed(new_focus): - logger.info('focus changed') - for pile in self.peerListPiles[:-1]: - pile.contents[-1][0].body.set_focus(new_focus) - - self.peerListPiles[0].contents[-1][0].body.set_focus_changed_callback(focus_changed) + for listWalker in listWalkers: + listWalker.columns = listWalkers - columnedList = Columns([('weight', 1, self.peerListPiles[0]), + columnedList = Columns([(0, self.peerListPiles[0]), # hidden connection ID column ('weight', 2, self.peerListPiles[1])]+self.peerListPiles[2:], dividechars=1, focus_column=0) self.peerLineBox = urwid.LineBox(columnedList, 'Peers:', 'left') @@ -363,18 +310,21 @@ def __init__(self, bytesReceived=0, bytesSent=0, connectionStarted=0): field = getattr(self, fieldName) field.set_text(str(int(sample.value))) else: - hostLabel = next(iter(sample.labels)) - fieldName = sample.labels[hostLabel] - addr, port = self.unmanglePrometheusHostLabel(hostLabel) - host = f'{str(addr.ipv4_mapped) if addr.ipv4_mapped else str(addr)}:{port}' - listwalker = getattr(self, 'ipAddressLW') - if host not in listwalker: + connID = next(iter(sample.labels)) + fieldName = sample.labels[connID] + listwalker = getattr(self, 'connectionIDLW') + if connID not in listwalker: startOffset = endOffset = len(listwalker) - listwalker.append(AttrMap(Text(host), None, 'reversed')) + listwalker.append(AttrMap(Text(connID), None, 'reversed')) else: - startOffset = listwalker.index(host) + startOffset = listwalker.index(connID) endOffset = startOffset + 1 - if fieldName == 'bytes_received': + if fieldName.startswith('addr_'): + listwalker = getattr(self, 'ipAddressLW') + addr = ipaddress.ip_address(fieldName[len('addr_'):]) + host = f'{str(addr.ipv4_mapped) if addr.ipv4_mapped else str(addr)}' + listwalker[startOffset:endOffset] = [AttrMap(Text(host), None, 'reversed')] + elif fieldName == 'bytes_received': bytesReceived = int(sample.value) stats = bandwidths.get(host, bandwidthStats()) stats.bytesReceived = bytesReceived From fffbbf38b0b77e9704f79f690d7242f16b4167df Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Mon, 14 Aug 2023 10:31:01 -0500 Subject: [PATCH 61/79] GH-1432 Allow speculative blocks unless we are syncing --- plugins/producer_plugin/producer_plugin.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/plugins/producer_plugin/producer_plugin.cpp b/plugins/producer_plugin/producer_plugin.cpp index e0d158c231..9b62af4c12 100644 --- a/plugins/producer_plugin/producer_plugin.cpp +++ b/plugins/producer_plugin/producer_plugin.cpp @@ -1879,9 +1879,14 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() { } if (in_speculating_mode()) { - auto head_block_age = now - chain.head_block_time(); - if (head_block_age > fc::seconds(5)) - return start_block_result::waiting_for_block; + static fc::time_point last_start_block_time = fc::time_point::maximum(); // always start with speculative block + // Determine if we are syncing: if we have recently started an old block then assume we are syncing + if (last_start_block_time < now + fc::microseconds(config::block_interval_us)) { + auto head_block_age = now - chain.head_block_time(); + if (head_block_age > fc::seconds(5)) + return start_block_result::waiting_for_block; // if syncing no need to create a block just to immediately abort it + } + last_start_block_time = now; } if (in_producing_mode()) { @@ -1902,10 +1907,10 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() { auto wake_time = block_timing_util::calculate_producer_wake_up_time(config::block_interval_us, chain.head_block_num(), chain.head_block_time(), _producers, chain.head_block_state()->active_schedule.producers, _producer_watermarks); - _pending_block_deadline = wake_time ? *wake_time : fc::time_point::maximum(); + _pending_block_deadline = wake_time ? *wake_time : now + fc::microseconds(config::block_interval_us); } else { - // set a deadline of 5 seconds to avoid speculatively executing trx on too old of state - _pending_block_deadline = chain.head_block_time() + fc::seconds(5); + // set a deadline for the next block time, so we consistently create blocks with "current" block time + _pending_block_deadline = now + fc::microseconds(config::block_interval_us); } const auto& preprocess_deadline = _pending_block_deadline; From bf0231911d95b465acda7b6179254621f9e50f3c Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Mon, 14 Aug 2023 10:53:01 -0500 Subject: [PATCH 62/79] GH-1432 Also restart speculative blocks every block interval when configured with producers --- plugins/producer_plugin/producer_plugin.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/producer_plugin/producer_plugin.cpp b/plugins/producer_plugin/producer_plugin.cpp index 9b62af4c12..a97557ee0e 100644 --- a/plugins/producer_plugin/producer_plugin.cpp +++ b/plugins/producer_plugin/producer_plugin.cpp @@ -1889,6 +1889,8 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() { last_start_block_time = now; } + // create speculative blocks at regular intervals, so we create blocks with "current" block time + _pending_block_deadline = now + fc::microseconds(config::block_interval_us); if (in_producing_mode()) { uint32_t production_round_index = block_timestamp_type(block_time).slot % chain::config::producer_repetitions; if (production_round_index == 0) { @@ -1907,10 +1909,8 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() { auto wake_time = block_timing_util::calculate_producer_wake_up_time(config::block_interval_us, chain.head_block_num(), chain.head_block_time(), _producers, chain.head_block_state()->active_schedule.producers, _producer_watermarks); - _pending_block_deadline = wake_time ? *wake_time : now + fc::microseconds(config::block_interval_us); - } else { - // set a deadline for the next block time, so we consistently create blocks with "current" block time - _pending_block_deadline = now + fc::microseconds(config::block_interval_us); + if (wake_time) + _pending_block_deadline = std::min(*wake_time, _pending_block_deadline); } const auto& preprocess_deadline = _pending_block_deadline; From 1eb4fcce1380a6ae24151fdbde011ead5c07e0ec Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Mon, 14 Aug 2023 11:38:24 -0500 Subject: [PATCH 63/79] GH-1432 Fix comment --- .../include/eosio/producer_plugin/block_timing_util.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/producer_plugin/include/eosio/producer_plugin/block_timing_util.hpp b/plugins/producer_plugin/include/eosio/producer_plugin/block_timing_util.hpp index f046d9449c..b4e3741874 100644 --- a/plugins/producer_plugin/include/eosio/producer_plugin/block_timing_util.hpp +++ b/plugins/producer_plugin/include/eosio/producer_plugin/block_timing_util.hpp @@ -44,7 +44,7 @@ namespace block_timing_util { // received it and start producing on schedule. To mitigate the problem, we leave no time gap in block producing. For // example, given block_interval=500 ms and cpu effort=400 ms, assuming the our round start at time point 0; in the // past, the block start time points would be at time point -500, 0, 500, 1000, 1500, 2000 .... With this new - // approach, the block time points would become -500, -100, 300, 700, 1200 ... + // approach, the block time points would become -500, -100, 300, 700, 1100 ... inline fc::time_point production_round_block_start_time(uint32_t cpu_effort_us, chain::block_timestamp_type block_time) { uint32_t block_slot = block_time.slot; uint32_t production_round_start_block_slot = From 2754f026cbc8e58c1e07ddfa6edfcad053acce06 Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Mon, 14 Aug 2023 14:24:18 -0500 Subject: [PATCH 64/79] Remove unnecessary retention of pointers to Prometheus gauges. --- plugins/prometheus_plugin/metrics.hpp | 44 +++++++++------------------ 1 file changed, 14 insertions(+), 30 deletions(-) diff --git a/plugins/prometheus_plugin/metrics.hpp b/plugins/prometheus_plugin/metrics.hpp index 627ad11739..fae701ceec 100644 --- a/plugins/prometheus_plugin/metrics.hpp +++ b/plugins/prometheus_plugin/metrics.hpp @@ -38,20 +38,6 @@ struct catalog_type { Gauge& num_peers; Gauge& num_clients; - std::vector> address_gauges; - std::vector> port_gauges; - std::vector> accepting_blocks_gauges; - std::vector> last_received_blocks_gauges; - std::vector> first_available_blocks_gauges; - std::vector> last_available_blocks_gauges; - std::vector> unique_first_block_counts_gauges; - std::vector> latency_gauges; - std::vector> bytes_received_gauges; - std::vector> last_bytes_received_gauges; - std::vector> bytes_sent_gauges; - std::vector> last_bytes_sent_gauges; - std::vector> connection_start_time_gauges; - std::vector> log_p2p_address_gauges; // net plugin failed p2p connection Counter& failed_p2p_connections; @@ -139,28 +125,26 @@ struct catalog_type { for(size_t i = 0; i < metrics.stats.peers.size(); ++i) { std::string label{"connid_" + to_string(metrics.stats.peers[i].connection_id)}; auto add_and_set_gauge = [&](const std::string& label_value, - std::vector>& gauges, const auto& value) { auto& gauge = p2p_connections.Add({{label, label_value}}); gauge.Set(value); - gauges.push_back(gauge); }; auto& peer = metrics.stats.peers[i]; auto addr = std::string("addr_") + boost::asio::ip::make_address_v6(peer.address).to_string(); - add_and_set_gauge(addr, address_gauges, 0); // Empty gauge; ipv6 address can't be transmitted as a double - add_and_set_gauge("port", port_gauges, peer.port); - add_and_set_gauge("accepting_blocks", accepting_blocks_gauges, peer.accepting_blocks); - add_and_set_gauge("last_received_block", last_received_blocks_gauges, peer.last_received_block); - add_and_set_gauge("first_available_block", first_available_blocks_gauges, peer.first_available_block); - add_and_set_gauge("last_available_block", last_available_blocks_gauges, peer.last_available_block); - add_and_set_gauge("unique_first_block_count", unique_first_block_counts_gauges, peer.unique_first_block_count); - add_and_set_gauge("latency", latency_gauges, peer.latency); - add_and_set_gauge("bytes_received", bytes_received_gauges, peer.bytes_received); - add_and_set_gauge("last_bytes_received", last_bytes_received_gauges, peer.last_bytes_received.count()); - add_and_set_gauge("bytes_sent", bytes_sent_gauges, peer.bytes_sent); - add_and_set_gauge("last_bytes_sent", last_bytes_sent_gauges, peer.last_bytes_sent.count()); - add_and_set_gauge("connection_start_time", connection_start_time_gauges, peer.connection_start_time.count()); - add_and_set_gauge(peer.log_p2p_address, log_p2p_address_gauges, 0); // Empty gauge; we only want the label + add_and_set_gauge(addr, 0); // Empty gauge; ipv6 address can't be transmitted as a double + add_and_set_gauge("port", peer.port); + add_and_set_gauge("accepting_blocks", peer.accepting_blocks); + add_and_set_gauge("last_received_block", peer.last_received_block); + add_and_set_gauge("first_available_block", peer.first_available_block); + add_and_set_gauge("last_available_block", peer.last_available_block); + add_and_set_gauge("unique_first_block_count", peer.unique_first_block_count); + add_and_set_gauge("latency", peer.latency); + add_and_set_gauge("bytes_received", peer.bytes_received); + add_and_set_gauge("last_bytes_received", peer.last_bytes_received.count()); + add_and_set_gauge("bytes_sent", peer.bytes_sent); + add_and_set_gauge("last_bytes_sent", peer.last_bytes_sent.count()); + add_and_set_gauge("connection_start_time", peer.connection_start_time.count()); + add_and_set_gauge(peer.log_p2p_address, 0); // Empty gauge; we only want the label } } From ef44bfb421f6f7834c0e578e10e70ac223865e9e Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Mon, 14 Aug 2023 14:25:34 -0500 Subject: [PATCH 65/79] Add logging when remote endpoint can't be retrieved. For traceability when Prometheus data is missing the address. --- plugins/net_plugin/net_plugin.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index beaa367e3a..25c83bb93d 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -1221,6 +1221,7 @@ namespace eosio { } } else { + fc_dlog( logger, "unable to retrieve remote endpoint for local ${address}:${port}", ("address", local_endpoint_ip)("port", local_endpoint_port)); remote_endpoint_ip_array = boost::asio::ip::address_v6().to_bytes(); } } From 6b6ea382b48167062a44b7207371a57b6ce8d9df Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Mon, 14 Aug 2023 14:34:50 -0500 Subject: [PATCH 66/79] Use fc::unique_lock on an fc::mutex. --- plugins/net_plugin/net_plugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index 25c83bb93d..f7f5d5d51c 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -4462,7 +4462,7 @@ namespace eosio { ++num_peers; } if (update_p2p_connection_metrics) { - std::unique_lock g_conn((*it)->conn_mtx); + fc::unique_lock g_conn((*it)->conn_mtx); boost::asio::ip::address_v6::bytes_type addr = (*it)->remote_endpoint_ip_array; g_conn.unlock(); net_plugin::p2p_per_connection_metrics::connection_metric metrics{ From 09ea0cc135cb67d06919c7a1c5fa87e209106160 Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Mon, 14 Aug 2023 14:41:12 -0500 Subject: [PATCH 67/79] Change over bandwidth field tracking to connection ID from IP. --- tools/net-util.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tools/net-util.py b/tools/net-util.py index 32a651f27d..061ec8b2b8 100755 --- a/tools/net-util.py +++ b/tools/net-util.py @@ -326,19 +326,19 @@ def __init__(self, bytesReceived=0, bytesSent=0, connectionStarted=0): listwalker[startOffset:endOffset] = [AttrMap(Text(host), None, 'reversed')] elif fieldName == 'bytes_received': bytesReceived = int(sample.value) - stats = bandwidths.get(host, bandwidthStats()) + stats = bandwidths.get(connID, bandwidthStats()) stats.bytesReceived = bytesReceived - bandwidths[host] = stats + bandwidths[connID] = stats elif fieldName == 'bytes_sent': bytesSent = int(sample.value) - stats = bandwidths.get(host, bandwidthStats()) + stats = bandwidths.get(connID, bandwidthStats()) stats.bytesSent = bytesSent - bandwidths[host] = stats + bandwidths[connID] = stats elif fieldName == 'connection_start_time': connectionStarted = int(sample.value) - stats = bandwidths.get(host, bandwidthStats()) + stats = bandwidths.get(connID, bandwidthStats()) stats.connectionStarted = connectionStarted - bandwidths[host] = stats + bandwidths[connID] = stats else: attrname = fieldName[:1] + fieldName.replace('_', ' ').title().replace(' ', '')[1:] + 'LW' if hasattr(self, attrname): @@ -361,9 +361,9 @@ def __init__(self, bytesReceived=0, bytesSent=0, connectionStarted=0): else: if sample.name == 'nodeos_p2p_connections': now = time.time_ns() - hostListwalker = getattr(self, 'ipAddressLW') - for host, stats in bandwidths.items(): - startOffset = hostListwalker.index(host) + connIDListwalker = getattr(self, 'connectionIDLW') + for connID, stats in bandwidths.items(): + startOffset = connIDListwalker.index(connID) endOffset = startOffset + 1 connected_seconds = (now - stats.connectionStarted)/1000000000 listwalker = getattr(self, 'receiveBandwidthLW') From e4aa07ee6c3fbbff9ed706b424a5a693eac85ea8 Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Mon, 14 Aug 2023 14:58:32 -0500 Subject: [PATCH 68/79] Adjust peer list column weightings. --- tools/net-util.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/net-util.py b/tools/net-util.py index 061ec8b2b8..672dd2855e 100755 --- a/tools/net-util.py +++ b/tools/net-util.py @@ -250,7 +250,9 @@ def focus_changed(self, new_focus): listWalker.columns = listWalkers columnedList = Columns([(0, self.peerListPiles[0]), # hidden connection ID column - ('weight', 2, self.peerListPiles[1])]+self.peerListPiles[2:], + ('weight', 1, self.peerListPiles[1]), + ('weight', 0.5, self.peerListPiles[2]), + ('weight', 2, self.peerListPiles[3])]+self.peerListPiles[4:], dividechars=1, focus_column=0) self.peerLineBox = urwid.LineBox(columnedList, 'Peers:', 'left') From 667a31f4015bf06624e19ad6b41a84ac8e6ac64f Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Mon, 14 Aug 2023 16:31:20 -0400 Subject: [PATCH 69/79] upgrade to boost 1.83 --- libraries/boost | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/boost b/libraries/boost index b6928ae5c9..564e2ac169 160000 --- a/libraries/boost +++ b/libraries/boost @@ -1 +1 @@ -Subproject commit b6928ae5c92e21a04bbe17a558e6e066dbe632f6 +Subproject commit 564e2ac16907019696cdaba8a93e3588ec596062 From df318331017c8d44e1958a655226473b4c1f5250 Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Mon, 14 Aug 2023 16:37:36 -0400 Subject: [PATCH 70/79] fix sign-compare warning in dry_run_trx_tests --- unittests/dry_run_trx_tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unittests/dry_run_trx_tests.cpp b/unittests/dry_run_trx_tests.cpp index 6da0f4e75e..6ca9409bb3 100644 --- a/unittests/dry_run_trx_tests.cpp +++ b/unittests/dry_run_trx_tests.cpp @@ -157,7 +157,7 @@ BOOST_FIXTURE_TEST_CASE(setabi_test, dry_run_trx_tester) { try { send_action(act, true); // should not throw const auto* accnt = control->db().template find( "setabitest"_n ); BOOST_REQUIRE(accnt); - BOOST_TEST(accnt->abi.size() == 0); // no abi actually set + BOOST_TEST(accnt->abi.size() == 0u); // no abi actually set } FC_LOG_AND_RETHROW() } BOOST_FIXTURE_TEST_CASE(updateauth_test, dry_run_trx_tester) { try { From e3adab4f6301dce9c4b7e5b40b50808a5cac4f26 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Mon, 14 Aug 2023 16:56:34 -0500 Subject: [PATCH 71/79] GH-1432 Fix comment --- plugins/producer_plugin/test/test_block_timing_util.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/producer_plugin/test/test_block_timing_util.cpp b/plugins/producer_plugin/test/test_block_timing_util.cpp index 652ed626af..efb045b477 100644 --- a/plugins/producer_plugin/test/test_block_timing_util.cpp +++ b/plugins/producer_plugin/test/test_block_timing_util.cpp @@ -1,3 +1,4 @@ + #include #include #include @@ -131,7 +132,7 @@ BOOST_AUTO_TEST_CASE(test_calculate_producer_wake_up_time) { BOOST_CHECK_EQUAL(calculate_producer_wake_up_time(full_cpu_effort, 2, block_timestamp, producers, active_schedule, empty_watermarks), block_time); } } - { // We have all producers in active_schedule in active_schedule of 21 (plus a couple of extra producers configured), we should produce every block + { // We have all producers in active_schedule of 21 (plus a couple of extra producers configured), we should produce every block std::set producers = { "inita"_n, "initb"_n, "initc"_n, "initd"_n, "inite"_n, "initf"_n, "initg"_n, "p1"_n, "inith"_n, "initi"_n, "initj"_n, "initk"_n, "initl"_n, "initm"_n, "initn"_n, From d175de698dd8103b3d40c45dedfab4e8cc730702 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Tue, 15 Aug 2023 10:58:28 -0400 Subject: [PATCH 72/79] Use sliced_pages_for_ro_thread EOS VM OC Tierup --- .../include/eosio/chain/webassembly/eos-vm-oc/memory.hpp | 4 ++++ libraries/chain/wasm_interface_collection.cpp | 2 +- libraries/chain/webassembly/runtimes/eos-vm-oc.cpp | 5 +---- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/libraries/chain/include/eosio/chain/webassembly/eos-vm-oc/memory.hpp b/libraries/chain/include/eosio/chain/webassembly/eos-vm-oc/memory.hpp index cce12a2703..2197878d30 100644 --- a/libraries/chain/include/eosio/chain/webassembly/eos-vm-oc/memory.hpp +++ b/libraries/chain/include/eosio/chain/webassembly/eos-vm-oc/memory.hpp @@ -48,6 +48,10 @@ class memory { static constexpr uintptr_t first_intrinsic_offset = cb_offset + 8u; // The maximum amount of data that PIC code can include in the prologue static constexpr uintptr_t max_prologue_size = mutable_global_size + table_size; + // Number of slices for read-only threads. + // Use a small number to save upfront virtual memory consumption. + // Memory uses beyond this limit will be handled by mprotect. + static constexpr uint32_t sliced_pages_for_ro_thread = 10; // Changed from -cb_offset == EOS_VM_OC_CONTROL_BLOCK_OFFSET to get around // of compile warning about comparing integers of different signedness diff --git a/libraries/chain/wasm_interface_collection.cpp b/libraries/chain/wasm_interface_collection.cpp index eace6f6517..8fb065e7b9 100644 --- a/libraries/chain/wasm_interface_collection.cpp +++ b/libraries/chain/wasm_interface_collection.cpp @@ -28,7 +28,7 @@ struct eosvmoc_tier { }; thread_local std::unique_ptr eosvmoc_tier::exec{}; -thread_local eosvmoc::memory eosvmoc_tier::mem{wasm_constraints::maximum_linear_memory / wasm_constraints::wasm_page_size}; +thread_local eosvmoc::memory eosvmoc_tier::mem{eosvmoc::memory::sliced_pages_for_ro_thread}; #endif wasm_interface_collection::wasm_interface_collection(wasm_interface::vm_type vm, wasm_interface::vm_oc_enable eosvmoc_tierup, diff --git a/libraries/chain/webassembly/runtimes/eos-vm-oc.cpp b/libraries/chain/webassembly/runtimes/eos-vm-oc.cpp index 9c7fd4ca21..6d0f06870b 100644 --- a/libraries/chain/webassembly/runtimes/eos-vm-oc.cpp +++ b/libraries/chain/webassembly/runtimes/eos-vm-oc.cpp @@ -60,9 +60,6 @@ void eosvmoc_runtime::init_thread_local_data() { } thread_local std::unique_ptr eosvmoc_runtime::exec_thread_local {}; -// Set sliced_pages_for_ro_thread to a small number to save upfront virtual memory -// consumption. Usage beyond this limit will be handled by mprotect. -constexpr uint32_t sliced_pages_for_ro_thread = 10; -thread_local eosvmoc::memory eosvmoc_runtime::mem_thread_local{sliced_pages_for_ro_thread}; +thread_local eosvmoc::memory eosvmoc_runtime::mem_thread_local{eosvmoc::memory::sliced_pages_for_ro_thread}; }}}} From 460eefb1bb5aa46ce8b8ff0ca7b6062b3cccf26d Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Tue, 15 Aug 2023 13:46:45 -0400 Subject: [PATCH 73/79] ifdef out EOS VM JIT when not supported --- libraries/chain/webassembly/runtimes/eos-vm.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libraries/chain/webassembly/runtimes/eos-vm.cpp b/libraries/chain/webassembly/runtimes/eos-vm.cpp index 033cf978a3..037162beda 100644 --- a/libraries/chain/webassembly/runtimes/eos-vm.cpp +++ b/libraries/chain/webassembly/runtimes/eos-vm.cpp @@ -240,11 +240,12 @@ std::unique_ptr eos_vm_runtime::instan apply_options options = { .max_pages = 65536, .max_call_depth = 0 }; std::unique_ptr bkend = nullptr; - if constexpr (std::is_same_v) { +#ifdef EOSIO_EOS_VM_JIT_RUNTIME_ENABLED + if constexpr (std::is_same_v) bkend = std::make_unique(code, code_size, nullptr, options, true); // true -- JIT uses single parsing - } else { + else +#endif bkend = std::make_unique(code, code_size, nullptr, options, false); // false -- Interpreter uses 2-passes parsing - } eos_vm_host_functions_t::resolve(bkend->get_module()); return std::make_unique>(this, std::move(bkend)); } catch(eosio::vm::exception& e) { From 0352ec5a5537dfdb642d9e86d0146ba431e85532 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Tue, 15 Aug 2023 15:43:15 -0400 Subject: [PATCH 74/79] Keep original 529 sliced pages for main thread OC tierup; make sure tierup and OC runtime do not create slices at the same time --- .../include/eosio/chain/webassembly/eos-vm-oc.hpp | 2 +- libraries/chain/wasm_interface_collection.cpp | 15 +++++++++------ .../chain/webassembly/runtimes/eos-vm-oc.cpp | 7 ++++--- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/libraries/chain/include/eosio/chain/webassembly/eos-vm-oc.hpp b/libraries/chain/include/eosio/chain/webassembly/eos-vm-oc.hpp index 21d6cf79b0..596e6fb76a 100644 --- a/libraries/chain/include/eosio/chain/webassembly/eos-vm-oc.hpp +++ b/libraries/chain/include/eosio/chain/webassembly/eos-vm-oc.hpp @@ -41,7 +41,7 @@ class eosvmoc_runtime : public eosio::chain::wasm_runtime_interface { // Defined in eos-vm-oc.cpp. Used for non-main thread in multi-threaded execution thread_local static std::unique_ptr exec_thread_local; - thread_local static eosvmoc::memory mem_thread_local; + thread_local static std::unique_ptr mem_thread_local; }; /** diff --git a/libraries/chain/wasm_interface_collection.cpp b/libraries/chain/wasm_interface_collection.cpp index 8fb065e7b9..0ea68397bf 100644 --- a/libraries/chain/wasm_interface_collection.cpp +++ b/libraries/chain/wasm_interface_collection.cpp @@ -9,26 +9,29 @@ namespace eosio::chain { #ifdef EOSIO_EOS_VM_OC_RUNTIME_ENABLED struct eosvmoc_tier { + // Called from main thread eosvmoc_tier(const std::filesystem::path& d, const eosvmoc::config& c, const chainbase::database& db) : cc(d, c, db) { - // construct exec for the main thread - init_thread_local_data(); + // Construct exec and mem for the main thread + exec = std::make_unique(cc); + mem = std::make_unique(wasm_constraints::maximum_linear_memory/wasm_constraints::wasm_page_size); } - // Support multi-threaded execution. + // Called from read-only threads void init_thread_local_data() { exec = std::make_unique(cc); + mem = std::make_unique(eosvmoc::memory::sliced_pages_for_ro_thread); } eosvmoc::code_cache_async cc; // Each thread requires its own exec and mem. thread_local static std::unique_ptr exec; - thread_local static eosvmoc::memory mem; + thread_local static std::unique_ptr mem; }; thread_local std::unique_ptr eosvmoc_tier::exec{}; -thread_local eosvmoc::memory eosvmoc_tier::mem{eosvmoc::memory::sliced_pages_for_ro_thread}; +thread_local std::unique_ptr eosvmoc_tier::mem{}; #endif wasm_interface_collection::wasm_interface_collection(wasm_interface::vm_type vm, wasm_interface::vm_oc_enable eosvmoc_tierup, @@ -71,7 +74,7 @@ void wasm_interface_collection::apply(const digest_type& code_hash, const uint8_ if (cd) { if (!context.is_applying_block()) // read_only_trx_test.py looks for this log statement tlog("${a} speculatively executing ${h} with eos vm oc", ("a", context.get_receiver())("h", code_hash)); - eosvmoc->exec->execute(*cd, eosvmoc->mem, context); + eosvmoc->exec->execute(*cd, *eosvmoc->mem, context); return; } } diff --git a/libraries/chain/webassembly/runtimes/eos-vm-oc.cpp b/libraries/chain/webassembly/runtimes/eos-vm-oc.cpp index 6d0f06870b..3a20d83e7c 100644 --- a/libraries/chain/webassembly/runtimes/eos-vm-oc.cpp +++ b/libraries/chain/webassembly/runtimes/eos-vm-oc.cpp @@ -34,7 +34,7 @@ class eosvmoc_instantiated_module : public wasm_instantiated_module_interface { if ( is_main_thread() ) _eosvmoc_runtime.exec.execute(*cd, _eosvmoc_runtime.mem, context); else - _eosvmoc_runtime.exec_thread_local->execute(*cd, _eosvmoc_runtime.mem_thread_local, context); + _eosvmoc_runtime.exec_thread_local->execute(*cd, *_eosvmoc_runtime.mem_thread_local, context); } const digest_type _code_hash; @@ -57,9 +57,10 @@ std::unique_ptr eosvmoc_runtime::instantiate void eosvmoc_runtime::init_thread_local_data() { exec_thread_local = std::make_unique(cc); + mem_thread_local = std::make_unique(eosvmoc::memory::sliced_pages_for_ro_thread); } -thread_local std::unique_ptr eosvmoc_runtime::exec_thread_local {}; -thread_local eosvmoc::memory eosvmoc_runtime::mem_thread_local{eosvmoc::memory::sliced_pages_for_ro_thread}; +thread_local std::unique_ptr eosvmoc_runtime::exec_thread_local{}; +thread_local std::unique_ptr eosvmoc_runtime::mem_thread_local{}; }}}} From 1f1ea007b300326d3b738985fe3afc3017fdd812 Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Tue, 15 Aug 2023 15:59:03 -0500 Subject: [PATCH 75/79] Update help preamble to better describe net-util's current capabilities. --- tools/net-util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/net-util.py b/tools/net-util.py index 672dd2855e..01d0862749 100755 --- a/tools/net-util.py +++ b/tools/net-util.py @@ -177,7 +177,7 @@ def labelToAttrName(label: str, fieldType='Text'): self.fields.update({k:v for k, v in zip(self.rightFieldLabels[1:], [labelToAttrName(e) for e in self.rightFieldLabels[1:]])}) self.fields.update({k:v for k, v in zip(self.infoFieldLabels, [labelToAttrName(e) for e in self.infoFieldLabels])}) - parser = argparse.ArgumentParser(description='Terminal UI for monitoring and managing nodeos P2P connections', + parser = argparse.ArgumentParser(description='Terminal UI for monitoring nodeos P2P connections', formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('--host', help='hostname or IP address to connect to', default='127.0.0.1') parser.add_argument('-p', '--port', help='port number to connect to', default='8888') From e9ace457e46898e377df1e0a6d1fb8049d8cb5e2 Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Tue, 15 Aug 2023 17:58:32 -0400 Subject: [PATCH 76/79] fix leaky EOS VM OC executor code mapping --- libraries/chain/webassembly/runtimes/eos-vm-oc/executor.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/chain/webassembly/runtimes/eos-vm-oc/executor.cpp b/libraries/chain/webassembly/runtimes/eos-vm-oc/executor.cpp index 8057c0e181..fe33ee3d0c 100644 --- a/libraries/chain/webassembly/runtimes/eos-vm-oc/executor.cpp +++ b/libraries/chain/webassembly/runtimes/eos-vm-oc/executor.cpp @@ -266,6 +266,7 @@ void executor::execute(const code_descriptor& code, memory& mem, apply_context& executor::~executor() { arch_prctl(ARCH_SET_GS, nullptr); + munmap(code_mapping, code_mapping_size); } }}} From 948d258846163809fbdbafa2cade48486a2519dc Mon Sep 17 00:00:00 2001 From: greg7mdp Date: Tue, 15 Aug 2023 20:24:07 -0400 Subject: [PATCH 77/79] Add some `[[nodiscard]]` attributes and remove unused type --- .../chain/include/eosio/chain/transaction_object.hpp | 1 - libraries/libfc/include/fc/mutex.hpp | 12 ++++++------ libraries/libfc/include/fc/scoped_exit.hpp | 4 ++-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/libraries/chain/include/eosio/chain/transaction_object.hpp b/libraries/chain/include/eosio/chain/transaction_object.hpp index d43b449be4..301988e33d 100644 --- a/libraries/chain/include/eosio/chain/transaction_object.hpp +++ b/libraries/chain/include/eosio/chain/transaction_object.hpp @@ -42,7 +42,6 @@ namespace eosio { namespace chain { > >; - typedef chainbase::generic_index transaction_index; } } CHAINBASE_SET_INDEX_TYPE(eosio::chain::transaction_object, eosio::chain::transaction_multi_index) diff --git a/libraries/libfc/include/fc/mutex.hpp b/libraries/libfc/include/fc/mutex.hpp index 518a9ccd8b..eaa1a13883 100644 --- a/libraries/libfc/include/fc/mutex.hpp +++ b/libraries/libfc/include/fc/mutex.hpp @@ -127,13 +127,13 @@ class SCOPED_CAPABILITY lock_guard { public: // Acquire mu, implicitly acquire *this and associate it with mu. - lock_guard(M& mu) ACQUIRE(mu) + [[nodiscard]] lock_guard(M& mu) ACQUIRE(mu) : mut(mu) { mu.lock(); } // Assume mu is held, implicitly acquire *this and associate it with mu. - lock_guard(M& mu, adopt_lock_t) REQUIRES(mu) + [[nodiscard]] lock_guard(M& mu, adopt_lock_t) REQUIRES(mu) : mut(mu) {} ~lock_guard() RELEASE() { mut.unlock(); } @@ -150,24 +150,24 @@ class SCOPED_CAPABILITY unique_lock { bool locked; public: - unique_lock() noexcept + [[nodiscard]] unique_lock() noexcept : mut(nullptr) , locked(false) {} // Acquire mu, implicitly acquire *this and associate it with mu. - explicit unique_lock(M& mu) ACQUIRE(mu) + [[nodiscard]] explicit unique_lock(M& mu) ACQUIRE(mu) : mut(&mu) , locked(true) { mut->lock(); } // Assume mu is held, implicitly acquire *this and associate it with mu. - unique_lock(M& mu, adopt_lock_t) REQUIRES(mu) + [[nodiscard]] unique_lock(M& mu, adopt_lock_t) REQUIRES(mu) : mut(&mu) , locked(true) {} // Assume mu is not held, implicitly acquire *this and associate it with mu. - unique_lock(M& mu, defer_lock_t) EXCLUDES(mu) + [[nodiscard]] unique_lock(M& mu, defer_lock_t) EXCLUDES(mu) : mut(mu) , locked(false) {} diff --git a/libraries/libfc/include/fc/scoped_exit.hpp b/libraries/libfc/include/fc/scoped_exit.hpp index 8cae626b87..657bfe6a08 100644 --- a/libraries/libfc/include/fc/scoped_exit.hpp +++ b/libraries/libfc/include/fc/scoped_exit.hpp @@ -8,9 +8,9 @@ namespace fc { class scoped_exit { public: template - scoped_exit( C&& c ):callback( std::forward(c) ){} + [[nodiscard]] scoped_exit( C&& c ):callback( std::forward(c) ){} - scoped_exit( scoped_exit&& mv ) + [[nodiscard]] scoped_exit( scoped_exit&& mv ) :callback( std::move( mv.callback ) ),canceled(mv.canceled) { mv.canceled = true; From 1923622ff8e3a428eda588aeee1034f912145ed4 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Tue, 15 Aug 2023 20:58:34 -0400 Subject: [PATCH 78/79] Add a test to verify virtual memory taking by OC does not grow by TBs as the number of read-only threads increases --- tests/read_only_trx_test.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/tests/read_only_trx_test.py b/tests/read_only_trx_test.py index 752f9775b7..9ce19d03da 100755 --- a/tests/read_only_trx_test.py +++ b/tests/read_only_trx_test.py @@ -4,6 +4,7 @@ import time import signal import threading +import os from TestHarness import Account, Cluster, ReturnType, TestHelper, Utils, WalletMgr from TestHarness.TestHelper import AppArgs @@ -132,6 +133,29 @@ def startCluster(): found = producerNode.findInLog(f"executing {eosioCodeHash} with eos vm oc") assert( found or (noOC and not found) ) + if args.eos_vm_oc_enable: + verifyOcVirtualMemory() + +def verifyOcVirtualMemory(): + try: + with open(f"/proc/{apiNode.pid}/statm") as f: + data = f.read().split() + vmPages = int(data[0]) + pageSize = os.sysconf("SC_PAGESIZE") + actualVmSize = vmPages * pageSize + + # When OC tierup is enabled, virtual memory used by IC is around + # 529 slices * 8GB (for main thread) + numReadOnlyThreads * 11 slices * 8GB + # This test verifies virtual memory taken by one read-only thread + # is not in the order of 1TB. + otherGB = 1000 # add 1TB for virtual memory used by others + expectedVmSize = ((529 * 8) + (args.read_only_threads * 88) + otherGB) * 1024 * 1024 * 1024 + Utils.Print(f"pid: {apiNode.pid}, actualVmSize: {actualVmSize}, expectedVmSize: {expectedVmSize}") + assert(actualVmSize < expectedVmSize) + except FileNotFoundError: + Utils.Print(f"/proc/{apiNode.pid}/statm not found") + assert(False) + def deployTestContracts(): Utils.Print("create test accounts") testAccount = Account(testAccountName) @@ -348,4 +372,4 @@ def runEverythingParallel(): TestHelper.shutdown(cluster, walletMgr, testSuccessful, dumpErrorDetails) errorCode = 0 if testSuccessful else 1 -exit(errorCode) \ No newline at end of file +exit(errorCode) From 75c5ebb476f66546fc4bd753e5a8b884eef91597 Mon Sep 17 00:00:00 2001 From: Lin Huang Date: Wed, 16 Aug 2023 12:35:52 -0400 Subject: [PATCH 79/79] skip OC test if platform is not Linux --- tests/read_only_trx_test.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/read_only_trx_test.py b/tests/read_only_trx_test.py index 9ce19d03da..661c3fded8 100755 --- a/tests/read_only_trx_test.py +++ b/tests/read_only_trx_test.py @@ -5,6 +5,7 @@ import signal import threading import os +import platform from TestHarness import Account, Cluster, ReturnType, TestHelper, Utils, WalletMgr from TestHarness.TestHelper import AppArgs @@ -110,6 +111,9 @@ def startCluster(): specificExtraNodeosArgs[pnodes]+=" --read-only-threads " specificExtraNodeosArgs[pnodes]+=str(args.read_only_threads) if args.eos_vm_oc_enable: + if platform.system() != "Linux": + Print("OC not run on Linux. Skip the test") + exit(True) # Do not fail the test specificExtraNodeosArgs[pnodes]+=" --eos-vm-oc-enable " specificExtraNodeosArgs[pnodes]+=args.eos_vm_oc_enable if args.wasm_runtime: