diff --git a/src/seraphis_impl/CMakeLists.txt b/src/seraphis_impl/CMakeLists.txt index 4ee232b540..12413cbda8 100644 --- a/src/seraphis_impl/CMakeLists.txt +++ b/src/seraphis_impl/CMakeLists.txt @@ -47,6 +47,7 @@ monero_add_library(seraphis_impl target_link_libraries(seraphis_impl PUBLIC + async cncrypto common cryptonote_basic diff --git a/src/seraphis_impl/serialization_demo_types.h b/src/seraphis_impl/serialization_demo_types.h index 4c9ea7e8e4..50dd0db586 100644 --- a/src/seraphis_impl/serialization_demo_types.h +++ b/src/seraphis_impl/serialization_demo_types.h @@ -1,4 +1,4 @@ -// Copyright (c) 2022, The Monero Project +// Copyright (c) 2023, The Monero Project // // All rights reserved. // @@ -36,6 +36,7 @@ #include "ringct/rctTypes.h" #include "seraphis_core/binned_reference_set.h" #include "seraphis_core/discretized_fee.h" +#include "seraphis_core/jamtis_destination.h" #include "seraphis_core/jamtis_support_types.h" #include "serialization/containers.h" #include "serialization/crypto.h" @@ -56,6 +57,12 @@ namespace sp namespace serialization { +/// serializable jamtis::address_tag_t +struct ser_address_tag_t final +{ + unsigned char bytes[sizeof(jamtis::address_tag_t)]; +}; + /// serializable jamtis::encrypted_address_tag_t struct ser_encrypted_address_tag_t final { @@ -406,8 +413,30 @@ struct ser_SpTxSquashedV1 final END_SERIALIZE() }; +/// serializable JamtisDestinationV1 +struct ser_JamtisDestinationV1 final +{ + /// K_1 (address spend key) + rct::key addr_K1; + /// xK_2 (address view key) + crypto::x25519_pubkey addr_K2; + /// xK_3 (DH base key) + crypto::x25519_pubkey addr_K3; + /// addr_tag + ser_address_tag_t addr_tag; + + BEGIN_SERIALIZE() + FIELD(addr_K1) + FIELD(addr_K2) + FIELD(addr_K3) + FIELD(addr_tag) static_assert(sizeof(addr_tag) == sizeof(jamtis::address_tag_t), ""); + END_SERIALIZE() +}; + + } //namespace serialization } //namespace sp +BLOB_SERIALIZER(sp::serialization::ser_address_tag_t); BLOB_SERIALIZER(sp::serialization::ser_encrypted_address_tag_t); BLOB_SERIALIZER(sp::serialization::ser_encoded_amount_t); diff --git a/src/seraphis_impl/serialization_demo_utils.cpp b/src/seraphis_impl/serialization_demo_utils.cpp index 48dda846a4..0e2949ee96 100644 --- a/src/seraphis_impl/serialization_demo_utils.cpp +++ b/src/seraphis_impl/serialization_demo_utils.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2022, The Monero Project +// Copyright (c) 2023, The Monero Project // // All rights reserved. // @@ -36,6 +36,7 @@ #include "ringct/rctTypes.h" #include "seraphis_core/binned_reference_set.h" #include "seraphis_core/discretized_fee.h" +#include "seraphis_core/jamtis_destination.h" #include "seraphis_crypto/bulletproofs_plus2.h" #include "seraphis_crypto/grootle.h" #include "seraphis_crypto/sp_composition_proof.h" @@ -389,6 +390,16 @@ void make_serializable_sp_tx_squashed_v1(const SpTxSquashedV1 &tx, ser_SpTxSquas make_serializable_discretized_fee(tx.tx_fee, serializable_tx_out.tx_fee); } //------------------------------------------------------------------------------------------------------------------- +void make_serializable_sp_destination_v1(const jamtis::JamtisDestinationV1 &dest, ser_JamtisDestinationV1 &serializable_dest_out) +{ + serializable_dest_out.addr_K1 = dest.addr_K1; + serializable_dest_out.addr_K2 = dest.addr_K2; + serializable_dest_out.addr_K3 = dest.addr_K3; + memcpy(serializable_dest_out.addr_tag.bytes, + dest.addr_tag.bytes, + sizeof(dest.addr_tag)); +} +//------------------------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------------------------- void recover_bpp2(ser_BulletproofPlus2_PARTIAL &serializable_bpp2_in, @@ -680,5 +691,15 @@ bool try_recover_sp_tx_squashed_v1(ser_SpTxSquashedV1 &serializable_tx_in, SpTxS return true; } //------------------------------------------------------------------------------------------------------------------- +void recover_sp_destination_v1(const ser_JamtisDestinationV1 &serializable_destination, jamtis::JamtisDestinationV1 &dest_out) +{ + dest_out.addr_K1 = serializable_destination.addr_K1; + dest_out.addr_K2 = serializable_destination.addr_K2; + dest_out.addr_K3 = serializable_destination.addr_K3; + memcpy(dest_out.addr_tag.bytes, + serializable_destination.addr_tag.bytes, + sizeof(serializable_destination.addr_tag)); +} +//------------------------------------------------------------------------------------------------------------------- } //namespace serialization } //namespace sp diff --git a/src/seraphis_impl/serialization_demo_utils.h b/src/seraphis_impl/serialization_demo_utils.h index fe3e44f0e1..62bb13d5b9 100644 --- a/src/seraphis_impl/serialization_demo_utils.h +++ b/src/seraphis_impl/serialization_demo_utils.h @@ -1,4 +1,4 @@ -// Copyright (c) 2022, The Monero Project +// Copyright (c) 2023, The Monero Project // // All rights reserved. // @@ -38,6 +38,7 @@ #include "ringct/rctTypes.h" #include "seraphis_core/binned_reference_set.h" #include "seraphis_core/discretized_fee.h" +#include "seraphis_core/jamtis_destination.h" #include "seraphis_core/sp_core_types.h" #include "seraphis_impl/serialization_demo_types.h" #include "seraphis_main/tx_component_types.h" @@ -135,6 +136,7 @@ void make_serializable_discretized_fee(const DiscretizedFee discretized_fee, unsigned char &serializable_discretized_fee_out); void make_serializable_sp_tx_coinbase_v1(const SpTxCoinbaseV1 &tx, ser_SpTxCoinbaseV1 &serializable_tx_out); void make_serializable_sp_tx_squashed_v1(const SpTxSquashedV1 &tx, ser_SpTxSquashedV1 &serializable_tx_out); +void make_serializable_sp_destination_v1(const jamtis::JamtisDestinationV1 &dest, ser_JamtisDestinationV1 &serializable_dest_out); /** * brief: recover_* - convert a serializable object back into its normal object parent * param: serializable_object_in - serializable object to be consumed (destructive: may be left in an unusable state) @@ -186,6 +188,7 @@ bool try_recover_sp_tx_squashed_v1(ser_SpTxSquashedV1 &serializable_tx_in, const std::size_t sp_ref_set_decomp_m, SpTxSquashedV1 &tx_out); bool try_recover_sp_tx_squashed_v1(ser_SpTxSquashedV1 &serializable_tx_in, SpTxSquashedV1 &tx_out); +void recover_sp_destination_v1(const ser_JamtisDestinationV1 &serializable_destination, jamtis::JamtisDestinationV1 &dest_out); } //namespace serialization } //namespace sp diff --git a/src/seraphis_main/enote_record_types.h b/src/seraphis_main/enote_record_types.h index a23b077003..d745a8ce7e 100644 --- a/src/seraphis_main/enote_record_types.h +++ b/src/seraphis_main/enote_record_types.h @@ -128,7 +128,7 @@ struct LegacyEnoteRecord final //////////////////////////////////////////////////////////////////////////////////////////////////////////// //// -// SpBasicEnoteRecordV1 (jamtis non-selfsend enote type only) +// SpBasicEnoteRecordV1 // - a seraphis enote that has passed the view-tag check using a jamtis find-received key /// struct SpBasicEnoteRecordV1 final @@ -139,12 +139,12 @@ struct SpBasicEnoteRecordV1 final crypto::x25519_pubkey enote_ephemeral_pubkey; /// context of the tx input(s) associated with this enote rct::key input_context; - /// t'_addr: nominal address tag + /// t'_addr: nominal address tag (only useful for jamtis non-selfsend enote types) jamtis::address_tag_t nominal_address_tag; }; //// -// SpIntermediateEnoteRecordV1 (jamtis non-selfsend enote type only) +// SpIntermediateEnoteRecordV1 (jamtis non-selfsend enote type only) // - a seraphis enote with info extracted using a jamtis find-received key, generate-address secret, and unlock-amounts key /// struct SpIntermediateEnoteRecordV1 final diff --git a/tests/performance_tests/main.cpp b/tests/performance_tests/main.cpp index dd2b085da0..7cc9bef705 100644 --- a/tests/performance_tests/main.cpp +++ b/tests/performance_tests/main.cpp @@ -343,7 +343,6 @@ int main(int argc, char** argv) TEST_PERFORMANCE6(filter, p, test_aggregated_bulletproof, true, 4, 1, 1, 0, 1); // 1x 4 TEST_PERFORMANCE6(filter, p, test_aggregated_bulletproof, true, 8, 1, 1, 0, 1); // 1x 8 TEST_PERFORMANCE6(filter, p, test_aggregated_bulletproof, true, 16, 1, 1, 0, 1); // 1x 16 - TEST_PERFORMANCE6(filter, p, test_aggregated_bulletproof, true, 32, 1, 1, 0, 1); // 1x 32 ParamsShuttleBPPAgg p_bpp_agg; p_bpp_agg = {p.core_params, true, {1}, {1}}; @@ -356,8 +355,6 @@ int main(int argc, char** argv) TEST_PERFORMANCE0(filter, p_bpp_agg, test_aggregated_bulletproof_plus); // 1x 8 p_bpp_agg = {p.core_params, true, {16}, {1}}; TEST_PERFORMANCE0(filter, p_bpp_agg, test_aggregated_bulletproof_plus); // 1x 16 - p_bpp_agg = {p.core_params, true, {32}, {1}}; - TEST_PERFORMANCE0(filter, p_bpp_agg, test_aggregated_bulletproof_plus); // 1x 32 /* diff --git a/tests/unit_tests/async.cpp b/tests/unit_tests/async.cpp index febea3d8b2..15b3a8f6a4 100644 --- a/tests/unit_tests/async.cpp +++ b/tests/unit_tests/async.cpp @@ -143,3 +143,78 @@ TEST(async, basic_multithreaded) std::cout << "tasks submitted\n"; } //------------------------------------------------------------------------------------------------------------------- +TEST(async, multithreaded_only_wait_for_first) +{ + async::Threadpool &pool{async::get_default_threadpool()}; + + // 1. make join signals + auto join_signal_a = pool.make_join_signal(); + auto join_signal_b = pool.make_join_signal(); + auto join_signal_c = pool.make_join_signal(); + + // 2. get join tokens + auto join_token_a = pool.get_join_token(join_signal_a); + auto join_token_b = pool.get_join_token(join_signal_b); + auto join_token_c = pool.get_join_token(join_signal_c); + + bool first_complete = false; + bool a_complete = false, b_complete = false, c_complete = false; + + // 3. submit tasks + pool.submit(async::make_simple_task(0, + [&first_complete, &a_complete, l_join_token = join_token_a]() mutable -> async::TaskVariant + { + std::cout << std::this_thread::get_id() <<": A\n"; + std::this_thread::sleep_for(std::chrono::seconds{5}); + std::cout << "A\n"; + a_complete = true; + first_complete = true; + l_join_token = nullptr; + return boost::none; + } + )); + pool.submit(async::make_simple_task(0, + [&first_complete, &b_complete, l_join_token = join_token_b]() mutable -> async::TaskVariant + { + std::cout << std::this_thread::get_id() <<": B\n"; + std::this_thread::sleep_for(std::chrono::seconds{5}); + std::cout << "B\n"; + b_complete = true; + first_complete = true; + l_join_token = nullptr; + return boost::none; + } + )); + pool.submit(async::make_simple_task(0, + [&first_complete, &c_complete, l_join_token = join_token_c]() mutable -> async::TaskVariant + { + std::cout << std::this_thread::get_id() <<": C\n"; + std::this_thread::sleep_for(std::chrono::milliseconds{100}); + std::cout << "C\n"; + c_complete = true; + first_complete = true; + l_join_token = nullptr; + return boost::none; + } + )); + + // 4. get join conditions + auto join_condition_a = pool.get_join_condition(std::move(join_signal_a), std::move(join_token_a)); + auto join_condition_b = pool.get_join_condition(std::move(join_signal_b), std::move(join_token_b)); + auto join_condition_c = pool.get_join_condition(std::move(join_signal_c), std::move(join_token_c)); + + auto check_any = [&join_condition_a, &join_condition_b, &join_condition_c] + { + return join_condition_a() || join_condition_b() || join_condition_c(); + }; + + // 5. join the tasks + std::this_thread::sleep_for(std::chrono::milliseconds{100}); + pool.work_while_waiting(std::move(check_any)); + + ASSERT_TRUE(first_complete); + ASSERT_TRUE(c_complete); + ASSERT_FALSE(a_complete); + ASSERT_FALSE(b_complete); +} +//-------------------------------------------------------------------------------------------------------------------