interim checkin - working RCT Carrot TX

This commit is contained in:
Some Random Crypto Guy
2025-06-27 16:05:08 +01:00
parent 14a6c6b8ef
commit 5306d4b94a
18 changed files with 279 additions and 131 deletions
+1 -1
View File
@@ -70,7 +70,7 @@ static constexpr const unsigned char CARROT_DOMAIN_SEP_SUBADDRESS_SCALAR[] = "Ca
static constexpr const unsigned int CARROT_MIN_TX_OUTPUTS = 2;
static constexpr const unsigned int CARROT_MAX_TX_OUTPUTS = 8;
static constexpr const unsigned int CARROT_MIN_TX_INPUTS = 1;
static constexpr const unsigned int CARROT_MAX_TX_INPUTS = 8;
static constexpr const unsigned int CARROT_MAX_TX_INPUTS = 128;
// SPARC addressing protocol domain separators
static constexpr const unsigned char SPARC_DOMAIN_SEP_RETURN_PUBKEY_ENCRYPTION_MASK[] = "SPARC return pubkey encryption mask";
+11
View File
@@ -37,6 +37,8 @@
#include "misc_log_ex.h"
#include "ringct/rctOps.h"
#include "string_tools.h"
//third party headers
//standard headers
@@ -117,6 +119,15 @@ static void get_normal_proposal_ecdh_parts(const CarrotPaymentProposalV1 &propos
make_carrot_uncontextualized_shared_key_sender(enote_ephemeral_privkey,
proposal.destination.address_view_pubkey,
s_sender_receiver_unctx_out);
/*
std::cerr << "Random:" << epee::string_tools::pod_to_hex(proposal.randomness) << std::endl;
std::cerr << "K_s: " << proposal.destination.address_spend_pubkey << std::endl;
std::cerr << "K_v: " << proposal.destination.address_view_pubkey << std::endl;
std::cerr << "d_e: " << epee::string_tools::pod_to_hex(unwrap(unwrap(enote_ephemeral_privkey))) << std::endl;
std::cerr << "D_e: " << epee::string_tools::pod_to_hex(enote_ephemeral_pubkey_out) << std::endl;
std::cerr << "s_sr: " << epee::string_tools::pod_to_hex(s_sender_receiver_unctx_out) << std::endl;
*/
}
//-------------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------------
+16 -6
View File
@@ -326,15 +326,25 @@ std::vector<std::size_t> get_input_counts_in_preferred_order()
// preferring 1 vs 2. See: https://lavalle.pl/planning/node437.html. Con to this approach: if we
// default to 1 over 2 always then there's scenarios where we net save tx fees and proving time.
static_assert(CARROT_MAX_TX_INPUTS == FCMP_PLUS_PLUS_MAX_INPUTS, "inconsistent input count max limit");
static_assert(CARROT_MIN_TX_INPUTS == 1 && CARROT_MAX_TX_INPUTS == 8,
//static_assert(CARROT_MAX_TX_INPUTS == FCMP_PLUS_PLUS_MAX_INPUTS, "inconsistent input count max limit");
static_assert(CARROT_MIN_TX_INPUTS == 1 && CARROT_MAX_TX_INPUTS == 128,
"refactor this function for different input count limits");
const bool random_bit = 0 == (crypto::rand<uint8_t>() & 0x01);
if (random_bit)
return {2, 1, 4, 8, 3, 5, 6, 7};
return {2, 1, 4, 8, 16, 32, 64, 128, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 65, 66, 67, 68, 69, 70, 71, 72, 73,
74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127};
else
return {1, 2, 4, 8, 3, 5, 6, 7};
return {1, 2, 4, 8, 16, 32, 64, 128, 3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 65, 66, 67, 68, 69, 70, 71, 72, 73,
74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127};
}
//-------------------------------------------------------------------------------------------------------------------
select_inputs_func_t make_single_transfer_input_selector(
@@ -388,7 +398,7 @@ select_inputs_func_t make_single_transfer_input_selector(
std::set<std::size_t> all_idxs; for (std::size_t i = 0; i < input_candidates.size(); ++i) all_idxs.insert(i);
const std::pair<std::size_t, boost::multiprecision::uint128_t> max_usable_money =
input_count_for_max_usable_money(input_candidates, all_idxs, FCMP_PLUS_PLUS_MAX_INPUTS, fee_by_input_count);
input_count_for_max_usable_money(input_candidates, all_idxs, CARROT_MAX_TX_INPUTS, fee_by_input_count);
CARROT_CHECK_AND_THROW(max_usable_money.second >= absolute_minimum_required_money,
not_enough_usable_money,
"Not enough usable money in top " << max_usable_money.first << " inputs ("
@@ -413,7 +423,7 @@ select_inputs_func_t make_single_transfer_input_selector(
// Skip if not enough money in this selectable set for max number of tx inputs...
const auto max_usable_money = input_count_for_max_usable_money(input_candidates,
input_candidate_subset, FCMP_PLUS_PLUS_MAX_INPUTS, fee_by_input_count);
input_candidate_subset, CARROT_MAX_TX_INPUTS, fee_by_input_count);
if (!max_usable_money.first)
continue;
else if (max_usable_money.second < required_money_by_input_count.at(max_usable_money.first))
+1 -1
View File
@@ -196,7 +196,7 @@ void make_carrot_transaction_proposal_v1(const std::vector<CarrotPaymentProposal
const std::size_t n_inputs = selected_inputs.size();
CARROT_CHECK_AND_THROW(n_inputs >= CARROT_MIN_TX_INPUTS,
too_few_inputs, "input selection returned too few inputs: " << n_inputs);
CARROT_CHECK_AND_THROW(n_inputs <= CARROT_MAX_TX_OUTPUTS,
CARROT_CHECK_AND_THROW(n_inputs <= CARROT_MAX_TX_INPUTS,
too_few_inputs, "input selection returned too many inputs: " << n_inputs);
CARROT_CHECK_AND_THROW(fee_per_input_count.count(n_inputs),
carrot_logic_error, "BUG: fee_per_input_count populated with holes, missing: " << n_inputs);
+58 -58
View File
@@ -313,24 +313,24 @@ namespace config
std::string const TREASURY_ADDRESS = "SaLvdZR6w1A21sf2Wh6jYEh1wzY4GSbT7RX6FjyPsnLsffWLrzFQeXUXJcmBLRWDzZC2YXeYe5t7qKsnrg9FpmxmEcxPHsEYfqA";
// treasury payout {tx-key, output-key} pairs
const std::vector<std::pair<std::string, std::string>> TREASURY_SAL1_MINT_OUTPUT_KEYS = {
{"a1bdd1da651fbbb845232816e1aa2d4ff29b790f10bbd4f574a012f1199e15a4", "b0733ab6f251b16458efa9ebb3fb99bd54d43173b5768fe9ffc42e0fe46ae3a8"},
{"47996eccbcc078b06d0f6ece37bf3a700c2bd60adfdd898b22096f16a9ad315c", "fd6bcceb4799ee067d59b97a6f66a0f9a70f134220259d3b4d6a2278ba4aca4c"},
{"a3e6754a849b80c21a77e6065fefdae29eeeabf17c407453356244a00545bdb8", "3d395454df1452d715d27190e022b20395871c99af578f7251c3f9752e0274a6"},
{"0d5e97a910e0f9c606ad9c711b6595aaed142d857cde2efa519112b9a29240d5", "56c29e28bdcf4f20b4b45906b93ae7c4bf9ee82e18cd45543cb69a14ce5efb88"},
{"495fa363de88915aa8b74818c4b80715a882a688b4f7127ab7cd3b6885f3567a", "d42dfe0da5579c82e8255eba8c0a17170023f14a6a5030da6abf9f10abb52cbb"},
{"85ea10ec40390e4f406446fb519e974d89536154045c6df28bb3b538b254e20d", "0ce2b7dd3a8ce8b596889dac8081a62f98fd70f1f043944ab4ac592c3c59e77b"},
{"40f201b38a319dda81e7201e57fea7924067a4a332ed71b8e51ec29ac2d67310", "8289aa6963b98d1034e94eae55d8be6b33d0a88f14f174ebcbaec70837986c7c"},
{"c5a648cc7846341357b7b4653a58f9eb4800d88b5de587bceec7a5c28f98d05a", "3f308a203845d88e5e728fcebcdcea1f90e2f424d461617993c672a6138ad2d8"},
{"4c51d6550b8eeb6cc8f0d395cc83a5f90ec2a4d86501b3f68da48d618ccf5711", "53f0bd8cebeefb3a88fffa5d7f6ad43d4712608ded561732467ca499df940454"},
{"ce2f5d82118fed03d5e269e285fc16189a6cd34f38999e5c055a5dea5fce61bc", "f7fc6948b194d9bd6f2df6ecb83f04e6c8d1a2556a63fedb310a4631fe1bfc42"},
{"6248028fd77fb02b5c6ea72dea10b417891a2da7aaf9565aed382e063b4981a3", "63986e1177499bdb23cd49afb519ec18f38cb1b0c386220b376d8ffdc2e37890"},
{"6adcb695aa5d6d01133c68900f29e501e9549816e827ea0c164bbc78f3534dd6", "6a440ccb18f5e703e8000de3865ac40d4c18f081270d32eef377dc831f28d8d0"},
{"b97a4d2259480f34f20e41c489ab5c2e5ae9ee84d8672a7eff8012f2260e121e", "e6eb9147ff40e22209d321d0f1bfbfe20acf5ceb6b9d0bfb13688ad28aa1232e"},
{"4fd214602a36902f22d16927244c456e8cc5a406a9570131f138a028214ffdf0", "34060b8bd96009b9b298280ebd84fa9587fa8c9df6fb5ad0270fb6cd2098885c"},
{"9d60178ec6d6599d7a31298f2559fb9c3111f2c70494b3a1638db877ea55b808", "7985ed03856a929663e954738d0938713407717835f760c7ca4d54844a128c91"},
{"cd65718eab234bf419332e53bd2f48e2ade70af48c5e126ab5080321e1493dfc", "581cb4cca7a0a029ee2cac51dfc00a0c3a657d2eaf67ed3c6ae7bacc11b4f007"},
// treasury payout {tx-key, output-key, anchor_enc, vie_tag} tuples
const std::map<uint64_t, std::tuple<std::string, std::string, std::string, std::string>> TREASURY_SAL1_MINT_OUTPUT_DATA = {
{1000000ULL, {"a1bdd1da651fbbb845232816e1aa2d4ff29b790f10bbd4f574a012f1199e15a4", "b0733ab6f251b16458efa9ebb3fb99bd54d43173b5768fe9ffc42e0fe46ae3a8", "00", "00"}},
{1020000ULL, {"47996eccbcc078b06d0f6ece37bf3a700c2bd60adfdd898b22096f16a9ad315c", "fd6bcceb4799ee067d59b97a6f66a0f9a70f134220259d3b4d6a2278ba4aca4c", "00", "00"}},
{1040000ULL, {"a3e6754a849b80c21a77e6065fefdae29eeeabf17c407453356244a00545bdb8", "3d395454df1452d715d27190e022b20395871c99af578f7251c3f9752e0274a6", "00", "00"}},
{1060000ULL, {"0d5e97a910e0f9c606ad9c711b6595aaed142d857cde2efa519112b9a29240d5", "56c29e28bdcf4f20b4b45906b93ae7c4bf9ee82e18cd45543cb69a14ce5efb88", "00", "00"}},
{1080000ULL, {"495fa363de88915aa8b74818c4b80715a882a688b4f7127ab7cd3b6885f3567a", "d42dfe0da5579c82e8255eba8c0a17170023f14a6a5030da6abf9f10abb52cbb", "00", "00"}},
{1100000ULL, {"85ea10ec40390e4f406446fb519e974d89536154045c6df28bb3b538b254e20d", "0ce2b7dd3a8ce8b596889dac8081a62f98fd70f1f043944ab4ac592c3c59e77b", "00", "00"}},
{1120000ULL, {"40f201b38a319dda81e7201e57fea7924067a4a332ed71b8e51ec29ac2d67310", "8289aa6963b98d1034e94eae55d8be6b33d0a88f14f174ebcbaec70837986c7c", "00", "00"}},
{1140000ULL, {"c5a648cc7846341357b7b4653a58f9eb4800d88b5de587bceec7a5c28f98d05a", "3f308a203845d88e5e728fcebcdcea1f90e2f424d461617993c672a6138ad2d8", "00", "00"}},
{1160000ULL, {"4c51d6550b8eeb6cc8f0d395cc83a5f90ec2a4d86501b3f68da48d618ccf5711", "53f0bd8cebeefb3a88fffa5d7f6ad43d4712608ded561732467ca499df940454", "00", "00"}},
{1180000ULL, {"ce2f5d82118fed03d5e269e285fc16189a6cd34f38999e5c055a5dea5fce61bc", "f7fc6948b194d9bd6f2df6ecb83f04e6c8d1a2556a63fedb310a4631fe1bfc42", "00", "00"}},
{1200000ULL, {"6248028fd77fb02b5c6ea72dea10b417891a2da7aaf9565aed382e063b4981a3", "63986e1177499bdb23cd49afb519ec18f38cb1b0c386220b376d8ffdc2e37890", "00", "00"}},
{1220000ULL, {"6adcb695aa5d6d01133c68900f29e501e9549816e827ea0c164bbc78f3534dd6", "6a440ccb18f5e703e8000de3865ac40d4c18f081270d32eef377dc831f28d8d0", "00", "00"}},
{1240000ULL, {"b97a4d2259480f34f20e41c489ab5c2e5ae9ee84d8672a7eff8012f2260e121e", "e6eb9147ff40e22209d321d0f1bfbfe20acf5ceb6b9d0bfb13688ad28aa1232e", "00", "00"}},
{1260000ULL, {"4fd214602a36902f22d16927244c456e8cc5a406a9570131f138a028214ffdf0", "34060b8bd96009b9b298280ebd84fa9587fa8c9df6fb5ad0270fb6cd2098885c", "00", "00"}},
{1280000ULL, {"9d60178ec6d6599d7a31298f2559fb9c3111f2c70494b3a1638db877ea55b808", "7985ed03856a929663e954738d0938713407717835f760c7ca4d54844a128c91", "00", "00"}},
{1300000ULL, {"cd65718eab234bf419332e53bd2f48e2ade70af48c5e126ab5080321e1493dfc", "581cb4cca7a0a029ee2cac51dfc00a0c3a657d2eaf67ed3c6ae7bacc11b4f007", "00", "00"}},
};
// Hash domain separators
@@ -422,24 +422,24 @@ namespace config
std::string const TREASURY_ADDRESS = "SaLvTyLFta9BiAXeUfFkKvViBkFt4ay5nEUBpWyDKewYggtsoxBbtCUVqaBjtcCDyY1euun8Giv7LLEgvztuurLo5a6Km1zskZn36";
// treasury payout {tx-key, output-key} pairs
const std::vector<std::pair<std::string, std::string>> TREASURY_SAL1_MINT_OUTPUT_KEYS = {
{"a1bdd1da651fbbb845232816e1aa2d4ff29b790f10bbd4f574a012f1199e15a4", "b0733ab6f251b16458efa9ebb3fb99bd54d43173b5768fe9ffc42e0fe46ae3a8"},
{"47996eccbcc078b06d0f6ece37bf3a700c2bd60adfdd898b22096f16a9ad315c", "fd6bcceb4799ee067d59b97a6f66a0f9a70f134220259d3b4d6a2278ba4aca4c"},
{"a3e6754a849b80c21a77e6065fefdae29eeeabf17c407453356244a00545bdb8", "3d395454df1452d715d27190e022b20395871c99af578f7251c3f9752e0274a6"},
{"0d5e97a910e0f9c606ad9c711b6595aaed142d857cde2efa519112b9a29240d5", "56c29e28bdcf4f20b4b45906b93ae7c4bf9ee82e18cd45543cb69a14ce5efb88"},
{"495fa363de88915aa8b74818c4b80715a882a688b4f7127ab7cd3b6885f3567a", "d42dfe0da5579c82e8255eba8c0a17170023f14a6a5030da6abf9f10abb52cbb"},
{"85ea10ec40390e4f406446fb519e974d89536154045c6df28bb3b538b254e20d", "0ce2b7dd3a8ce8b596889dac8081a62f98fd70f1f043944ab4ac592c3c59e77b"},
{"40f201b38a319dda81e7201e57fea7924067a4a332ed71b8e51ec29ac2d67310", "8289aa6963b98d1034e94eae55d8be6b33d0a88f14f174ebcbaec70837986c7c"},
{"c5a648cc7846341357b7b4653a58f9eb4800d88b5de587bceec7a5c28f98d05a", "3f308a203845d88e5e728fcebcdcea1f90e2f424d461617993c672a6138ad2d8"},
{"4c51d6550b8eeb6cc8f0d395cc83a5f90ec2a4d86501b3f68da48d618ccf5711", "53f0bd8cebeefb3a88fffa5d7f6ad43d4712608ded561732467ca499df940454"},
{"ce2f5d82118fed03d5e269e285fc16189a6cd34f38999e5c055a5dea5fce61bc", "f7fc6948b194d9bd6f2df6ecb83f04e6c8d1a2556a63fedb310a4631fe1bfc42"},
{"6248028fd77fb02b5c6ea72dea10b417891a2da7aaf9565aed382e063b4981a3", "63986e1177499bdb23cd49afb519ec18f38cb1b0c386220b376d8ffdc2e37890"},
{"6adcb695aa5d6d01133c68900f29e501e9549816e827ea0c164bbc78f3534dd6", "6a440ccb18f5e703e8000de3865ac40d4c18f081270d32eef377dc831f28d8d0"},
{"b97a4d2259480f34f20e41c489ab5c2e5ae9ee84d8672a7eff8012f2260e121e", "e6eb9147ff40e22209d321d0f1bfbfe20acf5ceb6b9d0bfb13688ad28aa1232e"},
{"4fd214602a36902f22d16927244c456e8cc5a406a9570131f138a028214ffdf0", "34060b8bd96009b9b298280ebd84fa9587fa8c9df6fb5ad0270fb6cd2098885c"},
{"9d60178ec6d6599d7a31298f2559fb9c3111f2c70494b3a1638db877ea55b808", "7985ed03856a929663e954738d0938713407717835f760c7ca4d54844a128c91"},
{"cd65718eab234bf419332e53bd2f48e2ade70af48c5e126ab5080321e1493dfc", "581cb4cca7a0a029ee2cac51dfc00a0c3a657d2eaf67ed3c6ae7bacc11b4f007"},
// treasury payout {tx-key, output-key, anchor_enc, vie_tag} tuples
const std::map<uint64_t, std::tuple<std::string, std::string, std::string, std::string>> TREASURY_SAL1_MINT_OUTPUT_DATA = {
{1100, {"310fe378b82e2475a87c83eef07c57d92fa0731d5c499258e774852158276968","f17c5a62efcc96710f2a173538fe5e79b190b44ab6facc01a619f0e227ac18d1","eb613855f58d093ae9d527e8ab69b46a","6c74f9"}},
{1120, {"adb74cea72d46ebe5a45e5886189e71c493308686f076ccfc053cb9b4f55b656","b40e958589238cc48a5a7f03f1f28406a13b2f724efe831cfec43c06bb0fcb60","77a51cc3a6c3c53d631cadad72f57c1d","e5fec0"}},
{1140, {"c5e9a67c695ddcab05b980de0c8cc7d9d5b9c09af58047843bfd7d29a038f671","6c3253bd837b899b87aedc97114feb9c10c2d255ce59b7ba5b470817a37d16df","fcf6e1907ea30dbafd510e33a37cc2dc","fa5c45"}},
{1160, {"e95c8b7fc3d0e7e34d544e97d3b526e94f70acb7d85cb0053b3cb830e863ac38","3a5ae93e922985ea1a126ff8fd35f6cbf39fa556525e15a049765510eb1360e1","7ea6d62add9387a28f3dbed5dbac120b","c26ac2"}},
{1180, {"9d453235a25e470df2d7ceaa8f8d4216a8939a0a93bc0c43f1b902cb461ee82d","2e990ed2de4d745389d88aa9868634ce430f09d2c0cb5ebc2ee8b9bcc23e221a","807e07241a48b97acb537241822a97b8","eb37c0"}},
{1200, {"92dbd7da158d4bcb4f002dcc505ed4c49ac4e4782724b506a5977119c80c4869","4505a9be31c2ac6ad5faa2ea8332b85b1a3efee84d0456740d208b8188ad842a","8870c1f88de25b5443d8323759f386d9","443c65"}},
{1220, {"1e4d5c44a112c3ac89ab2c7065bb2c8c094779b3a5d696652198f7dd05f88b77","01f56bf134652852688e30dd9559bdb5fe2edd046bed99dbea23b655d2475b89","da088fc1e1c2f2d0e348f06f2079e8ed","d7c7bf"}},
{1240, {"91ba144c930a65996b2d7c3b296217c692225756392b580a323838e48b357452","f2d5f4f2aaa599a52c557270cbc5cde138b753a98297d975b74a7223a9b80b13","0dc3a42cb1f36768a09c316790936356","172c22"}},
{1260, {"1d626ede8d2e34e888384655b30942a25be272a3ea58d49835265e6933a91a52","05666de1b136236f0682e128c0c3ae84578a6a4b233a578dd676e581a582fe19","c81ccf7f93e01e7872543907de8d17d0","21dd94"}},
{1280, {"85b10b5ae72ab59281f47be4edede17b7a017dc7ddd839813e3a12c0b2a39874","d34d259e2fee2b0c977242c473cf83997920c1e64ff7a9c364b2bf4abba4d5cc","43de6ce100ca3eeb6734fc44cc9f7dbc","574e2f"}},
{1300, {"c699ca0dcbe538e6be9e997acb50a4c13557d1e8cf3a105ab47406cb68300656","50c5e0fa60907c2c2b66748562193b7f5bfcba269eb398c5c975c9e125933942","05aeb41f8863152a7e0e36f216ecbb12","e413dd"}},
{1320, {"76bb126d6e0e5d3d7ee7ccabd194a248cbe006ae7d57f89c31c6826f8e7b4851","e1f2277b378630d92bc03003e3d206899404afde342fcb3a9b1790f798c8b5a4","26274ad1bbf5d483f2c747754b898873","a2df70"}},
{1340, {"5738dc94686bfffe1789b695785f270f6f616b1a52e071e975cf915063233b1a","982b4848ed74f2a5d899f778b182c35f40535579349435b466ff98c3fce678e7","67bd9b9a434b9028564a065a30ae34fa","36ceec"}},
{1360, {"473b6f6941d6eafaef007d3d932763b6e39c1428d3ba76dfff452ddc67f93b48","76e3b1280b959672d86c357e6f5fcd8a74e61a0a948a0541a0eb384060705bac","74b5ad8847471e3d8723ad3e101b8a13","5e5671"}},
{1380, {"6dae9a14e24b96caf8f7acb0edad936a4ecaa194a61b3785a2b1d08cbca0a158","26ca204c10481ed2447447e3893e0c46c9f01df16c3f3a671cf9e6054176ee5d","7c04e4ed28bfac12a0050bdae44f9979","4c23ad"}},
{1400, {"a5837480d8e17ddb9b29baaf5671545d59d18b546de0d7092768882cff94d125","dc76eb3892b3721da947fc71de8ab30ef32651f1b6bb1a45eb7b80882217a5ac","bb490940a3cdf4a17fd0bec0b578531f","84d899"}}
};
}
@@ -471,24 +471,24 @@ namespace config
std::string const TREASURY_ADDRESS = "fuLMowH85abK8nz9BBMEem7MAfUbQu4aSHHUV9j5Z86o6Go9Lv2U5ZQiJCWPY9R9HA8p5idburazjAhCqDngLo7fYPCD9ciM9ee1A";
// treasury payout {tx-key, output-key} pairs
const std::vector<std::pair<std::string, std::string>> TREASURY_SAL1_MINT_OUTPUT_KEYS = {
{"a1bdd1da651fbbb845232816e1aa2d4ff29b790f10bbd4f574a012f1199e15a4", "b0733ab6f251b16458efa9ebb3fb99bd54d43173b5768fe9ffc42e0fe46ae3a8"},
{"47996eccbcc078b06d0f6ece37bf3a700c2bd60adfdd898b22096f16a9ad315c", "fd6bcceb4799ee067d59b97a6f66a0f9a70f134220259d3b4d6a2278ba4aca4c"},
{"a3e6754a849b80c21a77e6065fefdae29eeeabf17c407453356244a00545bdb8", "3d395454df1452d715d27190e022b20395871c99af578f7251c3f9752e0274a6"},
{"0d5e97a910e0f9c606ad9c711b6595aaed142d857cde2efa519112b9a29240d5", "56c29e28bdcf4f20b4b45906b93ae7c4bf9ee82e18cd45543cb69a14ce5efb88"},
{"495fa363de88915aa8b74818c4b80715a882a688b4f7127ab7cd3b6885f3567a", "d42dfe0da5579c82e8255eba8c0a17170023f14a6a5030da6abf9f10abb52cbb"},
{"85ea10ec40390e4f406446fb519e974d89536154045c6df28bb3b538b254e20d", "0ce2b7dd3a8ce8b596889dac8081a62f98fd70f1f043944ab4ac592c3c59e77b"},
{"40f201b38a319dda81e7201e57fea7924067a4a332ed71b8e51ec29ac2d67310", "8289aa6963b98d1034e94eae55d8be6b33d0a88f14f174ebcbaec70837986c7c"},
{"c5a648cc7846341357b7b4653a58f9eb4800d88b5de587bceec7a5c28f98d05a", "3f308a203845d88e5e728fcebcdcea1f90e2f424d461617993c672a6138ad2d8"},
{"4c51d6550b8eeb6cc8f0d395cc83a5f90ec2a4d86501b3f68da48d618ccf5711", "53f0bd8cebeefb3a88fffa5d7f6ad43d4712608ded561732467ca499df940454"},
{"ce2f5d82118fed03d5e269e285fc16189a6cd34f38999e5c055a5dea5fce61bc", "f7fc6948b194d9bd6f2df6ecb83f04e6c8d1a2556a63fedb310a4631fe1bfc42"},
{"6248028fd77fb02b5c6ea72dea10b417891a2da7aaf9565aed382e063b4981a3", "63986e1177499bdb23cd49afb519ec18f38cb1b0c386220b376d8ffdc2e37890"},
{"6adcb695aa5d6d01133c68900f29e501e9549816e827ea0c164bbc78f3534dd6", "6a440ccb18f5e703e8000de3865ac40d4c18f081270d32eef377dc831f28d8d0"},
{"b97a4d2259480f34f20e41c489ab5c2e5ae9ee84d8672a7eff8012f2260e121e", "e6eb9147ff40e22209d321d0f1bfbfe20acf5ceb6b9d0bfb13688ad28aa1232e"},
{"4fd214602a36902f22d16927244c456e8cc5a406a9570131f138a028214ffdf0", "34060b8bd96009b9b298280ebd84fa9587fa8c9df6fb5ad0270fb6cd2098885c"},
{"9d60178ec6d6599d7a31298f2559fb9c3111f2c70494b3a1638db877ea55b808", "7985ed03856a929663e954738d0938713407717835f760c7ca4d54844a128c91"},
{"cd65718eab234bf419332e53bd2f48e2ade70af48c5e126ab5080321e1493dfc", "581cb4cca7a0a029ee2cac51dfc00a0c3a657d2eaf67ed3c6ae7bacc11b4f007"},
// treasury payout {tx-key, output-key, anchor_enc, view_tag} tuples
const std::map<uint64_t, std::tuple<std::string, std::string, std::string, std::string>> TREASURY_SAL1_MINT_OUTPUT_DATA = {
{1000000ULL, {"a1bdd1da651fbbb845232816e1aa2d4ff29b790f10bbd4f574a012f1199e15a4", "b0733ab6f251b16458efa9ebb3fb99bd54d43173b5768fe9ffc42e0fe46ae3a8", "00", "00"}},
{1020000ULL, {"47996eccbcc078b06d0f6ece37bf3a700c2bd60adfdd898b22096f16a9ad315c", "fd6bcceb4799ee067d59b97a6f66a0f9a70f134220259d3b4d6a2278ba4aca4c", "00", "00"}},
{1040000ULL, {"a3e6754a849b80c21a77e6065fefdae29eeeabf17c407453356244a00545bdb8", "3d395454df1452d715d27190e022b20395871c99af578f7251c3f9752e0274a6", "00", "00"}},
{1060000ULL, {"0d5e97a910e0f9c606ad9c711b6595aaed142d857cde2efa519112b9a29240d5", "56c29e28bdcf4f20b4b45906b93ae7c4bf9ee82e18cd45543cb69a14ce5efb88", "00", "00"}},
{1080000ULL, {"495fa363de88915aa8b74818c4b80715a882a688b4f7127ab7cd3b6885f3567a", "d42dfe0da5579c82e8255eba8c0a17170023f14a6a5030da6abf9f10abb52cbb", "00", "00"}},
{1100000ULL, {"85ea10ec40390e4f406446fb519e974d89536154045c6df28bb3b538b254e20d", "0ce2b7dd3a8ce8b596889dac8081a62f98fd70f1f043944ab4ac592c3c59e77b", "00", "00"}},
{1120000ULL, {"40f201b38a319dda81e7201e57fea7924067a4a332ed71b8e51ec29ac2d67310", "8289aa6963b98d1034e94eae55d8be6b33d0a88f14f174ebcbaec70837986c7c", "00", "00"}},
{1140000ULL, {"c5a648cc7846341357b7b4653a58f9eb4800d88b5de587bceec7a5c28f98d05a", "3f308a203845d88e5e728fcebcdcea1f90e2f424d461617993c672a6138ad2d8", "00", "00"}},
{1160000ULL, {"4c51d6550b8eeb6cc8f0d395cc83a5f90ec2a4d86501b3f68da48d618ccf5711", "53f0bd8cebeefb3a88fffa5d7f6ad43d4712608ded561732467ca499df940454", "00", "00"}},
{1180000ULL, {"ce2f5d82118fed03d5e269e285fc16189a6cd34f38999e5c055a5dea5fce61bc", "f7fc6948b194d9bd6f2df6ecb83f04e6c8d1a2556a63fedb310a4631fe1bfc42", "00", "00"}},
{1200000ULL, {"6248028fd77fb02b5c6ea72dea10b417891a2da7aaf9565aed382e063b4981a3", "63986e1177499bdb23cd49afb519ec18f38cb1b0c386220b376d8ffdc2e37890", "00", "00"}},
{1220000ULL, {"6adcb695aa5d6d01133c68900f29e501e9549816e827ea0c164bbc78f3534dd6", "6a440ccb18f5e703e8000de3865ac40d4c18f081270d32eef377dc831f28d8d0", "00", "00"}},
{1240000ULL, {"b97a4d2259480f34f20e41c489ab5c2e5ae9ee84d8672a7eff8012f2260e121e", "e6eb9147ff40e22209d321d0f1bfbfe20acf5ceb6b9d0bfb13688ad28aa1232e", "00", "00"}},
{1260000ULL, {"4fd214602a36902f22d16927244c456e8cc5a406a9570131f138a028214ffdf0", "34060b8bd96009b9b298280ebd84fa9587fa8c9df6fb5ad0270fb6cd2098885c", "00", "00"}},
{1280000ULL, {"9d60178ec6d6599d7a31298f2559fb9c3111f2c70494b3a1638db877ea55b808", "7985ed03856a929663e954738d0938713407717835f760c7ca4d54844a128c91", "00", "00"}},
{1300000ULL, {"cd65718eab234bf419332e53bd2f48e2ade70af48c5e126ab5080321e1493dfc", "581cb4cca7a0a029ee2cac51dfc00a0c3a657d2eaf67ed3c6ae7bacc11b4f007", "00", "00"}},
};
}
}
@@ -520,7 +520,7 @@ namespace cryptonote
uint64_t TREASURY_SAL1_MINT_PERIOD;
std::map<uint8_t, std::pair<uint64_t, std::pair<std::string, std::string>>> const AUDIT_HARD_FORKS;
std::string TREASURY_ADDRESS;
std::vector<std::pair<std::string, std::string>> TREASURY_SAL1_MINT_OUTPUT_KEYS;
std::map<uint64_t, std::tuple<std::string, std::string, std::string, std::string>> TREASURY_SAL1_MINT_OUTPUT_DATA;
};
inline const config_t& get_config(network_type nettype)
{
@@ -540,7 +540,7 @@ namespace cryptonote
::config::TREASURY_SAL1_MINT_PERIOD,
::config::AUDIT_HARD_FORKS,
::config::TREASURY_ADDRESS,
::config::TREASURY_SAL1_MINT_OUTPUT_KEYS
::config::TREASURY_SAL1_MINT_OUTPUT_DATA
};
static const config_t testnet = {
::config::testnet::CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX,
@@ -558,7 +558,7 @@ namespace cryptonote
::config::testnet::TREASURY_SAL1_MINT_PERIOD,
::config::testnet::AUDIT_HARD_FORKS,
::config::testnet::TREASURY_ADDRESS,
::config::testnet::TREASURY_SAL1_MINT_OUTPUT_KEYS
::config::testnet::TREASURY_SAL1_MINT_OUTPUT_DATA
};
static const config_t stagenet = {
::config::stagenet::CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX,
@@ -576,7 +576,7 @@ namespace cryptonote
::config::stagenet::TREASURY_SAL1_MINT_PERIOD,
::config::stagenet::AUDIT_HARD_FORKS,
::config::stagenet::TREASURY_ADDRESS,
::config::stagenet::TREASURY_SAL1_MINT_OUTPUT_KEYS
::config::stagenet::TREASURY_SAL1_MINT_OUTPUT_DATA
};
switch (nettype)
{
+27 -19
View File
@@ -1423,21 +1423,20 @@ bool Blockchain::prevalidate_protocol_transaction(const block& b, uint64_t heigh
return true;
}
//------------------------------------------------------------------
std::tuple<bool, size_t> Blockchain::validate_treasury_payout(const transaction& tx, const uint64_t payout_index, uint8_t hf_version) const {
std::tuple<bool, size_t> Blockchain::validate_treasury_payout(const transaction& tx, const std::tuple<std::string, std::string, std::string, std::string>& treasury_data, uint8_t hf_version) const {
// find the treasury output
const auto treasury_output_keys = get_config(m_nettype).TREASURY_SAL1_MINT_OUTPUT_KEYS;
const auto expected_output_key = treasury_output_keys[payout_index].second;
const auto &output = std::find_if(tx.vout.begin(), tx.vout.end(), [&expected_output_key](const tx_out &o) {
const auto [tx_key, onetime_address, anchor_enc, viewtag] = treasury_data;
//const auto expected_output_key = std::get<1>(treasury_output_data);
const auto &output = std::find_if(tx.vout.begin(), tx.vout.end(), [&onetime_address](const tx_out &o) {
std::string output_key;
if (o.target.type() == typeid(txout_to_key)) {
output_key = epee::string_tools::pod_to_hex(boost::get<txout_to_key>(o.target).key);
} else if (o.target.type() == typeid(txout_to_tagged_key)) {
output_key = epee::string_tools::pod_to_hex(boost::get<txout_to_tagged_key>(o.target).key);
if (o.target.type() == typeid(txout_to_carrot_v1)) {
output_key = epee::string_tools::pod_to_hex(boost::get<txout_to_carrot_v1>(o.target).key);
} else {
return false;
}
return output_key == expected_output_key;
return output_key == onetime_address;
});
if (output == tx.vout.end()) {
@@ -1450,30 +1449,39 @@ std::tuple<bool, size_t> Blockchain::validate_treasury_payout(const transaction&
return {false, 0};
}
if (output->target.type() != typeid(txout_to_key)) {
if (output->target.type() != typeid(txout_to_carrot_v1)) {
MERROR_VER("Miner transaction contains treasury output with invalid target type");
return {false, 0};
}
if (boost::get<txout_to_key>(output->target).unlock_time != CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW) {
const cryptonote::txout_to_carrot_v1 target = boost::get<txout_to_carrot_v1>(output->target);
if (target.asset_type != "SAL1") {
MERROR_VER("Miner transaction contains treasury output with invalid asset_type");
return {false, 0};
}
/*
if (target.unlock_time != CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW) {
MERROR_VER("Miner transaction contains treasury output with invalid target key");
return {false, 0};
}
*/
return {true, output - tx.vout.begin()};
}
//------------------------------------------------------------------
// This function validates the miner transaction reward
bool Blockchain::validate_miner_transaction(const block& b, size_t cumulative_block_weight, uint64_t fee, uint64_t& base_reward, uint64_t already_generated_coins, bool &partial_block_reward, uint8_t version)
bool Blockchain::validate_miner_transaction(const block& b, const uint64_t height, size_t cumulative_block_weight, uint64_t fee, uint64_t& base_reward, uint64_t already_generated_coins, bool &partial_block_reward, uint8_t version)
{
LOG_PRINT_L3("Blockchain::" << __func__);
// validate treasury payout
size_t treasury_index_in_tx_outputs;
auto [treasury_payout_exist, treasury_payout_index] = check_treasury_payout(m_nettype, boost::get<txin_gen>(b.miner_tx.vin[0]).height, m_hardfork->get_hardforks(), version);
if (treasury_payout_exist) {
// check for treasury payouts
const auto treasury_payout_data = get_config(m_nettype).TREASURY_SAL1_MINT_OUTPUT_DATA;
const bool treasury_payout_exists = (treasury_payout_data.count(height) == 1);
size_t treasury_index_in_tx_outputs = 0;
if (treasury_payout_exists) {
// check the treasury payout
auto [valid, index_in_tx_outputs] = validate_treasury_payout(b.miner_tx, treasury_payout_index, version);
auto [valid, index_in_tx_outputs] = validate_treasury_payout(b.miner_tx, treasury_payout_data.at(height), version);
if (!valid) {
MERROR_VER("Miner transaction treasury output was invalid");
return false;
@@ -1486,7 +1494,7 @@ bool Blockchain::validate_miner_transaction(const block& b, size_t cumulative_bl
for(size_t i = 0; i < b.miner_tx.vout.size(); i++)
{
// skip the treasury output
if (treasury_payout_exist && (i == treasury_index_in_tx_outputs)) {
if (treasury_payout_exists && (i == treasury_index_in_tx_outputs)) {
continue;
}
money_in_use += b.miner_tx.vout[i].amount;
@@ -5149,7 +5157,7 @@ leave:
TIME_MEASURE_START(vmt);
uint64_t base_reward = 0;
uint64_t already_generated_coins = blockchain_height ? m_db->get_block_already_generated_coins(blockchain_height - 1) : 0;
if(!validate_miner_transaction(bl, cumulative_block_weight, fee_summary, base_reward, already_generated_coins, bvc.m_partial_block_reward, m_hardfork->get_current_version()))
if(!validate_miner_transaction(bl, blockchain_height, cumulative_block_weight, fee_summary, base_reward, already_generated_coins, bvc.m_partial_block_reward, m_hardfork->get_current_version()))
{
MERROR_VER("Block with id: " << id << " has incorrect miner transaction");
bvc.m_verifivation_failed = true;
+2 -2
View File
@@ -1500,7 +1500,7 @@ namespace cryptonote
*
* @return bool indicating payout valid, and the index of the output within miner transaction outputs.
*/
std::tuple<bool, size_t> validate_treasury_payout(const transaction& tx, const uint64_t payout_index, uint8_t hf_version) const;
std::tuple<bool, size_t> validate_treasury_payout(const transaction& tx, const std::tuple<std::string, std::string, std::string, std::string>& treasury_data, uint8_t hf_version) const;
/**
* @brief sanity checks a miner transaction before validating an entire block
@@ -1546,7 +1546,7 @@ namespace cryptonote
*
* @return false if anything is found wrong with the miner transaction, otherwise true
*/
bool validate_miner_transaction(const block& b, size_t cumulative_block_weight, uint64_t fee, uint64_t& base_reward, uint64_t already_generated_coins, bool &partial_block_reward, uint8_t version);
bool validate_miner_transaction(const block& b, const uint64_t height, size_t cumulative_block_weight, uint64_t fee, uint64_t& base_reward, uint64_t already_generated_coins, bool &partial_block_reward, uint8_t version);
/**
* @brief validates a protocol (coinbase) transaction
+54 -5
View File
@@ -476,7 +476,8 @@ namespace cryptonote
tx.type = cryptonote::transaction_type::MINER;
// check for treasury payouts
auto[treasury_payout_exist, treasury_payout_index] = check_treasury_payout(nettype, height, hardforks, hard_fork_version);
const auto treasury_payout_data = get_config(nettype).TREASURY_SAL1_MINT_OUTPUT_DATA;
const bool treasury_payout_exists = (treasury_payout_data.count(height) == 1);
uint64_t block_reward;
if(!get_block_reward(median_weight, current_block_weight, already_generated_coins, block_reward, hard_fork_version))
@@ -496,13 +497,61 @@ namespace cryptonote
{
try
{
// Build the miner payout
carrot::CarrotDestinationV1 destination;
carrot::make_carrot_main_address_v1(miner_address.m_spend_public_key,
miner_address.m_view_public_key,
destination);
CHECK_AND_ASSERT_THROW_MES(!destination.is_subaddress,
"make_single_enote_carrot_coinbase_transaction_v1: subaddress are not allowed in miner transactions");
CHECK_AND_ASSERT_THROW_MES(destination.payment_id == carrot::null_payment_id,
"make_single_enote_carrot_coinbase_transaction_v1: integrated addresses are not allowed in miner transactions");
uint64_t stake_reward = block_reward / 5;
tx = carrot::make_single_enote_carrot_coinbase_transaction_v1(destination, block_reward - stake_reward, height, extra_nonce);
const carrot::CarrotPaymentProposalV1 payment_proposal{
.destination = destination,
.amount = block_reward - stake_reward,
.asset_type = "SAL1",
.randomness = carrot::gen_janus_anchor()
};
std::vector<carrot::CarrotCoinbaseEnoteV1> enotes(treasury_payout_exists ? 2 : 1);
carrot::get_coinbase_output_proposal_v1(payment_proposal, height, enotes.front());
// Check to see if there needs to be a treasury payout
if (treasury_payout_exists) {
// Convert the strings into meaningful data
const auto [tx_public_key_str, onetime_address_str, anchor_enc_str, view_tag_str] = treasury_payout_data.at(height);
mx25519_pubkey tx_public_key;
CHECK_AND_ASSERT_THROW_MES(epee::string_tools::hex_to_pod(tx_public_key_str, tx_public_key), "fail to deserialize treasury tx public key");
crypto::public_key onetime_address;
CHECK_AND_ASSERT_THROW_MES(epee::string_tools::hex_to_pod(onetime_address_str, onetime_address), "fail to deserialize treasury tx onetime address");
carrot::encrypted_janus_anchor_t anchor_enc;
CHECK_AND_ASSERT_THROW_MES(epee::string_tools::hex_to_pod(anchor_enc_str, anchor_enc), "fail to deserialize treasury tx anchor_enc");
carrot::view_tag_t view_tag;
CHECK_AND_ASSERT_THROW_MES(epee::string_tools::hex_to_pod(view_tag_str, view_tag), "fail to deserialize treasury tx view_tag");
// Manually produce an enote for the treasury payout using the hardcoded keys
carrot::CarrotCoinbaseEnoteV1 &treasury_enote = enotes.back();
treasury_enote.onetime_address = onetime_address;
treasury_enote.amount = TREASURY_SAL1_MINT_AMOUNT;
treasury_enote.asset_type = "SAL1";
treasury_enote.anchor_enc = anchor_enc;
treasury_enote.view_tag = view_tag;
treasury_enote.enote_ephemeral_pubkey = tx_public_key;
treasury_enote.block_index = height;
// sort enotes by K_o
if (enotes[0].onetime_address > enotes[1].onetime_address) {
std::swap(enotes[0], enotes[1]);
}
}
tx = carrot::store_carrot_to_coinbase_transaction_v1(enotes, extra_nonce, cryptonote::transaction_type::MINER, height);
tx.amount_burnt = stake_reward;
tx.invalidate_hashes();
}
@@ -573,7 +622,7 @@ namespace cryptonote
std::string asset_type = "SAL";
if (hard_fork_version >= HF_VERSION_SALVIUM_ONE_PROOFS)
asset_type = "SAL1";
cryptonote::set_tx_out(amount, asset_type, CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW, out_eph_public_key, !treasury_payout_exist, view_tag, out);
cryptonote::set_tx_out(amount, asset_type, CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW, out_eph_public_key, use_view_tags, view_tag, out);
tx.vout.push_back(out);
} else {
@@ -585,7 +634,7 @@ namespace cryptonote
}
CHECK_AND_ASSERT_MES(summary_amounts == block_reward, false, "Failed to construct miner tx, summary_amounts = " << summary_amounts << " not equal block_reward = " << block_reward);
/*
// add the treasury payout if needed
if (treasury_payout_exist) {
std::vector<crypto::public_key> additional_tx_public_keys = {txkey.pub};
@@ -606,7 +655,7 @@ namespace cryptonote
additional_tx_public_keys.push_back(tx_key);
add_additional_tx_pub_keys_to_extra(tx.extra, additional_tx_public_keys);
}
*/
tx.version = 2;
tx.vin.push_back(in);
tx.invalidate_hashes();
+5 -1
View File
@@ -1611,8 +1611,12 @@ namespace rct {
{
if (hwdev.get_mode() == hw::device::TRANSACTION_CREATE_FAKE)
rv.p.TCLSAGs[i] = make_dummy_tclsag(rv.mixRing[i].size());
else
else {
rv.p.TCLSAGs[i] = proveRctTCLSAGSimple(full_message, rv.mixRing[i], inSk[i].x, inSk[i].y, inSk[i].mask, a[i], pseudoOuts[i], index[i], hwdev);
#ifdef DBG
CHECK_AND_ASSERT_THROW_MES(verRctTCLSAGSimple(full_message, rv.p.TCLSAGs[i], rv.mixRing[i], pseudoOuts[i]), "T-CLSAG verification failed");
#endif
}
}
}
+36 -14
View File
@@ -252,7 +252,8 @@ static std::optional<enote_view_incoming_scan_info_t> view_incoming_scan_pre_car
.amount = amount,
.amount_blinding_factor = amount_blinding_factor,
.asset_type = enote.asset_type,
.main_tx_pubkey_index = main_deriv_idx
.main_tx_pubkey_index = main_deriv_idx,
.is_carrot = false
};
}
//-------------------------------------------------------------------------------------------------------------------
@@ -278,7 +279,19 @@ static std::optional<enote_view_incoming_scan_info_t> view_incoming_scan_carrot_
res.asset_type = enote.asset_type;
res.amount_blinding_factor = rct::I;
res.main_tx_pubkey_index = 0;
res.is_carrot = true;
/*
LOG_ERROR("wallet scanning values:" << std::endl <<
" height : " << std::to_string(enote.block_index) << std::endl <<
" Ko : " << epee::string_tools::pod_to_hex(enote.onetime_address) << std::endl <<
" C_a : " << epee::string_tools::pod_to_hex(rct::commit(res.amount, res.amount_blinding_factor)) << std::endl <<
" D_e : " << epee::string_tools::pod_to_hex(enote.enote_ephemeral_pubkey) << std::endl <<
" s_sr : " << epee::string_tools::pod_to_hex(s_sender_receiver_unctx.data) << std::endl <<
" k^o_g : " << epee::string_tools::pod_to_hex(res.sender_extension_g.data) << std::endl <<
" k^o_t : " << epee::string_tools::pod_to_hex(res.sender_extension_t.data) << std::endl <<
" K^j_s : " << epee::string_tools::pod_to_hex(res.address_spend_pubkey) << std::endl);
*/
return res;
}
//-------------------------------------------------------------------------------------------------------------------
@@ -322,6 +335,7 @@ static std::optional<enote_view_incoming_scan_info_t> view_incoming_scan_carrot_
res.amount_blinding_factor = rct::sk2rct(amount_blinding_factor_sk);
res.main_tx_pubkey_index = 0;
res.asset_type = enote.asset_type;
res.is_carrot = true;
return res;
}
@@ -375,6 +389,7 @@ static std::optional<enote_view_incoming_scan_info_t> view_incoming_scan_carrot_
res.amount_blinding_factor = rct::sk2rct(amount_blinding_factor_sk);
res.main_tx_pubkey_index = 0;
res.asset_type = enote.asset_type;
res.is_carrot = true;
return res;
}
@@ -864,7 +879,7 @@ bool is_long_payment_id(const crypto::hash &pid)
//-------------------------------------------------------------------------------------------------------------------
std::optional<crypto::key_image> try_derive_enote_key_image(
const enote_view_incoming_scan_info_t &enote_scan_info,
const cryptonote::account_keys &acc)
const carrot::carrot_and_legacy_account &acc)
{
if (!enote_scan_info.subaddr_index)
return std::nullopt;
@@ -872,20 +887,19 @@ std::optional<crypto::key_image> try_derive_enote_key_image(
// k^j_subext
rct::key subaddress_extension;
if (enote_scan_info.subaddr_index->index.is_subaddress())
{
{
const cryptonote::subaddress_index subaddr_index_cn{enote_scan_info.subaddr_index->index.major,
enote_scan_info.subaddr_index->index.minor};
subaddress_extension = rct::sk2rct(
acc.get_device().get_subaddress_secret_key(acc.m_view_secret_key, subaddr_index_cn));
}
enote_scan_info.subaddr_index->index.minor};
subaddress_extension = rct::sk2rct(acc.get_keys().get_device().get_subaddress_secret_key(acc.get_keys().m_view_secret_key, subaddr_index_cn));
}
else // !subaddr_index_cn.is_zero()
{
{
subaddress_extension = rct::Z;
}
}
// O = K^j_s + k^g_o G + k^t_o T
rct::key onetime_address = rct::scalarmultKey(rct::pk2rct(crypto::get_T()),
rct::sk2rct(enote_scan_info.sender_extension_t));
rct::sk2rct(enote_scan_info.sender_extension_t));
rct::addKeys1(onetime_address, rct::sk2rct(enote_scan_info.sender_extension_g), onetime_address);
rct::addKeys(onetime_address, onetime_address, rct::pk2rct(enote_scan_info.address_spend_pubkey));
@@ -896,11 +910,19 @@ std::optional<crypto::key_image> try_derive_enote_key_image(
//! @TODO: HW devices
// x = k_s + k^j_subext + k^g_o
rct::key x;
sc_add(x.bytes,
to_bytes(acc.m_spend_secret_key),
to_bytes(enote_scan_info.sender_extension_g));
sc_add(x.bytes, x.bytes, subaddress_extension.bytes);
if (enote_scan_info.is_carrot) {
return acc.derive_key_image(enote_scan_info.address_spend_pubkey,
enote_scan_info.sender_extension_g,
enote_scan_info.sender_extension_t,
rct::rct2pk(onetime_address));
} else {
sc_add(x.bytes,
to_bytes(acc.get_keys().m_spend_secret_key),
to_bytes(enote_scan_info.sender_extension_g));
sc_add(x.bytes, x.bytes, subaddress_extension.bytes);
}
// L = x I = (k_s + k^j_subext + k^g_o) Hp(O)
return rct::rct2ki(rct::scalarmultKey(rct::pt2rct(ki_generator), x));
}
+4 -1
View File
@@ -31,6 +31,7 @@
//local headers
#include "carrot_core/carrot_enote_types.h"
#include "carrot_core/device.h"
#include "carrot_impl/account.h"
#include "carrot_impl/subaddress_index.h"
#include "crypto/crypto.h"
#include "cryptonote_basic/account.h"
@@ -75,6 +76,8 @@ struct enote_view_incoming_scan_info_t
// the cold signing code used to have a bug which added multiple main tx pubkeys to extra
std::size_t main_tx_pubkey_index;
bool is_carrot;
};
struct PreCarrotEnote
@@ -141,6 +144,6 @@ bool is_long_payment_id(const crypto::hash &pid);
std::optional<crypto::key_image> try_derive_enote_key_image(
const enote_view_incoming_scan_info_t &enote_scan_info,
const cryptonote::account_keys &acc);
const carrot::carrot_and_legacy_account &acc);
} //namespace wallet
} //namespace tools
+34 -6
View File
@@ -91,6 +91,7 @@ static bool is_transfer_usable_for_input_selection(const wallet2::transfer_detai
&& (from_subaddresses.empty() || from_subaddresses.count(td.m_subaddr_index.minor) == 1)
&& td.amount() >= ignore_below
&& td.amount() <= ignore_above
&& td.asset_type == "SAL1"
;
}
//-------------------------------------------------------------------------------------------------------------------
@@ -173,11 +174,17 @@ static crypto::public_key find_change_address_spend_pubkey(
CHECK_AND_ASSERT_THROW_MES(change_it != subaddress_map.cend(),
"find_change_address_spend_pubkey: missing change address (index "
<< subaddr_account << ",0) in subaddress map");
// HERE BE DRAGONS!!!
// SRCG: Disabling the following check is necessary to allow return_payments to work...
// ...but if we can find an alternative to using the subaddress_map, we should!
/*
const auto change_it_2 = std::find_if(std::next(change_it), subaddress_map.cend(),
[subaddr_account](const auto &p) { return p.second.major == subaddr_account && p.second.minor == 0; });
CHECK_AND_ASSERT_THROW_MES(change_it_2 == subaddress_map.cend(),
"find_change_address_spend_pubkey: provided subaddress map is malformed!!! At least two spend pubkeys map to "
"index " << subaddr_account << ",0 in the subaddress map!");
*/
// LAND AHOY!!!
return change_it->first;
}
//-------------------------------------------------------------------------------------------------------------------
@@ -410,14 +417,14 @@ std::vector<carrot::CarrotTransactionProposalV1> make_carrot_transaction_proposa
const auto subaddress_map = w.get_subaddress_map_ref();
std::vector<carrot::CarrotTransactionProposalV1> tx_proposals;
tx_proposals.reserve(dsts.size() / (FCMP_PLUS_PLUS_MAX_OUTPUTS - 1) + 1);
tx_proposals.reserve(dsts.size() / (carrot::CARROT_MAX_TX_OUTPUTS - 1) + 1);
const crypto::public_key change_address_spend_pubkey
= find_change_address_spend_pubkey(subaddress_map, subaddr_account);
while (!dsts.empty())
{
const std::size_t num_dsts_to_complete = std::min<std::size_t>(dsts.size(), FCMP_PLUS_PLUS_MAX_OUTPUTS - 1);
const std::size_t num_dsts_to_complete = std::min<std::size_t>(dsts.size(), carrot::CARROT_MAX_TX_OUTPUTS - 1);
// build payment proposals and subtractable info from last `num_dsts_to_complete` dsts
std::vector<carrot::CarrotPaymentProposalV1> normal_payment_proposals;
@@ -847,10 +854,11 @@ cryptonote::transaction finalize_all_proofs_from_transfer_details(
ctkey.mask = sources[i].mask;
if (sources[i].carrot) {
const std::vector<crypto::public_key> v_pubkeys{sources[i].real_out_tx_key};
const epee::span<const crypto::public_key> main_tx_ephemeral_pubkeys =
epee::to_span(std::vector<crypto::public_key>{sources[i].real_out_tx_key});
epee::to_span(v_pubkeys);
const epee::span<const crypto::public_key> additional_tx_ephemeral_pubkeys =
epee::to_span(sources[i].real_out_additional_tx_keys);
epee::to_span(sources[i].real_out_additional_tx_keys);
// 2. perform ECDH derivations
std::vector<crypto::key_derivation> main_derivations;
@@ -917,8 +925,28 @@ cryptonote::transaction finalize_all_proofs_from_transfer_details(
nominal_janus_anchor_out
);
/*
LOG_ERROR("tx_builder values:" << std::endl <<
" Ko : " << epee::string_tools::pod_to_hex(sources[i].outputs[sources[i].real_output].second.dest) << std::endl <<
" C_a : " << epee::string_tools::pod_to_hex(sources[i].outputs[sources[i].real_output].second.mask) << std::endl <<
" D_e : " << epee::string_tools::pod_to_hex(sources[i].real_out_tx_key) << std::endl <<
" s_sr : " << epee::string_tools::pod_to_hex(s_sender_receiver_unctx.data) << std::endl <<
" s^ctx_sr : " << epee::string_tools::pod_to_hex(s_sender_receiver.data) << std::endl <<
" k^o_g : " << epee::string_tools::pod_to_hex(sender_extension_g_out.data) << std::endl <<
" k^o_t : " << epee::string_tools::pod_to_hex(sender_extension_t_out.data) << std::endl <<
" K^j_s : " << epee::string_tools::pod_to_hex(sources[i].address_spend_pubkey) << std::endl);
*/
bool r = w.get_account().can_open_fcmp_onetime_address(
sources[i].address_spend_pubkey,
sender_extension_g_out,
sender_extension_t_out,
rct::rct2pk(sources[i].outputs[sources[i].real_output].second.dest)
);
THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error,
"Failed to open onetime address");
crypto::secret_key x, y;
bool r = w.get_account().try_searching_for_opening_for_onetime_address(
r = w.get_account().try_searching_for_opening_for_onetime_address(
sources[i].address_spend_pubkey,
sender_extension_g_out,
sender_extension_t_out,
@@ -926,7 +954,7 @@ cryptonote::transaction finalize_all_proofs_from_transfer_details(
y
);
THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error,
"Failed to search for opening for onetime address");
"Failed to obtain openings for onetime address");
ctkey.x = rct::sk2rct(x);
ctkey.y = rct::sk2rct(y);
} else {
+1 -1
View File
@@ -2426,7 +2426,7 @@ void wallet2::scan_key_image(const wallet::enote_view_incoming_scan_info_t &enot
}
}
ki_out = wallet::try_derive_enote_key_image(enote_scan_info, m_account.get_keys());
ki_out = wallet::try_derive_enote_key_image(enote_scan_info, m_account);
}
//----------------------------------------------------------------------------------------------------
void wallet2::process_new_transaction(