Merge branch 'main' into develop
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
# Salvium One v1.0.0
|
# Salvium One v1.0.6
|
||||||
|
|
||||||
Copyright (c) 2023-2025, Salvium
|
Copyright (c) 2023-2025, Salvium
|
||||||
Portions Copyright (c) 2014-2023, The Monero Project
|
Portions Copyright (c) 2014-2023, The Monero Project
|
||||||
@@ -172,7 +172,7 @@ invokes cmake commands as needed.
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd salvium
|
cd salvium
|
||||||
git checkout v1.0.0
|
git checkout v1.0.6
|
||||||
make
|
make
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -251,7 +251,7 @@ Tested on a Raspberry Pi Zero with a clean install of minimal Raspbian Stretch (
|
|||||||
```bash
|
```bash
|
||||||
git clone https://github.com/salvium/salvium
|
git clone https://github.com/salvium/salvium
|
||||||
cd salvium
|
cd salvium
|
||||||
git checkout v1.0.0
|
git checkout v1.0.6
|
||||||
```
|
```
|
||||||
|
|
||||||
* Build:
|
* Build:
|
||||||
@@ -370,10 +370,10 @@ application.
|
|||||||
cd salvium
|
cd salvium
|
||||||
```
|
```
|
||||||
|
|
||||||
* If you would like a specific [version/tag](https://github.com/salvium/salvium/tags), do a git checkout for that version. eg. 'v1.0.0'. If you don't care about the version and just want binaries from master, skip this step:
|
* If you would like a specific [version/tag](https://github.com/salvium/salvium/tags), do a git checkout for that version. eg. 'v1.0.6'. If you don't care about the version and just want binaries from master, skip this step:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git checkout v1.0.0
|
git checkout v1.0.6
|
||||||
```
|
```
|
||||||
|
|
||||||
* If you are on a 64-bit system, run:
|
* If you are on a 64-bit system, run:
|
||||||
|
|||||||
@@ -282,13 +282,13 @@ crypto::key_image carrot_and_legacy_account::derive_key_image(const crypto::publ
|
|||||||
return L;
|
return L;
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
void carrot_and_legacy_account::generate_subaddress_map()
|
void carrot_and_legacy_account::generate_subaddress_map(const std::pair<size_t, size_t>& lookahead_size)
|
||||||
{
|
{
|
||||||
const std::vector<AddressDeriveType> derive_types{AddressDeriveType::Carrot, AddressDeriveType::PreCarrot};
|
const std::vector<AddressDeriveType> derive_types{AddressDeriveType::Carrot, AddressDeriveType::PreCarrot};
|
||||||
|
|
||||||
for (uint32_t major_index = 0; major_index <= MAX_SUBADDRESS_MAJOR_INDEX; ++major_index)
|
for (uint32_t major_index = 0; major_index <= lookahead_size.first; ++major_index)
|
||||||
{
|
{
|
||||||
for (uint32_t minor_index = 0; minor_index <= MAX_SUBADDRESS_MINOR_INDEX; ++minor_index)
|
for (uint32_t minor_index = 0; minor_index <= lookahead_size.first; ++minor_index)
|
||||||
{
|
{
|
||||||
for (const AddressDeriveType derive_type : derive_types)
|
for (const AddressDeriveType derive_type : derive_types)
|
||||||
{
|
{
|
||||||
@@ -361,7 +361,6 @@ void carrot_and_legacy_account::create_from_svb_key(const cryptonote::account_pu
|
|||||||
);
|
);
|
||||||
|
|
||||||
this->default_derive_type = AddressDeriveType::Carrot;
|
this->default_derive_type = AddressDeriveType::Carrot;
|
||||||
generate_subaddress_map();
|
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
void carrot_and_legacy_account::set_carrot_keys(const AddressDeriveType default_derive_type)
|
void carrot_and_legacy_account::set_carrot_keys(const AddressDeriveType default_derive_type)
|
||||||
@@ -393,13 +392,19 @@ void carrot_and_legacy_account::set_carrot_keys(const AddressDeriveType default_
|
|||||||
m_keys.m_carrot_main_address.m_is_carrot = true;
|
m_keys.m_carrot_main_address.m_is_carrot = true;
|
||||||
|
|
||||||
this->default_derive_type = default_derive_type;
|
this->default_derive_type = default_derive_type;
|
||||||
generate_subaddress_map();
|
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
void carrot_and_legacy_account::insert_subaddresses(const std::unordered_map<crypto::public_key, subaddress_index_extended>& subaddress_map_cn)
|
void carrot_and_legacy_account::insert_subaddresses(const std::unordered_map<crypto::public_key, subaddress_index_extended>& subaddress_map_cn)
|
||||||
{
|
{
|
||||||
for (const auto &p : subaddress_map_cn)
|
for (const auto &p : subaddress_map_cn) {
|
||||||
subaddress_map.insert({p.first, {{p.second.index.major, p.second.index.minor}, p.second.derive_type, p.second.is_return_spend_key}});
|
subaddress_map.insert({p.first, {{p.second.index.major, p.second.index.minor}, p.second.derive_type, p.second.is_return_spend_key}});
|
||||||
|
if (p.second.derive_type == AddressDeriveType::PreCarrot) {
|
||||||
|
// Create a matching Carrot address
|
||||||
|
const subaddress_index_extended subaddr_index{{p.second.index.major, p.second.index.minor}, AddressDeriveType::Carrot, p.second.is_return_spend_key};
|
||||||
|
const CarrotDestinationV1 addr = subaddress(subaddr_index);
|
||||||
|
subaddress_map.insert({addr.address_spend_pubkey, subaddr_index});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
void carrot_and_legacy_account::insert_return_output_info(const std::unordered_map<crypto::public_key, return_output_info_t>& roi_map)
|
void carrot_and_legacy_account::insert_return_output_info(const std::unordered_map<crypto::public_key, return_output_info_t>& roi_map)
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ namespace carrot
|
|||||||
const crypto::secret_key &sender_extension_t,
|
const crypto::secret_key &sender_extension_t,
|
||||||
const crypto::public_key &onetime_address) const;
|
const crypto::public_key &onetime_address) const;
|
||||||
|
|
||||||
void generate_subaddress_map();
|
void generate_subaddress_map(const std::pair<size_t, size_t>& lookahead_size);
|
||||||
|
|
||||||
crypto::secret_key generate(
|
crypto::secret_key generate(
|
||||||
const crypto::secret_key& recovery_key = crypto::secret_key(),
|
const crypto::secret_key& recovery_key = crypto::secret_key(),
|
||||||
|
|||||||
@@ -41,9 +41,9 @@
|
|||||||
|
|
||||||
namespace carrot
|
namespace carrot
|
||||||
{
|
{
|
||||||
#define CARROT_DEFINE_SIMPLE_ERROR_TYPE(e, b) class e: b { using b::b; };
|
#define CARROT_DEFINE_SIMPLE_ERROR_TYPE(e, b) class e: public b { using b::b; };
|
||||||
|
|
||||||
class carrot_logic_error: std::logic_error { using std::logic_error::logic_error; };
|
class carrot_logic_error: public std::logic_error { using std::logic_error::logic_error; };
|
||||||
|
|
||||||
CARROT_DEFINE_SIMPLE_ERROR_TYPE(bad_address_type, carrot_logic_error)
|
CARROT_DEFINE_SIMPLE_ERROR_TYPE(bad_address_type, carrot_logic_error)
|
||||||
CARROT_DEFINE_SIMPLE_ERROR_TYPE(component_out_of_order, carrot_logic_error)
|
CARROT_DEFINE_SIMPLE_ERROR_TYPE(component_out_of_order, carrot_logic_error)
|
||||||
@@ -55,7 +55,7 @@ CARROT_DEFINE_SIMPLE_ERROR_TYPE(too_few_outputs, carrot_logic_error)
|
|||||||
CARROT_DEFINE_SIMPLE_ERROR_TYPE(too_many_outputs, carrot_logic_error)
|
CARROT_DEFINE_SIMPLE_ERROR_TYPE(too_many_outputs, carrot_logic_error)
|
||||||
CARROT_DEFINE_SIMPLE_ERROR_TYPE(invalid_tx_type, carrot_logic_error)
|
CARROT_DEFINE_SIMPLE_ERROR_TYPE(invalid_tx_type, carrot_logic_error)
|
||||||
|
|
||||||
class carrot_runtime_error: std::runtime_error { using std::runtime_error::runtime_error; };
|
class carrot_runtime_error: public std::runtime_error { using std::runtime_error::runtime_error; };
|
||||||
|
|
||||||
CARROT_DEFINE_SIMPLE_ERROR_TYPE(crypto_function_failed, carrot_runtime_error)
|
CARROT_DEFINE_SIMPLE_ERROR_TYPE(crypto_function_failed, carrot_runtime_error)
|
||||||
CARROT_DEFINE_SIMPLE_ERROR_TYPE(not_enough_money, carrot_runtime_error)
|
CARROT_DEFINE_SIMPLE_ERROR_TYPE(not_enough_money, carrot_runtime_error)
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ std::optional<AdditionalOutputType> get_additional_output_type(const size_t num_
|
|||||||
}
|
}
|
||||||
else if (!need_change_output)
|
else if (!need_change_output)
|
||||||
{
|
{
|
||||||
return AdditionalOutputType::DUMMY;
|
return AdditionalOutputType::CHANGE_UNIQUE;
|
||||||
}
|
}
|
||||||
else // num_selfsend == 1 && need_change_output
|
else // num_selfsend == 1 && need_change_output
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -519,7 +519,7 @@ bool try_scan_carrot_enote_internal_receiver(const CarrotEnoteV1 &enote,
|
|||||||
crypto::secret_key sum_g;
|
crypto::secret_key sum_g;
|
||||||
sc_add(to_bytes(sum_g), to_bytes(sender_extension_g_out), to_bytes(k_return));
|
sc_add(to_bytes(sum_g), to_bytes(sender_extension_g_out), to_bytes(k_return));
|
||||||
crypto::key_image key_image = account.derive_key_image(
|
crypto::key_image key_image = account.derive_key_image(
|
||||||
account.get_keys().m_carrot_account_address.m_spend_public_key,
|
address_spend_pubkey_out, // THIS WAS WRONG!!! -> account.get_keys().m_carrot_account_address.m_spend_public_key,
|
||||||
sum_g,
|
sum_g,
|
||||||
sender_extension_t_out,
|
sender_extension_t_out,
|
||||||
K_r
|
K_r
|
||||||
@@ -527,7 +527,7 @@ bool try_scan_carrot_enote_internal_receiver(const CarrotEnoteV1 &enote,
|
|||||||
|
|
||||||
crypto::secret_key x, y;
|
crypto::secret_key x, y;
|
||||||
account.try_searching_for_opening_for_onetime_address(
|
account.try_searching_for_opening_for_onetime_address(
|
||||||
account.get_keys().m_carrot_account_address.m_spend_public_key,
|
address_spend_pubkey_out, // THIS WAS WRONG!!! -> account.get_keys().m_carrot_account_address.m_spend_public_key,
|
||||||
sum_g,
|
sum_g,
|
||||||
sender_extension_t_out,
|
sender_extension_t_out,
|
||||||
x,
|
x,
|
||||||
|
|||||||
@@ -283,9 +283,9 @@ DISABLE_VS_WARNINGS(4244 4345)
|
|||||||
std::string account_base::get_carrot_public_address_str(network_type nettype) const
|
std::string account_base::get_carrot_public_address_str(network_type nettype) const
|
||||||
{
|
{
|
||||||
// Build the cryptonote::account_public_address
|
// Build the cryptonote::account_public_address
|
||||||
account_public_address addr{m_keys.m_carrot_main_address.m_spend_public_key, m_keys.m_carrot_main_address.m_view_public_key};
|
account_public_address addr{m_keys.m_carrot_main_address.m_spend_public_key, m_keys.m_carrot_main_address.m_view_public_key, true};
|
||||||
// change this code into base 58
|
// change this code into base 58
|
||||||
return get_account_address_as_str(nettype, false, addr, true);
|
return get_account_address_as_str(nettype, false, addr);
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
||||||
std::string account_base::get_public_integrated_address_str(const crypto::hash8 &payment_id, network_type nettype) const
|
std::string account_base::get_public_integrated_address_str(const crypto::hash8 &payment_id, network_type nettype) const
|
||||||
|
|||||||
@@ -155,10 +155,9 @@ namespace cryptonote {
|
|||||||
network_type nettype
|
network_type nettype
|
||||||
, bool subaddress
|
, bool subaddress
|
||||||
, account_public_address const & adr
|
, account_public_address const & adr
|
||||||
, bool is_carrot
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
uint64_t address_prefix = is_carrot
|
uint64_t address_prefix = adr.m_is_carrot
|
||||||
? (subaddress ? get_config(nettype).CARROT_PUBLIC_SUBADDRESS_BASE58_PREFIX : get_config(nettype).CARROT_PUBLIC_ADDRESS_BASE58_PREFIX)
|
? (subaddress ? get_config(nettype).CARROT_PUBLIC_SUBADDRESS_BASE58_PREFIX : get_config(nettype).CARROT_PUBLIC_ADDRESS_BASE58_PREFIX)
|
||||||
: (subaddress ? get_config(nettype).CRYPTONOTE_PUBLIC_SUBADDRESS_BASE58_PREFIX : get_config(nettype).CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX);
|
: (subaddress ? get_config(nettype).CRYPTONOTE_PUBLIC_SUBADDRESS_BASE58_PREFIX : get_config(nettype).CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX);
|
||||||
|
|
||||||
@@ -169,10 +168,9 @@ namespace cryptonote {
|
|||||||
network_type nettype
|
network_type nettype
|
||||||
, account_public_address const & adr
|
, account_public_address const & adr
|
||||||
, crypto::hash8 const & payment_id
|
, crypto::hash8 const & payment_id
|
||||||
, bool is_carrot
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
uint64_t integrated_address_prefix = is_carrot ? get_config(nettype).CARROT_PUBLIC_INTEGRATED_ADDRESS_BASE58_PREFIX : get_config(nettype).CRYPTONOTE_PUBLIC_INTEGRATED_ADDRESS_BASE58_PREFIX;
|
uint64_t integrated_address_prefix = adr.m_is_carrot ? get_config(nettype).CARROT_PUBLIC_INTEGRATED_ADDRESS_BASE58_PREFIX : get_config(nettype).CRYPTONOTE_PUBLIC_INTEGRATED_ADDRESS_BASE58_PREFIX;
|
||||||
|
|
||||||
integrated_address iadr = {
|
integrated_address iadr = {
|
||||||
adr, payment_id
|
adr, payment_id
|
||||||
|
|||||||
@@ -88,14 +88,12 @@ namespace cryptonote {
|
|||||||
network_type nettype
|
network_type nettype
|
||||||
, bool subaddress
|
, bool subaddress
|
||||||
, const account_public_address& adr
|
, const account_public_address& adr
|
||||||
, bool is_carrot = false
|
|
||||||
);
|
);
|
||||||
|
|
||||||
std::string get_account_integrated_address_as_str(
|
std::string get_account_integrated_address_as_str(
|
||||||
network_type nettype
|
network_type nettype
|
||||||
, const account_public_address& adr
|
, const account_public_address& adr
|
||||||
, const crypto::hash8& payment_id
|
, const crypto::hash8& payment_id
|
||||||
, bool is_carrot = false
|
|
||||||
);
|
);
|
||||||
|
|
||||||
bool get_account_address_from_str(
|
bool get_account_address_from_str(
|
||||||
|
|||||||
@@ -1355,7 +1355,7 @@ bool t_rpc_command_executor::print_transaction_pool_stats() {
|
|||||||
bool t_rpc_command_executor::start_mining(cryptonote::account_public_address address, uint64_t num_threads, cryptonote::network_type nettype, bool do_background_mining, bool ignore_battery, bool is_carrot) {
|
bool t_rpc_command_executor::start_mining(cryptonote::account_public_address address, uint64_t num_threads, cryptonote::network_type nettype, bool do_background_mining, bool ignore_battery, bool is_carrot) {
|
||||||
cryptonote::COMMAND_RPC_START_MINING::request req;
|
cryptonote::COMMAND_RPC_START_MINING::request req;
|
||||||
cryptonote::COMMAND_RPC_START_MINING::response res;
|
cryptonote::COMMAND_RPC_START_MINING::response res;
|
||||||
req.miner_address = cryptonote::get_account_address_as_str(nettype, false, address, is_carrot);
|
req.miner_address = cryptonote::get_account_address_as_str(nettype, false, address);
|
||||||
req.threads_count = num_threads;
|
req.threads_count = num_threads;
|
||||||
req.do_background_mining = do_background_mining;
|
req.do_background_mining = do_background_mining;
|
||||||
req.ignore_battery = ignore_battery;
|
req.ignore_battery = ignore_battery;
|
||||||
|
|||||||
@@ -1879,12 +1879,29 @@ namespace cryptonote
|
|||||||
}
|
}
|
||||||
blobdata block_blob = t_serializable_object_to_blob(b);
|
blobdata block_blob = t_serializable_object_to_blob(b);
|
||||||
crypto::public_key tx_pub_key = cryptonote::get_tx_pub_key_from_extra(b.miner_tx);
|
crypto::public_key tx_pub_key = cryptonote::get_tx_pub_key_from_extra(b.miner_tx);
|
||||||
|
const std::vector<crypto::public_key> additional_tx_pub_keys = cryptonote::get_additional_tx_pub_keys_from_extra(b.miner_tx);
|
||||||
if(tx_pub_key == crypto::null_pkey)
|
if(tx_pub_key == crypto::null_pkey)
|
||||||
{
|
{
|
||||||
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
|
// Check for Carrot treasury payout
|
||||||
error_resp.message = "Internal error: failed to create block template";
|
const uint8_t hf_version = m_core.get_blockchain_storage().get_current_hard_fork_version();
|
||||||
LOG_ERROR("Failed to get tx pub key in coinbase extra");
|
if (hf_version >= HF_VERSION_CARROT && b.miner_tx.vout.size() == 2) {
|
||||||
return false;
|
|
||||||
|
const auto treasury_payout_data = get_config(nettype()).TREASURY_SAL1_MINT_OUTPUT_DATA;
|
||||||
|
const bool treasury_payout_exists = (treasury_payout_data.count(height) == 1);
|
||||||
|
if (!treasury_payout_exists) {
|
||||||
|
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
|
||||||
|
error_resp.message = "Internal error: failed to create block template (missing treasury payout)";
|
||||||
|
LOG_ERROR("Failed to get tx pub key in coinbase extra (missing treasury payout)");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
tx_pub_key = additional_tx_pub_keys.back();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
|
||||||
|
error_resp.message = "Internal error: failed to create block template";
|
||||||
|
LOG_ERROR("Failed to get tx pub key in coinbase extra");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t next_height;
|
uint64_t next_height;
|
||||||
|
|||||||
@@ -5335,7 +5335,7 @@ boost::optional<epee::wipeable_string> simple_wallet::new_wallet(const boost::pr
|
|||||||
.m_is_carrot = true
|
.m_is_carrot = true
|
||||||
};
|
};
|
||||||
message_writer(console_color_white, true) << tr("Generated new Carrot wallet: ")
|
message_writer(console_color_white, true) << tr("Generated new Carrot wallet: ")
|
||||||
<< cryptonote::get_account_address_as_str(m_wallet->nettype(), false, carrot_address, true);
|
<< cryptonote::get_account_address_as_str(m_wallet->nettype(), false, carrot_address);
|
||||||
PAUSE_READLINE();
|
PAUSE_READLINE();
|
||||||
std::cout << tr("View key: ");
|
std::cout << tr("View key: ");
|
||||||
print_secret_key(m_wallet->get_account().get_keys().m_view_secret_key);
|
print_secret_key(m_wallet->get_account().get_keys().m_view_secret_key);
|
||||||
@@ -11231,9 +11231,9 @@ bool simple_wallet::address_book(const std::vector<std::string> &args/* = std::v
|
|||||||
success_msg_writer() << tr("Index: ") << i;
|
success_msg_writer() << tr("Index: ") << i;
|
||||||
std::string address;
|
std::string address;
|
||||||
if (row.m_has_payment_id)
|
if (row.m_has_payment_id)
|
||||||
address = cryptonote::get_account_integrated_address_as_str(m_wallet->nettype(), row.m_address, row.m_payment_id, row.m_is_carrot);
|
address = cryptonote::get_account_integrated_address_as_str(m_wallet->nettype(), row.m_address, row.m_payment_id);
|
||||||
else
|
else
|
||||||
address = get_account_address_as_str(m_wallet->nettype(), row.m_is_subaddress, row.m_address, row.m_is_carrot);
|
address = get_account_address_as_str(m_wallet->nettype(), row.m_is_subaddress, row.m_address);
|
||||||
success_msg_writer() << tr("Address: ") << address;
|
success_msg_writer() << tr("Address: ") << address;
|
||||||
success_msg_writer() << tr("Description: ") << row.m_description << "\n";
|
success_msg_writer() << tr("Description: ") << row.m_description << "\n";
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
#define DEF_SALVIUM_VERSION_TAG "@VERSIONTAG@"
|
#define DEF_SALVIUM_VERSION_TAG "@VERSIONTAG@"
|
||||||
#define DEF_SALVIUM_VERSION "1.0.0"
|
#define DEF_SALVIUM_VERSION "1.0.6"
|
||||||
#define DEF_MONERO_VERSION_TAG "release"
|
#define DEF_MONERO_VERSION_TAG "release"
|
||||||
#define DEF_MONERO_VERSION "0.18.3.4"
|
#define DEF_MONERO_VERSION "0.18.3.4"
|
||||||
#define DEF_MONERO_RELEASE_NAME "One"
|
#define DEF_MONERO_RELEASE_NAME "One"
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ static cryptonote::tx_destination_entry make_tx_destination_entry(
|
|||||||
const carrot::CarrotPaymentProposalV1 &payment_proposal)
|
const carrot::CarrotPaymentProposalV1 &payment_proposal)
|
||||||
{
|
{
|
||||||
cryptonote::tx_destination_entry dest = cryptonote::tx_destination_entry(payment_proposal.amount,
|
cryptonote::tx_destination_entry dest = cryptonote::tx_destination_entry(payment_proposal.amount,
|
||||||
{payment_proposal.destination.address_spend_pubkey, payment_proposal.destination.address_view_pubkey},
|
{payment_proposal.destination.address_spend_pubkey, payment_proposal.destination.address_view_pubkey, /*m_is_carrot*/true},
|
||||||
payment_proposal.destination.is_subaddress);
|
payment_proposal.destination.is_subaddress);
|
||||||
dest.is_integrated = payment_proposal.destination.payment_id != carrot::null_payment_id;
|
dest.is_integrated = payment_proposal.destination.payment_id != carrot::null_payment_id;
|
||||||
return dest;
|
return dest;
|
||||||
@@ -166,8 +166,8 @@ static cryptonote::tx_destination_entry make_tx_destination_entry(
|
|||||||
"make_tx_destination_entry: view-key multiplication failed");
|
"make_tx_destination_entry: view-key multiplication failed");
|
||||||
|
|
||||||
return cryptonote::tx_destination_entry(payment_proposal.proposal.amount,
|
return cryptonote::tx_destination_entry(payment_proposal.proposal.amount,
|
||||||
{payment_proposal.proposal.destination_address_spend_pubkey, address_view_pubkey},
|
{payment_proposal.proposal.destination_address_spend_pubkey, address_view_pubkey, /*m_is_carrot*/true},
|
||||||
payment_proposal.subaddr_index.index.is_subaddress());
|
payment_proposal.subaddr_index.index.is_subaddress());
|
||||||
}
|
}
|
||||||
//-------------------------------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------------------------------
|
||||||
//-------------------------------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------------------------------
|
||||||
@@ -1360,11 +1360,16 @@ wallet2::pending_tx make_pending_carrot_tx(const carrot::CarrotTransactionPropos
|
|||||||
ptx.change_dts = change_dts;
|
ptx.change_dts = change_dts;
|
||||||
ptx.selected_transfers = std::move(selected_transfers);
|
ptx.selected_transfers = std::move(selected_transfers);
|
||||||
ptx.key_images = key_images_string.str();
|
ptx.key_images = key_images_string.str();
|
||||||
ptx.tx_key = shared_ephemeral_pubkey ? ephemeral_privkeys.at(0) : crypto::null_skey;
|
if (ephemeral_privkeys.size() == 1) {
|
||||||
if (shared_ephemeral_pubkey)
|
ptx.tx_key = ephemeral_privkeys.at(0);
|
||||||
ptx.additional_tx_keys = std::move(ephemeral_privkeys);
|
ptx.additional_tx_keys.clear();
|
||||||
else
|
} else if (ephemeral_privkeys.size() == 2 && shared_ephemeral_pubkey) {
|
||||||
ptx.additional_tx_keys.clear();
|
ptx.tx_key = (ephemeral_privkeys.at(0) == crypto::null_skey) ? ephemeral_privkeys.at(1) : ephemeral_privkeys.at(0);
|
||||||
|
ptx.additional_tx_keys.clear();
|
||||||
|
} else {
|
||||||
|
ptx.tx_key = crypto::null_skey;
|
||||||
|
ptx.additional_tx_keys = std::move(ephemeral_privkeys);
|
||||||
|
}
|
||||||
ptx.dests = std::move(dests);
|
ptx.dests = std::move(dests);
|
||||||
ptx.multisig_sigs = {};
|
ptx.multisig_sigs = {};
|
||||||
ptx.multisig_tx_key_entropy = {};
|
ptx.multisig_tx_key_entropy = {};
|
||||||
|
|||||||
+42
-12
@@ -1572,10 +1572,12 @@ cryptonote::account_public_address wallet2::get_subaddress(const cryptonote::sub
|
|||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
boost::optional<cryptonote::subaddress_index> wallet2::get_subaddress_index(const cryptonote::account_public_address& address) const
|
boost::optional<cryptonote::subaddress_index> wallet2::get_subaddress_index(const cryptonote::account_public_address& address) const
|
||||||
{
|
{
|
||||||
auto index = m_subaddresses.find(address.m_spend_public_key);
|
const auto subaddress_map = m_account.get_subaddress_map_ref();
|
||||||
if (index == m_subaddresses.end())
|
auto carrot_index = subaddress_map.find(address.m_spend_public_key);
|
||||||
|
if (carrot_index == subaddress_map.end())
|
||||||
return boost::none;
|
return boost::none;
|
||||||
return index->second;
|
cryptonote::subaddress_index index{carrot_index->second.index.major, carrot_index->second.index.minor};
|
||||||
|
return index;
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
crypto::public_key wallet2::get_subaddress_spend_public_key(const cryptonote::subaddress_index& index) const
|
crypto::public_key wallet2::get_subaddress_spend_public_key(const cryptonote::subaddress_index& index) const
|
||||||
@@ -1606,7 +1608,7 @@ std::string wallet2::get_subaddress_as_str(const carrot::subaddress_index_extend
|
|||||||
addr.m_is_carrot = subaddr.derive_type == carrot::AddressDeriveType::Carrot;
|
addr.m_is_carrot = subaddr.derive_type == carrot::AddressDeriveType::Carrot;
|
||||||
|
|
||||||
// change this code into base 58
|
// change this code into base 58
|
||||||
return cryptonote::get_account_address_as_str(m_nettype, address.is_subaddress, addr, addr.m_is_carrot);
|
return cryptonote::get_account_address_as_str(m_nettype, address.is_subaddress, addr);
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
std::string wallet2::get_integrated_address_as_str(const crypto::hash8& payment_id, bool carrot) const
|
std::string wallet2::get_integrated_address_as_str(const crypto::hash8& payment_id, bool carrot) const
|
||||||
@@ -1618,7 +1620,7 @@ std::string wallet2::get_integrated_address_as_str(const crypto::hash8& payment_
|
|||||||
account_public_address addr{address.address_spend_pubkey, address.address_view_pubkey};
|
account_public_address addr{address.address_spend_pubkey, address.address_view_pubkey};
|
||||||
addr.m_is_carrot = carrot;
|
addr.m_is_carrot = carrot;
|
||||||
|
|
||||||
return cryptonote::get_account_integrated_address_as_str(m_nettype, addr, payment_id, carrot);
|
return cryptonote::get_account_integrated_address_as_str(m_nettype, addr, payment_id);
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
void wallet2::add_subaddress_account(const std::string& label)
|
void wallet2::add_subaddress_account(const std::string& label)
|
||||||
@@ -1651,6 +1653,7 @@ bool wallet2::should_expand(const cryptonote::subaddress_index &index) const
|
|||||||
void wallet2::expand_subaddresses(const cryptonote::subaddress_index& index)
|
void wallet2::expand_subaddresses(const cryptonote::subaddress_index& index)
|
||||||
{
|
{
|
||||||
hw::device &hwdev = m_account.get_device();
|
hw::device &hwdev = m_account.get_device();
|
||||||
|
std::unordered_map<crypto::public_key, carrot::subaddress_index_extended> new_addresses;
|
||||||
if (m_subaddress_labels.size() <= index.major)
|
if (m_subaddress_labels.size() <= index.major)
|
||||||
{
|
{
|
||||||
// add new accounts
|
// add new accounts
|
||||||
@@ -1664,6 +1667,7 @@ void wallet2::expand_subaddresses(const cryptonote::subaddress_index& index)
|
|||||||
{
|
{
|
||||||
const crypto::public_key &D = pkeys[index2.minor];
|
const crypto::public_key &D = pkeys[index2.minor];
|
||||||
m_subaddresses[D] = index2;
|
m_subaddresses[D] = index2;
|
||||||
|
new_addresses.insert({D, {{index2.major, index2.minor}, carrot::AddressDeriveType::PreCarrot, false}});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_subaddress_labels.resize(index.major + 1, {"Untitled account"});
|
m_subaddress_labels.resize(index.major + 1, {"Untitled account"});
|
||||||
@@ -1681,9 +1685,12 @@ void wallet2::expand_subaddresses(const cryptonote::subaddress_index& index)
|
|||||||
{
|
{
|
||||||
const crypto::public_key &D = pkeys[index2.minor - begin];
|
const crypto::public_key &D = pkeys[index2.minor - begin];
|
||||||
m_subaddresses[D] = index2;
|
m_subaddresses[D] = index2;
|
||||||
|
new_addresses.insert({D, {{index2.major, index2.minor}, carrot::AddressDeriveType::PreCarrot, false}});
|
||||||
}
|
}
|
||||||
m_subaddress_labels[index.major].resize(index.minor + 1);
|
m_subaddress_labels[index.major].resize(index.minor + 1);
|
||||||
}
|
}
|
||||||
|
// Add to the Carrot account
|
||||||
|
m_account.insert_subaddresses(new_addresses);
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
void wallet2::create_one_off_subaddress(const cryptonote::subaddress_index& index)
|
void wallet2::create_one_off_subaddress(const cryptonote::subaddress_index& index)
|
||||||
@@ -5623,7 +5630,8 @@ void wallet2::create_keys_file(const std::string &wallet_, bool watch_only, cons
|
|||||||
|
|
||||||
if (create_address_file)
|
if (create_address_file)
|
||||||
{
|
{
|
||||||
r = save_to_file(m_wallet_file + ".address.txt", m_account.get_public_address_str(m_nettype), true);
|
std::string addresses = m_account.get_public_address_str(m_nettype) + "\n" + m_account.get_carrot_public_address_str(m_nettype) + "\n";
|
||||||
|
r = save_to_file(m_wallet_file + ".address.txt", addresses, true);
|
||||||
if(!r) MERROR("String with address text not saved");
|
if(!r) MERROR("String with address text not saved");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6606,7 +6614,9 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass
|
|||||||
{
|
{
|
||||||
THROW_WALLET_EXCEPTION_IF(true, error::file_read_error, m_keys_file);
|
THROW_WALLET_EXCEPTION_IF(true, error::file_read_error, m_keys_file);
|
||||||
}
|
}
|
||||||
LOG_PRINT_L0("Loaded wallet keys file, with public address: " << m_account.get_public_address_str(m_nettype));
|
LOG_PRINT_L0("Loaded wallet keys file, with public addresses: ");
|
||||||
|
LOG_PRINT_L0(" CN : " << m_account.get_public_address_str(m_nettype));
|
||||||
|
LOG_PRINT_L0(" Carrot : " << m_account.get_carrot_public_address_str(m_nettype));
|
||||||
lock_keys_file();
|
lock_keys_file();
|
||||||
}
|
}
|
||||||
else if (!load_keys_buf(keys_buf, password))
|
else if (!load_keys_buf(keys_buf, password))
|
||||||
@@ -6653,6 +6663,8 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass
|
|||||||
if (get_num_subaddress_accounts() == 0)
|
if (get_num_subaddress_accounts() == 0)
|
||||||
add_subaddress_account(tr("Primary account"));
|
add_subaddress_account(tr("Primary account"));
|
||||||
|
|
||||||
|
m_account.generate_subaddress_map(get_subaddress_lookahead());
|
||||||
|
|
||||||
// populate account subaddress list
|
// populate account subaddress list
|
||||||
if (!m_subaddresses.empty())
|
if (!m_subaddresses.empty())
|
||||||
{
|
{
|
||||||
@@ -7824,7 +7836,7 @@ void wallet2::commit_tx(pending_tx& ptx)
|
|||||||
amount_in += m_transfers[idx].amount();
|
amount_in += m_transfers[idx].amount();
|
||||||
}
|
}
|
||||||
add_unconfirmed_tx(ptx.tx, amount_in, dests, payment_id, ptx.change_dts.amount, subaddr_account, subaddr_indices);
|
add_unconfirmed_tx(ptx.tx, amount_in, dests, payment_id, ptx.change_dts.amount, subaddr_account, subaddr_indices);
|
||||||
if (store_tx_info() && ptx.tx_key != crypto::null_skey)
|
if (store_tx_info() && (ptx.tx_key != crypto::null_skey || ptx.additional_tx_keys.size() != 0))
|
||||||
{
|
{
|
||||||
m_tx_keys[txid] = ptx.tx_key;
|
m_tx_keys[txid] = ptx.tx_key;
|
||||||
m_additional_tx_keys[txid] = ptx.additional_tx_keys;
|
m_additional_tx_keys[txid] = ptx.additional_tx_keys;
|
||||||
@@ -11645,6 +11657,9 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below
|
|||||||
const bool do_carrot_tx_construction = use_fork_rules(HF_VERSION_CARROT);
|
const bool do_carrot_tx_construction = use_fork_rules(HF_VERSION_CARROT);
|
||||||
if (do_carrot_tx_construction)
|
if (do_carrot_tx_construction)
|
||||||
{
|
{
|
||||||
|
// Sanity checks
|
||||||
|
THROW_WALLET_EXCEPTION_IF(!address.m_is_carrot, error::wallet_internal_error, "CryptoNote address supplied, but Carrot is now active");
|
||||||
|
|
||||||
const auto tx_proposals = tools::wallet::make_carrot_transaction_proposals_wallet2_sweep_all(*this, below, address, is_subaddress, outputs, priority, extra, tx_type, subaddr_account, subaddr_indices);
|
const auto tx_proposals = tools::wallet::make_carrot_transaction_proposals_wallet2_sweep_all(*this, below, address, is_subaddress, outputs, priority, extra, tx_type, subaddr_account, subaddr_indices);
|
||||||
std::vector<pending_tx> ptx_vector;
|
std::vector<pending_tx> ptx_vector;
|
||||||
ptx_vector.reserve(tx_proposals.size());
|
ptx_vector.reserve(tx_proposals.size());
|
||||||
@@ -11653,6 +11668,9 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below
|
|||||||
return ptx_vector;
|
return ptx_vector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sanity checks
|
||||||
|
THROW_WALLET_EXCEPTION_IF(address.m_is_carrot, error::wallet_internal_error, "Carrot address supplied, but Carrot not yet active");
|
||||||
|
|
||||||
std::vector<size_t> unused_transfers_indices;
|
std::vector<size_t> unused_transfers_indices;
|
||||||
std::vector<size_t> unused_dust_indices;
|
std::vector<size_t> unused_dust_indices;
|
||||||
const bool use_per_byte_fee = true;
|
const bool use_per_byte_fee = true;
|
||||||
@@ -11735,6 +11753,9 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_single(const crypt
|
|||||||
const bool do_carrot_tx_construction = use_fork_rules(HF_VERSION_CARROT);
|
const bool do_carrot_tx_construction = use_fork_rules(HF_VERSION_CARROT);
|
||||||
if (do_carrot_tx_construction)
|
if (do_carrot_tx_construction)
|
||||||
{
|
{
|
||||||
|
// Sanity checks
|
||||||
|
THROW_WALLET_EXCEPTION_IF(!address.m_is_carrot, error::wallet_internal_error, "CryptoNote address supplied, but Carrot is now active");
|
||||||
|
|
||||||
const auto tx_proposals = tools::wallet::make_carrot_transaction_proposals_wallet2_sweep(*this, {ki}, address, is_subaddress, outputs, priority, extra, tx_type);
|
const auto tx_proposals = tools::wallet::make_carrot_transaction_proposals_wallet2_sweep(*this, {ki}, address, is_subaddress, outputs, priority, extra, tx_type);
|
||||||
std::vector<pending_tx> ptx_vector;
|
std::vector<pending_tx> ptx_vector;
|
||||||
ptx_vector.reserve(tx_proposals.size());
|
ptx_vector.reserve(tx_proposals.size());
|
||||||
@@ -11744,6 +11765,9 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_single(const crypt
|
|||||||
return ptx_vector;
|
return ptx_vector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sanity checks
|
||||||
|
THROW_WALLET_EXCEPTION_IF(address.m_is_carrot, error::wallet_internal_error, "Carrot address supplied, but Carrot not yet active");
|
||||||
|
|
||||||
std::vector<size_t> unused_transfers_indices;
|
std::vector<size_t> unused_transfers_indices;
|
||||||
std::vector<size_t> unused_dust_indices;
|
std::vector<size_t> unused_dust_indices;
|
||||||
const bool use_rct = use_fork_rules(4, 0);
|
const bool use_rct = use_fork_rules(4, 0);
|
||||||
@@ -11831,8 +11855,13 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_return(std::vector
|
|||||||
} else {
|
} else {
|
||||||
THROW_WALLET_EXCEPTION_IF(true, error::wallet_internal_error, "Unsupported input type for return_payment");
|
THROW_WALLET_EXCEPTION_IF(true, error::wallet_internal_error, "Unsupported input type for return_payment");
|
||||||
}
|
}
|
||||||
const mx25519_pubkey origin_tx_shared_secret_unctx = carrot::raw_byte_convert<mx25519_pubkey>(main_derivations[0]);
|
THROW_WALLET_EXCEPTION_IF(!main_derivations.size() && !additional_derivations.size(), error::wallet_internal_error, "No derivations found");
|
||||||
|
THROW_WALLET_EXCEPTION_IF(!main_derivations.size() && additional_derivations.size() < td_origin.m_internal_output_index + 1, error::wallet_internal_error, "No derivations found");
|
||||||
|
|
||||||
|
const key_derivation derivation = (main_derivations.size() == 1) ? main_derivations[0] : additional_derivations[td_origin.m_internal_output_index];
|
||||||
|
const mx25519_pubkey origin_tx_shared_secret_unctx = carrot::raw_byte_convert<mx25519_pubkey>(derivation);
|
||||||
|
|
||||||
|
|
||||||
// 4. compute m_return
|
// 4. compute m_return
|
||||||
crypto::public_key output_key;
|
crypto::public_key output_key;
|
||||||
carrot::encrypted_return_pubkey_t m_return;
|
carrot::encrypted_return_pubkey_t m_return;
|
||||||
@@ -11862,7 +11891,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_return(std::vector
|
|||||||
|
|
||||||
// 6. compute the change index
|
// 6. compute the change index
|
||||||
crypto::secret_key z_i;
|
crypto::secret_key z_i;
|
||||||
derivation_to_scalar(main_derivations[0], td_origin.m_internal_output_index, z_i);
|
derivation_to_scalar(derivation, td_origin.m_internal_output_index, z_i);
|
||||||
struct {
|
struct {
|
||||||
char domain_separator[8];
|
char domain_separator[8];
|
||||||
crypto::secret_key output_index_key;
|
crypto::secret_key output_index_key;
|
||||||
@@ -11886,6 +11915,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_return(std::vector
|
|||||||
cryptonote::account_public_address address;
|
cryptonote::account_public_address address;
|
||||||
address.m_spend_public_key = change_key;
|
address.m_spend_public_key = change_key;
|
||||||
address.m_view_public_key = return_pub;
|
address.m_view_public_key = return_pub;
|
||||||
|
address.m_is_carrot = true;
|
||||||
|
|
||||||
return create_transactions_from(address, cryptonote::transaction_type::RETURN, asset_type, is_subaddress, outputs, transfers_indices, unused_dust_indices, fake_outs_count, unlock_time, priority, extra);
|
return create_transactions_from(address, cryptonote::transaction_type::RETURN, asset_type, is_subaddress, outputs, transfers_indices, unused_dust_indices, fake_outs_count, unlock_time, priority, extra);
|
||||||
}
|
}
|
||||||
@@ -12570,8 +12600,8 @@ bool wallet2::get_tx_key_cached(const crypto::hash &txid, crypto::secret_key &tx
|
|||||||
if (i == m_tx_keys.end())
|
if (i == m_tx_keys.end())
|
||||||
return false;
|
return false;
|
||||||
tx_key = i->second;
|
tx_key = i->second;
|
||||||
if (tx_key == crypto::null_skey)
|
//if (tx_key == crypto::null_skey)
|
||||||
return false;
|
// return false;
|
||||||
const auto j = m_additional_tx_keys.find(txid);
|
const auto j = m_additional_tx_keys.find(txid);
|
||||||
if (j != m_additional_tx_keys.end())
|
if (j != m_additional_tx_keys.end())
|
||||||
additional_tx_keys = j->second;
|
additional_tx_keys = j->second;
|
||||||
|
|||||||
@@ -3354,9 +3354,9 @@ namespace tools
|
|||||||
const auto &entry = ab[idx];
|
const auto &entry = ab[idx];
|
||||||
std::string address;
|
std::string address;
|
||||||
if (entry.m_has_payment_id)
|
if (entry.m_has_payment_id)
|
||||||
address = cryptonote::get_account_integrated_address_as_str(m_wallet->nettype(), entry.m_address, entry.m_payment_id, entry.m_is_carrot);
|
address = cryptonote::get_account_integrated_address_as_str(m_wallet->nettype(), entry.m_address, entry.m_payment_id);
|
||||||
else
|
else
|
||||||
address = get_account_address_as_str(m_wallet->nettype(), entry.m_is_subaddress, entry.m_address, entry.m_is_carrot);
|
address = get_account_address_as_str(m_wallet->nettype(), entry.m_is_subaddress, entry.m_address);
|
||||||
res.entries.push_back(wallet_rpc::COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY::entry{idx, address, entry.m_description});
|
res.entries.push_back(wallet_rpc::COMMAND_RPC_GET_ADDRESS_BOOK_ENTRY::entry{idx, address, entry.m_description});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3637
-3375
File diff suppressed because it is too large
Load Diff
+3833
-3572
File diff suppressed because one or more lines are too long
+3832
-3571
File diff suppressed because it is too large
Load Diff
+3973
-3712
File diff suppressed because one or more lines are too long
+3832
-3571
File diff suppressed because it is too large
Load Diff
+3832
-3571
File diff suppressed because one or more lines are too long
+3832
-3571
File diff suppressed because it is too large
Load Diff
+3832
-3571
File diff suppressed because it is too large
Load Diff
+3832
-3571
File diff suppressed because one or more lines are too long
+3832
-3571
File diff suppressed because it is too large
Load Diff
+3832
-3571
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user