Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
authority.hpp
Go to the documentation of this file.
1#pragma once
5
6#include <type_traits>
7
8namespace sysio { namespace chain {
9
10using shared_public_key_data = std::variant<fc::ecc::public_key_shim, fc::crypto::r1::public_key_shim, shared_string, fc::em::public_key_shim>;
11
15
16 operator public_key_type() const {
17 fc::crypto::public_key::storage_type public_key_storage;
18 std::visit(overloaded {
19 [&](const auto& k1r1em) {
20 public_key_storage = k1r1em;
21 },
22 [&](const shared_string& wa) {
23 fc::datastream<const char*> ds(wa.data(), wa.size());
26 public_key_storage = pub;
27 }
28 }, pubkey);
29 return std::move(public_key_storage);
30 }
31
32 std::string to_string() const {
33 return this->operator public_key_type().to_string();
34 }
35
37
38 friend bool operator == ( const shared_public_key& lhs, const shared_public_key& rhs ) {
39 if(lhs.pubkey.index() != rhs.pubkey.index())
40 return false;
41
42 return std::visit(overloaded {
43 [&](const fc::ecc::public_key_shim& k1) {
44 return k1._data == std::get<fc::ecc::public_key_shim>(rhs.pubkey)._data;
45 },
46 [&](const fc::em::public_key_shim& em) { // Added EM handling
47 return em._data == std::get<fc::em::public_key_shim>(rhs.pubkey)._data;
48 },
49 [&](const fc::crypto::r1::public_key_shim& r1) {
50 return r1._data == std::get<fc::crypto::r1::public_key_shim>(rhs.pubkey)._data;
51 },
52 [&](const shared_string& wa) {
53 return wa == std::get<shared_string>(rhs.pubkey);
54 }
55 }, lhs.pubkey);
56 }
57
58 friend bool operator==(const shared_public_key& l, const public_key_type& r) {
59 if(l.pubkey.index() != r._storage.index())
60 return false;
61
62 return std::visit(overloaded {
63 [&](const fc::ecc::public_key_shim& k1) {
64 return k1._data == std::get<fc::ecc::public_key_shim>(r._storage)._data;
65 },
66 [&](const fc::em::public_key_shim& em) {
67 return em._data == std::get<fc::em::public_key_shim>(r._storage)._data;
68 },
69 [&](const fc::crypto::r1::public_key_shim& r1) {
70 return r1._data == std::get<fc::crypto::r1::public_key_shim>(r._storage)._data;
71 },
72 [&](const shared_string& wa) {
73 fc::datastream<const char*> ds(wa.data(), wa.size());
76 return pub == std::get<fc::crypto::webauthn::public_key>(r._storage);
77 }
78 }, l.pubkey);
79 }
80
81 friend bool operator==(const public_key_type& l, const shared_public_key& r) {
82 return r == l;
83 }
84};
85
89
90 friend bool operator == ( const permission_level_weight& lhs, const permission_level_weight& rhs ) {
91 return tie( lhs.permission, lhs.weight ) == tie( rhs.permission, rhs.weight );
92 }
93};
94
95struct key_weight {
98
99 friend bool operator == ( const key_weight& lhs, const key_weight& rhs ) {
100 return tie( lhs.key, lhs.weight ) == tie( rhs.key, rhs.weight );
101 }
102};
103
104
107 key(std::move(k)), weight(w) {}
108
109 operator key_weight() const {
110 return key_weight{key, weight};
111 }
112
114 return std::visit(overloaded {
115 [&](const auto& k1r1em) {
116 return shared_key_weight(k1r1em, k.weight);
117 },
119 size_t psz = fc::raw::pack_size(wa);
120 shared_string wa_ss(std::move(allocator));
121 wa_ss.resize_and_fill( psz, [&wa]( char* data, std::size_t sz ) {
122 fc::datastream<char*> ds(data, sz);
123 fc::raw::pack(ds, wa);
124 });
125
126 return shared_key_weight(std::move(wa_ss), k.weight);
127 }
128 }, k.key._storage);
129 }
130
133
134 friend bool operator == ( const shared_key_weight& lhs, const shared_key_weight& rhs ) {
135 return tie( lhs.key, lhs.weight ) == tie( rhs.key, rhs.weight );
136 }
137};
138
142
143 friend bool operator == ( const wait_weight& lhs, const wait_weight& rhs ) {
144 return tie( lhs.wait_sec, lhs.weight ) == tie( rhs.wait_sec, rhs.weight );
145 }
146};
147
148namespace config {
149 template<>
151 static const uint64_t value = 24;
152 };
153
154 template<>
156 static const uint64_t value = 8;
157 };
158
159 template<>
161 static const uint64_t value = 16;
162 };
163}
164
165struct authority {
167 :threshold(1),keys({{k,1}})
168 {
169 if( delay_sec > 0 ) {
170 threshold = 2;
171 waits.push_back(wait_weight{delay_sec, 1});
172 }
173 }
174
176 :threshold(1),accounts({{p,1}})
177 {
178 if( delay_sec > 0 ) {
179 threshold = 2;
180 waits.push_back(wait_weight{delay_sec, 1});
181 }
182 }
183
187
192
193 friend bool operator == ( const authority& lhs, const authority& rhs ) {
194 return tie( lhs.threshold, lhs.keys, lhs.accounts, lhs.waits ) == tie( rhs.threshold, rhs.keys, rhs.accounts, rhs.waits );
195 }
196
197 friend bool operator != ( const authority& lhs, const authority& rhs ) {
198 return tie( lhs.threshold, lhs.keys, lhs.accounts, lhs.waits ) != tie( rhs.threshold, rhs.keys, rhs.accounts, rhs.waits );
199 }
200};
201
202
205 :keys(alloc),accounts(alloc),waits(alloc){}
206
209 keys.clear();
210 keys.reserve(a.keys.size());
211 for(const key_weight& k : a.keys) {
212 keys.emplace_back(shared_key_weight::convert(keys.get_allocator(), k));
213 }
214 accounts = decltype(accounts)(a.accounts.begin(), a.accounts.end(), accounts.get_allocator());
215 waits = decltype(waits)(a.waits.begin(), a.waits.end(), waits.get_allocator());
216 return *this;
217 }
218
223
224 operator authority()const { return to_authority(); }
226 authority auth;
227 auth.threshold = threshold;
228 auth.keys.reserve(keys.size());
229 auth.accounts.reserve(accounts.size());
230 auth.waits.reserve(waits.size());
231 for( const auto& k : keys ) { auth.keys.emplace_back( k ); }
232 for( const auto& a : accounts ) { auth.accounts.emplace_back( a ); }
233 for( const auto& w : waits ) { auth.waits.emplace_back( w ); }
234 return auth;
235 }
236
237 size_t get_billable_size() const {
238 size_t accounts_size = accounts.size() * config::billable_size_v<permission_level_weight>;
239 size_t waits_size = waits.size() * config::billable_size_v<wait_weight>;
240 size_t keys_size = 0;
241 for (const auto& k: keys) {
243 keys_size += fc::raw::pack_size(k.key);
244 }
245
246 return accounts_size + waits_size + keys_size;
247 }
248};
249
250namespace config {
251 template<>
253 static const uint64_t value = (3 * config::fixed_overhead_shared_vector_ram_bytes) + 4;
254 };
255}
256
261template<typename Authority>
262inline bool validate( const Authority& auth ) {
263 decltype(auth.threshold) total_weight = 0;
264
265 static_assert( std::is_same<decltype(auth.threshold), uint32_t>::value &&
266 std::is_same<weight_type, uint16_t>::value &&
267 std::is_same<typename decltype(auth.keys)::value_type, key_weight>::value &&
268 std::is_same<typename decltype(auth.accounts)::value_type, permission_level_weight>::value &&
269 std::is_same<typename decltype(auth.waits)::value_type, wait_weight>::value,
270 "unexpected type for threshold and/or weight in authority" );
271
272 if( ( auth.keys.size() + auth.accounts.size() + auth.waits.size() ) > (1 << 16) )
273 return false; // overflow protection (assumes weight_type is uint16_t and threshold is of type uint32_t)
274
275 if( auth.threshold == 0 )
276 return false;
277
278 {
279 const key_weight* prev = nullptr;
280 for( const auto& k : auth.keys ) {
281 if( prev && !(prev->key < k.key) ) return false; // TODO: require keys to be sorted in ascending order rather than descending (requires modifying many tests)
282 total_weight += k.weight;
283 prev = &k;
284 }
285 }
286 {
287 const permission_level_weight* prev = nullptr;
288 for( const auto& a : auth.accounts ) {
289 if( prev && ( prev->permission >= a.permission ) ) return false; // TODO: require permission_levels to be sorted in ascending order rather than descending (requires modifying many tests)
290 total_weight += a.weight;
291 prev = &a;
292 }
293 }
294 {
295 const wait_weight* prev = nullptr;
296 if( auth.waits.size() > 0 && auth.waits.front().wait_sec == 0 )
297 return false;
298 for( const auto& w : auth.waits ) {
299 if( prev && ( prev->wait_sec >= w.wait_sec ) ) return false;
300 total_weight += w.weight;
301 prev = &w;
302 }
303 }
304
305 return total_weight >= auth.threshold;
306}
307
308} } // namespace sysio::chain
309
310namespace fc {
312} // namespace fc
313
316FC_REFLECT(sysio::chain::wait_weight, (wait_sec)(weight) )
317FC_REFLECT(sysio::chain::authority, (threshold)(keys)(accounts)(waits) )
319FC_REFLECT(sysio::chain::shared_authority, (threshold)(keys)(accounts)(waits) )
wasm_allocator wa
Definition main.cpp:10
const mie::Vuint & p
Definition bn.cpp:27
const mie::Vuint & r
Definition bn.cpp:28
void resize_and_fill(std::size_t new_size, F &&f)
std::variant< ecc::public_key_shim, r1::public_key_shim, webauthn::public_key, em::public_key_shim > storage_type
std::string to_string(const fc::yield_function_t &yield=fc::yield_function_t()) const
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object's.
Definition variant.hpp:191
bip::allocator< T, pinnable_mapped_file::segment_manager > allocator
Definition chainbase.hpp:56
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
size_t pack_size(const T &v)
Definition raw.hpp:671
namespace sysio::chain
Definition authority.cpp:3
void to_variant(const sysio::chain::shared_public_key &var, fc::variant &vo)
Definition authority.cpp:4
Definition name.hpp:106
constexpr uint64_t billable_size_v
Definition config.hpp:147
fc::crypto::public_key public_key_type
Definition types.hpp:76
std::variant< fc::ecc::public_key_shim, fc::crypto::r1::public_key_shim, shared_string, fc::em::public_key_shim > shared_public_key_data
Definition authority.hpp:10
boost::interprocess::vector< T, allocator< T > > shared_vector
Definition types.hpp:85
bool validate(const Authority &auth)
uint16_t weight_type
Definition types.hpp:238
#define value
Definition pkcs11.h:157
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1181
#define FC_REFLECT(TYPE, MEMBERS)
Specializes fc::reflector for TYPE.
Definition reflect.hpp:311
unsigned int uint32_t
Definition stdint.h:126
unsigned __int64 uint64_t
Definition stdint.h:136
authority(public_key_type k, uint32_t delay_sec=0)
authority(uint32_t t, vector< key_weight > k, vector< permission_level_weight > p={}, vector< wait_weight > w={})
friend bool operator!=(const authority &lhs, const authority &rhs)
friend bool operator==(const authority &lhs, const authority &rhs)
vector< wait_weight > waits
vector< permission_level_weight > accounts
authority(permission_level p, uint32_t delay_sec=0)
vector< key_weight > keys
friend bool operator==(const key_weight &lhs, const key_weight &rhs)
Definition authority.hpp:99
public_key_type key
Definition authority.hpp:96
friend bool operator==(const permission_level_weight &lhs, const permission_level_weight &rhs)
Definition authority.hpp:90
permission_name permission
Definition action.hpp:10
shared_authority(chainbase::allocator< char > alloc)
shared_vector< permission_level_weight > accounts
authority to_authority() const
shared_vector< wait_weight > waits
shared_authority & operator=(const authority &a)
shared_vector< shared_key_weight > keys
friend bool operator==(const shared_key_weight &lhs, const shared_key_weight &rhs)
static shared_key_weight convert(chainbase::allocator< char > allocator, const key_weight &k)
shared_key_weight(shared_public_key_data &&k, const weight_type &w)
shared_public_key_data pubkey
Definition authority.hpp:36
friend bool operator==(const public_key_type &l, const shared_public_key &r)
Definition authority.hpp:81
friend bool operator==(const shared_public_key &lhs, const shared_public_key &rhs)
Definition authority.hpp:38
std::string to_string() const
Definition authority.hpp:32
shared_public_key(shared_public_key_data &&p)
Definition authority.hpp:13
friend bool operator==(const shared_public_key &l, const public_key_type &r)
Definition authority.hpp:58
friend bool operator==(const wait_weight &lhs, const wait_weight &rhs)
bool pub
int l
CK_BYTE_PTR pubkey