2929#pragma once
3030
3131#include " common/threadpool.h"
32+ #include " common/unordered_containers_boost_serialization.h"
3233#include " curve_trees.h"
3334#include " fcmp_pp_types.h"
35+ #include " serialization/containers.h"
36+ #include " serialization/crypto.h"
37+ #include " serialization/pair.h"
38+ #include " serialization/serialization.h"
39+
40+ #include < boost/serialization/deque.hpp>
41+ #include < boost/serialization/vector.hpp>
42+ #include < boost/serialization/version.hpp>
3443
3544#include < deque>
3645#include < memory>
@@ -43,20 +52,44 @@ namespace fcmp_pp
4352namespace curve_trees
4453{
4554// ----------------------------------------------------------------------------------------------------------------------
46- struct PendingBlind final
55+ static constexpr int BLINDS_CACHE_VERSION = 0 ;
56+ // ----------------------------------------------------------------------------------------------------------------------
57+ struct OutputBlinds final
4758{
48- uint8_t *result{nullptr };
49- PendingBlind () : result{nullptr } {};
59+ FcmpRerandomizedOutputCompressed rerandomized_output;
60+
61+ std::shared_ptr<OutputBlind> blinded_o_blind;
62+ std::shared_ptr<OutputBlind> blinded_i_blind;
63+ std::shared_ptr<OutputBlind> blinded_i_blind_blind;
64+ std::shared_ptr<OutputBlind> blinded_c_blind;
5065};
5166
52- struct PendingOutputBlinds final
67+ struct SerializableOutputBlinds final
5368{
54- FcmpRerandomizedOutputCompressed rerandomized_output;
55-
56- std::shared_ptr<PendingBlind> blinded_o_blind;
57- std::shared_ptr<PendingBlind> blinded_i_blind;
58- std::shared_ptr<PendingBlind> blinded_i_blind_blind;
59- std::shared_ptr<PendingBlind> blinded_c_blind;
69+ SerializableRerandomizedOutput rerandomized_output;
70+
71+ OutputBlind blinded_o_blind;
72+ OutputBlind blinded_i_blind;
73+ OutputBlind blinded_i_blind_blind;
74+ OutputBlind blinded_c_blind;
75+
76+ template <class Archive >
77+ inline void serialize (Archive &a, const unsigned int ver)
78+ {
79+ a & rerandomized_output;
80+ a & blinded_o_blind;
81+ a & blinded_i_blind;
82+ a & blinded_i_blind_blind;
83+ a & blinded_c_blind;
84+ }
85+
86+ BEGIN_SERIALIZE_OBJECT ()
87+ FIELD (rerandomized_output)
88+ FIELD (blinded_o_blind)
89+ FIELD (blinded_i_blind)
90+ FIELD (blinded_i_blind_blind)
91+ FIELD (blinded_c_blind)
92+ END_SERIALIZE ()
6093};
6194// ----------------------------------------------------------------------------------------------------------------------
6295template <typename C1, typename C2>
@@ -94,24 +127,32 @@ class BlindsCache final
94127
95128// Internal helper functions
96129private:
97- std::shared_ptr<PendingBlind> get_blinded_o_blind_async (const SeleneScalar o_blind);
98- std::shared_ptr<PendingBlind> get_blinded_i_blind_async (const SeleneScalar i_blind);
99- std::shared_ptr<PendingBlind> get_blinded_i_blind_blind_async (const SeleneScalar i_blind_blind);
100- std::shared_ptr<PendingBlind> get_blinded_c_blind_async (const SeleneScalar c_blind);
130+ std::shared_ptr<OutputBlind> get_blinded_o_blind_async (const SeleneScalar o_blind);
131+ std::shared_ptr<OutputBlind> get_blinded_i_blind_async (const SeleneScalar i_blind);
132+ std::shared_ptr<OutputBlind> get_blinded_i_blind_blind_async (const SeleneScalar i_blind_blind);
133+ std::shared_ptr<OutputBlind> get_blinded_c_blind_async (const SeleneScalar c_blind);
134+
135+ std::shared_ptr<BranchBlind> get_c1_branch_blind_async ();
136+ std::shared_ptr<BranchBlind> get_c2_branch_blind_async ();
101137
102- std::shared_ptr<PendingBlind> get_c1_branch_blind_async ();
103- std::shared_ptr<PendingBlind> get_c2_branch_blind_async ();
138+ void export_serializable_members (std::unordered_map<OutputPairRef, SerializableOutputBlinds> &output_blinds_out,
139+ std::vector<BranchBlind> &c1_branch_blinds_out,
140+ std::vector<BranchBlind> &c2_branch_blinds_out);
141+
142+ void import_serializable_members (std::unordered_map<OutputPairRef, SerializableOutputBlinds> &&output_blinds,
143+ std::vector<BranchBlind> &&c1_branch_blinds,
144+ std::vector<BranchBlind> &&c2_branch_blinds);
104145
105146// State held in memory
106147private:
107148 std::mutex m_mutex;
108149
109150 uint8_t m_n_tree_layers;
110151
111- std::unordered_map<OutputPairRef, PendingOutputBlinds > m_output_blindings;
152+ std::unordered_map<OutputPairRef, OutputBlinds > m_output_blindings;
112153
113- std::deque<std::shared_ptr<PendingBlind >> m_pending_c1_branch_blinds;
114- std::deque<std::shared_ptr<PendingBlind >> m_pending_c2_branch_blinds;
154+ std::deque<std::shared_ptr<BranchBlind >> m_pending_c1_branch_blinds;
155+ std::deque<std::shared_ptr<BranchBlind >> m_pending_c2_branch_blinds;
115156
116157// Config
117158private:
@@ -122,18 +163,47 @@ class BlindsCache final
122163 tools::threadpool::waiter m_waiter;
123164
124165// Serialization
125- // TODO: serialization: grab the lock and wait for all tasks to finish, read all results from pending objects into serializable data types
126- // TODO: de-serialization: grab the lock and wait for all tasks to finish, clear all pending objects, initialze pending objects by reading the serializable data types
127- // public:
128- // template <class Archive>
129- // inline void serialize(Archive &a, const unsigned int ver)
130- // {
131-
132- // }
133-
134- // BEGIN_SERIALIZE_OBJECT()
135-
136- // END_SERIALIZE()
166+ public:
167+ template <class Archive >
168+ inline void serialize (Archive &a, const unsigned int ver)
169+ {
170+ std::unordered_map<OutputPairRef, SerializableOutputBlinds> output_blinds;
171+ std::vector<BranchBlind> c1_branch_blinds;
172+ std::vector<BranchBlind> c2_branch_blinds;
173+
174+ if (typename Archive::is_saving ())
175+ this ->export_serializable_members (output_blinds, c1_branch_blinds, c2_branch_blinds);
176+
177+ a & output_blinds;
178+ a & c1_branch_blinds;
179+ a & c2_branch_blinds;
180+
181+ if (!typename Archive::is_saving ())
182+ this ->import_serializable_members (std::move (output_blinds),
183+ std::move (c1_branch_blinds),
184+ std::move (c2_branch_blinds));
185+ }
186+
187+ BEGIN_SERIALIZE_OBJECT ()
188+ VERSION_FIELD (BLINDS_CACHE_VERSION)
189+
190+ std::unordered_map<OutputPairRef, SerializableOutputBlinds> output_blinds;
191+ std::vector<BranchBlind> c1_branch_blinds;
192+ std::vector<BranchBlind> c2_branch_blinds;
193+
194+ if (typename Archive<W>::is_saving())
195+ this ->export_serializable_members (output_blinds, c1_branch_blinds, c2_branch_blinds);
196+
197+ FIELD (output_blinds)
198+ FIELD(c1_branch_blinds)
199+ FIELD(c2_branch_blinds)
200+
201+ if (!typename Archive<W>::is_saving())
202+ this->import_serializable_members(std::move(output_blinds),
203+ std::move(c1_branch_blinds),
204+ std::move(c2_branch_blinds));
205+
206+ END_SERIALIZE ()
137207};
138208
139209using BlindsCacheV1 = BlindsCache<Selene, Helios>;
@@ -143,3 +213,23 @@ using BlindsCacheV1 = BlindsCache<Selene, Helios>;
143213}// namespace curve_trees
144214}// namespace fcmp_pp
145215
216+ // Since BOOST_CLASS_VERSION does not work for templated class, implement it
217+ namespace boost
218+ {
219+ namespace serialization
220+ {
221+ template <typename C1, typename C2>
222+ struct version <fcmp_pp::curve_trees::BlindsCache<C1, C2>>
223+ {
224+ typedef mpl::int_<fcmp_pp::curve_trees::BLINDS_CACHE_VERSION> type;
225+ typedef mpl::integral_c_tag tag;
226+ static constexpr int value = version::type::value;
227+ BOOST_MPL_ASSERT ((
228+ boost::mpl::less<
229+ boost::mpl::int_<fcmp_pp::curve_trees::BLINDS_CACHE_VERSION>,
230+ boost::mpl::int_<256 >
231+ >
232+ ));
233+ };
234+ }
235+ }
0 commit comments