1111
1212namespace eosio { namespace chain {
1313
14+ using shared_public_key_data = fc::static_variant<fc::ecc::public_key_shim, fc::crypto::r1::public_key_shim, shared_string>;
15+
16+ template <class ... Ts> struct overloaded : Ts... { using Ts::operator ()...; };
17+ template <class ... Ts> overloaded (Ts...) -> overloaded<Ts...>;
18+
19+ struct shared_public_key {
20+ shared_public_key ( shared_public_key_data&& p ) :
21+ pubkey (std::move(p)) {}
22+
23+ operator public_key_type () const {
24+ fc::crypto::public_key::storage_type public_key_storage;
25+ pubkey.visit (overloaded {
26+ [&](const auto & k1r1) {
27+ public_key_storage = k1r1;
28+ },
29+ [&](const shared_string& wa) {
30+ fc::datastream ds (wa.data (), wa.size ());
31+ fc::crypto::webauthn::public_key pub;
32+ fc::raw::unpack (ds, pub);
33+ public_key_storage = pub;
34+ }
35+ });
36+ return std::move (public_key_storage);
37+ }
38+
39+ operator string () const {
40+ return (string)this ->operator public_key_type ();
41+ }
42+
43+ shared_public_key_data pubkey;
44+
45+ friend bool operator == ( const shared_public_key& lhs, const shared_public_key& rhs ) {
46+ if (lhs.pubkey .which () != rhs.pubkey .which ())
47+ return false ;
48+
49+ return lhs.pubkey .visit <bool >(overloaded {
50+ [&](const fc::ecc::public_key_shim& k1) {
51+ return k1._data == rhs.pubkey .get <fc::ecc::public_key_shim>()._data ;
52+ },
53+ [&](const fc::crypto::r1::public_key_shim& r1) {
54+ return r1._data == rhs.pubkey .get <fc::crypto::r1::public_key_shim>()._data ;
55+ },
56+ [&](const shared_string& wa) {
57+ return wa == rhs.pubkey .get <shared_string>();
58+ }
59+ });
60+ }
61+
62+ friend bool operator ==(const shared_public_key& l, const public_key_type& r) {
63+ if (l.pubkey .which () != r._storage .which ())
64+ return false ;
65+
66+ return l.pubkey .visit <bool >(overloaded {
67+ [&](const fc::ecc::public_key_shim& k1) {
68+ return k1._data == r._storage .get <fc::ecc::public_key_shim>()._data ;
69+ },
70+ [&](const fc::crypto::r1::public_key_shim& r1) {
71+ return r1._data == r._storage .get <fc::crypto::r1::public_key_shim>()._data ;
72+ },
73+ [&](const shared_string& wa) {
74+ fc::datastream ds (wa.data (), wa.size ());
75+ fc::crypto::webauthn::public_key pub;
76+ fc::raw::unpack (ds, pub);
77+ return pub == r._storage .get <fc::crypto::webauthn::public_key>();
78+ }
79+ });
80+ }
81+
82+ friend bool operator ==(const public_key_type& l, const shared_public_key& r) {
83+ return r == l;
84+ }
85+ };
1486
1587struct permission_level_weight {
1688 permission_level permission;
@@ -30,6 +102,23 @@ struct key_weight {
30102 }
31103};
32104
105+
106+ struct shared_key_weight {
107+ shared_key_weight (shared_public_key_data&& k, const weight_type& w) :
108+ key (std::move(k)), weight(w) {}
109+
110+ operator key_weight () const {
111+ return key_weight{key, weight};
112+ }
113+
114+ shared_public_key key;
115+ weight_type weight;
116+
117+ friend bool operator == ( const shared_key_weight& lhs, const shared_key_weight& rhs ) {
118+ return tie ( lhs.key , lhs.weight ) == tie ( rhs.key , rhs.weight );
119+ }
120+ };
121+
33122struct wait_weight {
34123 uint32_t wait_sec;
35124 weight_type weight;
@@ -100,14 +189,31 @@ struct shared_authority {
100189
101190 shared_authority& operator =(const authority& a) {
102191 threshold = a.threshold ;
103- keys = decltype (keys)(a.keys .begin (), a.keys .end (), keys.get_allocator ());
192+ keys.clear ();
193+ keys.reserve (a.keys .size ());
194+ for (const key_weight& k : a.keys ) {
195+ k.key ._storage .visit (overloaded {
196+ [&](const auto & k1r1) {
197+ keys.emplace_back (k1r1, k.weight );
198+ },
199+ [&](const fc::crypto::webauthn::public_key& wa) {
200+ fc::datastream<size_t > dsz;
201+ fc::raw::pack (dsz, wa);
202+ shared_string wa_ss (dsz.tellp (), boost::container::default_init, keys.get_allocator ());
203+ fc::datastream<char *> ds (wa_ss.data (), wa_ss.size ());
204+ fc::raw::pack (ds, wa);
205+
206+ keys.emplace_back (std::move (wa_ss), k.weight );
207+ }
208+ });
209+ }
104210 accounts = decltype (accounts)(a.accounts .begin (), a.accounts .end (), accounts.get_allocator ());
105211 waits = decltype (waits)(a.waits .begin (), a.waits .end (), waits.get_allocator ());
106212 return *this ;
107213 }
108214
109215 uint32_t threshold = 0 ;
110- shared_vector<key_weight> keys;
216+ shared_vector<shared_key_weight> keys;
111217 shared_vector<permission_level_weight> accounts;
112218 shared_vector<wait_weight> waits;
113219
@@ -202,4 +308,6 @@ FC_REFLECT(eosio::chain::permission_level_weight, (permission)(weight) )
202308FC_REFLECT (eosio::chain::key_weight, (key)(weight) )
203309FC_REFLECT (eosio::chain::wait_weight, (wait_sec)(weight) )
204310FC_REFLECT (eosio::chain::authority, (threshold)(keys)(accounts)(waits) )
311+ FC_REFLECT (eosio::chain::shared_key_weight, (key)(weight) )
205312FC_REFLECT (eosio::chain::shared_authority, (threshold)(keys)(accounts)(waits) )
313+ FC_REFLECT (eosio::chain::shared_public_key, (pubkey))
0 commit comments