Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
common.hpp
Go to the documentation of this file.
1#pragma once
5#include <fc/io/raw.hpp>
6#include <fc/utility.hpp>
8
9namespace fc { namespace crypto {
10 template<typename DataType>
13 uint32_t check = 0;
14 DataType data;
15
16 static auto calculate_checksum(const DataType& data, const char *prefix = nullptr) {
17 auto encoder = ripemd160::encoder();
18 raw::pack(encoder, data);
19
20 if (prefix != nullptr) {
21 encoder.write(prefix, const_strlen(prefix));
22 }
23 return encoder.result()._hash[0];
24 }
25 };
26
27 inline bool prefix_matches(const char* prefix, const std::string& str) {
28 auto prefix_len = const_strlen(prefix);
29 return str.size() > prefix_len && str.substr(0, prefix_len).compare(prefix) == 0;
30 }
31
32 template<typename, const char * const *, int, typename ...>
34
35 template<typename Result, const char * const * Prefixes, int Position, typename KeyType, typename ...Rem>
36 struct base58_str_parser_impl<Result, Prefixes, Position, KeyType, Rem...> {
37 static Result apply(const std::string& prefix_str, const std::string& data_str)
38 {
39 using data_type = typename KeyType::data_type;
40 using wrapper = checksummed_data<data_type>;
41 constexpr auto prefix = Prefixes[Position];
42
43 if (prefix == prefix_str) {
44 auto bin = fc::from_base58(data_str);
45 fc::datastream<const char*> unpacker(bin.data(), bin.size());
46 wrapper wrapped;
47 fc::raw::unpack(unpacker, wrapped);
48 FC_ASSERT(!unpacker.remaining(), "decoded base58 length too long");
49 auto checksum = wrapper::calculate_checksum(wrapped.data, prefix);
50 FC_ASSERT(checksum == wrapped.check);
51 return Result(KeyType(wrapped.data));
52 }
53
55 }
56 };
57
58 template<typename Result, const char * const * Prefixes, int Position>
59 struct base58_str_parser_impl<Result, Prefixes, Position> {
60 static Result apply(const std::string& prefix_str, const std::string& data_str ) {
61 FC_ASSERT(false, "No matching suite type for ${prefix}_${data}", ("prefix", prefix_str)("data",data_str));
62 }
63 };
64
65 template<typename, const char * const * Prefixes>
67
74 template<const char * const * Prefixes, typename ...Ts>
75 struct base58_str_parser<std::variant<Ts...>, Prefixes> {
76 static std::variant<Ts...> apply(const std::string& base58str) {
77 const auto pivot = base58str.find('_');
78 FC_ASSERT(pivot != std::string::npos, "No delimiter in data, cannot determine suite type: ${str}", ("str", base58str));
79
80 const auto prefix_str = base58str.substr(0, pivot);
81 auto data_str = base58str.substr(pivot + 1);
82 FC_ASSERT(!data_str.empty(), "Data only has suite type prefix: ${str}", ("str", base58str));
83
84 return base58_str_parser_impl<std::variant<Ts...>, Prefixes, 0, Ts...>::apply(prefix_str, data_str);
85 }
86 };
87
88 template<typename Storage, const char * const * Prefixes, int DefaultPosition = -1>
89 struct base58str_visitor : public fc::visitor<std::string> {
90 explicit base58str_visitor( const fc::yield_function_t& yield )
91 : _yield(yield) {};
92 template< typename KeyType >
93 std::string operator()( const KeyType& key ) const {
94 using data_type = typename KeyType::data_type;
95 constexpr int position = fc::get_index<Storage, KeyType>();
96 constexpr bool is_default = position == DefaultPosition;
97
99 wrapper.data = key.serialize();
100 _yield();
101 wrapper.check = checksummed_data<data_type>::calculate_checksum(wrapper.data, !is_default ? Prefixes[position] : nullptr);
102 _yield();
103 auto packed = raw::pack( wrapper );
104 _yield();
105 auto data_str = to_base58( packed.data(), packed.size(), _yield );
106 _yield();
107 if (!is_default) {
108 data_str = string(Prefixes[position]) + "_" + data_str;
109 }
110 _yield();
111
112 return data_str;
113 }
115 };
116
117 template<typename T>
119 static bool apply(const T& a, const T& b) {
120 return a.serialize() == b.serialize();
121 }
122 };
123
124 template<typename ... Ts>
125 struct eq_comparator<std::variant<Ts...>> {
126 using variant_type = std::variant<Ts...>;
127 struct visitor : public fc::visitor<bool> {
129 : _b(b) {}
130
131 template<typename KeyType>
132 bool operator()(const KeyType &a) const {
133 const auto &b = std::template get<KeyType>(_b);
135 }
136
138 };
139
140 static bool apply(const variant_type& a, const variant_type& b) {
141 return a.index() == b.index() && std::visit(visitor(b), a);
142 }
143 };
144
145 template<typename T>
147 static bool apply(const T& a, const T& b) {
148 return a.serialize() < b.serialize();
149 }
150 };
151
152 template<typename ... Ts>
153 struct less_comparator<std::variant<Ts...>> {
154 using variant_type = std::variant<Ts...>;
155 struct visitor : public fc::visitor<bool> {
157 : _b(b) {}
158
159 template<typename KeyType>
160 bool operator()(const KeyType &a) const {
161 const auto &b = std::template get<KeyType>(_b);
163 }
164
166 };
167
168 static bool apply(const variant_type& a, const variant_type& b) {
169 return a.index() < b.index() || (a.index() == b.index() && std::visit(visitor(b), a));
170 }
171 };
172
173 template<typename Data>
174 struct shim {
176
178 {}
179
181 :_data(forward<data_type>(data))
182 {}
183
184 shim(const data_type& data)
185 :_data(data)
186 {}
187
188 const data_type& serialize() const {
189 return _data;
190 }
191
193 };
194
195} }
196
198FC_REFLECT_TEMPLATE((typename T), fc::crypto::shim<T>, (_data) )
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object's.
Definition variant.hpp:191
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
bool prefix_matches(const char *prefix, const std::string &str)
Definition common.hpp:27
void unpack(Stream &s, std::deque< T > &value)
Definition raw.hpp:540
void pack(Stream &s, const std::deque< T > &value)
Definition raw.hpp:531
namespace sysio::chain
Definition authority.cpp:3
std::string to_base58(const char *d, size_t s, const fc::yield_function_t &yield)
Definition base58.cpp:618
std::string string
Definition string.hpp:10
constexpr size_t const_strlen(const char *str)
Definition utility.hpp:142
std::vector< char > from_base58(const std::string &base58_str)
Definition base58.cpp:628
constexpr std::size_t get_index()
Definition name.hpp:106
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1181
void apply(uint64_t, uint64_t, uint64_t)
#define T(meth, val, expected)
#define FC_REFLECT_TEMPLATE(TEMPLATE_ARGS, TYPE, MEMBERS)
Definition reflect.hpp:314
unsigned int uint32_t
Definition stdint.h:126
Definition zm2.cpp:48
static std::variant< Ts... > apply(const std::string &base58str)
Definition common.hpp:76
static Result apply(const std::string &prefix_str, const std::string &data_str)
Definition common.hpp:37
static Result apply(const std::string &prefix_str, const std::string &data_str)
Definition common.hpp:60
const fc::yield_function_t _yield
Definition common.hpp:114
base58str_visitor(const fc::yield_function_t &yield)
Definition common.hpp:90
std::string operator()(const KeyType &key) const
Definition common.hpp:93
static auto calculate_checksum(const DataType &data, const char *prefix=nullptr)
Definition common.hpp:16
static bool apply(const variant_type &a, const variant_type &b)
Definition common.hpp:140
static bool apply(const T &a, const T &b)
Definition common.hpp:119
static bool apply(const variant_type &a, const variant_type &b)
Definition common.hpp:168
static bool apply(const T &a, const T &b)
Definition common.hpp:147
const data_type & serialize() const
Definition common.hpp:188
shim(data_type &&data)
Definition common.hpp:180
data_type _data
Definition common.hpp:192
shim(const data_type &data)
Definition common.hpp:184