Compare commits

...

7 Commits

Author SHA1 Message Date
Some Random Crypto Guy d91729268f fixed output of split TXs with multiple blank lines 2024-07-03 12:22:50 +01:00
Some Random Crypto Guy 1c3d026972 fixed problem with RETURN_PAYMENT on SWEEP_ALL TX outputs; bumped version 2024-07-03 11:17:53 +01:00
Some Random Crypto Guy 847db19867 various fixes for show_transfers, locked_transfer command, blocking of invalid TXs 2024-07-02 21:00:29 +01:00
Some Random Crypto Guy 0663a5ead7 fixed support for XMRIG mining RandomX; updated genesis_tx for testnet to support RandomX; bumped version 2024-06-28 13:32:01 +01:00
Some Random Crypto Guy 7ad904a9ae fixed output type checking for all HF versions; bumped TESTNET version; bumped version 2024-06-24 17:02:19 +01:00
Some Random Crypto Guy 12cf6be402 Merge branch 'main' into develop 2024-06-24 10:10:54 +01:00
Some Random Crypto Guy 292845d721 changed some errant monero strings to salvium 2024-06-24 10:10:13 +01:00
21 changed files with 172 additions and 135 deletions
@@ -959,7 +959,7 @@ static void open_db(const std::string &filename, MDB_env **env, MDB_txn **txn, M
dbr = mdb_env_set_maxdbs(*env, 1);
CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to set max env dbs: " + std::string(mdb_strerror(dbr)));
const std::string actual_filename = filename;
MINFO("Opening monero blockchain at " << actual_filename);
MINFO("Opening Salvium blockchain at " << actual_filename);
dbr = mdb_env_open(*env, actual_filename.c_str(), flags, 0664);
CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to open rings database file '"
+ actual_filename + "': " + std::string(mdb_strerror(dbr)));
+2
View File
@@ -182,6 +182,7 @@ namespace cryptonote
bool checkpoints::init_default_checkpoints(network_type nettype)
{
/*
if (nettype == TESTNET)
{
ADD_CHECKPOINT2(0, "48ca7cd3c8de5b6a4d53d2861fbdaedca141553559f9be9520068053cda8430b", "0x1");
@@ -250,6 +251,7 @@ namespace cryptonote
ADD_CHECKPOINT2(2985000, "08f5e6b7301c1b6ed88268a28f8677a06e8ff943b3f9e48d3080f71f9c134bfb", "0x444b7b42a633c96");
ADD_CHECKPOINT2(3088000, "bddf8ca09110d33d6d497f13a113630c2b6af1c84d4f3a6f35cb1446f2604ade", "0x4aed3615c2f8c3e");
ADD_CHECKPOINT2(3102800, "083f4a34f9490403b564286e7f13fd1ed45c52c86fa47195f151594e5bc87504", "0x4bbed52d4da5dfb");
*/
return true;
}
+1 -1
View File
@@ -91,7 +91,7 @@ namespace cryptonote
BEGIN_SERIALIZE_OBJECT()
FIELD(key)
FIELD(asset_type)
FIELD(unlock_time)
VARINT_FIELD(unlock_time)
END_SERIALIZE()
};
@@ -82,7 +82,7 @@ namespace cryptonote {
//-----------------------------------------------------------------------------------------------
bool get_block_reward(size_t median_weight, size_t current_block_weight, uint64_t already_generated_coins, uint64_t &reward, uint8_t version) {
static_assert(DIFFICULTY_TARGET_V2%60==0&&DIFFICULTY_TARGET_V1%60==0,"difficulty targets must be a multiple of 60");
const int target = version < 2 ? DIFFICULTY_TARGET_V1 : DIFFICULTY_TARGET_V2;
const int target = DIFFICULTY_TARGET_V2;
const int target_minutes = target / 60;
const int emission_speed_factor = EMISSION_SPEED_FACTOR_PER_MINUTE - (target_minutes-1);
@@ -1256,6 +1256,11 @@ namespace cryptonote
<< o.target.type().name() << " and " << tx.vout[0].target.type().name() << ", "
<< "expected matching variant types in transaction id=" << get_transaction_hash(tx));
}
// Verify the asset type
std::string asset_type;
CHECK_AND_ASSERT_MES(cryptonote::get_output_asset_type(o, asset_type), false, "failed to get asset type");
CHECK_AND_ASSERT_MES(asset_type == "SAL", false, "wrong output asset type:" << asset_type);
}
return true;
}
@@ -1790,6 +1795,7 @@ namespace cryptonote
CHECK_AND_ASSERT_MES(r, false, "Failed to parse block from blob");
b.invalidate_hashes();
b.miner_tx.invalidate_hashes();
b.protocol_tx.invalidate_hashes();
if (block_hash)
{
calculate_block_hash(b, *block_hash, &b_blob);
+1 -1
View File
@@ -577,7 +577,7 @@ namespace cryptonote
b.nonce = nonce;
crypto::hash h;
if ((b.major_version >= RX_BLOCK_VERSION) && !rx_set)
if (!rx_set)
{
crypto::rx_set_miner_thread(th_local_index, tools::get_max_concurrency());
rx_set = true;
+4 -4
View File
@@ -52,7 +52,7 @@
// MONEY_SUPPLY - total number coins to be generated
#define MONEY_SUPPLY ((uint64_t)(18440000000000000ull)) // 184.4M coins * pow(10, 8)
#define EMISSION_SPEED_FACTOR_PER_MINUTE (20)
#define EMISSION_SPEED_FACTOR_PER_MINUTE (21)
#define FINAL_SUBSIDY_PER_MINUTE ((uint64_t)30000000) // 3 * pow(10, 7)
#define BURN_LOCK_PERIOD 0
@@ -208,15 +208,15 @@
#define HF_VERSION_REJECT_SIGS_IN_COINBASE 1
#define HF_VERSION_BULLETPROOF_PLUS 1
#define HF_VERSION_ENABLE_RETURN 1
#define HF_VERSION_VIEW_TAGS 1
#define HF_VERSION_LONG_TERM_BLOCK_WEIGHT 2
#define HF_VERSION_VIEW_TAGS 2
#define HF_VERSION_2021_SCALING 2
#define HF_VERSION_ENABLE_CONVERT 2
#define HF_VERSION_ENABLE_ORACLE 2
#define HF_VERSION_SLIPPAGE_YIELD 2
#define TESTNET_VERSION 8
#define TESTNET_VERSION 11
#define STAGENET_VERSION 1
#define PER_KB_FEE_QUANTIZATION_DECIMALS 8
@@ -337,7 +337,7 @@ namespace config
boost::uuids::uuid const NETWORK_ID = { {
0x12 ,0x30, 0xF1, 0x71 , 0x61, 0x04 , 0x41, 0x61, 0x17, 0x31, 0x82, 0x53, 0x41, 0x4C, 0x00, TESTNET_VERSION
} };
std::string const GENESIS_TX = "020001ff000180c0d0c7bbbff60302800b6eb882218e901c1c36bce474224456d82226260226d252459dfbadf186f70353414c3c00000000000000210171af115cca70fdcfdac362854ed9de472e242c8be5a3684e8a809d54f5dbdb18010000";
std::string const GENESIS_TX = "020001ff000180c0d0c7bbbff60302838f76f69b70bb0d0f1961a12f6082a033d22285c07d4f12ec93c28197ae2a600353414c3c2101009e8b0abce686c417a1b1344eb7337176bdca90cc928b0facec8a9516190645010000";
uint32_t const GENESIS_NONCE = 10001;
const uint64_t STAKE_LOCK_PERIOD = 20;
+4 -4
View File
@@ -1044,7 +1044,7 @@ size_t Blockchain::recalculate_difficulties(boost::optional<uint64_t> start_heig
std::vector<difficulty_type> new_cumulative_difficulties;
for (uint64_t height = start_height; height <= top_height; ++height)
{
size_t target = get_ideal_hard_fork_version(height) < 2 ? DIFFICULTY_TARGET_V1 : DIFFICULTY_TARGET_V2;
size_t target = DIFFICULTY_TARGET_V2;
difficulty_type recalculated_diff = next_difficulty(timestamps, difficulties, target);
boost::multiprecision::uint256_t recalculated_cum_diff_256 = boost::multiprecision::uint256_t(recalculated_diff) + last_cum_diff;
@@ -1351,7 +1351,7 @@ difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std:
}
// FIXME: This will fail if fork activation heights are subject to voting
size_t target = get_ideal_hard_fork_version(bei.height) < 2 ? DIFFICULTY_TARGET_V1 : DIFFICULTY_TARGET_V2;
size_t target = DIFFICULTY_TARGET_V2;
// calculate the difficulty target for the block and return it
return next_difficulty(timestamps, cumulative_difficulties, target);
@@ -3555,7 +3555,7 @@ bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context
}
}
// from v15, require view tags on outputs
// from v15, require view tags and asset types on outputs
if (!check_output_types(tx, hf_version))
{
tvc.m_invalid_output = true;
@@ -5978,7 +5978,7 @@ bool Blockchain::get_hard_fork_voting_info(uint8_t version, uint32_t &window, ui
uint64_t Blockchain::get_difficulty_target() const
{
return get_current_hard_fork_version() < 2 ? DIFFICULTY_TARGET_V1 : DIFFICULTY_TARGET_V2;
return DIFFICULTY_TARGET_V2;
}
std::map<uint64_t, std::tuple<uint64_t, uint64_t, uint64_t>> Blockchain:: get_output_histogram(const std::vector<uint64_t> &amounts, bool unlocked, uint64_t recent_cutoff, uint64_t min_count) const
+3 -3
View File
@@ -170,7 +170,7 @@ namespace cryptonote
};
static const command_line::arg_descriptor<std::string> arg_check_updates = {
"check-updates"
, "Check for new versions of monero: [disabled|notify|download|update]"
, "Check for new versions of Salvium: [disabled|notify|download|update]"
, "disabled"
};
static const command_line::arg_descriptor<bool> arg_fluffy_blocks = {
@@ -504,7 +504,7 @@ namespace cryptonote
if (boost::filesystem::exists(old_files / "blockchain.bin"))
{
MWARNING("Found old-style blockchain.bin in " << old_files.string());
MWARNING("Monero now uses a new format. You can either remove blockchain.bin to start syncing");
MWARNING("Salvium now uses a new format. You can either remove blockchain.bin to start syncing");
MWARNING("the blockchain anew, or use salvium-blockchain-export and salvium-blockchain-import to");
MWARNING("convert your existing blockchain.bin to the new format. See README.md for instructions.");
return false;
@@ -1878,7 +1878,7 @@ namespace cryptonote
//-----------------------------------------------------------------------------------------------
bool core::check_updates()
{
static const char software[] = "monero";
static const char software[] = "salvium";
#ifdef BUILD_TAG
static const char buildtag[] = BOOST_PP_STRINGIZE(BUILD_TAG);
static const char subdir[] = "cli"; // because it can never be simple
+7 -20
View File
@@ -1236,29 +1236,16 @@ namespace cryptonote
bool get_block_longhash(const Blockchain *pbc, const blobdata& bd, crypto::hash& res, const uint64_t height, const int major_version, const crypto::hash *seed_hash, const int miners)
{
// block 202612 bug workaround
if (height == 202612)
crypto::hash hash;
if (pbc != NULL)
{
static const std::string longhash_202612 = "84f64766475d51837ac9efbef1926486e58563c95a19fef4aec3254f03000000";
epee::string_tools::hex_to_pod(longhash_202612, res);
return true;
}
if (major_version >= RX_BLOCK_VERSION)
const uint64_t seed_height = rx_seedheight(height);
hash = seed_hash ? *seed_hash : pbc->get_pending_block_id_by_height(seed_height);
} else
{
crypto::hash hash;
if (pbc != NULL)
{
const uint64_t seed_height = rx_seedheight(height);
hash = seed_hash ? *seed_hash : pbc->get_pending_block_id_by_height(seed_height);
} else
{
memset(&hash, 0, sizeof(hash)); // only happens when generating genesis block
}
rx_slow_hash(hash.data, bd.data(), bd.size(), res.data);
} else {
const int pow_variant = major_version >= 7 ? major_version - 6 : 0;
crypto::cn_slow_hash(bd.data(), bd.size(), res, pow_variant, height);
memset(&hash, 0, sizeof(hash)); // only happens when generating genesis block
}
rx_slow_hash(hash.data, bd.data(), bd.size(), res.data);
return true;
}
+7
View File
@@ -260,6 +260,13 @@ namespace cryptonote
return false;
}
// Check the TX type
if (tx.type <= cryptonote::transaction_type::UNSET || tx.type > cryptonote::transaction_type::MAX) {
LOG_PRINT_L1("Transaction with id= "<< id << " has invalid type " << (uint8_t)tx.type);
tvc.m_verifivation_failed = true;
return false;
}
// assume failure during verification steps until success is certain
tvc.m_verifivation_failed = true;
+2 -1
View File
@@ -52,6 +52,7 @@ namespace cryptonote
CONVERT = 4,
BURN = 5,
STAKE = 6,
RETURN = 7
RETURN = 7,
MAX = 7
};
}
+2 -10
View File
@@ -234,16 +234,8 @@ namespace cryptonote
block = is_current ? info.block : info.previous_block;
*(uint32_t*)(hashing_blob.data() + 39) = SWAP32LE(nonce);
if (block.major_version >= RX_BLOCK_VERSION)
{
const crypto::hash &seed_hash = is_current ? info.seed_hash : info.previous_seed_hash;
crypto::rx_slow_hash(seed_hash.data, hashing_blob.data(), hashing_blob.size(), hash.data);
}
else
{
const int cn_variant = hashing_blob[0] >= 7 ? hashing_blob[0] - 6 : 0;
crypto::cn_slow_hash(hashing_blob.data(), hashing_blob.size(), hash, cn_variant, cryptonote::get_block_height(block));
}
const crypto::hash &seed_hash = is_current ? info.seed_hash : info.previous_seed_hash;
crypto::rx_slow_hash(seed_hash.data, hashing_blob.data(), hashing_blob.size(), hash.data);
if (!check_hash(hash, m_diff))
{
MWARNING("Payment too low");
+25 -28
View File
@@ -239,7 +239,7 @@ namespace
const char* USAGE_CHECK_SPEND_PROOF("check_spend_proof <txid> <signature_file> [<message>]");
const char* USAGE_GET_RESERVE_PROOF("get_reserve_proof (all|<amount>) [<message>]");
const char* USAGE_CHECK_RESERVE_PROOF("check_reserve_proof <address> <signature_file> [<message>]");
const char* USAGE_SHOW_TRANSFERS("show_transfers [in|out|all|pending|failed|pool|coinbase] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]]");
const char* USAGE_SHOW_TRANSFERS("show_transfers [in|out|all|pending|failed|pool|coinbase|burnt|staked|yield] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]]");
const char* USAGE_UNSPENT_OUTPUTS("unspent_outputs [index=<N1>[,<N2>,...]] [<min_amount> [<max_amount>]]");
const char* USAGE_RESCAN_BC("rescan_bc [hard|soft|keep_ki] [start_height=0]");
const char* USAGE_SET_TX_NOTE("set_tx_note <txid> [free text note]");
@@ -3222,7 +3222,7 @@ bool simple_wallet::help(const std::vector<std::string> &args/* = std::vector<st
message_writer() << tr("\"price_info\" - Display current pricing information for supported assets.");
message_writer() << tr("\"supply_info\" - Display circulating supply information.");
message_writer() << tr("\"yield_info\" - Display current stats on Salvium staking / yield.");
message_writer() << tr("\"show_transfers [in|out|pending|failed|pool|coinbase|burnt|yield]\" - Show transactions.");
message_writer() << tr("\"show_transfers [in|out|pending|failed|pool|coinbase|burnt|staked|yield]\" - Show transactions.");
message_writer() << tr("\"sweep_all <address>\" - Send whole balance to another wallet.");
message_writer() << tr("\"seed\" - Show secret 25 words that can be used to recover this wallet.");
message_writer() << tr("\"refresh\" - Synchronize wallet with the Salvium network.");
@@ -3606,15 +3606,16 @@ simple_wallet::simple_wallet()
// Seemingly broken formatting to compensate for the backslash before the quotes.
tr("Show the incoming/outgoing transfers within an optional height range.\n\n"
"Output format:\n"
"In or Coinbase: Block Number, \"block\"|\"in\", Time, Amount, Transaction Hash, Payment ID, Subaddress Index, \"-\", Note\n"
"Out: Block Number, \"out\", Time, Amount*, Transaction Hash, Payment ID, Fee, Destinations, Input addresses**, \"-\", Note\n"
"Pool: \"pool\", \"in\", Time, Amount, Transaction Hash, Payment Id, Subaddress Index, \"-\", Note, Double Spend Note\n"
"Pending or Failed: \"failed\"|\"pending\", \"out\", Time, Amount*, Transaction Hash, Payment ID, Fee, Input addresses**, \"-\", Note\n\n"
"In or Coinbase: Block Number, \"block\"|\"in\", Time, Amount, Asset Type, Transaction Hash, Payment ID, Subaddress Index, \"-\", Note\n"
"Out: Block Number, \"out\", Time, Amount*, Asset Type, Transaction Hash, Payment ID, Fee, Destinations, Input addresses**, \"-\", Note\n"
"Pool: \"pool\", \"in\", Time, Amount, Asset Type, Transaction Hash, Payment Id, Subaddress Index, \"-\", Note, Double Spend Note\n"
"Pending or Failed: \"failed\"|\"pending\", \"out\", Time, Amount*, Transaction Hash, Payment ID, Fee, Input addresses**, \"-\", Note\n"
"Staked or Burnt: Block Number, \"out\", Time, Amount*, Asset Type, Transaction Hash, Payment ID, Fee, Input addresses**, \"-\", Note\n\n"
"* Excluding change and fee.\n"
"** Set of address indices used as inputs in this transfer."));
m_cmd_binder.set_handler("export_transfers",
boost::bind(&simple_wallet::on_command, this, &simple_wallet::export_transfers, _1),
tr("export_transfers [in|out|all|pending|failed|pool|coinbase|burnt|yield] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]] [output=<filepath>] [option=<with_keys>]"),
tr("export_transfers [in|out|all|pending|failed|pool|coinbase|burnt|staked|yield] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]] [output=<filepath>] [option=<with_keys>]"),
tr("Export to CSV the incoming/outgoing transfers within an optional height range."));
m_cmd_binder.set_handler("unspent_outputs",
boost::bind(&simple_wallet::on_command, this, &simple_wallet::unspent_outputs, _1),
@@ -6591,9 +6592,11 @@ bool simple_wallet::process_ring_members(const std::vector<tools::wallet2::pendi
ostr
<< tr("\nWarning: Some input keys being spent are from ")
<< (are_keys_from_same_tx ? tr("the same transaction") : tr("blocks that are temporally very close"))
<< tr(", which can break the anonymity of ring signatures. Make sure this is intentional!");
<< tr(", which can break the anonymity of ring signatures. Make sure this is intentional!\n")
<< ENDL;
}
ostr << ENDL;
if (verbose)
ostr << ENDL;
}
return true;
}
@@ -6962,7 +6965,7 @@ bool simple_wallet::transfer_main(
fail_msg_writer() << tr("failed to get blockchain height: ") << err;
return false;
}
unlock_block = bc_height + locked_blocks;
unlock_block = locked_blocks;
ptx_vector = m_wallet->create_transactions_2(dsts, source_asset, dest_asset, cryptonote::transaction_type::TRANSFER, fake_outs_count, unlock_block /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, subtract_fee_from_outputs);
break;
default:
@@ -7092,7 +7095,7 @@ bool simple_wallet::transfer_main(
if (transfer_type == TransferLocked)
{
float days = locked_blocks / 720.0f;
prompt << boost::format(tr(".\nThis transaction (including %s change) will unlock on block %llu, in approximately %s days (assuming 2 minutes per block)")) % cryptonote::print_money(change) % ((unsigned long long)unlock_block) % days;
prompt << boost::format(tr(".\nThis transaction (including %s change) will unlock in %llu blocks, approximately %s days (assuming 2 minutes per block)")) % cryptonote::print_money(change) % ((unsigned long long)unlock_block) % days;
}
if (!process_ring_members(ptx_vector, prompt, m_wallet->print_ring_members()))
return false;
@@ -7272,7 +7275,7 @@ bool simple_wallet::locked_transfer(const std::vector<std::string> &args_)
local_args.pop_back();
}
transfer_main(Transfer, source_asset, source_asset, local_args, false);
transfer_main(TransferLocked, source_asset, source_asset, local_args, false);
return true;
}
//----------------------------------------------------------------------------------------------------
@@ -7620,8 +7623,12 @@ bool simple_wallet::sweep_main(uint32_t account, uint64_t below, bool locked, co
if (subaddr_indices.size() > 1)
prompt << tr("WARNING: Outputs of multiple addresses are being used together, which might potentially compromise your privacy.\n");
}
if (!process_ring_members(ptx_vector, prompt, m_wallet->print_ring_members()))
return true;
message_writer() << "\n======\n" << prompt.str() << "\n=====\n";
if (ptx_vector.size() > 1) {
prompt << boost::format(tr("Sweeping %s in %llu transactions for a total fee of %s. Is this okay?")) %
print_money(total_sent) %
@@ -9462,19 +9469,9 @@ bool simple_wallet::get_transfers(std::vector<std::string>& local_args, std::vec
if (!unlocked)
{
locked_msg = "locked";
if (pd.m_unlock_time < CRYPTONOTE_MAX_BLOCK_NUMBER)
{
uint64_t bh = std::max(pd.m_unlock_time, pd.m_block_height + CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE);
if (bh >= last_block_height)
locked_msg = std::to_string(bh - last_block_height) + " blks";
}
else
{
const uint64_t adjusted_time = m_wallet->get_daemon_adjusted_time();
uint64_t threshold = adjusted_time + (m_wallet->use_fork_rules(2, 0) ? CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V2 : CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V1);
if (threshold < pd.m_unlock_time)
locked_msg = get_human_readable_timespan(std::chrono::seconds(pd.m_unlock_time - threshold));
}
uint64_t bh = pd.m_block_height + std::max(pd.m_unlock_time, (uint64_t)CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE);
if (bh >= last_block_height)
locked_msg = std::to_string(bh - last_block_height) + " blks";
}
transfers.push_back({
type,
@@ -9483,7 +9480,7 @@ bool simple_wallet::get_transfers(std::vector<std::string>& local_args, std::vec
type,
true,
pd.m_amount,
pd.m_asset_type,
pd.m_asset_type,
pd.m_tx_hash,
payment_id,
(pd.m_tx_type == cryptonote::transaction_type::STAKE) ? pd.m_fee : 0,
@@ -9636,7 +9633,7 @@ bool simple_wallet::show_transfers(const std::vector<std::string> &args_)
std::vector<std::string> local_args = args_;
if(local_args.size() > 4) {
fail_msg_writer() << tr("usage: show_transfers [in|out|all|pending|failed|pool|coinbase] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]]");
fail_msg_writer() << tr("usage: show_transfers [in|out|all|pending|failed|pool|coinbase|burnt|staked|yield] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]]");
return true;
}
@@ -9695,7 +9692,7 @@ bool simple_wallet::export_transfers(const std::vector<std::string>& args_)
std::vector<std::string> local_args = args_;
if(local_args.size() > 6) {
fail_msg_writer() << tr("usage: export_transfers [in|out|all|pending|failed|pool|coinbase] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]] [output=<path>] [option=<with_keys>]");
fail_msg_writer() << tr("usage: export_transfers [in|out|all|pending|failed|pool|coinbase|burnt|staked|yield] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]] [output=<path>] [option=<with_keys>]");
return true;
}
+1 -1
View File
@@ -1,5 +1,5 @@
#define DEF_SALVIUM_VERSION_TAG "@VERSIONTAG@"
#define DEF_SALVIUM_VERSION "0.3.2"
#define DEF_SALVIUM_VERSION "0.3.7"
#define DEF_MONERO_VERSION_TAG "release"
#define DEF_MONERO_VERSION "0.18.3.3"
#define DEF_MONERO_RELEASE_NAME "Zero"
+96 -46
View File
@@ -2169,8 +2169,8 @@ void wallet2::scan_output(const cryptonote::transaction &tx, bool miner_tx, cons
if (!m_encrypt_keys_after_refresh)
{
boost::optional<epee::wipeable_string> pwd = m_callback->on_get_password(pool ? "output found in pool" : "output received");
THROW_WALLET_EXCEPTION_IF(!pwd, error::password_needed, tr("Password is needed to compute key image for incoming monero"));
THROW_WALLET_EXCEPTION_IF(!verify_password(*pwd), error::password_needed, tr("Invalid password: password is needed to compute key image for incoming monero"));
THROW_WALLET_EXCEPTION_IF(!pwd, error::password_needed, tr("Password is needed to compute key image for incoming SALs"));
THROW_WALLET_EXCEPTION_IF(!verify_password(*pwd), error::password_needed, tr("Invalid password: password is needed to compute key image for incoming SALs"));
m_encrypt_keys_after_refresh.reset(new wallet_keys_unlocker(*this, m_ask_password == AskPasswordToDecrypt && !m_unattended && !m_watch_only, *pwd));
}
}
@@ -2223,6 +2223,9 @@ void wallet2::scan_output(const cryptonote::transaction &tx, bool miner_tx, cons
{
tx_scan_info.money_transfered = tools::decodeRct(tx.rct_signatures, tx_scan_info.received->derivation, i, tx_scan_info.mask, m_account.get_device());
}
// SRCG: The following "if" block is commented out for a GOOD REASON...
// 1. Monero doesn't care about 0 amounts, because they don't have a value or purpose.
// 2. Salvium NEEDS to care about 0 amounts, because they are the CHANGE for a TX, and we need the CHANGE to accept RETURN_PAYMENTs.
/*
if (tx_scan_info.money_transfered == 0)
{
@@ -2231,6 +2234,9 @@ void wallet2::scan_output(const cryptonote::transaction &tx, bool miner_tx, cons
return;
}
*/
// Populate the unlock_time
THROW_WALLET_EXCEPTION_IF(!cryptonote::get_output_unlock_time(tx.vout[i], tx_scan_info.unlock_time), error::wallet_internal_error, "failed to get output unlock_time");
outs.push_back(i);
THROW_WALLET_EXCEPTION_IF(tx_money_got_in_outs[tx_scan_info.received->index][tx_scan_info.asset_type] >= std::numeric_limits<uint64_t>::max() - tx_scan_info.money_transfered,
error::wallet_internal_error, "Overflow in received amounts");
@@ -2382,8 +2388,10 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
if (!miner_tx && !pool)
process_unconfirmed(txid, tx, height);
std::string source_asset = tx.source_asset_type;
std::string dest_asset = tx.destination_asset_type;
std::string source_asset =
(tx.type == cryptonote::transaction_type::MINER) ? "SAL" :
(tx.type == cryptonote::transaction_type::PROTOCOL) ? "SAL" :
tx.source_asset_type;
// per receiving subaddress index
std::unordered_map<cryptonote::subaddress_index, std::map<std::string, uint64_t>> tx_money_got_in_outs;
@@ -2407,7 +2415,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
size_t pk_index = 0;
std::vector<tx_scan_info_t> tx_scan_info(tx.vout.size());
std::deque<bool> output_found(tx.vout.size(), false);
uint64_t total_received_1 = 0;
std::map<std::string, uint64_t> total_received_1;
uint64_t td_origin_idx = ((uint64_t)-1);
while (!tx.vout.empty())
{
@@ -2679,7 +2687,11 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
if (!ignore_callbacks && 0 != m_callback)
m_callback->on_money_received(height, txid, tx, td.m_amount, td.asset_type, 0, td.m_subaddr_index, spends_one_of_ours(tx), td.m_tx.unlock_time, td.m_td_origin_idx);
}
total_received_1 += amount;
std::string asset_type = m_transfers.back().asset_type;
if (total_received_1.count(asset_type))
total_received_1[asset_type] += amount;
else
total_received_1[asset_type] = amount;
notify = true;
if (tx.type == cryptonote::transaction_type::CONVERT || tx.type == cryptonote::transaction_type::STAKE) {
@@ -2790,7 +2802,11 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
if (!ignore_callbacks && 0 != m_callback)
m_callback->on_money_received(height, txid, tx, td.m_amount, td.asset_type, burnt, td.m_subaddr_index, spends_one_of_ours(tx), td.m_tx.unlock_time, td.m_td_origin_idx);
}
total_received_1 += extra_amount;
std::string asset_type = m_transfers.back().asset_type;
if (total_received_1.count(asset_type))
total_received_1[asset_type] += extra_amount;
else
total_received_1[asset_type] = extra_amount;
notify = true;
}
}
@@ -2975,51 +2991,84 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
}
}
uint64_t total_received_2 = sub_change;
std::map<std::string, uint64_t> total_received_2;
for (auto& i : tx_money_got_in_outs)
total_received_2 += i.second[source_asset];
for (auto& asset: i.second)
total_received_2[asset.first] += asset.second;
// only for regular transfers
if (source_asset == dest_asset && !miner_tx) {
if (total_received_1 != total_received_2)
{
const el::Level level = el::Level::Warning;
MCLOG_RED(level, "global", "**********************************************************************");
MCLOG_RED(level, "global", "Consistency failure in amounts received");
MCLOG_RED(level, "global", "Check transaction " << txid);
MCLOG_RED(level, "global", "**********************************************************************");
exit(1);
return;
if (!miner_tx) {
for (auto& asset: total_received_1) {
if (asset.second != total_received_2[asset.first]) {
//if (source_asset == dest_asset && !miner_tx) {
//if (total_received_1 != total_received_2)
//{
const el::Level level = el::Level::Warning;
MCLOG_RED(level, "global", "**********************************************************************");
MCLOG_RED(level, "global", "Consistency failure in amounts received");
MCLOG_RED(level, "global", "Check transaction " << txid);
MCLOG_RED(level, "global", "**********************************************************************");
exit(1);
return;
}
}
}
bool all_same = true;
for (auto& i : tx_money_got_in_outs)
{
payment_details payment;
payment.m_tx_hash = txid;
payment.m_fee = fee;
std::vector<payment_details> temp_payments;
for (auto& tsi : tx_scan_info) {
if (!tsi.received) continue;
cryptonote::subaddress_index si = tsi.received->index;
bool updated_payment = false;
for (auto& payment : temp_payments) {
if (payment.m_subaddr_index == si && payment.m_unlock_time == tsi.unlock_time) {
// Add to existing payment
payment.m_amount += tsi.amount;
payment.m_amounts.push_back(tsi.amount);
updated_payment = true;
}
if (updated_payment) break;
}
if (updated_payment) continue;
// Create a new payment
temp_payments.push_back(payment_details{});
payment_details& payment = temp_payments.back();
payment.m_tx_hash = txid;
payment.m_fee = fee;
// SRCG - figure out what this needs to be (pretty sure we should never get here with CONVERT!)
payment.m_amount = source_asset == dest_asset ? i.second[dest_asset] : tx.amount_burnt;
payment.m_asset_type = (tx.type == cryptonote::transaction_type::PROTOCOL) ? "SAL" : dest_asset;
payment.m_amounts = tx_amounts_individual_outs[i.first];
payment.m_block_height = height;
payment.m_unlock_time = tx.unlock_time; // SRCG: this is incorrect - work out which vout entry it is and query that
payment.m_timestamp = ts;
payment.m_coinbase = miner_tx;
payment.m_subaddr_index = i.first;
if (tx.type == cryptonote::transaction_type::PROTOCOL) {
payment.m_amount = tsi.amount;
payment.m_asset_type = tsi.asset_type;
payment.m_amounts.push_back(tsi.amount);
payment.m_block_height = height;
payment.m_unlock_time = tsi.unlock_time;
payment.m_timestamp = ts;
payment.m_coinbase = miner_tx;
payment.m_subaddr_index = si;
if (tx.type == cryptonote::transaction_type::MINER) {
payment.m_unlock_time = CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW; // All protocol_tx payments are coinbase
payment.m_tx_type = cryptonote::transaction_type::MINER;
} else if (tx.type == cryptonote::transaction_type::PROTOCOL) {
payment.m_unlock_time = CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW; // All protocol_tx payments are coinbase
if (td_origin_idx != ((uint64_t)-1)) {
// Get the origin TD information
payment.m_amount = payment.m_amounts.empty() ? 0 : payment.m_amounts[0];
payment.m_tx_type = m_transfers[td_origin_idx].m_tx.type;
payment.m_fee = m_transfers[td_origin_idx].m_tx.amount_burnt;
payment.m_amount = payment.m_amounts.empty() ? 0 : payment.m_amounts[0];
payment.m_tx_type = m_transfers[td_origin_idx].m_tx.type;
payment.m_fee = m_transfers[td_origin_idx].m_tx.amount_burnt;
} else {
assert(false);
}
} else {
payment.m_tx_type = tx.type;
payment.m_tx_type = tx.type;
}
}
// Now iterate over the temp_payment entries
for (auto& payment : temp_payments) {
if (pool) {
if (emplace_or_replace(m_unconfirmed_payments, payment_id, pool_payment_details{payment, double_spend_seen}))
all_same = false;
@@ -3030,7 +3079,6 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
m_payments.emplace(payment_id, payment);
LOG_PRINT_L2("Payment found in " << (pool ? "pool" : "block") << ": " << payment_id << " / " << payment.m_tx_hash << " / " << payment.m_amount);
}
// if it's a pool tx and we already had it, don't notify again
if (pool && all_same)
notify = false;
@@ -6871,14 +6919,16 @@ std::map<uint32_t, std::pair<uint64_t, std::pair<uint64_t, uint64_t>>> wallet2::
}
else
{
uint64_t unlock_height = td.m_block_height + std::max<uint64_t>(CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE, CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_BLOCKS);
if (td.m_tx.unlock_time < CRYPTONOTE_MAX_BLOCK_NUMBER && td.m_tx.unlock_time > unlock_height)
unlock_height = td.m_tx.unlock_time;
if (td.m_tx.type == cryptonote::transaction_type::MINER)
uint64_t unlock_height = 0;
if (td.m_tx.type == cryptonote::transaction_type::MINER || td.m_tx.type == cryptonote::transaction_type::PROTOCOL)
unlock_height = td.m_block_height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW;
uint64_t unlock_time = td.m_tx.unlock_time >= CRYPTONOTE_MAX_BLOCK_NUMBER ? td.m_tx.unlock_time : 0;
blocks_to_unlock = unlock_height > blockchain_height ? unlock_height - blockchain_height : 0;
time_to_unlock = unlock_time > now ? unlock_time - now : 0;
else {
uint64_t unlock_blocks = 0;
THROW_WALLET_EXCEPTION_IF(!cryptonote::get_output_unlock_time(td.m_tx.vout[td.m_internal_output_index], unlock_blocks), error::wallet_internal_error, "failed to get unlock_time");
unlock_height = td.m_block_height + ((unlock_blocks > CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE) ? unlock_blocks : CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE);
}
blocks_to_unlock = (unlock_height > blockchain_height) ? unlock_height - blockchain_height : 0;
time_to_unlock = 0;
amount = 0;
}
auto found = amount_per_subaddr.find(td.m_subaddr_index.minor);
@@ -14908,7 +14958,7 @@ mms::multisig_wallet_state wallet2::get_multisig_wallet_state() const
state.num_transfer_details = m_transfers.size();
if (state.multisig)
{
THROW_WALLET_EXCEPTION_IF(!m_original_keys_available, error::wallet_internal_error, "MMS use not possible because own original Monero address not available");
THROW_WALLET_EXCEPTION_IF(!m_original_keys_available, error::wallet_internal_error, "MMS use not possible because own original Salvium address not available");
state.address = m_original_address;
state.view_secret_key = m_original_view_secret_key;
}
+2 -1
View File
@@ -320,12 +320,13 @@ private:
rct::key mask;
uint64_t amount;
std::string asset_type;
uint64_t unlock_time;
uint64_t money_transfered;
uint64_t origin_idx;
bool error;
boost::optional<cryptonote::subaddress_receive_info> received;
tx_scan_info_t(): amount(0), asset_type(""), money_transfered(0), origin_idx((uint64_t)-1), error(true) {}
tx_scan_info_t(): amount(0), asset_type(""), unlock_time(0), money_transfered(0), origin_idx((uint64_t)-1), error(true) {}
};
struct transfer_details
+1 -2
View File
@@ -149,8 +149,7 @@ namespace wallet_args
if (command_line::get_arg(vm, command_line::arg_help))
{
Print(print) << "Salvium '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL;
Print(print) << wallet_args::tr("This is the command line monero wallet. It needs to connect to a monero\n"
"daemon to work correctly.") << ENDL;
Print(print) << wallet_args::tr("This is the command line Salvium wallet. It needs to connect to a Salvium daemon to work correctly.") << ENDL;
Print(print) << wallet_args::tr("Usage:") << ENDL << " " << usage;
Print(print) << desc_all;
should_terminate = true;
+1 -9
View File
@@ -153,15 +153,7 @@ bool wallet2::search_for_rpc_payment(uint64_t credits_target, uint32_t n_threads
tpool.submit(&waiter, [&, i] {
*(uint32_t*)(hashing_blob.data() + 39) = SWAP32LE(local_nonce-i);
const uint8_t major_version = hashing_blob[0];
if (major_version >= RX_BLOCK_VERSION)
{
crypto::rx_slow_hash(seed_hash.data, hashing_blob.data(), hashing_blob.size(), hash[i].data);
}
else
{
int cn_variant = hashing_blob[0] >= 7 ? hashing_blob[0] - 6 : 0;
crypto::cn_slow_hash(hashing_blob.data(), hashing_blob.size(), hash[i], cn_variant, height);
}
crypto::rx_slow_hash(seed_hash.data, hashing_blob.data(), hashing_blob.size(), hash[i].data);
});
}
waiter.wait();
+3 -2
View File
@@ -320,7 +320,7 @@ namespace tools
{
MINFO("The daemon is not set up to background mine.");
MINFO("With background mining enabled, the daemon will mine when idle and not on battery.");
MINFO("Enabling this supports the network you are using, and makes you eligible for receiving new monero");
MINFO("Enabling this supports the network you are using, and makes you eligible for receiving new SALs");
MINFO("Set setup-background-mining to 1 in salvium-wallet-cli to change.");
return;
}
@@ -358,6 +358,7 @@ namespace tools
entry.timestamp = pd.m_timestamp;
entry.amount = pd.m_amount;
entry.amounts = pd.m_amounts;
entry.asset_type = pd.m_asset_type;
entry.unlock_time = pd.m_unlock_time;
entry.locked = !m_wallet->is_transfer_unlocked(pd.m_unlock_time, pd.m_block_height);
entry.fee = pd.m_fee;
@@ -4780,7 +4781,7 @@ int main(int argc, char** argv) {
std::tie(vm, should_terminate) = wallet_args::main(
argc, argv,
"salvium-wallet-rpc [--wallet-file=<file>|--generate-from-json=<file>|--wallet-dir=<directory>] [--rpc-bind-port=<port>]",
tools::wallet_rpc_server::tr("This is the RPC monero wallet. It needs to connect to a monero\ndaemon to work correctly."),
tools::wallet_rpc_server::tr("This is the RPC Salvium wallet. It needs to connect to a Salvium daemon to work correctly."),
desc_params,
po::positional_options_description(),
[](const std::string &s, bool emphasis){ tools::scoped_message_writer(emphasis ? epee::console_color_white : epee::console_color_default, true) << s; },
@@ -1439,6 +1439,7 @@ namespace wallet_rpc
uint64_t amount;
amounts_container amounts;
uint64_t fee;
std::string asset_type;
std::string note;
std::list<transfer_destination> destinations;
std::string type;
@@ -1460,6 +1461,7 @@ namespace wallet_rpc
KV_SERIALIZE(amounts);
KV_SERIALIZE(fee);
KV_SERIALIZE(note);
KV_SERIALIZE(asset_type);
KV_SERIALIZE(destinations);
KV_SERIALIZE(type);
KV_SERIALIZE(unlock_time)