Compare commits

..

8 Commits

Author SHA1 Message Date
Some Random Crypto Guy 6571df4c76 added private viewkey support; upgraded scanner; bumped version 2025-01-21 13:49:53 +00:00
Some Random Crypto Guy 89180a6727 removed ability to BURN the SAL coins post-audit 2025-01-20 10:52:55 +00:00
Some Random Crypto Guy 2ccd388153 updated scanner 2025-01-18 22:40:44 +00:00
Some Random Crypto Guy 5757c67e17 updated provisional HF for audit; fixed wallet default asset type pre-fork; fixed circ_supply management (hopefully) 2025-01-17 11:55:34 +00:00
Some Random Crypto Guy 013011cde7 fixed BURN command 2025-01-16 21:09:49 +00:00
Some Random Crypto Guy 400ec099d1 working audit commands 2025-01-16 21:02:16 +00:00
Some Random Crypto Guy 60825ae753 interim checkin of AUDIT command 2025-01-16 12:21:35 +00:00
Some Random Crypto Guy 0c5d6e92e6 updated blockchain scanner to make sure bugs are fixed 2025-01-02 13:02:42 +00:00
43 changed files with 393 additions and 663 deletions
-3
View File
@@ -30,9 +30,6 @@ contrib/gitian/builder/
contrib/gitian/docker/
contrib/gitian/sigs/
# Audit tool
src/blockchain_utilities/blockchain_audit.cpp
# Created by https://www.gitignore.io
### C++ ###
-3
View File
@@ -14,6 +14,3 @@
[submodule "external/miniupnp"]
path = external/miniupnp
url = https://github.com/miniupnp/miniupnp
[submodule "external/mx25519"]
path = external/mx25519
url = https://github.com/tevador/mx25519
+5 -5
View File
@@ -1,4 +1,4 @@
# Salvium Zero v0.9.2
# Salvium Zero v0.9.0-rc2
Copyright (c) 2023-2024, Salvium
Portions Copyright (c) 2014-2023, The Monero Project
@@ -172,7 +172,7 @@ invokes cmake commands as needed.
```bash
cd salvium
git checkout v0.9.2
git checkout v0.9.0
make
```
@@ -251,7 +251,7 @@ Tested on a Raspberry Pi Zero with a clean install of minimal Raspbian Stretch (
```bash
git clone https://github.com/salvium/salvium
cd salvium
git checkout v0.9.2
git checkout v0.9.0
```
* Build:
@@ -370,10 +370,10 @@ application.
cd salvium
```
* If you would like a specific [version/tag](https://github.com/salvium/salvium/tags), do a git checkout for that version. eg. 'v0.9.2'. 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. 'v0.9.0'. If you don't care about the version and just want binaries from master, skip this step:
```bash
git checkout v0.9.2
git checkout v0.9.0
```
* If you are on a 64-bit system, run:
+1 -1
View File
@@ -215,7 +215,7 @@ namespace
* yield_block_data block height {slippage_coins, locked_coins, lc_total, network_health}
* yield_tx_data block height {txn hash, locked_coins, return_address}
*
* audit_block_data block height {locked_coins, lc_total}
* audit_data block height {locked_coins, lc_total}
* audit_tx_data block height {txn hash, locked_coins, return_address}
*
* Note: where the data items are of uniform size, DUPFIXED tables have
+1 -6
View File
@@ -140,9 +140,6 @@ public:
virtual bool get_txpool_tx_blob(const crypto::hash& txid, cryptonote::blobdata &bd, relay_category tx_category) const override { return false; }
virtual uint64_t get_database_size() const override { return 0; }
virtual int get_audit_block_info(const uint64_t height, audit_block_info& abi) const override { return 0; }
virtual int get_audit_tx_info(const uint64_t height, std::vector<yield_tx_info>& ati_container) const override { return 0; }
virtual int get_yield_block_info(const uint64_t height, yield_block_info& ybi) const override { return 0; }
virtual int get_yield_tx_info(const uint64_t height, std::vector<yield_tx_info>& yti_container) const override { return 0; }
@@ -159,10 +156,8 @@ public:
const crypto::hash& blk_hash,
uint64_t slippage_total,
uint64_t yield_total,
uint64_t audit_total,
const cryptonote::network_type nettype,
cryptonote::yield_block_info& ybi,
cryptonote::audit_block_info& abi
cryptonote::yield_block_info& ybi
) override { }
virtual cryptonote::block get_block_from_height(const uint64_t& height) const override { return cryptonote::block(); }
virtual void set_hard_fork_version(uint64_t height, uint8_t version) override {}
+3 -50
View File
@@ -142,24 +142,6 @@ set(blockchain_scanner_private_headers)
monero_private_headers(blockchain_scanner
${blockchain_scanner_private_headers})
if (BUILD_TAG)
else()
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/blockchain_audit.cpp" AND NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/blockchain_audit.cpp")
set(blockchain_audit_sources
blockchain_audit.cpp
threadpool_boost.cpp
)
set(blockchain_audit_private_headers
threadpool_boost.h
)
monero_private_headers(blockchain_audit
${blockchain_audit_private_headers})
else()
message(STATUS "blockchain_audit.cpp not found - not building the audit tool")
endif()
endif()
monero_add_executable(blockchain_import
${blockchain_import_sources}
@@ -315,6 +297,9 @@ monero_add_executable(blockchain_scanner
target_link_libraries(blockchain_scanner
PRIVATE
wallet
crypto
cncrypto
cryptonote_core
blockchain_db
version
@@ -330,38 +315,6 @@ set_property(TARGET blockchain_scanner
OUTPUT_NAME "salvium-blockchain-scanner")
install(TARGETS blockchain_scanner DESTINATION bin)
if (BUILD_TAG)
else()
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/blockchain_audit.cpp" AND NOT IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/blockchain_audit.cpp")
monero_add_executable(blockchain_audit
${blockchain_audit_sources}
${blockchain_audit_private_headers})
target_include_directories(blockchain_audit PRIVATE /usr/include/mysql-cppconn/jdbc)
target_link_libraries(blockchain_audit
PRIVATE
wallet
crypto
cncrypto
cryptonote_core
blockchain_db
version
epee
mysqlcppconn
${Boost_FILESYSTEM_LIBRARY}
${Boost_SYSTEM_LIBRARY}
${Boost_THREAD_LIBRARY}
${CMAKE_THREAD_LIBS_INIT}
${EXTRA_LIBRARIES})
set_property(TARGET blockchain_audit
PROPERTY
OUTPUT_NAME "salvium-blockchain-audit")
install(TARGETS blockchain_audit DESTINATION bin)
endif()
endif()
monero_add_executable(blockchain_stats
${blockchain_stats_sources}
${blockchain_stats_private_headers})
@@ -40,6 +40,7 @@
#include "blockchain_db/blockchain_db.h"
#include "oracle/pricing_record.h"
#include "version.h"
#include "wallet/wallet2.h"
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "bcutil"
@@ -61,6 +62,10 @@ namespace scanner
static bool stop_requested = false;
static const std::vector<std::string> suspect_output_pubkeys = {
"1234567890123456789012345678901234567890123456789012345678901234"
};
int main(int argc, char* argv[])
{
TRY_ENTRY();
@@ -82,6 +87,8 @@ int main(int argc, char* argv[])
const command_line::arg_descriptor<uint64_t> arg_block_stop = {"block-stop", "Stop at block number", block_stop};
const command_line::arg_descriptor<std::string> arg_delimiter = {"delimiter", "\"<string>\"", DELIM};
const command_line::arg_descriptor<std::string> arg_stake_mode = {"stake", "\"<string>\"", DEF_STAKE_MODE};
const command_line::arg_descriptor<bool> arg_audit = {"audit", "Scan for audit issues", false};
const command_line::arg_descriptor<bool> arg_decode_pvk = {"decodepvk", "Attempt to decode private view key data", false};
const command_line::arg_descriptor<bool> arg_check_asset_types = {"check-asset-types", "Scan for asset-type issues", false};
command_line::add_arg(desc_cmd_sett, cryptonote::arg_data_dir);
@@ -92,6 +99,8 @@ int main(int argc, char* argv[])
command_line::add_arg(desc_cmd_sett, arg_block_stop);
command_line::add_arg(desc_cmd_sett, arg_delimiter);
command_line::add_arg(desc_cmd_sett, arg_stake_mode);
command_line::add_arg(desc_cmd_sett, arg_audit);
command_line::add_arg(desc_cmd_sett, arg_decode_pvk);
command_line::add_arg(desc_cmd_sett, arg_check_asset_types);
command_line::add_arg(desc_cmd_only, command_line::arg_help);
@@ -132,6 +141,8 @@ int main(int argc, char* argv[])
block_stop = command_line::get_arg(vm, arg_block_stop);
std::string delimiter = command_line::get_arg(vm, arg_delimiter);
std::string stake_mode = command_line::get_arg(vm, arg_stake_mode);
bool opt_audit = command_line::get_arg(vm, arg_audit);
bool opt_decode_pvk = command_line::get_arg(vm, arg_decode_pvk);
bool opt_check_asset_types = command_line::get_arg(vm, arg_check_asset_types);
// If we wanted to use the memory pool, we would set up a fake_core.
@@ -166,6 +177,26 @@ int main(int argc, char* argv[])
LOG_PRINT_L0("Loading blockchain from folder " << folder << " ...");
const std::string filename = folder.string();
crypto::secret_key SK = crypto::null_skey;
if (opt_decode_pvk) {
epee::wipeable_string private_key_passphrase;
auto pwd_container = tools::password_container::prompt(true, "Enter passphrase for decoding private keys");
if (!pwd_container) {
std::cerr << scanner::tr("Failed to read passphrase") << std::endl;
return 1;
}
private_key_passphrase = pwd_container->password();
crypto::hash_to_scalar(private_key_passphrase.data(), private_key_passphrase.size(), SK);
crypto::public_key PK;
crypto::secret_key_to_public_key(SK, PK);
std::string PK_str = epee::string_tools::pod_to_hex(PK);
const std::string expected_PK_str = "5e860406bf9221dba6409faa6eb8fecd6f34acc4935634e76b64b90bf2b6d6a6";
if (PK_str != expected_PK_str) {
std::cerr << scanner::tr("Invalid passphrase - PK produced was ") << PK_str << std::endl;
return 1;
}
}
try
{
db->open(filename, DBF_RDONLY);
@@ -220,9 +251,21 @@ plot 'stats.csv' index "DATA" using (timecolumn(1,"%Y-%m-%d")):4 with lines, ''
uint32_t txhr[24] = {0};
unsigned int i;
struct wallet_summary {
uint64_t total_amount;
std::vector<std::pair<uint64_t, std::pair<crypto::hash, std::string>>> txs;
bool seen_closing_tx;
std::string enc_view_privkey_str;
bool flagged;
std::string reason;
};
const std::map<uint8_t, std::pair<std::string, std::string>> audit_hard_forks = get_config(net_type).AUDIT_HARD_FORKS;
const uint64_t audit_lock_period = get_config(net_type).AUDIT_LOCK_PERIOD;
// Create a map of wallet addresses and total amounts in them
std::map<crypto::public_key, wallet_summary> wallet_details;
for (uint64_t h = block_start; h < block_stop; ++h)
{
cryptonote::blobdata bd = db->get_block_blob_from_height(h);
@@ -373,6 +416,103 @@ skip:
// Add the source currency to the list of expected ones
used_assets.insert(tx.source_asset_type);
}
// Are we auditing?
if (!opt_audit) continue;
// Audit commencing - check hard fork version for _this_block_
if (audit_hard_forks.find(hf_version) == audit_hard_forks.end()) continue;
// Pre-check - only attempt to verify legitimate AUDIT TXs
if (tx.type != cryptonote::transaction_type::AUDIT) continue;
// Make sure the RCT data is correct
if (tx.rct_signatures.type != rct::RCTTypeSalviumOne) {
std::cerr << "Aborting: Invalid RCT type " << tx.rct_signatures.type << " detected in AUDIT tx:" << tx_id << std::endl;
throw std::runtime_error("Aborting: Invalid RCT type detected in AUDIT tx");
}
if (tx.rct_signatures.salvium_data.salvium_data_type != rct::SalviumAudit) {
std::cerr << "Aborting: Invalid 'salvium_data_type' " << tx.rct_signatures.salvium_data.salvium_data_type << " detected in AUDIT tx:" << tx_id << std::endl;
throw std::runtime_error("Aborting: Invalid 'salvium_data_type' detected in AUDIT tx");
}
// WE ARE AUDITING - RETRIEVE ANY WALLET SUMMARY FOR THIS WALLET
wallet_summary &ws = wallet_details[tx.rct_signatures.salvium_data.spend_pubkey];
if (ws.txs.size()) {
if (ws.txs.back().first < (h-1)) {
std::cout << timebuf << "" << delimiter << "" << h << "" << delimiter << "" << tx_id << "" << delimiter << "REVIEW: interval detected between audit TXs" << delimiter << "amount:" << (tx.amount_burnt / 100000000) << std::endl;
}
} else {
ws.enc_view_privkey_str = tx.rct_signatures.salvium_data.enc_view_privkey_str;
ws.flagged = false;
ws.seen_closing_tx = false;
}
ws.txs.push_back({h, {tx_id, ""}});
// Increment the total amount for this wallet that has been audited
if (ws.total_amount + tx.amount_burnt < ws.total_amount) {
std::cerr << "overflow in total_amount for Ks:" << tx.rct_signatures.salvium_data.spend_pubkey << std::endl;
//throw std::runtime_error("Aborting: overflow in total_amount for Ks");
ws.txs.back().second.second = "wallet overflow";
ws.flagged = true;
}
ws.total_amount += tx.amount_burnt;
// Check - asset_type of SAL on all inputs
if (tx.source_asset_type != "SAL") {
// TX must spend SALs in audit
std::cerr << "invalid source asset_type for Ks:" << tx.rct_signatures.salvium_data.spend_pubkey << std::endl;
//throw std::runtime_error("Aborting: invalid source asset type found in tx");
ws.txs.back().second.second = "invalid source asset_type '" + tx.source_asset_type + "'";
ws.flagged = true;
}
// Check - amount in STAKE TX
if (tx.amount_burnt >= 25000000000000llu) {
std::cout << timebuf << "" << delimiter << "" << h << "" << delimiter << "" << tx_id << "" << delimiter << "BLACKLIST: large AUDIT TX detected" << delimiter << "amount:" << (tx.amount_burnt / 100000000) << std::endl;
ws.txs.back().second.second = "large AUDIT TX detected - amount:" + std::to_string(tx.amount_burnt/100000000) + std::string(" SAL");
ws.flagged = true;
} else if (tx.amount_burnt >= 10000000000000llu) {
std::cout << timebuf << "" << delimiter << "" << h << "" << delimiter << "" << tx_id << "" << delimiter << "REVIEW: large AUDIT TX detected" << delimiter << "amount:" << (tx.amount_burnt / 100000000) <<
std::endl;
ws.txs.back().second.second = "large AUDIT TX detected - amount:" + std::to_string(tx.amount_burnt/100000000) + std::string(" SAL");
ws.flagged = true;
}
// Check - total amount for this wallet
if (ws.total_amount >= 25000000000000llu) {
std::cout << timebuf << "" << delimiter << "" << h << "" << delimiter << "" << tx_id << "" << delimiter << "BLACKLIST: large BALANCE detected" << delimiter << "amount:" << (ws.total_amount / 100000000) << std::endl;
ws.txs.back().second.second = "large wallet balance detected - amount:" + std::to_string(ws.total_amount/100000000) + std::string(" SAL");
ws.flagged = true;
} else if (ws.total_amount >= 10000000000000llu) {
std::cout << timebuf << "" << delimiter << "" << h << "" << delimiter << "" << tx_id << "" << delimiter << "REVIEW: large BALANCE TX detected" << delimiter << "amount:" << (ws.total_amount / 100000000) << std::endl;
ws.txs.back().second.second = "large wallet balance detected - amount:" + std::to_string(ws.total_amount/100000000) + std::string(" SAL");
ws.flagged = true;
}
// Validate the Salvium audit data
//CHECK_AND_ASSERT_THROW_MES(PRProof_Ver(rv.outPk[0].mask, rv.salvium_data.cz_proof), "PRProof_Ver() failed on change proof");
//CHECK_AND_ASSERT_THROW_MES(pseudoOuts.size() == rv.salvium_data.input_verification_data.size(), "incorrect number of input verification datasets");
//CHECK_AND_ASSERT_THROW_MES(rv.salvium_data.spend_pubkey != crypto::null_pkey, "Invalid spend pubkey provided in audit data");
//CHECK_AND_ASSERT_THROW_MES(rv.salvium_data.enc_view_privkey_str != "", "Invalid encrypted viewkey provided in audit data");
for (size_t i=0; i < tx.rct_signatures.salvium_data.input_verification_data.size(); ++i) {
// Recalculate the value of Ks from the Ko value
crypto::public_key ephemeral_pub = crypto::null_pkey;
CHECK_AND_ASSERT_THROW_MES(crypto::derive_public_key(tx.rct_signatures.salvium_data.input_verification_data[i].aR,
tx.rct_signatures.salvium_data.input_verification_data[i].i,
tx.rct_signatures.salvium_data.spend_pubkey, ephemeral_pub),
"Failed to derive ephemeral public key from audit data");
// Now check this isn't in the list of suspect_output_pubkeys
std::string ephemeral_pub_str = epee::string_tools::pod_to_hex(ephemeral_pub);
for (size_t n=0; n<suspect_output_pubkeys.size(); ++n) {
if (ephemeral_pub_str == suspect_output_pubkeys[n]) {
ws.txs.back().second.second = "SUSPECT OUTPUT PUBKEY DETECTED : '" + ephemeral_pub_str + "'";
ws.flagged = true;
break;
}
}
}
}
currblks++;
@@ -381,6 +521,57 @@ skip:
break;
}
// Iterate over all the flagged wallets
for (const auto &wallet_entry: wallet_details) {
// Was the wallet flagged?
if (!wallet_entry.second.flagged) continue;
// Decrypt the wallet private viewkey
crypto::secret_key wallet_private_view_key;
bool ok = cryptonote::decrypt_pvk(wallet_entry.second.enc_view_privkey_str, SK, wallet_private_view_key);
if (!ok) {
// report error
throw std::runtime_error("Well shit");
}
// Why was it flagged?
for (const auto &tx: wallet_entry.second.txs) {
// Check for a reason on this TX
if (tx.second.second != "") {
}
}
// Create a new "view only" wallet file
try {
// Derive the public view key from the private view key
crypto::public_key wallet_public_view_key;
bool ok = crypto::secret_key_to_public_key(wallet_private_view_key, wallet_public_view_key);
// Construct the Monero address with the public keys
cryptonote::account_public_address address;
address.m_view_public_key = wallet_public_view_key;
address.m_spend_public_key = wallet_entry.first;
std::string daemon_address = (opt_testnet) ? "http://127.0.0.1:29081" : (opt_stagenet) ? "http://127.0.0.1:39081" : "http://127.0.0.1:19081";
std::string wallet_password = "1234";
std::string wallet_path = epee::string_tools::pod_to_hex(wallet_entry.first) + "_wallet";
// Initialize the view-only wallet
tools::wallet2 w{net_type};
w.set_daemon(daemon_address);
w.set_refresh_from_block_height(0); // Set scanning from the genesis block
// Generate the wallet file
w.generate(wallet_path, wallet_password, address, wallet_private_view_key, true);
// Save the wallet file
w.store();
std::cout << "View-only wallet created successfully at: " << wallet_path << std::endl;
} catch (const std::exception &e) {
std::cerr << "Error creating view-only wallet: " << e.what() << std::endl;
}
}
return 0;
CATCH_ENTRY("Stats reporting error", 1);
@@ -1,44 +0,0 @@
#include <iostream>
#include "threadpool_boost.h"
ThreadPool::ThreadPool(size_t numThreads)
: workGuard(boost::asio::make_work_guard(ioService)) {
for (size_t i = 0; i < numThreads; ++i) {
workers.emplace_back([this]() {
std::cerr << "Thread started" << std::endl;
ioService.run();
std::cerr << "Thread finished" << std::endl;
});
}
}
void ThreadPool::enqueue(std::function<void()> task) {
ioService.post([task]() {
try {
task(); // Run the task
} catch (const std::exception& e) {
std::cerr << "Exception in thread pool task: " << e.what() << std::endl;
} catch (...) {
std::cerr << "Unknown exception in thread pool task!" << std::endl;
}
});
}
bool ThreadPool::isStopping() const {
return ioService.stopped(); // Check if io_context has stopped
}
void ThreadPool::waitForCompletion() {
std::cout << "Waiting for completion...\n";
workGuard.reset(); // Allow ioService to stop when no more tasks
ioService.run(); // Ensure no threads are left hanging
for (auto &worker : workers) {
if (worker.joinable()) worker.join();
}
std::cout << "All threads joined.\n";
}
ThreadPool::~ThreadPool() {
waitForCompletion();
}
@@ -1,24 +0,0 @@
#ifndef THREADPOOL_BOOST_H
#define THREADPOOL_BOOST_H
#include <boost/thread.hpp>
#include <boost/asio.hpp>
#include <functional>
#include <vector>
class ThreadPool {
public:
explicit ThreadPool(size_t numThreads);
~ThreadPool();
void enqueue(std::function<void()> task);
bool isStopping() const;
void waitForCompletion();
private:
boost::asio::io_service ioService;
boost::asio::executor_work_guard<boost::asio::io_context::executor_type> workGuard;
std::vector<boost::thread> workers;
};
#endif // THREADPOOL_BOOST_H
@@ -317,13 +317,13 @@ namespace cryptonote
boost::optional<subaddress_receive_info> subaddr_recv_info = is_out_to_acc_precomp(subaddresses, out_key, recv_derivation, additional_recv_derivations, real_output_index,hwdev);
CHECK_AND_ASSERT_MES(subaddr_recv_info, false, "key image helper: given output pubkey doesn't seem to belong to this address");
sid.aR = subaddr_recv_info->derivation;
sid.i = real_output_index;
return generate_key_image_helper_precomp(ack, out_key, subaddr_recv_info->derivation, real_output_index, subaddr_recv_info->index, in_ephemeral, ki, hwdev, use_origin_data, od, sid);
return generate_key_image_helper_precomp(ack, out_key, subaddr_recv_info->derivation, real_output_index, subaddr_recv_info->index, in_ephemeral, ki, hwdev, use_origin_data, od);
}
//---------------------------------------------------------------
bool generate_key_image_helper_precomp(const account_keys& ack, const crypto::public_key& out_key, const crypto::key_derivation& recv_derivation, size_t real_output_index, const subaddress_index& received_index, keypair& in_ephemeral, crypto::key_image& ki, hw::device &hwdev, const bool use_origin_data, const origin_data& od, rct::salvium_input_data_t& sid)
bool generate_key_image_helper_precomp(const account_keys& ack, const crypto::public_key& out_key, const crypto::key_derivation& recv_derivation, size_t real_output_index, const subaddress_index& received_index, keypair& in_ephemeral, crypto::key_image& ki, hw::device &hwdev, const bool use_origin_data, const origin_data& od)
{
if (hwdev.compute_key_image(ack, out_key, recv_derivation, real_output_index, received_index, in_ephemeral, ki))
{
@@ -417,13 +417,6 @@ namespace cryptonote
crypto::secret_key sk_spend = crypto::null_skey;
CHECK_AND_ASSERT_MES(hwdev.derive_secret_key(derivation_P_change_tx, od.output_index, spend_skey, sk_spend), false, "Failed to derive secret key for P_change");
// 3.5 Handle subaddresses
if (!received_index.is_zero()) {
crypto::secret_key scalar_step3;
hwdev.sc_secret_add(scalar_step3, sk_spend, subaddr_sk);
sk_spend = scalar_step3;
}
// 4. Derive the public key from the secret key for verification purposes
crypto::public_key change_pk;
CHECK_AND_ASSERT_MES(hwdev.secret_key_to_public_key(sk_spend, change_pk), false, "Failed to derive public key for P_change");
@@ -442,11 +435,7 @@ namespace cryptonote
// 6. Create the key_image needed to be able to spend the output
hwdev.generate_key_image(in_ephemeral.pub, in_ephemeral.sec, ki);
// Update the SID to have the correct derivation for P_change as well
sid.aR_stake = derivation_P_change_tx;
sid.i_stake = od.output_index;
return true;
} else {
@@ -1368,13 +1357,15 @@ namespace cryptonote
CHECK_AND_ASSERT_MES(output_index < additional_derivations.size(), boost::none, "wrong number of additional derivations");
if (out_can_be_to_acc(view_tag_opt, additional_derivations[output_index], output_index, &hwdev))
{
// HERE BE DRAGONS!!!
// SRCG: This is NOT going to work for PROTOCOL_TX except where there is only a single output
CHECK_AND_ASSERT_MES(hwdev.derive_subaddress_public_key(out_key, additional_derivations[output_index], output_index, subaddress_spendkey), boost::none, "Failed to derive subaddress public key");
// LAND AHOY!!!
auto found = subaddresses.find(subaddress_spendkey);
if (found != subaddresses.end())
return subaddress_receive_info{ found->second, additional_derivations[output_index] };
// If we get here, odds are that it is a PROTOCOL_TX
// If we get here, odds are that it is a PROTOCOL_TX (rare for other TX types to have additional derivations!)
if (output_index != 0) {
// Try the derivation with a 0 index as an override - CONVERT / YIELD TXs cannot know their index in the PROTOCOL_TX, so they use 0 in all cases
CHECK_AND_ASSERT_MES(hwdev.derive_subaddress_public_key(out_key, additional_derivations[output_index], 0, subaddress_spendkey), boost::none, "Failed to derive subaddress public key");
@@ -105,7 +105,7 @@ namespace cryptonote
bool get_tx_fee(const transaction& tx, uint64_t & fee);
uint64_t get_tx_fee(const transaction& tx);
bool generate_key_image_helper(const account_keys& ack, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, const crypto::public_key& out_key, const crypto::public_key& tx_public_key, const std::vector<crypto::public_key>& additional_tx_public_keys, size_t real_output_index, keypair& in_ephemeral, crypto::key_image& ki, hw::device &hwdev, const bool use_origin_data, const origin_data& od, rct::salvium_input_data_t& sid);
bool generate_key_image_helper_precomp(const account_keys& ack, const crypto::public_key& out_key, const crypto::key_derivation& recv_derivation, size_t real_output_index, const subaddress_index& received_index, keypair& in_ephemeral, crypto::key_image& ki, hw::device &hwdev, const bool use_origin_data, const origin_data& od, rct::salvium_input_data_t& sid);
bool generate_key_image_helper_precomp(const account_keys& ack, const crypto::public_key& out_key, const crypto::key_derivation& recv_derivation, size_t real_output_index, const subaddress_index& received_index, keypair& in_ephemeral, crypto::key_image& ki, hw::device &hwdev, const bool use_origin_data, const origin_data& od);
void get_blob_hash(const blobdata& blob, crypto::hash& res);
void get_blob_hash(const blobdata_ref& blob, crypto::hash& res);
crypto::hash get_blob_hash(const blobdata& blob);
+1 -3
View File
@@ -231,14 +231,12 @@
#define HF_VERSION_AUDIT1 6
#define HF_VERSION_SALVIUM_ONE_PROOFS 6
#define HF_VERSION_AUDIT1_PAUSE 7
#define HF_VERSION_REQUIRE_VIEW_TAGS 255
#define HF_VERSION_ENABLE_CONVERT 255
#define HF_VERSION_ENABLE_ORACLE 255
#define HF_VERSION_SLIPPAGE_YIELD 255
#define TESTNET_VERSION 14
#define TESTNET_VERSION 12
#define STAGENET_VERSION 1
#define PER_KB_FEE_QUANTIZATION_DECIMALS 8
+9 -36
View File
@@ -161,7 +161,6 @@ bool Blockchain::scan_outputkeys_for_indexes(size_t tx_version, const txin_to_ke
std::vector<output_data_t> outputs;
bool found = false;
/*
auto it = m_scan_table.find(tx_prefix_hash);
if (it != m_scan_table.end())
{
@@ -172,7 +171,6 @@ bool Blockchain::scan_outputkeys_for_indexes(size_t tx_version, const txin_to_ke
found = true;
}
}
*/
if (!found)
{
@@ -1505,7 +1503,6 @@ bool Blockchain::validate_miner_transaction(const block& b, size_t cumulative_bl
case HF_VERSION_ENFORCE_FULL_PROOFS:
case HF_VERSION_SHUTDOWN_USER_TXS:
case HF_VERSION_SALVIUM_ONE_PROOFS:
case HF_VERSION_AUDIT1_PAUSE:
if (b.miner_tx.amount_burnt > 0) {
CHECK_AND_ASSERT_MES(money_in_use + b.miner_tx.amount_burnt > money_in_use, false, "miner transaction is overflowed by amount_burnt");
money_in_use += b.miner_tx.amount_burnt;
@@ -1557,7 +1554,7 @@ bool Blockchain::validate_protocol_transaction(const block& b, uint64_t height,
LOG_PRINT_L2("coinbase protocol transaction in the block has no outputs");
return true;
}
// Can we have matured STAKE transactions yet?
uint64_t stake_lock_period = get_config(m_nettype).STAKE_LOCK_PERIOD;
if (height <= stake_lock_period) {
@@ -1955,22 +1952,14 @@ bool Blockchain::create_block_template(block& b, const crypto::hash *from_block,
return false;
}
// Work out what the asset_type should be based on height of submission
uint8_t hf_submitted = m_hardfork->get_ideal_version(start_height);
// Create the protocol_metadata entries here
for (const auto& yield_entry: yield_payouts) {
cryptonote::protocol_data_entry entry;
entry.amount_burnt = yield_entry.second;
entry.amount_minted = 0;
entry.amount_slippage_limit = 0;
if (hf_submitted >= HF_VERSION_SALVIUM_ONE_PROOFS) {
entry.source_asset = "SAL1";
entry.destination_asset = "SAL1";
} else {
entry.source_asset = "SAL";
entry.destination_asset = "SAL";
}
entry.source_asset = "SAL";
entry.destination_asset = "SAL";
entry.return_address = yield_entry.first.return_address;
entry.type = cryptonote::transaction_type::STAKE;
entry.P_change = yield_entry.first.P_change;
@@ -3952,20 +3941,6 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
}
}
if (tx.type == cryptonote::transaction_type::AUDIT) {
// Make sure we are supposed to accept AUDIT txs at this point
const std::map<uint8_t, std::pair<std::string, std::string>> audit_hard_forks = get_config(m_nettype).AUDIT_HARD_FORKS;
CHECK_AND_ASSERT_MES(audit_hard_forks.find(hf_version) != audit_hard_forks.end(), false, "trying to audit outside an audit fork");
std::string expected_asset_type = audit_hard_forks.at(hf_version).first;
CHECK_AND_ASSERT_MES(tx.source_asset_type == expected_asset_type, false, "trying to spend " << tx.source_asset_type << " coins in an AUDIT TX");
} else {
if (hf_version >= HF_VERSION_SALVIUM_ONE_PROOFS) {
CHECK_AND_ASSERT_MES(tx.source_asset_type == "SAL1", false, "trying to spend " << tx.source_asset_type << " coins in a non-AUDIT TX");
} else {
CHECK_AND_ASSERT_MES(tx.source_asset_type == "SAL", false, "trying to spend " << tx.source_asset_type << " coins in a non-AUDIT TX");
}
}
std::vector<std::vector<rct::ctkey>> pubkeys(tx.vin.size());
std::vector < uint64_t > results;
results.resize(tx.vin.size(), 0);
@@ -4088,7 +4063,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
const rct::rctSig &rv = tx.rct_signatures;
// Check that after full proofs are enabled, the RCT version is set to enforce full proofs
if (hf_version >= HF_VERSION_SALVIUM_ONE_PROOFS) {
if (hf_version == HF_VERSION_SALVIUM_ONE_PROOFS) {
if (rv.type != rct::RCTTypeNull && rv.type != rct::RCTTypeSalviumOne) {
MERROR_VER("Unsupported rct type (full proofs (with audit data) are required): " << rv.type);
return false;
@@ -4515,9 +4490,7 @@ bool Blockchain::calculate_audit_payouts(const uint64_t start_height, std::vecto
}
// Build a blacklist of staking TXs _not_ to pay out for
const std::set<std::string> txs_blacklist = {
"017a79539e69ce16e91d9aa2267c102f336678c41636567c1129e3e72149499a"
};
const std::set<std::string> txs_blacklist = {};
// Get the ABI information for the 21,600 blocks that the matured TX(s), we can calculate audit
for (const auto& entry: audit_entries) {
@@ -5997,10 +5970,10 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::vector<block_complete
// no need to check for duplicate here.
// HERE BE DRAGONS!!!
// SRCG: ring tweak to indexed per asset_type - DO NOT COMMIT UNTIL IT IS ALL WORKING
auto absolute_offsets = relative_output_offsets_to_absolute(in_to_key.key_offsets);
//std::vector<uint64_t> asset_offsets = relative_output_offsets_to_absolute(in_to_key.key_offsets);
//std::vector<uint64_t> absolute_offsets;
//m_db->get_output_id_from_asset_type_output_index(in_to_key.asset_type, asset_offsets, absolute_offsets);
//auto absolute_offsets = relative_output_offsets_to_absolute(in_to_key.key_offsets);
std::vector<uint64_t> asset_offsets = relative_output_offsets_to_absolute(in_to_key.key_offsets);
std::vector<uint64_t> absolute_offsets;
m_db->get_output_id_from_asset_type_output_index(in_to_key.asset_type, asset_offsets, absolute_offsets);
// LAND AHOY!!!
for (const auto & offset : absolute_offsets)
offset_map[in_to_key.amount].push_back(offset);
+10 -17
View File
@@ -363,7 +363,10 @@ namespace cryptonote
// Create the TX output for this refund
tx_out out;
cryptonote::set_tx_out(entry.amount_burnt, entry.destination_asset, CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW, entry.return_address, false, crypto::view_tag{}, out);
std::string asset_type = "SAL";
if (hf_version >= HF_VERSION_SALVIUM_ONE_PROOFS)
asset_type = "SAL1";
cryptonote::set_tx_out(entry.amount_burnt, asset_type, CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW, entry.return_address, false, crypto::view_tag{}, out);
additional_tx_public_keys.push_back(entry.return_pubkey);
tx.vout.push_back(out);
} else if (entry.type == cryptonote::transaction_type::AUDIT) {
@@ -372,7 +375,10 @@ namespace cryptonote
// Create the TX output for this refund
tx_out out;
cryptonote::set_tx_out(entry.amount_burnt, entry.destination_asset, CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW, entry.return_address, false, crypto::view_tag{}, out);
std::string asset_type = "SAL";
if (hf_version >= HF_VERSION_SALVIUM_ONE_PROOFS)
asset_type = "SAL1";
cryptonote::set_tx_out(entry.amount_burnt, asset_type, CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW, entry.return_address, false, crypto::view_tag{}, out);
additional_tx_public_keys.push_back(entry.return_pubkey);
tx.vout.push_back(out);
}
@@ -448,7 +454,6 @@ namespace cryptonote
case HF_VERSION_ENFORCE_FULL_PROOFS:
case HF_VERSION_SHUTDOWN_USER_TXS:
case HF_VERSION_SALVIUM_ONE_PROOFS:
case HF_VERSION_AUDIT1_PAUSE:
// SRCG: subtract 20% that will be rewarded to staking users
CHECK_AND_ASSERT_MES(tx.amount_burnt == 0, false, "while creating outs: amount_burnt is nonzero");
tx.amount_burnt = amount / 5;
@@ -538,20 +543,13 @@ namespace cryptonote
std::string encrypted_data = std::string(reinterpret_cast<char*>(&ephemeral_pk), sizeof(ephemeral_pk)) +
std::string(reinterpret_cast<char*>(&iv), sizeof(iv)) +
ciphertext;
return epee::string_tools::buff_to_hex_nodelimer(encrypted_data);
return encrypted_data;
}
//---------------------------------------------------------------
// Decrypt function
bool decrypt_pvk(const std::string &encrypted_data_hex, const crypto::secret_key &SK, crypto::secret_key &pvk) {
bool decrypt_pvk(const std::string &encrypted_data, const crypto::secret_key &SK, crypto::secret_key &pvk) {
//std::string decrypt_pvk(const std::string &encrypted_data, const crypto::secret_key &SK) {
// Step 1: Extract ephemeral_pk, iv, and ciphertext from encrypted_data
std::string encrypted_data;
for (size_t i = 0; i < encrypted_data_hex.length(); i += 2) {
std::istringstream iss(encrypted_data_hex.substr(i, 2));
int byte;
iss >> std::hex >> byte;
encrypted_data += static_cast<char>(byte);
}
const char *data_ptr = encrypted_data.data();
crypto::public_key ephemeral_pk;
memcpy(&ephemeral_pk, data_ptr, sizeof(ephemeral_pk));
@@ -733,7 +731,6 @@ namespace cryptonote
rct::salvium_input_data_t sid;
const auto& out_key = reinterpret_cast<const crypto::public_key&>(src_entr.outputs[src_entr.real_output].second.dest);
bool use_origin_data = (src_entr.origin_tx_data.tx_type != cryptonote::transaction_type::UNSET);
sid.origin_tx_type = src_entr.origin_tx_data.tx_type;
if(!generate_key_image_helper(sender_account_keys, subaddresses, out_key, src_entr.real_out_tx_key, src_entr.real_out_additional_tx_keys, src_entr.real_output_in_tx_index, in_ephemeral,img, hwdev, use_origin_data, src_entr.origin_tx_data, sid))
{
LOG_ERROR("Key image generation failed!");
@@ -743,10 +740,6 @@ namespace cryptonote
// SRCG: store the audit data for the source here
if (audit) {
sid.amount = src_entr.amount;
if (sid.origin_tx_type == cryptonote::transaction_type::STAKE) {
// STAKE TXs have to use "output_index 0" because they don't know what the actual output_index value will be ahead of time
sid.i = 0;
}
salvium_data.input_verification_data.push_back(sid);
}
+2
View File
@@ -1662,11 +1662,13 @@ namespace cryptonote
continue;
}
// HERE BE DRAGONS!!!
// SRCG: skip all user TXs for HF 5 - when the node restarts, it'll discard them fully in `tx_memory_pool::validate()`
if (version == HF_VERSION_SHUTDOWN_USER_TXS) {
LOG_PRINT_L2(" User TXs forbidden by consensus for HF 5 - skipping");
continue;
}
// LAND AHOY!!!
LOG_PRINT_L2("Considering " << sorted_it->second << ", weight " << meta.weight << ", current block weight " << total_weight << "/" << max_total_weight << ", current coinbase " << print_money(best_coinbase) << ", relay method " << (unsigned)meta.get_relay_method());
+7 -13
View File
@@ -47,11 +47,8 @@ const hardfork_t mainnet_hard_forks[] = {
// version 5 starts from block 136100, which is on or around the 9th of January, 2025. Fork time finalised on 2025-01-08. No fork voting occurs for the v5 fork.
{ 5, 136100, 0, 1736265945 },
// version 6 starts from block 154750, which is on or around the 4th of February, 2025. Fork time finalised on 2025-01-31. No fork voting occurs for the v6 fork.
{ 6, 154750, 0, 1738336000 },
// version 7 starts from block 161900, which is on or around the 14th of February, 2025. Fork time finalised on 2025-02-04. No fork voting occurs for the v7 fork.
{ 7, 161900, 0, 1739264400 },
// version 6 starts from block 146146, which is on or around the 23rd of January, 2025. Fork time finalised on 2025-01-17. No fork voting occurs for the v6 fork.
//{ 6, 146146, 0, 1736592100 },
};
const size_t num_mainnet_hard_forks = sizeof(mainnet_hard_forks) / sizeof(mainnet_hard_forks[0]);
const uint64_t mainnet_hard_fork_version_1_till = ((uint64_t)-1);
@@ -66,17 +63,14 @@ const hardfork_t testnet_hard_forks[] = {
// version 3 starts from block 500
{ 3, 500, 0, 1729518000 },
// version 4 (full proofs) starts from block 600
// version 4 starts from block 600
{ 4, 600, 0, 1734607000 },
// version 5 (TX shutdown) starts from block 800
{ 5, 800, 0, 1734607005 },
// version 5 starts from block 700
{ 5, 700, 0, 1734607005 },
// version 6 (audit 1) starts from block 815
{ 6, 815, 0, 1734608000 },
// version 7 (audit 1 pause) starts from block 900
{ 7, 900, 0, 1739264400 },
// version 5 starts from block 800
{ 6, 800, 0, 1734608000 },
};
const size_t num_testnet_hard_forks = sizeof(testnet_hard_forks) / sizeof(testnet_hard_forks[0]);
const uint64_t testnet_hard_fork_version_1_till = ((uint64_t)-1);
+2 -12
View File
@@ -1,5 +1,5 @@
// Copyright (c) 2016, Monero Research Labs
// Portions Copyright (c) 2023-2025, Salvium (author: SRCG)
// Portions Copyright (c) 2023-2024, Salvium (author: SRCG)
//
// Author: Shen Noether <shen.noether@gmx.com>
//
@@ -1726,25 +1726,15 @@ namespace rct {
CHECK_AND_ASSERT_THROW_MES(rv.salvium_data.spend_pubkey != crypto::null_pkey, "Invalid spend pubkey provided in audit data");
CHECK_AND_ASSERT_THROW_MES(rv.salvium_data.enc_view_privkey_str != "", "Invalid encrypted viewkey provided in audit data");
for (size_t i=0; i < rv.salvium_data.input_verification_data.size(); ++i) {
// Check for STAKE origin
crypto::public_key Ks = rv.salvium_data.spend_pubkey;
if (rv.salvium_data.input_verification_data[i].origin_tx_type != cryptonote::transaction_type::UNSET) {
// Verify the origin data provided
CHECK_AND_ASSERT_THROW_MES(crypto::derive_public_key(rv.salvium_data.input_verification_data[i].aR_stake, rv.salvium_data.input_verification_data[i].i_stake, rv.salvium_data.spend_pubkey, Ks),
"Failed to derive ephemeral public key from audit data");
}
// Recalculate the value of Ks from the Ko value
crypto::public_key ephemeral_pub = crypto::null_pkey;
CHECK_AND_ASSERT_THROW_MES(crypto::derive_public_key(rv.salvium_data.input_verification_data[i].aR, rv.salvium_data.input_verification_data[i].i, Ks, ephemeral_pub),
CHECK_AND_ASSERT_THROW_MES(crypto::derive_public_key(rv.salvium_data.input_verification_data[i].aR, rv.salvium_data.input_verification_data[i].i, rv.salvium_data.spend_pubkey, ephemeral_pub),
"Failed to derive ephemeral public key from audit data");
// Now find this in the list of mixring entries
bool found = false;
for (size_t n=0; n<rv.mixRing[i].size(); ++n) {
if (ephemeral_pub == rct::rct2pk(rv.mixRing[i][n].dest)) {
found = true;
break;
}
}
CHECK_AND_ASSERT_THROW_MES(found, "Failed to match ephemeral public key provided in audit data");
-9
View File
@@ -55,7 +55,6 @@ extern "C" {
#include "serialization/binary_archive.h"
#include "serialization/json_archive.h"
#include "cryptonote_protocol/enums.h"
//Define this flag when debugging to get additional info on the console
#ifdef DBG
@@ -337,19 +336,11 @@ namespace rct {
crypto::key_derivation aR;
xmr_amount amount;
size_t i;
uint8_t origin_tx_type;
crypto::key_derivation aR_stake;
size_t i_stake;
BEGIN_SERIALIZE_OBJECT()
FIELD(aR)
VARINT_FIELD(amount)
VARINT_FIELD(i)
VARINT_FIELD(origin_tx_type)
if (origin_tx_type != cryptonote::transaction_type::UNSET) {
FIELD(aR_stake)
FIELD(i_stake)
}
END_SERIALIZE()
};
struct salvium_data_t {
+1 -12
View File
@@ -1506,12 +1506,7 @@ void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const rct::salvium_
INSERT_INTO_JSON_OBJECT(dest, aR, salvium_input_data.aR);
INSERT_INTO_JSON_OBJECT(dest, i, salvium_input_data.i);
INSERT_INTO_JSON_OBJECT(dest, amount, salvium_input_data.amount);
INSERT_INTO_JSON_OBJECT(dest, origin_tx_type, salvium_input_data.origin_tx_type);
if (salvium_input_data.origin_tx_type != cryptonote::transaction_type::UNSET) {
INSERT_INTO_JSON_OBJECT(dest, aR_stake, salvium_input_data.aR_stake);
INSERT_INTO_JSON_OBJECT(dest, i_stake, salvium_input_data.i_stake);
}
dest.EndObject();
}
@@ -1524,12 +1519,6 @@ void fromJsonValue(const rapidjson::Value& val, rct::salvium_input_data_t& salvi
GET_FROM_JSON_OBJECT(val, salvium_input_data.aR, aR);
GET_FROM_JSON_OBJECT(val, salvium_input_data.i, i);
GET_FROM_JSON_OBJECT(val, salvium_input_data.amount, amount);
GET_FROM_JSON_OBJECT(val, salvium_input_data.origin_tx_type, origin_tx_type);
if (salvium_input_data.origin_tx_type != cryptonote::transaction_type::UNSET) {
GET_FROM_JSON_OBJECT(val, salvium_input_data.aR_stake, aR_stake);
GET_FROM_JSON_OBJECT(val, salvium_input_data.i_stake, i_stake);
}
}
void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const rct::salvium_data_t& salvium_data)
+61 -91
View File
@@ -214,7 +214,7 @@ namespace
const char* USAGE_BURN("burn <amount> <asset_type>");
const char* USAGE_CONVERT("convert <source_amount> <source_asset> <dest_asset> [<slippage_limit>]");
const char* USAGE_STAKE("stake <amount>");
const char* USAGE_AUDIT("audit [index=<N1>[,<N2>,...] | index=all]");
const char* USAGE_AUDIT("audit");
const char* USAGE_PRICE_INFO("price_info");
const char* USAGE_SUPPLY_INFO("supply_info");
const char* USAGE_YIELD_INFO("yield_info");
@@ -3221,7 +3221,7 @@ bool simple_wallet::help(const std::vector<std::string> &args/* = std::vector<st
message_writer() << tr("\"burn <amount> <asset_type>\" - destroy coins forever.");
message_writer() << tr("\"convert <amount> <source_asset> <dest_asset> [<slippage_limit>]\" - convert between coin types.");
message_writer() << tr("\"stake <amount>\" - stake SAL for 30 days to earn yield.");
message_writer() << tr("\"audit\" - audit your wallet main address (or subaddress(es) if specified).");
message_writer() << tr("\"audit\" - audit your wallet.");
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.");
@@ -3418,7 +3418,7 @@ simple_wallet::simple_wallet()
m_cmd_binder.set_handler("audit",
boost::bind(&simple_wallet::audit, this, _1),
tr(USAGE_AUDIT),
tr("Sends your wallet balance (or a single address or subaddress(es)) to audit (only available during AUDIT hard forks)"));
tr("Sends your wallet balance for audit (only available during AUDIT hard forks)"));
m_cmd_binder.set_handler("price_info",
boost::bind(&simple_wallet::price_info, this, _1),
tr(USAGE_PRICE_INFO),
@@ -5863,26 +5863,22 @@ void simple_wallet::on_money_received(uint64_t height, const crypto::hash &txid,
message_writer(console_color_yellow, false) << "\r" <<
tr("Height ") << height << ", " <<
tr("txid ") << txid << ", " <<
tr("burnt ") << print_money(tx.amount_burnt) << " " << asset_type << ", " <<
tr("idx ") << subaddr_index;
tr("burnt ") << print_money(tx.amount_burnt) << " " << asset_type;
} else if (tx.type == cryptonote::transaction_type::CONVERT) {
message_writer(console_color_blue, false) << "\r" <<
tr("Height ") << height << ", " <<
tr("txid ") << txid << ", " <<
tr("converting ") << print_money(tx.amount_burnt) << " " << asset_type << ", " <<
tr("idx ") << subaddr_index;
tr("converting ") << print_money(tx.amount_burnt) << " " << asset_type;
} else if (tx.type == cryptonote::transaction_type::STAKE) {
message_writer(console_color_cyan, false) << "\r" <<
tr("Height ") << height << ", " <<
tr("txid ") << txid << ", " <<
tr("staked ") << print_money(tx.amount_burnt) << " " << asset_type << ", " <<
tr("idx ") << subaddr_index;
tr("staked ") << print_money(tx.amount_burnt) << " " << asset_type;
} else if (tx.type == cryptonote::transaction_type::AUDIT) {
message_writer(console_color_yellow, false) << "\r" <<
tr("Height ") << height << ", " <<
tr("txid ") << txid << ", " <<
tr("audited ") << print_money(tx.amount_burnt) << " " << asset_type << ", " <<
tr("idx ") << subaddr_index;
tr("audited ") << print_money(tx.amount_burnt) << " " << asset_type;
}
message_writer(asset_type == "SAL" ? console_color_green : console_color_blue, false) << "\r" <<
@@ -6741,20 +6737,26 @@ bool simple_wallet::transfer_main(
// "transfer [index=<N1>[,<N2>,...]] [<priority>] [<ring_size>] <address> <amount> [<payment_id>]"
if (!try_connect_to_daemon())
return false;
bool audit = false;
if (m_wallet->get_current_hard_fork() >= HF_VERSION_SALVIUM_ONE_PROOFS) {
if (transfer_type == Audit) {
audit = true;
/*
} else if (source_asset != "SAL1") {
fail_msg_writer() << tr("Only SAL1 may be spent now");
return false;
*/
}
}
std::vector<std::string> local_args = args_;
std::set<uint32_t> subaddr_indices;
if (local_args.size() > 0 && local_args[0].substr(0, 6) == "index=")
{
if (local_args[0] == "index=all")
{
for (uint32_t i = 0; i < m_wallet->get_num_subaddresses(m_current_subaddress_account); ++i)
subaddr_indices.insert(i);
}
else if (!parse_subaddress_indices(local_args[0], subaddr_indices))
{
return true;
}
if (!parse_subaddress_indices(local_args[0], subaddr_indices))
return false;
local_args.erase(local_args.begin());
}
@@ -6794,7 +6796,7 @@ bool simple_wallet::transfer_main(
return false;
}
const size_t min_args = (transfer_type == Audit) ? 0 : (transfer_type == TransferLocked) ? 2 : 1;
const size_t min_args = (transfer_type == TransferLocked) ? 2 : 1;
if(local_args.size() < min_args)
{
fail_msg_writer() << tr("wrong number of arguments");
@@ -6972,35 +6974,9 @@ bool simple_wallet::transfer_main(
std::vector<tools::wallet2::pending_tx> ptx_vector;
uint64_t unlock_block = 0;
std::string err;
if (transfer_type == Audit) {
// Get the subaddress unlocked balances
std::map<uint32_t, std::pair<uint64_t, std::pair<uint64_t, uint64_t>>> unlocked_balance_per_subaddr = m_wallet->unlocked_balance_per_subaddress(m_current_subaddress_account, source_asset, true);
unlock_block = get_config(m_wallet->nettype()).AUDIT_LOCK_PERIOD;
for (const auto subaddr_index : subaddr_indices) {
// Skip this wallet if there is no balance unlocked to audit
if (unlocked_balance_per_subaddr.count(subaddr_index) == 0) continue;
try {
std::set<uint32_t> subaddr_indices_single;
subaddr_indices_single.insert(subaddr_index);
uint64_t unlock_block = get_config(m_wallet->nettype()).AUDIT_LOCK_PERIOD;
std::vector<tools::wallet2::pending_tx> ptx_vector_audit = m_wallet->create_transactions_all(0, cryptonote::transaction_type::AUDIT, source_asset, m_wallet->get_subaddress({m_current_subaddress_account, subaddr_index}), (subaddr_index>0), 1, fake_outs_count, unlock_block, priority, extra, m_current_subaddress_account, subaddr_indices_single);
ptx_vector.insert(ptx_vector.end(), ptx_vector_audit.begin(), ptx_vector_audit.end());
} catch (const std::exception &e) {
// Let's skip this wallet - we have already reported the error
if (unlocked_balance_per_subaddr[subaddr_index].first < 250000000) {
fail_msg_writer() << boost::format(tr("Subaddress index %u has insufficient funds (%s) to pay for audit")) % subaddr_index % print_money(unlocked_balance_per_subaddr[subaddr_index].first);
}
}
}
} else {
switch (transfer_type) {
cryptonote::address_parse_info info;
switch (transfer_type)
{
case Burn:
unlock_block = 0;
ptx_vector = m_wallet->create_transactions_2(dsts, source_asset, dest_asset, cryptonote::transaction_type::BURN, fake_outs_count, unlock_block /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, subtract_fee_from_outputs);
@@ -7009,6 +6985,10 @@ bool simple_wallet::transfer_main(
unlock_block = CONVERT_LOCK_PERIOD;
ptx_vector = m_wallet->create_transactions_2(dsts, source_asset, dest_asset, cryptonote::transaction_type::CONVERT, fake_outs_count, unlock_block /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, subtract_fee_from_outputs);
break;
case Audit:
unlock_block = get_config(m_wallet->nettype()).AUDIT_LOCK_PERIOD;
ptx_vector = m_wallet->create_transactions_all(0, cryptonote::transaction_type::AUDIT, source_asset, m_wallet->get_subaddress({m_current_subaddress_account, 0}), false, 1, fake_outs_count, unlock_block, priority, extra, m_current_subaddress_account, subaddr_indices);
break;
case Stake:
unlock_block = get_config(m_wallet->nettype()).STAKE_LOCK_PERIOD;
ptx_vector = m_wallet->create_transactions_2(dsts, source_asset, dest_asset, cryptonote::transaction_type::STAKE, fake_outs_count, unlock_block, priority, extra, m_current_subaddress_account, subaddr_indices, subtract_fee_from_outputs);
@@ -7023,7 +7003,6 @@ bool simple_wallet::transfer_main(
case Transfer:
ptx_vector = m_wallet->create_transactions_2(dsts, source_asset, dest_asset, cryptonote::transaction_type::TRANSFER, fake_outs_count, 0 /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, subtract_fee_from_outputs);
break;
}
}
if (ptx_vector.empty())
@@ -7456,7 +7435,7 @@ bool simple_wallet::sweep_unmixable(const std::vector<std::string> &args_)
//----------------------------------------------------------------------------------------------------
bool simple_wallet::sweep_main(uint32_t account, uint64_t below, bool locked, const std::vector<std::string> &args_)
{
std::string asset_type = (args_.size() > 1) ? args_.back() : (m_wallet->get_current_hard_fork() >= HF_VERSION_SALVIUM_ONE_PROOFS) ? "SAL1" : "SAL";
std::string asset_type = (args_.size() > 1) ? args_.back() : "SAL";
auto print_usage = [this, account, below]()
{
if (below)
@@ -8126,8 +8105,9 @@ bool simple_wallet::return_payment(const std::vector<std::string> &args_)
}
}
// We found the one(s) we were looking for - take a copy of the key_image, etc.
// We found the one we were looking for - take a copy of the key_image, etc.
transfers_indices.push_back(idx);
break;
}
// Check we have a valid key_image
@@ -8152,32 +8132,21 @@ bool simple_wallet::return_payment(const std::vector<std::string> &args_)
fail_msg_writer() << tr("Multiple transactions are created, which is not supposed to happen");
return true;
}
if (ptx_vector[0].selected_transfers.size() != transfers_indices.size())
if (ptx_vector[0].selected_transfers.size() != 1)
{
fail_msg_writer() << tr("The transaction uses incorrect number of inputs, which is not supposed to happen");
fail_msg_writer() << tr("The transaction uses multiple or no inputs, which is not supposed to happen");
return true;
}
// give user total and fee, and prompt to confirm
uint64_t total_fee = ptx_vector[0].fee;
uint64_t total_sent = 0;
std::string asset_type;
for (auto idx: ptx_vector[0].selected_transfers) {
const tools::wallet2::transfer_details &td = m_wallet->get_transfer_details(idx);
uint64_t sent = td.amount();
if (total_sent + sent < total_sent) {
fail_msg_writer() << tr("amount overflow detected");
return true;
}
total_sent += sent;
asset_type = td.asset_type;
}
uint64_t total_sent = m_wallet->get_transfer_details(ptx_vector[0].selected_transfers.front()).amount();
std::ostringstream prompt;
if (!process_ring_members(ptx_vector, prompt, m_wallet->print_ring_members()))
return true;
prompt << boost::format(tr("Returning %s %s for a total fee of %s %s. Is this okay?")) %
print_money(total_sent) % asset_type %
print_money(total_fee) % asset_type;
prompt << boost::format(tr("Returning %s for a total fee of %s. Is this okay?")) %
print_money(total_sent) %
print_money(total_fee);
std::string accepted = input_line(prompt.str(), true);
if (std::cin.eof())
return true;
@@ -8381,11 +8350,8 @@ bool simple_wallet::convert(const std::vector<std::string> &args_)
bool simple_wallet::audit(const std::vector<std::string> &args_)
{
// TODO: add locked versions
std::vector<std::string> local_args = args_;
if (args_.size() == 0)
if (args_.size() != 0)
{
local_args.push_back("index=0");
} else if (args_.size() > 1) {
PRINT_USAGE(USAGE_AUDIT);
return true;
}
@@ -8396,14 +8362,24 @@ bool simple_wallet::audit(const std::vector<std::string> &args_)
return true;
}
std::vector<std::string> local_args;
local_args.push_back(m_wallet->get_subaddress_as_str({m_current_subaddress_account,0}));
//local_args.insert(local_args.end(), args_.begin(), args_.end());
const std::map<uint8_t, std::pair<std::string, std::string>> audit_hard_forks = get_config(m_wallet->nettype()).AUDIT_HARD_FORKS;
const uint8_t hf_version = m_wallet->get_current_hard_fork();
if (audit_hard_forks.find(hf_version) != audit_hard_forks.end()) {
// Get the asset types
const std::pair<std::string, std::string> audit_asset_types = audit_hard_forks.at(hf_version);
transfer_main(Audit, audit_asset_types.first, audit_asset_types.first, local_args, false);
// Check to see if the user has a balance of the coins being audited
uint64_t unlocked_balance = m_wallet->unlocked_balance_all(true, audit_asset_types.first);
if (unlocked_balance > 0) {
local_args.push_back(print_money(unlocked_balance));
transfer_main(Audit, audit_asset_types.first, audit_asset_types.first, local_args, false);
} else {
fail_msg_writer() << tr("No coins currently available to audit. Only unlocked coins can be audited.");
}
} else {
fail_msg_writer() << tr("Audit command is not available at this time.");
}
@@ -8519,7 +8495,7 @@ bool simple_wallet::yield_info(const std::vector<std::string> &args) {
// EXPERIMENTAL - change to get_yield_summary_info() method
uint64_t t_burnt, t_supply, t_locked, t_yield, yps, ybi_size;
std::vector<std::tuple<size_t, std::string, std::string, uint64_t, uint64_t>> yield_payouts;
std::vector<std::tuple<size_t, std::string, uint64_t, uint64_t>> yield_payouts;
if (!m_wallet->get_yield_summary_info(t_burnt, t_supply, t_locked, t_yield, yps, ybi_size, yield_payouts)) {
fail_msg_writer() << "failed to get yield info. Make sure you are connected to a daemon.";
return false;
@@ -8527,35 +8503,29 @@ bool simple_wallet::yield_info(const std::vector<std::string> &args) {
// Get the chain height
const uint64_t blockchain_height = m_wallet->get_blockchain_current_height();
uint64_t stake_lock_period = get_config(m_wallet->nettype()).STAKE_LOCK_PERIOD;
message_writer(console_color_default, false) << boost::format(tr("\nSTAKED FUNDS:"));
for (auto &p: yield_payouts) {
uint64_t height, burnt, yield;
std::string txid, asset_type;
std::tie(height, txid, asset_type, burnt, yield) = p;
epee::console_colors asset_type_color = (asset_type == "SAL") ? console_color_green : (asset_type == "SAL1") ? console_color_blue : console_color_green;
std::string txid;
std::tie(height, txid, burnt, yield) = p;
if (blockchain_height > ybi_size + height)
message_writer(asset_type_color, true) << boost::format(tr("Height %d, txid %s, staked %s %s, earned %s %s"))
message_writer(console_color_green, true) << boost::format(tr("Height %d, txid %s, staked %s SAL, earned %s SAL"))
% height
% txid
% print_money(burnt)
% asset_type
% print_money(yield)
% asset_type;
% print_money(yield);
else
message_writer(asset_type_color, false) << boost::format(tr("Height %d (matures %d), txid %s, staked %s %s, %s %s accrued so far"))
message_writer(console_color_green, false) << boost::format(tr("Height %d (matures %d), txid %s, staked %s SAL, %s SAL accrued so far"))
% height
% (height + stake_lock_period)
% (height + 21601)
% txid
% print_money(burnt)
% asset_type
% print_money(yield)
% asset_type;
}
% print_money(yield);
}
// Output the necessary information about yield stats
message_writer(console_color_default, false) << boost::format(tr("\nYIELD INFO:\n\tSupply coins burnt over last %s: %d\n\tTotal coins locked: %d\n\tYield accrued over last %s: %d\n\tYield per coin staked: %d"))
message_writer(console_color_default, false) << boost::format(tr("\nYIELD INFO:\n\tSupply coins burnt over last %s: %d\n\tTotal coins locked: %d\n\tYield accrued over last %s: %d\n\tYield per SAL staked: %d"))
% get_human_readable_timespan((ybi_size-1) * DIFFICULTY_TARGET_V2)
% print_money(t_burnt)
% print_money(t_locked)
+1 -1
View File
@@ -1,5 +1,5 @@
#define DEF_SALVIUM_VERSION_TAG "@VERSIONTAG@"
#define DEF_SALVIUM_VERSION "0.9.2"
#define DEF_SALVIUM_VERSION "0.9.0-rc2"
#define DEF_MONERO_VERSION_TAG "release"
#define DEF_MONERO_VERSION "0.18.3.3"
#define DEF_MONERO_RELEASE_NAME "Zero"
+2 -30
View File
@@ -1444,34 +1444,6 @@ PendingTransaction *WalletImpl::createStakeTransaction(uint64_t amount, uint32_t
return createTransactionMultDest(Monero::transaction_type::STAKE, std::vector<string> {dst_addr}, payment_id, amount ? (std::vector<uint64_t> {amount}) : (optional<std::vector<uint64_t>>()), mixin_count, asset_type, is_return, priority, subaddr_account, subaddr_indices);
}
PendingTransaction *WalletImpl::createAuditTransaction(
uint32_t mixin_count,
PendingTransaction::Priority priority,
uint32_t subaddr_account,
std::set<uint32_t> subaddr_indices
) {
// Need to populate {dst_entr, payment_id, asset_type, is_return}
const string dst_addr = m_wallet->get_subaddress_as_str({subaddr_account, 0});//MY LOCAL (SUB)ADDRESS
const string payment_id = "";
const string asset_type = "SAL";
const bool is_return = false;
LOG_ERROR("createAuditTransaction: called");
return createTransactionMultDest(
Monero::transaction_type::AUDIT,
std::vector<string> {dst_addr},
payment_id,
(optional<std::vector<uint64_t>>()),
mixin_count,
asset_type,
is_return,
priority,
subaddr_account,
subaddr_indices
);
}
// TODO:
// 1 - properly handle payment id (add another menthod with explicit 'payment_id' param)
// 2 - check / design how "Transaction" can be single interface
@@ -1564,11 +1536,11 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const Monero::transact
fake_outs_count = m_wallet->adjust_mixin(mixin_count);
if (amount) {
transaction->m_pending_tx = m_wallet->create_transactions_2(dsts, asset_type, asset_type, converted_tx_type, fake_outs_count, 0 /* unlock_time */,
transaction->m_pending_tx = m_wallet->create_transactions_2(dsts, "SAL", "SAL", converted_tx_type, fake_outs_count, 0 /* unlock_time */,
adjusted_priority,
extra, subaddr_account, subaddr_indices);
} else {
transaction->m_pending_tx = m_wallet->create_transactions_all(0, converted_tx_type, asset_type, info.address, info.is_subaddress, 1, fake_outs_count, 0 /* unlock_time */,
transaction->m_pending_tx = m_wallet->create_transactions_all(0, converted_tx_type, "SAL", info.address, info.is_subaddress, 1, fake_outs_count, 0 /* unlock_time */,
adjusted_priority,
extra, subaddr_account, subaddr_indices);
}
-4
View File
@@ -158,10 +158,6 @@ public:
PendingTransaction::Priority priority = PendingTransaction::Priority_Low,
uint32_t subaddr_account = 0,
std::set<uint32_t> subaddr_indices = {}) override;
PendingTransaction * createAuditTransaction(uint32_t mixin_count,
PendingTransaction::Priority priority = PendingTransaction::Priority_Low,
uint32_t subaddr_account = 0,
std::set<uint32_t> subaddr_indices = {}) override;
PendingTransaction * createTransactionMultDest(const transaction_type &tx_type,
const std::vector<std::string> &dst_addr, const std::string &payment_id,
optional<std::vector<uint64_t>> amount, uint32_t mixin_count,
+2 -17
View File
@@ -58,8 +58,7 @@ enum transaction_type : uint8_t {
BURN = 5,
STAKE = 6,
RETURN = 7,
AUDIT = 8,
MAX = 8
MAX = 7
};
namespace Utils {
@@ -98,7 +97,7 @@ struct YieldInfo
virtual uint64_t yield() const = 0;
virtual uint64_t yield_per_stake() const = 0;
virtual std::string period() const = 0;
virtual std::vector<std::tuple<size_t, std::string, std::string, uint64_t, uint64_t>> payouts() const = 0;
virtual std::vector<std::tuple<size_t, std::string, uint64_t, uint64_t>> payouts() const = 0;
};
@@ -879,20 +878,6 @@ struct Wallet
uint32_t subaddr_account = 0,
std::set<uint32_t> subaddr_indices = {}) = 0;
/*!
* \brief createAuditTransaction creates audit transaction.
* \param mixin_count mixin count. if 0 passed, wallet will use default value
* \param subaddr_indices set of subaddress indices to use for transfer or sweeping. if set empty, all are chosen when sweeping, and one or more are automatically chosen when transferring. after execution, returns the set of actually used indices
* \param priority
* \return PendingTransaction object. caller is responsible to check PendingTransaction::status()
* after object returned
*/
virtual PendingTransaction * createAuditTransaction(uint32_t mixin_count,
PendingTransaction::Priority = PendingTransaction::Priority_Low,
uint32_t subaddr_account = 0,
std::set<uint32_t> subaddr_indices = {}) = 0;
/*!
* \brief createTransactionMultDest creates transaction with multiple destinations. if dst_addr is an integrated address, payment_id is ignored
* \param tx_type the type of transaction being created
+1 -1
View File
@@ -123,7 +123,7 @@ namespace Monero {
return m_yield_per_stake;
}
std::vector<std::tuple<size_t, std::string, std::string, uint64_t, uint64_t>> YieldInfoImpl::payouts() const
std::vector<std::tuple<size_t, std::string, uint64_t, uint64_t>> YieldInfoImpl::payouts() const
{
return m_payouts;
}
+2 -2
View File
@@ -53,7 +53,7 @@ public:
uint64_t yield() const override;
uint64_t yield_per_stake() const override;
std::string period() const override;
std::vector<std::tuple<size_t, std::string, std::string, uint64_t, uint64_t>> payouts() const override;
std::vector<std::tuple<size_t, std::string, uint64_t, uint64_t>> payouts() const override;
private:
friend class WalletImpl;
@@ -68,7 +68,7 @@ private:
uint64_t m_yield_per_stake;
uint64_t m_num_entries;
std::string m_period;
std::vector<std::tuple<size_t, std::string, std::string, uint64_t, uint64_t>> m_payouts;
std::vector<std::tuple<size_t, std::string, uint64_t, uint64_t>> m_payouts;
};
}
+26 -55
View File
@@ -2204,7 +2204,6 @@ void wallet2::scan_output(const cryptonote::transaction &tx, bool miner_tx, cons
// Flag to indicate this is a TX that uses a return_address
bool use_od = false;
cryptonote::origin_data od = AUTO_VAL_INIT(od);
rct::salvium_input_data_t sid;
auto search = m_salvium_txs.find(pk_change);
if (search != m_salvium_txs.end()) {
size_t idx = search->second;
@@ -2215,9 +2214,6 @@ void wallet2::scan_output(const cryptonote::transaction &tx, bool miner_tx, cons
od.tx_pub_key = get_tx_pub_key_from_extra(td_origin.m_tx);
od.output_index = td_origin.m_internal_output_index;
od.tx_type = td_origin.m_tx.type;
// SRCG: this is necessary to be able to receive protocol_tx outputs to the correct wallet subaddress
tx_scan_info.received->index = td_origin.m_subaddr_index;
}
if (m_multisig)
@@ -2228,7 +2224,7 @@ void wallet2::scan_output(const cryptonote::transaction &tx, bool miner_tx, cons
}
else
{
bool r = cryptonote::generate_key_image_helper_precomp(m_account.get_keys(), output_public_key, tx_scan_info.received->derivation, i, tx_scan_info.received->index, tx_scan_info.in_ephemeral, tx_scan_info.ki, m_account.get_device(), use_od, od, sid);
bool r = cryptonote::generate_key_image_helper_precomp(m_account.get_keys(), output_public_key, tx_scan_info.received->derivation, i, tx_scan_info.received->index, tx_scan_info.in_ephemeral, tx_scan_info.ki, m_account.get_device(), use_od, od);
THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "Failed to generate key image");
THROW_WALLET_EXCEPTION_IF(tx_scan_info.in_ephemeral.pub != output_public_key,
error::wallet_internal_error, "key_image generated ephemeral public key not matched with output_key");
@@ -2402,7 +2398,7 @@ bool wallet2::get_yield_summary_info(uint64_t &total_burnt,
uint64_t &total_yield,
uint64_t &yield_per_stake,
uint64_t &ybi_data_size,
std::vector<std::tuple<size_t, std::string, std::string, uint64_t, uint64_t>> &payouts
std::vector<std::tuple<size_t, std::string, uint64_t, uint64_t>> &payouts
)
{
// Get the total circulating supply of SALs
@@ -2430,17 +2426,17 @@ bool wallet2::get_yield_summary_info(uint64_t &total_burnt,
// Iterate over the transfers in our wallet
std::map<size_t, size_t> map_payouts;
std::map<std::string, std::tuple<size_t, std::string, uint64_t, uint64_t>> payouts_active;
std::map<std::string, std::pair<size_t, std::pair<uint64_t, uint64_t>>> payouts_active;
if (m_transfers.size() > 0) {
for (size_t idx = m_transfers.size()-1; idx>0; --idx) {
const tools::wallet2::transfer_details& td = m_transfers[idx];
//if (td.m_block_height < ybi_data[0].block_height) break;
if (td.m_tx.type == cryptonote::transaction_type::STAKE) {
if (td.m_tx.type == cryptonote::transaction_type::STAKE || td.m_tx.type == cryptonote::transaction_type::AUDIT) {
if (map_payouts.count(idx)) {
payouts.push_back(std::make_tuple(td.m_block_height, epee::string_tools::pod_to_hex(td.m_txid), td.asset_type, td.m_tx.amount_burnt, m_transfers[map_payouts[idx]].m_amount - td.m_tx.amount_burnt));
payouts.push_back(std::make_tuple(td.m_block_height, epee::string_tools::pod_to_hex(td.m_txid), td.m_tx.amount_burnt, m_transfers[map_payouts[idx]].m_amount - td.m_tx.amount_burnt));
} else {
//payouts.push_back(std::make_tuple(td.m_block_height, epee::string_tools::pod_to_hex(td.m_txid), td.m_tx.amount_burnt, 0));
payouts_active[epee::string_tools::pod_to_hex(td.m_txid)] = std::make_tuple(td.m_block_height, td.asset_type, td.m_tx.amount_burnt, 0);
payouts_active[epee::string_tools::pod_to_hex(td.m_txid)] = std::make_pair(td.m_block_height, std::make_pair(td.m_tx.amount_burnt, 0));
}
} else if (td.m_tx.type == cryptonote::transaction_type::PROTOCOL) {
// Store list of reverse-lookup indices to tell YIELD TXs how much they earned
@@ -2462,21 +2458,18 @@ bool wallet2::get_yield_summary_info(uint64_t &total_burnt,
// EXPERIMENTAL - add up yield earned for active STAKE TXs
for (auto &payout: payouts_active) {
auto&[height,asset_type,total_burnt,total_accrued] = payout.second;
if (ybi_data[idx].block_height < height) continue;
if (ybi_data[idx].block_height < payout.second.first) continue;
boost::multiprecision::uint128_t amount_128 = ybi_data[idx].slippage_total_this_block;
amount_128 *= total_burnt;
amount_128 *= payout.second.second.first;
amount_128 /= ybi_data[idx].locked_coins_tally;
total_accrued += amount_128.convert_to<uint64_t>();
payout.second.second.second += amount_128.convert_to<uint64_t>();
}
}
}
for (auto &payout: payouts_active) {
// Copy to the list of payouts proper
auto&[height,asset_type,total_burnt,total_accrued] = payout.second;
payouts.push_back(std::make_tuple(height, payout.first, asset_type, total_burnt, total_accrued));
payouts.push_back(std::make_tuple(payout.second.first, payout.first, payout.second.second.first, payout.second.second.second));
}
// Get the total currently locked
@@ -2900,15 +2893,14 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
crypto::public_key P_change = crypto::null_pkey;
THROW_WALLET_EXCEPTION_IF(!cryptonote::get_output_public_key(tx.vout[0], P_change), error::wallet_internal_error, "Failed to get change output public key");
//m_subaddresses[P_change] = {0x50524F54,0x4F434F4C}; /* {PROT,OCOL} - seemed like a good idea at the time, but harder to implement! */
m_subaddresses[P_change] = tx_scan_info[o].received->index;//{0,0};
//m_subaddresses[P_change] = {0,0};
m_subaddresses[P_change] = {0,0};
m_salvium_txs.insert({P_change, m_transfers.size()-1});
if (tx.type == cryptonote::transaction_type::STAKE || tx.type == cryptonote::transaction_type::AUDIT) {
// Additionally, with STAKE and AUDIT TXs, we need to update our "balance staked" subtotal, because otherwise our balance is out by the staked coins until they mature!
// SRCG: must remember to deduct the number of staked coins when they mature!!
LOG_PRINT_L1("***** STAKED/AUDITED COINS : " << tx.amount_burnt << " *****");
m_locked_coins.insert({P_change, {0, tx.amount_burnt, tx.source_asset_type}});
m_locked_coins.insert({P_change, {0, tx.amount_burnt}});
}
} else if (tx.type == cryptonote::transaction_type::TRANSFER) {
@@ -7029,12 +7021,10 @@ uint64_t wallet2::balance(uint32_t index_major, const std::string& asset_type, b
uint64_t amount = 0;
for (const auto& i : balance_per_subaddress(index_major, asset_type, strict))
amount += i.second;
// Iterate over the locked coins, adding them to the _locked_ balance
for (const auto& i : m_locked_coins) {
if (index_major == 0 && asset_type == i.second.m_asset_type) {
if (index_major == 0 && asset_type == "SAL") {
// Iterate over the locked coins, adding them to the _locked_ balance
for (const auto& i : m_locked_coins)
amount += i.second.m_amount;
}
}
return amount;
}
@@ -10133,13 +10123,9 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry
THROW_WALLET_EXCEPTION_IF(found_money < needed_money, error::not_enough_unlocked_money, found_money, needed_money - fee, fee);
uint32_t subaddr_account = m_transfers[*selected_transfers.begin()].m_subaddr_index.major;
uint32_t subaddr_index = m_transfers[*selected_transfers.begin()].m_subaddr_index.minor;
for (auto i = ++selected_transfers.begin(); i != selected_transfers.end(); ++i) {
for (auto i = ++selected_transfers.begin(); i != selected_transfers.end(); ++i)
THROW_WALLET_EXCEPTION_IF(subaddr_account != m_transfers[*i].m_subaddr_index.major, error::wallet_internal_error, "the tx uses funds from multiple accounts");
if (tx_type == cryptonote::transaction_type::AUDIT) {
THROW_WALLET_EXCEPTION_IF(subaddr_index != m_transfers[*i].m_subaddr_index.minor, error::wallet_internal_error, "the AUDIT tx uses funds from multiple subaddresses");
}
}
if (outs.empty())
get_outs(outs, selected_transfers, fake_outputs_count, all_rct, valid_public_keys_cache); // may throw
@@ -10226,18 +10212,11 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry
cryptonote::tx_destination_entry change_dts = AUTO_VAL_INIT(change_dts);
change_dts.amount = found_money - needed_money;
change_dts.asset_type = source_asset;
change_dts.addr = get_subaddress({subaddr_account, subaddr_index});
change_dts.is_subaddress = subaddr_account != 0 || subaddr_index != 0;
change_dts.addr = get_subaddress({subaddr_account, 0});
change_dts.is_subaddress = subaddr_account != 0;
change_dts.is_change = true;
splitted_dsts.push_back(change_dts);
account_keys a_keys = m_account.get_keys();
// SRCG: add support for auditing of subaddresses
if (tx_type == cryptonote::transaction_type::AUDIT && (subaddr_account != 0 || subaddr_index != 0)) {
// Overwrite the public spend key and view key
a_keys.m_account_address = get_subaddress({subaddr_account, subaddr_index});
}
crypto::secret_key tx_key;
std::vector<crypto::secret_key> additional_tx_keys;
crypto::secret_key multisig_tx_key_entropy;
@@ -10281,7 +10260,7 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry
std::vector<std::pair<std::string, std::string>> circ_amounts;
THROW_WALLET_EXCEPTION_IF(!get_circulating_supply(circ_amounts), error::wallet_internal_error, "Failed to get circulating supply");
// make a normal tx
bool r = cryptonote::construct_tx_and_get_tx_key(a_keys/*m_account.get_keys()*/, m_subaddresses, sources, splitted_dsts, hf_version, source_asset, dest_asset, tx_type, change_dts.addr, extra, tx, unlock_time, tx_key, additional_tx_keys, true, rct_config, use_view_tags);
bool r = cryptonote::construct_tx_and_get_tx_key(m_account.get_keys(), m_subaddresses, sources, splitted_dsts, hf_version, source_asset, dest_asset, tx_type, change_dts.addr, extra, tx, unlock_time, tx_key, additional_tx_keys, true, rct_config, use_view_tags);
LOG_PRINT_L2("constructed tx, r="<<r);
THROW_WALLET_EXCEPTION_IF(!r, error::tx_not_constructed, sources, dsts, unlock_time, m_nettype);
}
@@ -11510,7 +11489,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_single(const crypt
std::vector<wallet2::pending_tx> wallet2::create_transactions_return(std::vector<size_t> transfers_indices)
{
// Get the asset_type and associated information
THROW_WALLET_EXCEPTION_IF(transfers_indices.empty() || transfers_indices.size()>15, error::wallet_internal_error, tr("Incorrect number of transfers_indices on return_payment"));
THROW_WALLET_EXCEPTION_IF(transfers_indices.empty() || transfers_indices.size()>1, error::wallet_internal_error, tr("Incorrect number of transfers_indices on return_payment"));
size_t idx = transfers_indices[0];
THROW_WALLET_EXCEPTION_IF(idx >= get_num_transfer_details(), error::wallet_internal_error, tr("cannot locate return_payment origin index in m_transfers"));
const transfer_details& td_origin = get_transfer_details(idx);
@@ -11523,14 +11502,6 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_return(std::vector
uint32_t priority = adjust_priority(0);
std::vector<uint8_t> extra; // No need for a TX extra beyond that which will be calculated herein
// Verify that all the indices share an origin
for (const auto &td_idx : transfers_indices) {
THROW_WALLET_EXCEPTION_IF(td_idx >= get_num_transfer_details(), error::wallet_internal_error, tr("cannot locate return_payment origin index in m_transfers"));
const transfer_details &td = get_transfer_details(td_idx);
THROW_WALLET_EXCEPTION_IF(td.m_txid != td_origin.m_txid, error::wallet_internal_error, tr("TX hashes do not match for inputs to return_payment"));
THROW_WALLET_EXCEPTION_IF(td.asset_type != td_origin.asset_type, error::wallet_internal_error, tr("TX asset_type values do not match for inputs to return_payment"));
}
// To return a payment, we need to know the y value to process the F value
// ...but the y value is calculated differently depending on the original TX
ec_scalar y;
@@ -11744,11 +11715,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton
// SRCG: should the subaddress be forced to TRUE for _RETURN_ TXs and FALSE for all others?!?!?
// add N - 1 outputs for correct initial fee estimation
for (size_t i = 0; i < ((outputs > 1) ? outputs - 1 : outputs); ++i) {
if (tx_type == cryptonote::transaction_type::AUDIT) {
tx.dsts.push_back(tx_destination_entry(1, address, tx_type == cryptonote::transaction_type::RETURN, tx_type == cryptonote::transaction_type::RETURN));
} else {
tx.dsts.push_back(tx_destination_entry(1, address, tx_type == cryptonote::transaction_type::RETURN, tx_type == cryptonote::transaction_type::RETURN));
}
tx.dsts.push_back(tx_destination_entry(1, address, tx_type == cryptonote::transaction_type::RETURN, tx_type == cryptonote::transaction_type::RETURN));
tx.dsts.back().asset_type = asset_type;
}
@@ -12613,11 +12580,13 @@ void wallet2::check_tx_key_helper(const cryptonote::transaction &tx, const crypt
}
}
// HERE BE DRAGONS!!!
// SRCG: if this returns 0 received, but it's an AUDIT TX, then that is EXPECTED
bool audit = (tx.rct_signatures.type == rct::RCTTypeSalviumOne && tx.rct_signatures.salvium_data.salvium_data_type == rct::SalviumAudit);
if (audit && received == 0) {
received += tx.amount_burnt;
}
// LAND AHOY!!!
}
void wallet2::check_tx_key_helper(const crypto::hash &txid, const crypto::key_derivation &derivation, const std::vector<crypto::key_derivation> &additional_derivations, const cryptonote::account_public_address &address, uint64_t &received, bool &in_pool, uint64_t &confirmations)
@@ -12871,8 +12840,10 @@ std::string wallet2::get_tx_proof(const cryptonote::transaction &tx, const crypt
THROW_WALLET_EXCEPTION_IF(!crypto::generate_key_derivation(shared_secret[i], rct::rct2sk(rct::I), additional_derivations[i - 1]), error::wallet_internal_error, "Failed to generate key derivation");
uint64_t received;
check_tx_key_helper(tx, derivation, additional_derivations, address, received);
// HERE BE DRAGONS!!!
// SRCG: if this returns 0 received, but it's an AUDIT TX, then that is EXPECTED
THROW_WALLET_EXCEPTION_IF(!received, error::wallet_internal_error, tr("No funds received in this tx."));
// LAND AHOY!!!
// concatenate all signature strings
for (size_t i = 0; i < num_sigs; ++i)
+1 -4
View File
@@ -486,13 +486,11 @@ private:
{
uint32_t m_index_major;
uint64_t m_amount;
std::string m_asset_type;
BEGIN_SERIALIZE_OBJECT()
VERSION_FIELD(0)
VARINT_FIELD(m_index_major)
VARINT_FIELD(m_amount)
FIELD(m_asset_type)
END_SERIALIZE()
};
@@ -1757,7 +1755,7 @@ private:
uint64_t &total_yield,
uint64_t &yield_per_stake,
uint64_t &ybi_data_size,
std::vector<std::tuple<size_t, std::string, std::string, uint64_t, uint64_t>> &payouts
std::vector<std::tuple<size_t, std::string, uint64_t, uint64_t>> &payouts
);
private:
@@ -2367,7 +2365,6 @@ namespace boost
{
a & x.m_index_major;
a & x.m_amount;
a & x.m_asset_type;
}
template <class Archive>
-71
View File
@@ -1093,77 +1093,6 @@ namespace tools
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
bool wallet_rpc_server::on_audit(const wallet_rpc::COMMAND_RPC_AUDIT::request& req, wallet_rpc::COMMAND_RPC_AUDIT::response& res, epee::json_rpc::error& er, const connection_context *ctx)
{
std::vector<cryptonote::tx_destination_entry> dsts;
std::vector<uint8_t> extra;
if (!m_wallet) return not_open(er);
if (m_restricted)
{
er.code = WALLET_RPC_ERROR_CODE_DENIED;
er.message = "Command unavailable in restricted mode.";
return false;
}
CHECK_MULTISIG_ENABLED();
std::string asset_type = req.asset_type.empty() ? "SAL" : req.asset_type;
// validate the transfer requested and populate dsts & extra
std::list<wallet_rpc::transfer_destination> destinations;
destinations.push_back(wallet_rpc::transfer_destination());
destinations.back().amount = 0;
destinations.back().address = req.address;
destinations.back().asset_type = asset_type;
// validate the transfer requested and populate dsts & extra
if (!validate_transfer(destinations, asset_type, asset_type, cryptonote::transaction_type::AUDIT, req.payment_id, dsts, extra, true, er))
{
return false;
}
std::set<uint32_t> subaddr_indices;
if (req.subaddr_indices_all)
{
for (uint32_t i = 0; i < m_wallet->get_num_subaddresses(req.account_index); ++i)
subaddr_indices.insert(i);
}
else
{
subaddr_indices= req.subaddr_indices;
}
try
{
std::vector<wallet2::pending_tx> ptx_vector_all;
// Get the subaddress unlocked balances
std::map<uint32_t, std::pair<uint64_t, std::pair<uint64_t, uint64_t>>> unlocked_balance_per_subaddr = m_wallet->unlocked_balance_per_subaddress(req.account_index, asset_type, true);
for (const auto subaddr_index : subaddr_indices) {
// Skip this wallet if there is no balance unlocked to audit
if (unlocked_balance_per_subaddr.count(subaddr_index) == 0) continue;
std::set<uint32_t> subaddr_indices_single;
subaddr_indices_single.insert(subaddr_index);
uint64_t mixin = m_wallet->adjust_mixin(req.ring_size ? req.ring_size - 1 : 0);
uint32_t priority = m_wallet->adjust_priority(0);
uint64_t unlock_block = get_config(m_wallet->nettype()).AUDIT_LOCK_PERIOD;
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_all(0, cryptonote::transaction_type::AUDIT, asset_type, m_wallet->get_subaddress({req.account_index, subaddr_index}), (subaddr_index > 0), 1, mixin, unlock_block, priority, extra, req.account_index, subaddr_indices_single);
ptx_vector_all.insert(ptx_vector_all.end(), ptx_vector.begin(), ptx_vector.end());
}
return fill_response(ptx_vector_all, req.get_tx_keys, res.tx_key_list, res.amount_list, res.amounts_by_dest_list, res.fee_list, res.weight_list, res.multisig_txset, res.unsigned_txset, req.do_not_relay,
res.tx_hash_list, req.get_tx_hex, res.tx_blob_list, req.get_tx_metadata, res.tx_metadata_list, res.spent_key_images_list, er);
}
catch (const std::exception& e)
{
handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR);
return false;
}
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
bool wallet_rpc_server::on_transfer(const wallet_rpc::COMMAND_RPC_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_TRANSFER::response& res, epee::json_rpc::error& er, const connection_context *ctx)
{
-2
View File
@@ -87,7 +87,6 @@ namespace tools
MAP_JON_RPC_WE("freeze", on_freeze, wallet_rpc::COMMAND_RPC_FREEZE)
MAP_JON_RPC_WE("thaw", on_thaw, wallet_rpc::COMMAND_RPC_THAW)
MAP_JON_RPC_WE("frozen", on_frozen, wallet_rpc::COMMAND_RPC_FROZEN)
MAP_JON_RPC_WE("audit", on_audit, wallet_rpc::COMMAND_RPC_AUDIT)
MAP_JON_RPC_WE("transfer", on_transfer, wallet_rpc::COMMAND_RPC_TRANSFER)
MAP_JON_RPC_WE("transfer_split", on_transfer_split, wallet_rpc::COMMAND_RPC_TRANSFER_SPLIT)
MAP_JON_RPC_WE("sign_transfer", on_sign_transfer, wallet_rpc::COMMAND_RPC_SIGN_TRANSFER)
@@ -181,7 +180,6 @@ namespace tools
bool on_freeze(const wallet_rpc::COMMAND_RPC_FREEZE::request& req, wallet_rpc::COMMAND_RPC_FREEZE::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_thaw(const wallet_rpc::COMMAND_RPC_THAW::request& req, wallet_rpc::COMMAND_RPC_THAW::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_frozen(const wallet_rpc::COMMAND_RPC_FROZEN::request& req, wallet_rpc::COMMAND_RPC_FROZEN::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_audit(const wallet_rpc::COMMAND_RPC_AUDIT::request& req, wallet_rpc::COMMAND_RPC_AUDIT::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_transfer(const wallet_rpc::COMMAND_RPC_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_TRANSFER::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_transfer_split(const wallet_rpc::COMMAND_RPC_TRANSFER_SPLIT::request& req, wallet_rpc::COMMAND_RPC_TRANSFER_SPLIT::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_sign_transfer(const wallet_rpc::COMMAND_RPC_SIGN_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_SIGN_TRANSFER::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
@@ -864,42 +864,6 @@ namespace wallet_rpc
typedef epee::misc_utils::struct_init<response_t> response;
};
struct COMMAND_RPC_AUDIT
{
struct request_t
{
std::string address;
uint32_t account_index;
std::set<uint32_t> subaddr_indices;
bool subaddr_indices_all;
uint64_t ring_size;
std::string payment_id;
bool get_tx_keys;
bool do_not_relay;
bool get_tx_hex;
bool get_tx_metadata;
std::string asset_type;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(address)
KV_SERIALIZE(account_index)
KV_SERIALIZE(subaddr_indices)
KV_SERIALIZE_OPT(subaddr_indices_all, false)
KV_SERIALIZE_OPT(ring_size, (uint64_t)0)
KV_SERIALIZE(payment_id)
KV_SERIALIZE(get_tx_keys)
KV_SERIALIZE_OPT(do_not_relay, false)
KV_SERIALIZE_OPT(get_tx_hex, false)
KV_SERIALIZE_OPT(get_tx_metadata, false)
KV_SERIALIZE(asset_type)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<request_t> request;
typedef split_transfer_response response_t;
typedef epee::misc_utils::struct_init<response_t> response;
};
struct COMMAND_RPC_SWEEP_ALL
{
struct request_t
+2 -6
View File
@@ -69,10 +69,8 @@ public:
, const crypto::hash& blk_hash
, uint64_t slippage_total
, uint64_t yield_total
, uint64_t audit_total
, const cryptonote::network_type nettype
, cryptonote::yield_block_info& ybi
, cryptonote::audit_block_info& abi
) override {
blocks.push_back({block_weight, long_term_block_weight});
}
@@ -154,9 +152,8 @@ static void test(test_t t, uint64_t blocks)
cryptonote::block b;
b.major_version = 1;
b.minor_version = 1;
cryptonote::audit_block_info abi;
cryptonote::yield_block_info ybi;
bc->get_db().add_block(std::make_pair(b, ""), 300000, 300000, bc->get_db().height(), bc->get_db().height(), {}, cryptonote::FAKECHAIN, ybi, abi);
bc->get_db().add_block(std::make_pair(b, ""), 300000, 300000, bc->get_db().height(), bc->get_db().height(), {}, cryptonote::FAKECHAIN, ybi);
if (!bc->update_next_cumulative_weight_limit())
{
fprintf(stderr, "Failed to update cumulative weight limit 1\n");
@@ -190,9 +187,8 @@ static void test(test_t t, uint64_t blocks)
cryptonote::block b;
b.major_version = HF_VERSION_2021_SCALING;
b.minor_version = HF_VERSION_2021_SCALING;
cryptonote::audit_block_info abi;
cryptonote::yield_block_info ybi;
bc->get_db().add_block(std::make_pair(std::move(b), ""), w, ltw, bc->get_db().height(), bc->get_db().height(), {}, cryptonote::FAKECHAIN, ybi, abi);
bc->get_db().add_block(std::make_pair(std::move(b), ""), w, ltw, bc->get_db().height(), bc->get_db().height(), {}, cryptonote::FAKECHAIN, ybi);
if (!bc->update_next_cumulative_weight_limit())
{
+3 -7
View File
@@ -91,10 +91,8 @@ namespace
const crypto::hash& blk_hash,
uint64_t slippage_total,
uint64_t yield_total,
uint64_t audit_total,
const cryptonote::network_type nettype,
cryptonote::yield_block_info& ybi,
cryptonote::audit_block_info& abi
cryptonote::yield_block_info& ybi
) override
{
blocks.push_back({blk, blk_hash});
@@ -180,8 +178,7 @@ static std::unique_ptr<cryptonote::BlockchainAndPool> init_blockchain(const std:
auto blk_hash = get_block_hash(*blk);
oracle::asset_type_counts num_rct_outs_by_asset_type;
cryptonote::yield_block_info ybi;
cryptonote::audit_block_info abi;
bdb->add_block(*blk, 1, 1, 1, 0, 0, num_rct_outs_by_asset_type, blk_hash, 0, 0, 0, cryptonote::FAKECHAIN, ybi, abi);
bdb->add_block(*blk, 1, 1, 1, 0, 0, num_rct_outs_by_asset_type, blk_hash, 0, 0, cryptonote::FAKECHAIN, ybi);
}
bool r = bap->blockchain.init(bdb, nettype, true, test_options, 2, nullptr);
@@ -495,8 +492,7 @@ bool init_spent_output_indices(map_output_idx_t& outs, map_output_t& outs_mine,
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
subaddresses[from.get_keys().m_account_address.m_spend_public_key] = {0,0};
cryptonote::origin_data od{3, crypto::null_pkey, 0};
rct::salvium_input_data_t sid;
generate_key_image_helper(from.get_keys(), subaddresses, out_key, get_tx_pub_key_from_extra(*oi.p_tx), get_additional_tx_pub_keys_from_extra(*oi.p_tx), oi.out_no, in_ephemeral, img, hw::get_device(("default")), false, od, sid);
generate_key_image_helper(from.get_keys(), subaddresses, out_key, get_tx_pub_key_from_extra(*oi.p_tx), get_additional_tx_pub_keys_from_extra(*oi.p_tx), oi.out_no, in_ephemeral, img, hw::get_device(("default")), false, od);
// lookup for this key image in the events vector
BOOST_FOREACH(auto& tx_pair, mtx) {
+2 -3
View File
@@ -246,7 +246,6 @@ bool gen_multisig_tx_validation_base::generate_with(std::vector<test_event_entry
std::vector<rct::multisig_kLRki> kLRkis;
std::unordered_set<crypto::public_key> used_L;
const cryptonote::origin_data origin_tx_data{3,crypto::null_pkey, 0};
rct::salvium_input_data_t sid;
for (size_t tdidx = 0; tdidx < inputs; ++tdidx)
{
kLRkis.push_back(rct::multisig_kLRki());
@@ -255,13 +254,13 @@ bool gen_multisig_tx_validation_base::generate_with(std::vector<test_event_entry
for (size_t msidx = 0; msidx < total; ++msidx)
for (size_t n = 0; n < account_ki[msidx][tdidx].size(); ++n)
pkis.push_back(account_ki[msidx][tdidx][n]);
r = multisig::generate_multisig_composite_key_image(miner_account[0].get_keys(), subaddresses, output_pub_key[tdidx], tx_pub_key[tdidx], additional_tx_keys, 0, pkis, (crypto::key_image&)kLRki.ki, false, origin_tx_data, sid);
r = multisig::generate_multisig_composite_key_image(miner_account[0].get_keys(), subaddresses, output_pub_key[tdidx], tx_pub_key[tdidx], additional_tx_keys, 0, pkis, (crypto::key_image&)kLRki.ki, false, origin_tx_data);
CHECK_AND_ASSERT_MES(r, false, "Failed to generate composite key image");
MDEBUG("composite ki: " << kLRki.ki);
for (size_t n = 1; n < total; ++n)
{
rct::key ki;
r = multisig::generate_multisig_composite_key_image(miner_account[n].get_keys(), subaddresses, output_pub_key[tdidx], tx_pub_key[tdidx], additional_tx_keys, 0, pkis, (crypto::key_image&)ki, false, origin_tx_data, sid);
r = multisig::generate_multisig_composite_key_image(miner_account[n].get_keys(), subaddresses, output_pub_key[tdidx], tx_pub_key[tdidx], additional_tx_keys, 0, pkis, (crypto::key_image&)ki, false, origin_tx_data);
CHECK_AND_ASSERT_MES(r, false, "Failed to generate composite key image");
CHECK_AND_ASSERT_MES(kLRki.ki == ki, false, "Composite key images do not match");
}
+1 -2
View File
@@ -63,9 +63,8 @@ namespace
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
subaddresses[sender_account_keys.m_account_address.m_spend_public_key] = {0,0};
auto& out_key = reinterpret_cast<const crypto::public_key&>(src_entr.outputs[src_entr.real_output].second.dest);
rct::salvium_input_data_t sid;
const cryptonote::origin_data od{3, crypto::null_pkey, src_entr.real_output};
generate_key_image_helper(sender_account_keys, subaddresses, out_key, src_entr.real_out_tx_key, src_entr.real_out_additional_tx_keys, src_entr.real_output_in_tx_index, in_ephemeral, img, hw::get_device(("default")), false, od, sid);
generate_key_image_helper(sender_account_keys, subaddresses, out_key, src_entr.real_out_tx_key, src_entr.real_out_additional_tx_keys, src_entr.real_output_in_tx_index, in_ephemeral, img, hw::get_device(("default")), false, od);
// put key image into tx input
txin_to_key input_to_key;
@@ -50,7 +50,6 @@ public:
subaddresses[m_bob.get_keys().m_account_address.m_spend_public_key] = {0,0};
crypto::public_key out_key = boost::get<cryptonote::txout_to_key>(m_tx.vout[0].target).key;
cryptonote::origin_data od{3,crypto::null_pkey,0};
rct::salvium_input_data_t sid;
return cryptonote::generate_key_image_helper(m_bob.get_keys(), subaddresses, out_key, m_tx_pub_key, m_additional_tx_pub_keys, 0, in_ephemeral, ki, hw::get_device("default"), false, od, sid);
return cryptonote::generate_key_image_helper(m_bob.get_keys(), subaddresses, out_key, m_tx_pub_key, m_additional_tx_pub_keys, 0, in_ephemeral, ki, hw::get_device("default"), false, od);
}
};
+5 -7
View File
@@ -274,10 +274,9 @@ TYPED_TEST(BlockchainDBTest, AddBlock)
// no blocks have been added yet (because genesis has no parent).
//ASSERT_THROW(this->m_db->add_block(this->m_blocks[1], t_sizes[1], t_sizes[1], t_diffs[1], t_coins[1], this->m_txs[1]), BLOCK_PARENT_DNE);
cryptonote::audit_block_info abi;
cryptonote::yield_block_info ybi;
ASSERT_NO_THROW(this->m_db->add_block(this->m_blocks[0], t_sizes[0], t_sizes[0], t_diffs[0], t_coins[0], this->m_txs[0], cryptonote::FAKECHAIN, ybi, abi));
ASSERT_NO_THROW(this->m_db->add_block(this->m_blocks[1], t_sizes[1], t_sizes[1], t_diffs[1], t_coins[1], this->m_txs[1], cryptonote::FAKECHAIN, ybi, abi));
ASSERT_NO_THROW(this->m_db->add_block(this->m_blocks[0], t_sizes[0], t_sizes[0], t_diffs[0], t_coins[0], this->m_txs[0], cryptonote::FAKECHAIN, ybi));
ASSERT_NO_THROW(this->m_db->add_block(this->m_blocks[1], t_sizes[1], t_sizes[1], t_diffs[1], t_coins[1], this->m_txs[1], cryptonote::FAKECHAIN, ybi));
block b;
ASSERT_TRUE(this->m_db->block_exists(get_block_hash(this->m_blocks[0].first)));
@@ -290,7 +289,7 @@ TYPED_TEST(BlockchainDBTest, AddBlock)
ASSERT_TRUE(compare_blocks(this->m_blocks[0].first, b));
// assert that we can't add the same block twice
ASSERT_THROW(this->m_db->add_block(this->m_blocks[0], t_sizes[0], t_sizes[0], t_diffs[0], t_coins[0], this->m_txs[0], cryptonote::FAKECHAIN, ybi, abi), TX_EXISTS);
ASSERT_THROW(this->m_db->add_block(this->m_blocks[0], t_sizes[0], t_sizes[0], t_diffs[0], t_coins[0], this->m_txs[0], cryptonote::FAKECHAIN, ybi), TX_EXISTS);
for (auto& h : this->m_blocks[0].first.tx_hashes)
{
@@ -316,16 +315,15 @@ TYPED_TEST(BlockchainDBTest, RetrieveBlockData)
db_wtxn_guard guard(this->m_db);
cryptonote::audit_block_info abi;
cryptonote::yield_block_info ybi;
ASSERT_NO_THROW(this->m_db->add_block(this->m_blocks[0], t_sizes[0], t_sizes[0], t_diffs[0], t_coins[0], this->m_txs[0], cryptonote::FAKECHAIN, ybi, abi));
ASSERT_NO_THROW(this->m_db->add_block(this->m_blocks[0], t_sizes[0], t_sizes[0], t_diffs[0], t_coins[0], this->m_txs[0], cryptonote::FAKECHAIN, ybi));
ASSERT_EQ(t_sizes[0], this->m_db->get_block_weight(0));
ASSERT_EQ(t_diffs[0], this->m_db->get_block_cumulative_difficulty(0));
ASSERT_EQ(t_diffs[0], this->m_db->get_block_difficulty(0));
ASSERT_EQ(t_coins[0], this->m_db->get_block_already_generated_coins(0));
ASSERT_NO_THROW(this->m_db->add_block(this->m_blocks[1], t_sizes[1], t_sizes[1], t_diffs[1], t_coins[1], this->m_txs[1], cryptonote::FAKECHAIN, ybi, abi));
ASSERT_NO_THROW(this->m_db->add_block(this->m_blocks[1], t_sizes[1], t_sizes[1], t_diffs[1], t_coins[1], this->m_txs[1], cryptonote::FAKECHAIN, ybi));
ASSERT_EQ(t_diffs[1] - t_diffs[0], this->m_db->get_block_difficulty(1));
ASSERT_HASH_EQ(get_block_hash(this->m_blocks[0].first), this->m_db->get_block_hash_from_height(0));
+1 -2
View File
@@ -138,8 +138,7 @@ TEST(bulletproofs, multi_splitting)
for (size_t i = 0; i < destinations.size(); ++i)
destination_asset_types.push_back("SAL");
rct::salvium_data_t salvium_data;
rct::rctSig s = rct::genRctSimple(rct::zero(), sc, destinations, tx_type, in_asset_type, destination_asset_types, inamounts, outamounts, available, mixRing, amount_keys, index, outSk, rct_config, hw::get_device("default"), salvium_data);
rct::rctSig s = rct::genRctSimple(rct::zero(), sc, destinations, tx_type, in_asset_type, destination_asset_types, inamounts, outamounts, available, mixRing, amount_keys, index, outSk, rct_config, hw::get_device("default"));
ASSERT_TRUE(rct::verRctSimple(s));
for (size_t i = 0; i < n_outputs; ++i)
{
+18 -32
View File
@@ -57,10 +57,8 @@ public:
, const crypto::hash& blk_hash
, uint64_t slippage_total
, uint64_t yield_total
, uint64_t audit_total
, const cryptonote::network_type nettype
, cryptonote::yield_block_info& ybi
, cryptonote::audit_block_info& abi
) override {
blocks.push_back(blk);
}
@@ -105,7 +103,6 @@ TEST(major, Only)
TestDB db;
HardFork hf(db, 1, 0, 0, 0, 1, 0); // no voting
oracle::asset_type_counts num_rct_outs_by_asset_type;
cryptonote::audit_block_info abi;
cryptonote::yield_block_info ybi;
// v h t
@@ -117,20 +114,20 @@ TEST(major, Only)
ASSERT_FALSE(hf.add(mkblock(0, 2), 0));
ASSERT_FALSE(hf.add(mkblock(2, 2), 0));
ASSERT_TRUE(hf.add(mkblock(1, 2), 0));
db.add_block(mkblock(1, 1), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, 0, cryptonote::FAKECHAIN, ybi, abi);
db.add_block(mkblock(1, 1), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, cryptonote::FAKECHAIN, ybi);
// block height 1, only version 1 is accepted
ASSERT_FALSE(hf.add(mkblock(0, 2), 1));
ASSERT_FALSE(hf.add(mkblock(2, 2), 1));
ASSERT_TRUE(hf.add(mkblock(1, 2), 1));
db.add_block(mkblock(1, 1), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, 0, cryptonote::FAKECHAIN, ybi, abi);
db.add_block(mkblock(1, 1), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, cryptonote::FAKECHAIN, ybi);
// block height 2, only version 2 is accepted
ASSERT_FALSE(hf.add(mkblock(0, 2), 2));
ASSERT_FALSE(hf.add(mkblock(1, 2), 2));
ASSERT_FALSE(hf.add(mkblock(3, 2), 2));
ASSERT_TRUE(hf.add(mkblock(2, 2), 2));
db.add_block(mkblock(2, 1), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, 0, cryptonote::FAKECHAIN, ybi, abi);
db.add_block(mkblock(2, 1), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, cryptonote::FAKECHAIN, ybi);
}
TEST(empty_hardforks, Success)
@@ -138,7 +135,6 @@ TEST(empty_hardforks, Success)
TestDB db;
HardFork hf(db);
oracle::asset_type_counts num_rct_outs_by_asset_type;
cryptonote::audit_block_info abi;
cryptonote::yield_block_info ybi;
ASSERT_TRUE(hf.add_fork(1, 0, 0));
@@ -147,7 +143,7 @@ TEST(empty_hardforks, Success)
ASSERT_TRUE(hf.get_state(time(NULL) + 3600*24*400) == HardFork::Ready);
for (uint64_t h = 0; h <= 10; ++h) {
db.add_block(mkblock(hf, h, 1), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, 0, cryptonote::FAKECHAIN, ybi, abi);
db.add_block(mkblock(hf, h, 1), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, cryptonote::FAKECHAIN, ybi);
ASSERT_TRUE(hf.add(db.get_block_from_height(h), h));
}
ASSERT_EQ(hf.get(0), 1);
@@ -174,7 +170,6 @@ TEST(check_for_height, Success)
TestDB db;
HardFork hf(db, 1, 0, 0, 0, 1, 0); // no voting
oracle::asset_type_counts num_rct_outs_by_asset_type;
cryptonote::audit_block_info abi;
cryptonote::yield_block_info ybi;
ASSERT_TRUE(hf.add_fork(1, 0, 0));
@@ -184,14 +179,14 @@ TEST(check_for_height, Success)
for (uint64_t h = 0; h <= 4; ++h) {
ASSERT_TRUE(hf.check_for_height(mkblock(1, 1), h));
ASSERT_FALSE(hf.check_for_height(mkblock(2, 2), h)); // block version is too high
db.add_block(mkblock(hf, h, 1), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, 0, cryptonote::FAKECHAIN, ybi, abi);
db.add_block(mkblock(hf, h, 1), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, cryptonote::FAKECHAIN, ybi);
ASSERT_TRUE(hf.add(db.get_block_from_height(h), h));
}
for (uint64_t h = 5; h <= 10; ++h) {
ASSERT_FALSE(hf.check_for_height(mkblock(1, 1), h)); // block version is too low
ASSERT_TRUE(hf.check_for_height(mkblock(2, 2), h));
db.add_block(mkblock(hf, h, 2), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, 0, cryptonote::FAKECHAIN, ybi, abi);
db.add_block(mkblock(hf, h, 2), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, cryptonote::FAKECHAIN, ybi);
ASSERT_TRUE(hf.add(db.get_block_from_height(h), h));
}
}
@@ -201,7 +196,6 @@ TEST(get, next_version)
TestDB db;
HardFork hf(db);
oracle::asset_type_counts num_rct_outs_by_asset_type;
cryptonote::audit_block_info abi;
cryptonote::yield_block_info ybi;
ASSERT_TRUE(hf.add_fork(1, 0, 0));
@@ -211,19 +205,19 @@ TEST(get, next_version)
for (uint64_t h = 0; h <= 4; ++h) {
ASSERT_EQ(2, hf.get_next_version());
db.add_block(mkblock(hf, h, 1), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, 0, cryptonote::FAKECHAIN, ybi, abi);
db.add_block(mkblock(hf, h, 1), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, cryptonote::FAKECHAIN, ybi);
ASSERT_TRUE(hf.add(db.get_block_from_height(h), h));
}
for (uint64_t h = 5; h <= 9; ++h) {
ASSERT_EQ(4, hf.get_next_version());
db.add_block(mkblock(hf, h, 2), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, 0, cryptonote::FAKECHAIN, ybi, abi);
db.add_block(mkblock(hf, h, 2), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, cryptonote::FAKECHAIN, ybi);
ASSERT_TRUE(hf.add(db.get_block_from_height(h), h));
}
for (uint64_t h = 10; h <= 15; ++h) {
ASSERT_EQ(4, hf.get_next_version());
db.add_block(mkblock(hf, h, 4), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, 0, cryptonote::FAKECHAIN, ybi, abi);
db.add_block(mkblock(hf, h, 4), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, cryptonote::FAKECHAIN, ybi);
ASSERT_TRUE(hf.add(db.get_block_from_height(h), h));
}
}
@@ -257,7 +251,6 @@ TEST(steps_asap, Success)
TestDB db;
HardFork hf(db, 1,0,1,1,1);
oracle::asset_type_counts num_rct_outs_by_asset_type;
cryptonote::audit_block_info abi;
cryptonote::yield_block_info ybi;
// v h t
@@ -268,7 +261,7 @@ TEST(steps_asap, Success)
hf.init();
for (uint64_t h = 0; h < 10; ++h) {
db.add_block(mkblock(hf, h, 9), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, 0, cryptonote::FAKECHAIN, ybi, abi);
db.add_block(mkblock(hf, h, 9), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, cryptonote::FAKECHAIN, ybi);
ASSERT_TRUE(hf.add(db.get_block_from_height(h), h));
}
@@ -289,7 +282,6 @@ TEST(steps_1, Success)
TestDB db;
HardFork hf(db, 1,0,1,1,1);
oracle::asset_type_counts num_rct_outs_by_asset_type;
cryptonote::audit_block_info abi;
cryptonote::yield_block_info ybi;
ASSERT_TRUE(hf.add_fork(1, 0, 0));
@@ -298,7 +290,7 @@ TEST(steps_1, Success)
hf.init();
for (uint64_t h = 0 ; h < 10; ++h) {
db.add_block(mkblock(hf, h, h+1), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, 0, cryptonote::FAKECHAIN, ybi, abi);
db.add_block(mkblock(hf, h, h+1), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, cryptonote::FAKECHAIN, ybi);
ASSERT_TRUE(hf.add(db.get_block_from_height(h), h));
}
@@ -313,7 +305,6 @@ TEST(reorganize, Same)
TestDB db;
HardFork hf(db, 1, 0, 1, 1, history, 100);
oracle::asset_type_counts num_rct_outs_by_asset_type;
cryptonote::audit_block_info abi;
cryptonote::yield_block_info ybi;
// v h t
@@ -326,7 +317,7 @@ TEST(reorganize, Same)
// index 0 1 2 3 4 5 6 7 8 9
static const uint8_t block_versions[] = { 1, 1, 4, 4, 7, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };
for (uint64_t h = 0; h < 20; ++h) {
db.add_block(mkblock(hf, h, block_versions[h]), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, 0, cryptonote::FAKECHAIN, ybi, abi);
db.add_block(mkblock(hf, h, block_versions[h]), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, cryptonote::FAKECHAIN, ybi);
ASSERT_TRUE(hf.add(db.get_block_from_height(h), h));
}
@@ -345,7 +336,6 @@ TEST(reorganize, Changed)
TestDB db;
HardFork hf(db, 1, 0, 1, 1, 4, 100);
oracle::asset_type_counts num_rct_outs_by_asset_type;
cryptonote::audit_block_info abi;
cryptonote::yield_block_info ybi;
// v h t
@@ -360,7 +350,7 @@ TEST(reorganize, Changed)
static const uint8_t block_versions[] = { 1, 1, 4, 4, 7, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };
static const uint8_t expected_versions[] = { 1, 1, 1, 1, 1, 1, 4, 4, 7, 7, 9, 9, 9, 9, 9, 9 };
for (uint64_t h = 0; h < 16; ++h) {
db.add_block(mkblock(hf, h, block_versions[h]), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, 0, cryptonote::FAKECHAIN, ybi, abi);
db.add_block(mkblock(hf, h, block_versions[h]), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, cryptonote::FAKECHAIN, ybi);
ASSERT_TRUE (hf.add(db.get_block_from_height(h), h));
}
@@ -380,7 +370,7 @@ TEST(reorganize, Changed)
ASSERT_EQ(db.height(), 3);
hf.reorganize_from_block_height(2);
for (uint64_t h = 3; h < 16; ++h) {
db.add_block(mkblock(hf, h, block_versions_new[h]), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, 0, cryptonote::FAKECHAIN, ybi, abi);
db.add_block(mkblock(hf, h, block_versions_new[h]), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, cryptonote::FAKECHAIN, ybi);
bool ret = hf.add(db.get_block_from_height(h), h);
ASSERT_EQ (ret, h < 15);
}
@@ -394,7 +384,6 @@ TEST(reorganize, Changed)
TEST(voting, threshold)
{
oracle::asset_type_counts num_rct_outs_by_asset_type;
cryptonote::audit_block_info abi;
cryptonote::yield_block_info ybi;
for (int threshold = 87; threshold <= 88; ++threshold) {
TestDB db;
@@ -407,7 +396,7 @@ TEST(voting, threshold)
for (uint64_t h = 0; h <= 8; ++h) {
uint8_t v = 1 + !!(h % 8);
db.add_block(mkblock(hf, h, v), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, 0, cryptonote::FAKECHAIN, ybi, abi);
db.add_block(mkblock(hf, h, v), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, cryptonote::FAKECHAIN, ybi);
bool ret = hf.add(db.get_block_from_height(h), h);
if (h >= 8 && threshold == 87) {
// for threshold 87, we reach the treshold at height 7, so from height 8, hard fork to version 2, but 8 tries to add 1
@@ -426,7 +415,6 @@ TEST(voting, threshold)
TEST(voting, different_thresholds)
{
oracle::asset_type_counts num_rct_outs_by_asset_type;
cryptonote::audit_block_info abi;
cryptonote::yield_block_info ybi;
for (int threshold = 87; threshold <= 88; ++threshold) {
TestDB db;
@@ -444,7 +432,7 @@ TEST(voting, different_thresholds)
static const uint8_t expected_versions[] = { 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4 };
for (uint64_t h = 0; h < sizeof(block_versions) / sizeof(block_versions[0]); ++h) {
db.add_block(mkblock(hf, h, block_versions[h]), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, 0, cryptonote::FAKECHAIN, ybi, abi);
db.add_block(mkblock(hf, h, block_versions[h]), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, cryptonote::FAKECHAIN, ybi);
bool ret = hf.add(db.get_block_from_height(h), h);
ASSERT_EQ(ret, true);
}
@@ -459,7 +447,6 @@ TEST(voting, info)
TestDB db;
HardFork hf(db, 1, 0, 1, 1, 4, 50); // window size 4, default threshold 50%
oracle::asset_type_counts num_rct_outs_by_asset_type;
cryptonote::audit_block_info abi;
cryptonote::yield_block_info ybi;
// v h ts
@@ -500,7 +487,7 @@ TEST(voting, info)
ASSERT_EQ(expected_thresholds[h], threshold);
ASSERT_EQ(4, voting);
db.add_block(mkblock(hf, h, block_versions[h]), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, 0, cryptonote::FAKECHAIN, ybi, abi);
db.add_block(mkblock(hf, h, block_versions[h]), 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, cryptonote::FAKECHAIN, ybi);
ASSERT_TRUE(hf.add(db.get_block_from_height(h), h));
}
}
@@ -564,9 +551,8 @@ TEST(reorganize, changed)
do { \
cryptonote::block b = mkblock(hf, h, v); \
oracle::asset_type_counts num_rct_outs_by_asset_type; \
cryptonote::audit_block_info abi; \
cryptonote::yield_block_info ybi; \
db.add_block(b, 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, 0, cryptonote::FAKECHAIN, ybi, abi); \
db.add_block(b, 0, 0, 0, 0, 0, num_rct_outs_by_asset_type, crypto::hash(), 0, 0, cryptonote::FAKECHAIN, ybi); \
ASSERT_##a(hf.add(b, h)); \
} while(0)
#define ADD_TRUE(v, h) ADD(v, h, TRUE)
+14 -17
View File
@@ -61,10 +61,8 @@ public:
, const crypto::hash& blk_hash
, uint64_t slippage_total
, uint64_t yield_total
, uint64_t audit_total
, const cryptonote::network_type nettype
, cryptonote::yield_block_info& ybi
, cryptonote::audit_block_info& abi
) override {
blocks.push_back({block_weight, long_term_block_weight});
}
@@ -116,7 +114,6 @@ static uint32_t lcg()
#define PREFIX_WINDOW(hf_version,window) \
cryptonote::BlockchainAndPool bap; \
cryptonote::Blockchain *bc = &bap.blockchain; \
cryptonote::audit_block_info abi; \
cryptonote::yield_block_info ybi; \
struct get_test_options { \
const std::pair<uint8_t, uint64_t> hard_forks[3]; \
@@ -149,7 +146,7 @@ TEST(long_term_block_weight, identical_before_fork)
{
size_t w = h < CRYPTONOTE_REWARD_BLOCKS_WINDOW ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : bc->get_current_cumulative_block_weight_limit();
uint64_t ltw = bc->get_next_long_term_block_weight(w);
bc->get_db().add_block(std::make_pair(cryptonote::block(), ""), w, ltw, h, h, {}, cryptonote::FAKECHAIN, ybi, abi);
bc->get_db().add_block(std::make_pair(cryptonote::block(), ""), w, ltw, h, h, {}, cryptonote::FAKECHAIN, ybi);
ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
}
for (uint64_t h = 0; h < 10 * TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW; ++h)
@@ -166,7 +163,7 @@ TEST(long_term_block_weight, identical_after_fork_before_long_term_window)
{
size_t w = h < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : bc->get_current_cumulative_block_weight_limit();
uint64_t ltw = bc->get_next_long_term_block_weight(w);
bc->get_db().add_block(std::make_pair(cryptonote::block(), ""), w, ltw, h, h, {}, cryptonote::FAKECHAIN, ybi, abi);
bc->get_db().add_block(std::make_pair(cryptonote::block(), ""), w, ltw, h, h, {}, cryptonote::FAKECHAIN, ybi);
ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
}
for (uint64_t h = 0; h < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW; ++h)
@@ -183,7 +180,7 @@ TEST(long_term_block_weight, ceiling_at_30000000)
{
size_t w = h < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : bc->get_current_cumulative_block_weight_limit();
uint64_t ltw = bc->get_next_long_term_block_weight(w);
bc->get_db().add_block(std::make_pair(cryptonote::block(), ""), w, ltw, h, h, {}, cryptonote::FAKECHAIN, ybi, abi);
bc->get_db().add_block(std::make_pair(cryptonote::block(), ""), w, ltw, h, h, {}, cryptonote::FAKECHAIN, ybi);
ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
}
ASSERT_EQ(bc->get_current_cumulative_block_weight_median(), 15000000);
@@ -198,7 +195,7 @@ TEST(long_term_block_weight, multi_pop)
{
size_t w = h < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : bc->get_current_cumulative_block_weight_limit();
uint64_t ltw = bc->get_next_long_term_block_weight(w);
bc->get_db().add_block(std::make_pair(cryptonote::block(), ""), w, ltw, h, h, {}, cryptonote::FAKECHAIN, ybi, abi);
bc->get_db().add_block(std::make_pair(cryptonote::block(), ""), w, ltw, h, h, {}, cryptonote::FAKECHAIN, ybi);
ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
}
@@ -210,7 +207,7 @@ TEST(long_term_block_weight, multi_pop)
{
size_t w = bc->get_current_cumulative_block_weight_limit();
uint64_t ltw = bc->get_next_long_term_block_weight(w);
bc->get_db().add_block(std::make_pair(cryptonote::block(), ""), w, ltw, h, h, {}, cryptonote::FAKECHAIN, ybi, abi);
bc->get_db().add_block(std::make_pair(cryptonote::block(), ""), w, ltw, h, h, {}, cryptonote::FAKECHAIN, ybi);
ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
}
@@ -232,7 +229,7 @@ TEST(long_term_block_weight, multiple_updates)
{
size_t w = h < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : bc->get_current_cumulative_block_weight_limit();
uint64_t ltw = bc->get_next_long_term_block_weight(w);
bc->get_db().add_block(std::make_pair(cryptonote::block(), ""), w, ltw, h, h, {}, cryptonote::FAKECHAIN, ybi, abi);
bc->get_db().add_block(std::make_pair(cryptonote::block(), ""), w, ltw, h, h, {}, cryptonote::FAKECHAIN, ybi);
ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
const uint64_t effective_median = bc->get_current_cumulative_block_weight_median();
const uint64_t effective_limit = bc->get_current_cumulative_block_weight_limit();
@@ -256,7 +253,7 @@ TEST(long_term_block_weight, pop_invariant_max)
{
size_t w = bc->get_db().height() < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : bc->get_current_cumulative_block_weight_limit();
uint64_t ltw = bc->get_next_long_term_block_weight(w);
bc->get_db().add_block(std::make_pair(cryptonote::block(), ""), w, ltw, h, h, {}, cryptonote::FAKECHAIN, ybi, abi);
bc->get_db().add_block(std::make_pair(cryptonote::block(), ""), w, ltw, h, h, {}, cryptonote::FAKECHAIN, ybi);
ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
}
@@ -284,7 +281,7 @@ TEST(long_term_block_weight, pop_invariant_max)
{
size_t w = bc->get_db().height() < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : bc->get_current_cumulative_block_weight_limit();
uint64_t ltw = bc->get_next_long_term_block_weight(w);
bc->get_db().add_block(std::make_pair(cryptonote::block(), ""), w, ltw, bc->get_db().height(), bc->get_db().height(), {}, cryptonote::FAKECHAIN, ybi, abi);
bc->get_db().add_block(std::make_pair(cryptonote::block(), ""), w, ltw, bc->get_db().height(), bc->get_db().height(), {}, cryptonote::FAKECHAIN, ybi);
ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
}
@@ -306,7 +303,7 @@ TEST(long_term_block_weight, pop_invariant_random)
uint32_t r = lcg();
size_t w = bc->get_db().height() < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : (r % bc->get_current_cumulative_block_weight_limit());
uint64_t ltw = bc->get_next_long_term_block_weight(w);
bc->get_db().add_block(std::make_pair(cryptonote::block(), ""), w, ltw, h, h, {}, cryptonote::FAKECHAIN, ybi, abi);
bc->get_db().add_block(std::make_pair(cryptonote::block(), ""), w, ltw, h, h, {}, cryptonote::FAKECHAIN, ybi);
ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
}
@@ -341,7 +338,7 @@ TEST(long_term_block_weight, pop_invariant_random)
uint32_t r = lcg();
size_t w = bc->get_db().height() < TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW ? CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 : (r % bc->get_current_cumulative_block_weight_limit());
uint64_t ltw = bc->get_next_long_term_block_weight(w);
bc->get_db().add_block(std::make_pair(cryptonote::block(), ""), w, ltw, bc->get_db().height(), bc->get_db().height(), {}, cryptonote::FAKECHAIN, ybi, abi);
bc->get_db().add_block(std::make_pair(cryptonote::block(), ""), w, ltw, bc->get_db().height(), bc->get_db().height(), {}, cryptonote::FAKECHAIN, ybi);
ASSERT_TRUE(bc->update_next_cumulative_weight_limit());
const uint64_t effective_median = bc->get_current_cumulative_block_weight_median();
const uint64_t effective_limit = bc->get_current_cumulative_block_weight_limit();
@@ -369,7 +366,7 @@ TEST(long_term_block_weight, long_growth_spike_and_drop)
{
size_t w = CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5;
uint64_t ltw = bc->get_next_long_term_block_weight(w);
bc->get_db().add_block(std::make_pair(cryptonote::block(), ""), w, ltw, h, h, {}, cryptonote::FAKECHAIN, ybi, abi);
bc->get_db().add_block(std::make_pair(cryptonote::block(), ""), w, ltw, h, h, {}, cryptonote::FAKECHAIN, ybi);
ASSERT_TRUE(bc->update_next_cumulative_weight_limit(&long_term_effective_median_block_weight));
}
ASSERT_EQ(long_term_effective_median_block_weight, 300000);
@@ -381,7 +378,7 @@ TEST(long_term_block_weight, long_growth_spike_and_drop)
float t = h / float(365 * 720 * TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW / 100000);
size_t w = 300000 + t * 30000;
uint64_t ltw = bc->get_next_long_term_block_weight(w);
bc->get_db().add_block(std::make_pair(cryptonote::block(), ""), w, ltw, h, h, {}, cryptonote::FAKECHAIN, ybi, abi);
bc->get_db().add_block(std::make_pair(cryptonote::block(), ""), w, ltw, h, h, {}, cryptonote::FAKECHAIN, ybi);
ASSERT_TRUE(bc->update_next_cumulative_weight_limit(&long_term_effective_median_block_weight));
}
ASSERT_GT(long_term_effective_median_block_weight, 300000 * 1.07);
@@ -392,7 +389,7 @@ TEST(long_term_block_weight, long_growth_spike_and_drop)
{
size_t w = bc->get_current_cumulative_block_weight_limit();
uint64_t ltw = bc->get_next_long_term_block_weight(w);
bc->get_db().add_block(std::make_pair(cryptonote::block(), ""), w, ltw, h, h, {}, cryptonote::FAKECHAIN, ybi, abi);
bc->get_db().add_block(std::make_pair(cryptonote::block(), ""), w, ltw, h, h, {}, cryptonote::FAKECHAIN, ybi);
ASSERT_TRUE(bc->update_next_cumulative_weight_limit(&long_term_effective_median_block_weight));
}
ASSERT_GT(long_term_effective_median_block_weight, 300000 * 1.07);
@@ -403,7 +400,7 @@ TEST(long_term_block_weight, long_growth_spike_and_drop)
{
size_t w = bc->get_current_cumulative_block_weight_median() * .25;
uint64_t ltw = bc->get_next_long_term_block_weight(w);
bc->get_db().add_block(std::make_pair(cryptonote::block(), ""), w, ltw, h, h, {}, cryptonote::FAKECHAIN, ybi, abi);
bc->get_db().add_block(std::make_pair(cryptonote::block(), ""), w, ltw, h, h, {}, cryptonote::FAKECHAIN, ybi);
ASSERT_TRUE(bc->update_next_cumulative_weight_limit(&long_term_effective_median_block_weight));
}
ASSERT_GT(long_term_effective_median_block_weight, 300000 * 1.07);
+1 -3
View File
@@ -433,7 +433,6 @@ TEST(cryptonote_protocol_handler, race_condition)
const block_t &block,
const stat::chain &stat
){
cryptonote::audit_block_info abi;
cryptonote::yield_block_info ybi;
core.get_blockchain_storage().get_db().batch_start({}, {});
core.get_blockchain_storage().get_db().add_block(
@@ -446,8 +445,7 @@ TEST(cryptonote_protocol_handler, race_condition)
stat.reward,
{},
cryptonote::FAKECHAIN,
ybi,
abi
ybi
);
core.get_blockchain_storage().get_db().batch_stop();
};
+6 -10
View File
@@ -351,8 +351,7 @@ TEST(ringct, range_proofs)
destination_asset_types.push_back("SAL");
//compute rct data with mixin 3
rct::salvium_data_t salvium_data;
rctSig s = genRctSimple(rct::zero(), sc, pc, destinations, tx_type, in_asset_type, destination_asset_types, inamounts, amounts, amount_keys, 0, 3, rct_config, hw::get_device("default"), salvium_data);
rctSig s = genRctSimple(rct::zero(), sc, pc, destinations, tx_type, in_asset_type, destination_asset_types, inamounts, amounts, amount_keys, 0, 3, rct_config, hw::get_device("default"));
//verify rct data
ASSERT_TRUE(verRctSimple(s));
@@ -369,7 +368,7 @@ TEST(ringct, range_proofs)
//compute rct data with mixin 3
s = genRctSimple(rct::zero(), sc, pc, destinations, tx_type, in_asset_type, destination_asset_types, inamounts, amounts, amount_keys, 0, 3, rct_config, hw::get_device("default"), salvium_data);
s = genRctSimple(rct::zero(), sc, pc, destinations, tx_type, in_asset_type, destination_asset_types, inamounts, amounts, amount_keys, 0, 3, rct_config, hw::get_device("default"));
//verify rct data
ASSERT_FALSE(verRctSimple(s));
@@ -423,8 +422,7 @@ TEST(ringct, range_proofs_with_fee)
destination_asset_types.push_back("SAL");
//compute rct data with mixin 3
rct::salvium_data_t salvium_data;
rctSig s = genRctSimple(rct::zero(), sc, pc, destinations, tx_type, in_asset_type, destination_asset_types, inamounts, amounts, amount_keys, 1, 3, rct_config, hw::get_device("default"), salvium_data);
rctSig s = genRctSimple(rct::zero(), sc, pc, destinations, tx_type, in_asset_type, destination_asset_types, inamounts, amounts, amount_keys, 1, 3, rct_config, hw::get_device("default"));
//verify rct data
ASSERT_TRUE(verRctSimple(s));
@@ -441,7 +439,7 @@ TEST(ringct, range_proofs_with_fee)
//compute rct data with mixin 3
s = genRctSimple(rct::zero(), sc, pc, destinations, tx_type, in_asset_type, destination_asset_types, inamounts, amounts, amount_keys, 500, 3, rct_config, hw::get_device("default"), salvium_data);
s = genRctSimple(rct::zero(), sc, pc, destinations, tx_type, in_asset_type, destination_asset_types, inamounts, amounts, amount_keys, 500, 3, rct_config, hw::get_device("default"));
//verify rct data
ASSERT_FALSE(verRctSimple(s));
@@ -506,8 +504,7 @@ TEST(ringct, simple)
for (size_t i = 0; i < destinations.size(); ++i)
destination_asset_types.push_back("SAL");
rct::salvium_data_t salvium_data;
rctSig s = genRctSimple(message, sc, pc, destinations, tx_type, in_asset_type, destination_asset_types, inamounts, outamounts, amount_keys, txnfee, 2, rct_config, hw::get_device("default"), salvium_data);
rctSig s = genRctSimple(message, sc, pc, destinations, tx_type, in_asset_type, destination_asset_types, inamounts, outamounts, amount_keys, txnfee, 2, rct_config, hw::get_device("default"));
//verify ring ct signature
ASSERT_TRUE(verRctSimple(s));
@@ -575,8 +572,7 @@ static rct::rctSig make_sample_simple_rct_sig(int n_inputs, const uint64_t input
for (size_t i = 0; i < destinations.size(); ++i)
destination_asset_types.push_back("SAL");
rct::salvium_data_t salvium_data;
return genRctSimple(rct::zero(), sc, pc, destinations, tx_type, in_asset_type, destination_asset_types, inamounts, outamounts, amount_keys, fee, 3, rct_config, hw::get_device("default"), salvium_data);
return genRctSimple(rct::zero(), sc, pc, destinations, tx_type, in_asset_type, destination_asset_types, inamounts, outamounts, amount_keys, fee, 3, rct_config, hw::get_device("default"));
}
static bool range_proof_test(bool expected_valid,
+2 -3
View File
@@ -613,8 +613,7 @@ TEST(Serialization, serializes_ringct_types)
for (size_t i = 0; i < destinations.size(); ++i)
destination_asset_types.push_back("SAL");
rct::salvium_data_t salvium_data;
s0 = rct::genRctSimple(rct::zero(), sc, pc, destinations, tx_type, in_asset_type, destination_asset_types, inamounts, amounts, amount_keys, 0, 3, rct_config, hw::get_device("default"), salvium_data);
s0 = rct::genRctSimple(rct::zero(), sc, pc, destinations, tx_type, in_asset_type, destination_asset_types, inamounts, amounts, amount_keys, 0, 3, rct_config, hw::get_device("default"));
ASSERT_FALSE(s0.p.MGs.empty());
ASSERT_TRUE(s0.p.CLSAGs.empty());
@@ -639,7 +638,7 @@ TEST(Serialization, serializes_ringct_types)
ASSERT_EQ(bp0, bp1);
const rct::RCTConfig rct_config_clsag{ rct::RangeProofPaddedBulletproof, 3 };
s0 = rct::genRctSimple(rct::zero(), sc, pc, destinations, tx_type, in_asset_type, destination_asset_types, inamounts, amounts, amount_keys, 0, 3, rct_config_clsag, hw::get_device("default"), salvium_data);
s0 = rct::genRctSimple(rct::zero(), sc, pc, destinations, tx_type, in_asset_type, destination_asset_types, inamounts, amounts, amount_keys, 0, 3, rct_config_clsag, hw::get_device("default"));
ASSERT_FALSE(s0.p.CLSAGs.empty());
ASSERT_TRUE(s0.p.MGs.empty());