Compare commits

...

10 Commits

Author SHA1 Message Date
Some Random Crypto Guy 91d52ba063 updated fast sync checkpoints; bumped version for BETA1 2024-08-12 11:27:30 +01:00
Some Random Crypto Guy 71d50f1b3f simplified blockchain height estimation, which should fix wallet restore height issue 2024-08-12 09:50:14 +01:00
Some Random Crypto Guy 1b0a1b6047 updated seed node IP addresses + port numbers 2024-08-12 09:49:32 +01:00
Some Random Crypto Guy 5a10a54563 changed seed URLs 2024-08-09 21:37:53 +01:00
Some Random Crypto Guy 2dfbcce6a4 possible fixes for 'make depends' build for Win64 2024-08-09 20:51:13 +01:00
Some Random Crypto Guy 9f34b46961 fixed wallet API to expose TX type to GUI wallet; updated Dockerfile 2024-08-09 16:03:18 +01:00
Some Random Crypto Guy 8a82655fa4 added GUI yield support 2024-07-31 12:39:06 +01:00
Some Random Crypto Guy 301f2973d7 various fixes to support GUI wallet; bumped version number 2024-07-31 10:52:58 +01:00
Some Random Crypto Guy 5f48afaf31 added support for GUI wallet staking 2024-07-26 10:51:20 +01:00
Some Random Crypto Guy b4379b005a revised error message when querying balance of empty wallet via RPC - thanks @GeraldoNonKYC 2024-07-10 12:56:49 +01:00
23 changed files with 508 additions and 67 deletions
+13 -13
View File
@@ -41,26 +41,26 @@ RUN set -ex && \
rm -rf /var/lib/apt
COPY --from=builder /src/build/x86_64-linux-gnu/release/bin /usr/local/bin/
# Create monero user
RUN adduser --system --group --disabled-password monero && \
mkdir -p /wallet /home/monero/.bitmonero && \
chown -R monero:monero /home/monero/.bitmonero && \
chown -R monero:monero /wallet
# Create salvium user
RUN adduser --system --group --disabled-password salvium && \
mkdir -p /wallet /home/salvium/.salvium && \
chown -R salvium:salvium /home/salvium/.salvium && \
chown -R salvium:salvium /wallet
# Contains the blockchain
VOLUME /home/monero/.bitmonero
VOLUME /home/salvium/.salvium
# Generate your wallet via accessing the container and run:
# cd /wallet
# monero-wallet-cli
# salvium-wallet-cli
VOLUME /wallet
EXPOSE 18080
EXPOSE 18081
EXPOSE 19080
EXPOSE 19081
# switch to user monero
USER monero
# switch to user salvium
USER salvium
ENTRYPOINT ["monerod"]
CMD ["--p2p-bind-ip=0.0.0.0", "--p2p-bind-port=18080", "--rpc-bind-ip=0.0.0.0", "--rpc-bind-port=18081", "--non-interactive", "--confirm-external-bind"]
ENTRYPOINT ["salviumd"]
CMD ["--p2p-bind-ip=0.0.0.0", "--p2p-bind-port=19080", "--rpc-bind-ip=0.0.0.0", "--rpc-bind-port=19081", "--non-interactive", "--confirm-external-bind"]
+1 -1
View File
@@ -1,4 +1,4 @@
mingw32_CFLAGS=-pipe
mingw32_CFLAGS=-pipe -pthread
mingw32_CXXFLAGS=$(mingw32_CFLAGS)
mingw32_ARFLAGS=cr
+1 -1
View File
@@ -5,7 +5,7 @@ $(package)_file_name=$(package)-$($(package)_version).tar.gz
$(package)_sha256_hash=6653ef5910f17954861fe72332e68b03ca6e4d9c7160eb3a8de5a5a913bfab43
define $(package)_set_vars
$(package)_config_opts=--without-documentation --disable-shared --without-libsodium --disable-curve
$(package)_config_opts=--without-documentation --disable-shared --without-libsodium --disable-curve --with-cv-impl=pthread
$(package)_config_opts_linux=--with-pic
$(package)_config_opts_freebsd=--with-pic
$(package)_cxxflags=-std=c++11
Binary file not shown.
+1 -1
View File
@@ -6049,7 +6049,7 @@ void Blockchain::cancel()
}
#if defined(PER_BLOCK_CHECKPOINT)
static const char expected_block_hashes_hash[] = "df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119";
static const char expected_block_hashes_hash[] = "7f60b4980ea16b32e3f9fc1959d9d4116ba91f2b067bd70b3e21c44520096d14";
void Blockchain::load_compiled_in_block_hashes(const GetCheckpointsCallback& get_checkpoints)
{
if (get_checkpoints == nullptr || !m_fast_sync)
+3 -4
View File
@@ -299,10 +299,9 @@ namespace nodetool
private:
const std::vector<std::string> m_seed_nodes_list =
{ "seeds.moneroseeds.se"
, "seeds.moneroseeds.ae.org"
, "seeds.moneroseeds.ch"
, "seeds.moneroseeds.li"
{ "seed01.salvium.io"
, "seed02.salvium.io"
, "seed03.salvium.io"
};
bool islimitup=false;
+9 -17
View File
@@ -705,32 +705,24 @@ namespace nodetool
std::set<std::string> full_addrs;
if (m_nettype == cryptonote::TESTNET)
{
full_addrs.insert("176.9.0.187:28080");
full_addrs.insert("88.99.173.38:28080");
full_addrs.insert("51.79.173.165:28080");
full_addrs.insert("192.99.8.110:28080");
full_addrs.insert("37.187.74.171:28080");
full_addrs.insert("152.42.130.46:29080");
full_addrs.insert("45.55.138.87:29080");
full_addrs.insert("209.97.164.15:29080");
}
else if (m_nettype == cryptonote::STAGENET)
{
full_addrs.insert("176.9.0.187:38080");
full_addrs.insert("88.99.173.38:38080");
full_addrs.insert("51.79.173.165:38080");
full_addrs.insert("192.99.8.110:38080");
full_addrs.insert("37.187.74.171:38080");
full_addrs.insert("152.42.130.46:39080");
full_addrs.insert("45.55.138.87:39080");
full_addrs.insert("209.97.164.15:39080");
}
else if (m_nettype == cryptonote::FAKECHAIN)
{
}
else
{
full_addrs.insert("176.9.0.187:18080");
full_addrs.insert("88.198.163.90:18080");
full_addrs.insert("66.85.74.134:18080");
full_addrs.insert("88.99.173.38:18080");
full_addrs.insert("51.79.173.165:18080");
full_addrs.insert("192.99.8.110:18080");
full_addrs.insert("37.187.74.171:18080");
full_addrs.insert("152.42.130.46:19080");
full_addrs.insert("45.55.138.87:19080");
full_addrs.insert("209.97.164.15:19080");
}
return full_addrs;
}
+1 -1
View File
@@ -8444,7 +8444,7 @@ bool simple_wallet::yield_info(const std::vector<std::string> &args) {
% print_money(total_yield)
% print_money(yield_per_stake);
// Now summarise our own YIELD TXs that are yet to amture
// Now summarise our own YIELD TXs that are yet to mature
tools::wallet2::transfer_container transfers;
m_wallet->get_transfers(transfers);
if (transfers.empty())
+1 -1
View File
@@ -1,5 +1,5 @@
#define DEF_SALVIUM_VERSION_TAG "@VERSIONTAG@"
#define DEF_SALVIUM_VERSION "0.4.1"
#define DEF_SALVIUM_VERSION "0.4.4-beta1"
#define DEF_MONERO_VERSION_TAG "release"
#define DEF_MONERO_VERSION "0.18.3.3"
#define DEF_MONERO_RELEASE_NAME "Zero"
+2
View File
@@ -35,6 +35,7 @@ set(wallet_api_sources
wallet_manager.cpp
transaction_info.cpp
transaction_history.cpp
yield_info.cpp
pending_transaction.cpp
utils.cpp
address_book.cpp
@@ -50,6 +51,7 @@ set(wallet_api_private_headers
wallet_manager.h
transaction_info.h
transaction_history.h
yield_info.h
pending_transaction.h
common_defines.h
address_book.h
+4
View File
@@ -150,6 +150,7 @@ void TransactionHistoryImpl::refresh()
ti->m_timestamp = pd.m_timestamp;
ti->m_confirmations = (wallet_height > pd.m_block_height) ? wallet_height - pd.m_block_height : 0;
ti->m_unlock_time = pd.m_unlock_time;
ti->m_type = static_cast<Monero::transaction_type>(static_cast<uint8_t>(pd.m_tx_type));
m_history.push_back(ti);
}
@@ -193,6 +194,7 @@ void TransactionHistoryImpl::refresh()
ti->m_label = pd.m_subaddr_indices.size() == 1 ? m_wallet->m_wallet->get_subaddress_label({pd.m_subaddr_account, *pd.m_subaddr_indices.begin()}) : "";
ti->m_timestamp = pd.m_timestamp;
ti->m_confirmations = (wallet_height > pd.m_block_height) ? wallet_height - pd.m_block_height : 0;
ti->m_type = static_cast<Monero::transaction_type>(static_cast<uint8_t>(pd.m_tx.type));
// single output transaction might contain multiple transfers
for (const auto &d: pd.m_dests) {
@@ -229,6 +231,7 @@ void TransactionHistoryImpl::refresh()
ti->m_label = pd.m_subaddr_indices.size() == 1 ? m_wallet->m_wallet->get_subaddress_label({pd.m_subaddr_account, *pd.m_subaddr_indices.begin()}) : "";
ti->m_timestamp = pd.m_timestamp;
ti->m_confirmations = 0;
ti->m_type = static_cast<Monero::transaction_type>(static_cast<uint8_t>(pd.m_tx.type));
for (const auto &d : pd.m_dests)
{
ti->m_transfers.push_back({d.amount, d.address(m_wallet->m_wallet->nettype(), pd.m_payment_id)});
@@ -258,6 +261,7 @@ void TransactionHistoryImpl::refresh()
ti->m_label = m_wallet->m_wallet->get_subaddress_label(pd.m_subaddr_index);
ti->m_timestamp = pd.m_timestamp;
ti->m_confirmations = 0;
ti->m_type = static_cast<Monero::transaction_type>(static_cast<uint8_t>(pd.m_tx_type));
m_history.push_back(ti);
LOG_PRINT_L1(__FUNCTION__ << ": Unconfirmed payment found " << pd.m_amount);
+5
View File
@@ -149,4 +149,9 @@ uint64_t TransactionInfoImpl::unlockTime() const
return m_unlock_time;
}
Monero::transaction_type TransactionInfoImpl::type() const
{
return m_type;
}
} // namespace
+2
View File
@@ -62,6 +62,7 @@ public:
virtual const std::vector<Transfer> &transfers() const override;
virtual uint64_t confirmations() const override;
virtual uint64_t unlockTime() const override;
virtual Monero::transaction_type type() const override;
private:
int m_direction;
@@ -81,6 +82,7 @@ private:
std::vector<Transfer> m_transfers;
uint64_t m_confirmations;
uint64_t m_unlock_time;
Monero::transaction_type m_type;
friend class TransactionHistoryImpl;
+30 -5
View File
@@ -30,6 +30,7 @@
#include "wallet.h"
#include "yield_info.h"
#include "pending_transaction.h"
#include "unsigned_transaction.h"
#include "transaction_history.h"
@@ -1430,6 +1431,19 @@ PendingTransaction* WalletImpl::restoreMultisigTransaction(const string& signDat
return nullptr;
}
PendingTransaction *WalletImpl::createStakeTransaction(uint64_t amount, 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("createStakeTransaction: called");
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);
}
// TODO:
// 1 - properly handle payment id (add another menthod with explicit 'payment_id' param)
// 2 - check / design how "Transaction" can be single interface
@@ -1440,7 +1454,7 @@ PendingTransaction* WalletImpl::restoreMultisigTransaction(const string& signDat
// - unconfirmed_transfer_details;
// - confirmed_transfer_details)
PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector<string> &dst_addr, const string &payment_id, optional<std::vector<uint64_t>> amount, uint32_t mixin_count, PendingTransaction::Priority priority, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices)
PendingTransaction *WalletImpl::createTransactionMultDest(const Monero::transaction_type &tx_type, const std::vector<string> &dst_addr, const string &payment_id, optional<std::vector<uint64_t>> amount, uint32_t mixin_count, const std::string &asset_type, const bool is_return, PendingTransaction::Priority priority, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices)
{
clearStatus();
@@ -1451,6 +1465,8 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector<stri
uint32_t adjusted_priority = m_wallet->adjust_priority(static_cast<uint32_t>(priority));
const cryptonote::transaction_type converted_tx_type = static_cast<cryptonote::transaction_type>(static_cast<uint8_t>(tx_type));
PendingTransactionImpl * transaction = new PendingTransactionImpl(*this);
do {
@@ -1496,8 +1512,10 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector<stri
de.original = dst_addr[i];
de.addr = info.address;
de.amount = (*amount)[i];
de.asset_type = asset_type;
de.is_subaddress = info.is_subaddress;
de.is_integrated = info.has_payment_id;
de.is_return = is_return;
dsts.push_back(de);
} else {
if (subaddr_indices.empty()) {
@@ -1518,11 +1536,11 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector<stri
fake_outs_count = m_wallet->adjust_mixin(mixin_count);
if (amount) {
transaction->m_pending_tx = m_wallet->create_transactions_2(dsts, "SAL", "SAL", cryptonote::transaction_type::TRANSFER, 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, cryptonote::transaction_type::TRANSFER, "SAL", 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);
}
@@ -1605,10 +1623,10 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector<stri
}
PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, const string &payment_id, optional<uint64_t> amount, uint32_t mixin_count,
PendingTransaction::Priority priority, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices)
const std::string &asset_type, const bool is_return, PendingTransaction::Priority priority, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices)
{
return createTransactionMultDest(std::vector<string> {dst_addr}, payment_id, amount ? (std::vector<uint64_t> {*amount}) : (optional<std::vector<uint64_t>>()), mixin_count, priority, subaddr_account, subaddr_indices);
return createTransactionMultDest(Monero::transaction_type::TRANSFER, 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::createSweepUnmixableTransaction()
@@ -2590,4 +2608,11 @@ uint64_t WalletImpl::getBytesSent()
return m_wallet->get_bytes_sent();
}
YieldInfo * WalletImpl::getYieldInfo()
{
auto yi = new YieldInfoImpl(*this);
bool ok = m_wallet->get_yield_summary_info(yi->m_burnt, yi->m_supply, yi->m_locked, yi->m_yield, yi->m_yield_per_stake, yi->m_num_entries, yi->m_payouts);
return yi;
}
} // namespace
+21 -9
View File
@@ -42,6 +42,7 @@
namespace Monero {
class TransactionHistoryImpl;
class YieldInfoImpl;
class PendingTransactionImpl;
class UnsignedTransactionImpl;
class AddressBookImpl;
@@ -152,16 +153,24 @@ public:
bool hasMultisigPartialKeyImages() const override;
PendingTransaction* restoreMultisigTransaction(const std::string& signData) override;
PendingTransaction * createTransactionMultDest(const std::vector<std::string> &dst_addr, const std::string &payment_id,
optional<std::vector<uint64_t>> amount, uint32_t mixin_count,
PendingTransaction::Priority priority = PendingTransaction::Priority_Low,
uint32_t subaddr_account = 0,
std::set<uint32_t> subaddr_indices = {}) override;
PendingTransaction * createStakeTransaction(uint64_t amount,
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,
const std::string &asset_type, const bool is_return,
PendingTransaction::Priority priority = PendingTransaction::Priority_Low,
uint32_t subaddr_account = 0,
std::set<uint32_t> subaddr_indices = {}) override;
PendingTransaction * createTransaction(const std::string &dst_addr, const std::string &payment_id,
optional<uint64_t> amount, uint32_t mixin_count,
PendingTransaction::Priority priority = PendingTransaction::Priority_Low,
uint32_t subaddr_account = 0,
std::set<uint32_t> subaddr_indices = {}) override;
optional<uint64_t> amount, uint32_t mixin_count,
const std::string &asset_type, const bool is_return,
PendingTransaction::Priority priority = PendingTransaction::Priority_Low,
uint32_t subaddr_account = 0,
std::set<uint32_t> subaddr_indices = {}) override;
virtual PendingTransaction * createSweepUnmixableTransaction() override;
bool submitTransaction(const std::string &fileName) override;
virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename) override;
@@ -225,6 +234,8 @@ public:
virtual uint64_t getBytesReceived() override;
virtual uint64_t getBytesSent() override;
YieldInfo * getYieldInfo() override;
private:
void clearStatus() const;
void setStatusError(const std::string& message) const;
@@ -239,6 +250,7 @@ private:
bool doInit(const std::string &daemon_address, const std::string &proxy_address, uint64_t upper_transaction_size_limit = 0, bool ssl = false);
private:
friend class YieldInfoImpl;
friend class PendingTransactionImpl;
friend class UnsignedTransactionImpl;
friend class TransactionHistoryImpl;
+68 -5
View File
@@ -49,6 +49,18 @@ enum NetworkType : uint8_t {
STAGENET
};
enum transaction_type : uint8_t {
UNSET = 0,
MINER = 1,
PROTOCOL = 2,
TRANSFER = 3,
CONVERT = 4,
BURN = 5,
STAKE = 6,
RETURN = 7,
MAX = 7
};
namespace Utils {
bool isAddressLocal(const std::string &hostaddr);
void onStartup();
@@ -67,6 +79,28 @@ enum NetworkType : uint8_t {
bool set;
};
struct YieldInfo
{
enum Status {
Status_Ok,
Status_Error
};
virtual ~YieldInfo() = 0;
virtual int status() const = 0;
virtual std::string errorString() const = 0;
virtual bool update() = 0;
virtual uint64_t burnt() const = 0;
virtual uint64_t locked() const = 0;
virtual uint64_t supply() const = 0;
virtual uint64_t ybi_data_size() const = 0;
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, uint64_t, uint64_t>> payouts() const = 0;
};
/**
* @brief Transaction-like interface for sending money
*/
@@ -199,6 +233,7 @@ struct TransactionInfo
virtual std::string paymentId() const = 0;
//! only applicable for output transactions
virtual const std::vector<Transfer> & transfers() const = 0;
virtual Monero::transaction_type type() const = 0;
};
/**
* @brief The TransactionHistory - interface for displaying transaction history
@@ -826,12 +861,32 @@ struct Wallet
*/
virtual PendingTransaction* restoreMultisigTransaction(const std::string& signData) = 0;
/*!
* \brief createStakeTransaction creates staking transaction.
* \param amount amount
* \param mixin_count mixin count. if 0 passed, wallet will use default value
* \param subaddr_account subaddress account from which the input funds are taken
* \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 * createStakeTransaction(uint64_t amount,
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
* \param dst_addr vector of destination address as string
* \param payment_id optional payment_id, can be empty string
* \param amount vector of amounts
* \param mixin_count mixin count. if 0 passed, wallet will use default value
* \param asset_type type of asset to create as output
* \param is_return whether this is a return_payment or not
* \param subaddr_account subaddress account from which the input funds are taken
* \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
@@ -839,11 +894,13 @@ struct Wallet
* after object returned
*/
virtual PendingTransaction * createTransactionMultDest(const std::vector<std::string> &dst_addr, const std::string &payment_id,
optional<std::vector<uint64_t>> amount, uint32_t mixin_count,
PendingTransaction::Priority = PendingTransaction::Priority_Low,
uint32_t subaddr_account = 0,
std::set<uint32_t> subaddr_indices = {}) = 0;
virtual 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,
const std::string &asset_type, const bool is_return,
PendingTransaction::Priority = PendingTransaction::Priority_Low,
uint32_t subaddr_account = 0,
std::set<uint32_t> subaddr_indices = {}) = 0;
/*!
* \brief createTransaction creates transaction. if dst_addr is an integrated address, payment_id is ignored
@@ -851,6 +908,8 @@ struct Wallet
* \param payment_id optional payment_id, can be empty string
* \param amount amount
* \param mixin_count mixin count. if 0 passed, wallet will use default value
* \param asset_type type of asset to create as output
* \param is_return whether this is a return_payment or not
* \param subaddr_account subaddress account from which the input funds are taken
* \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
@@ -860,6 +919,7 @@ struct Wallet
virtual PendingTransaction * createTransaction(const std::string &dst_addr, const std::string &payment_id,
optional<uint64_t> amount, uint32_t mixin_count,
const std::string &asset_type, const bool is_return,
PendingTransaction::Priority = PendingTransaction::Priority_Low,
uint32_t subaddr_account = 0,
std::set<uint32_t> subaddr_indices = {}) = 0;
@@ -1092,6 +1152,9 @@ struct Wallet
//! get bytes sent
virtual uint64_t getBytesSent() = 0;
//! get yield information
virtual YieldInfo * getYieldInfo() = 0;
};
/**
+131
View File
@@ -0,0 +1,131 @@
// Copyright (c) 2024, Salvium (author: SRCG)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
#include "yield_info.h"
#include "wallet.h"
#include "common_defines.h"
#include "cryptonote_basic/cryptonote_format_utils.h"
#include "cryptonote_basic/cryptonote_basic_impl.h"
#include "common/base58.h"
#include <memory>
#include <vector>
#include <sstream>
#include <boost/format.hpp>
#include <boost/filesystem.hpp>
using namespace std;
namespace Monero {
YieldInfo::~YieldInfo() {}
YieldInfoImpl::YieldInfoImpl(WalletImpl &wallet)
: m_wallet(wallet)
{
m_status = Status_Ok;
m_burnt = 0;
m_locked = 0;
m_supply = 0;
m_yield = 0;
m_yield_per_stake = 0;
m_num_entries = 0;
}
YieldInfoImpl::~YieldInfoImpl()
{
}
int YieldInfoImpl::status() const
{
return m_status;
}
string YieldInfoImpl::errorString() const
{
return m_errorString;
}
std::string YieldInfoImpl::period() const
{
// Calculate the number of entries as a human-readable time period
uint64_t ts = m_num_entries * 120;
std::string result;
stringstream ss;
ss << std::setfill('0') << std::setw(2) << (ts / 86400)
<< ":" << std::setw(2) << ((ts % 86400) / 3600)
<< ":" << std::setw(2) << ((ts % 3600) / 60)
<< ":" << std::setw(2) << (ts % 60) << " (DD:HH:MM:SS)";
return ss.str();
}
bool YieldInfoImpl::update()
{
return false;
}
uint64_t YieldInfoImpl::burnt() const
{
return m_burnt;
}
uint64_t YieldInfoImpl::locked() const
{
return m_locked;
}
uint64_t YieldInfoImpl::supply() const
{
return m_supply;
}
uint64_t YieldInfoImpl::ybi_data_size() const
{
return m_num_entries;
}
uint64_t YieldInfoImpl::yield() const
{
return m_yield;
}
uint64_t YieldInfoImpl::yield_per_stake() const
{
return m_yield_per_stake;
}
std::vector<std::tuple<size_t, std::string, uint64_t, uint64_t>> YieldInfoImpl::payouts() const
{
return m_payouts;
}
}
+74
View File
@@ -0,0 +1,74 @@
// Copyright (c) 2024, Salvium (author: SRCG)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
#include "wallet/api/wallet2_api.h"
#include "wallet/wallet2.h"
#include <string>
#include <vector>
namespace Monero {
class WalletImpl;
class YieldInfoImpl : public YieldInfo
{
public:
YieldInfoImpl(WalletImpl &wallet);
~YieldInfoImpl();
int status() const override;
std::string errorString() const override;
bool update() override;
uint64_t burnt() const override;
uint64_t locked() const override;
uint64_t supply() const override;
uint64_t ybi_data_size() const override;
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, uint64_t, uint64_t>> payouts() const override;
private:
friend class WalletImpl;
WalletImpl &m_wallet;
int m_status;
std::string m_errorString;
uint64_t m_burnt;
uint64_t m_locked;
uint64_t m_supply;
uint64_t m_yield;
uint64_t m_yield_per_stake;
uint64_t m_num_entries;
std::string m_period;
std::vector<std::tuple<size_t, std::string, uint64_t, uint64_t>> m_payouts;
};
}
+103 -8
View File
@@ -2380,6 +2380,105 @@ bool wallet2::get_yield_info(std::vector<cryptonote::yield_block_info>& ybi_data
}
}
//----------------------------------------------------------------------------------------------------
bool wallet2::get_yield_summary_info(uint64_t &total_burnt,
uint64_t &total_supply,
uint64_t &total_locked,
uint64_t &total_yield,
uint64_t &yield_per_stake,
uint64_t &ybi_data_size,
std::vector<std::tuple<size_t, std::string, uint64_t, uint64_t>> &payouts
)
{
// Get the total circulating supply of SALs
std::vector<std::pair<std::string, std::string>> supply_amounts;
if(!get_circulating_supply(supply_amounts)) {
return false;
}
boost::multiprecision::uint128_t total_supply_128 = 0;
for (auto supply_asset: supply_amounts) {
if (supply_asset.first == "SAL") {
boost::multiprecision::uint128_t supply_128(supply_asset.second);
total_supply_128 = supply_128;
break;
}
}
total_supply = total_supply_128.convert_to<uint64_t>();
// Get the yield data from the blockchain
std::vector<cryptonote::yield_block_info> ybi_data;
bool r = get_yield_info(ybi_data);
if (!r)
return false;
ybi_data_size = ybi_data.size();
// Scan the entries we have received to gather the state (total yield over period captured)
total_burnt = 0;
total_yield = 0;
yield_per_stake = 0;
for (size_t idx=1; idx<ybi_data.size(); ++idx) {
if (ybi_data[idx].locked_coins_tally == 0) {
total_burnt += ybi_data[idx].slippage_total_this_block;
} else {
total_yield += ybi_data[idx].slippage_total_this_block;
}
}
// Get the total currently locked
total_locked = ybi_data.back().locked_coins_tally;
// Calculate the yield_per_staked_SAL value
if (ybi_data.back().locked_coins_tally > 0) {
boost::multiprecision::uint128_t yield_per_stake_128 = ybi_data.back().slippage_total_this_block;
yield_per_stake_128 *= COIN;
yield_per_stake_128 /= ybi_data.back().locked_coins_tally;
yield_per_stake = yield_per_stake_128.convert_to<uint64_t>();
}
// Iterate over the transfers in our wallet
std::map<size_t, size_t> map_payouts;
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 (map_payouts.count(idx)) {
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));
}
} else if (td.m_tx.type == cryptonote::transaction_type::PROTOCOL) {
// Store list of reverse-lookup indices to tell YIELD TXs how much they earned
if (m_transfers[td.m_td_origin_idx].m_tx.type == cryptonote::transaction_type::STAKE)
map_payouts[td.m_td_origin_idx] = idx;
}
}
// Return success to caller
return true;
}
//----------------------------------------------------------------------------------------------------
bool wallet2::get_yield_payouts(std::vector<std::tuple<size_t, std::string, uint64_t, uint64_t>> &payouts) {
// Iterate over the transfers in our wallet
std::map<size_t, size_t> map_payouts;
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 (map_payouts.count(idx)) {
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));
}
} else if (td.m_tx.type == cryptonote::transaction_type::PROTOCOL) {
// Store list of reverse-lookup indices to tell YIELD TXs how much they earned
if (m_transfers[td.m_td_origin_idx].m_tx.type == cryptonote::transaction_type::STAKE)
map_payouts[td.m_td_origin_idx] = idx;
}
}
return true;
}
//----------------------------------------------------------------------------------------------------
void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote::transaction& tx, const std::vector<uint64_t> &o_indices, const std::vector<uint64_t> &asset_type_output_indices, uint64_t height, uint8_t block_version, uint64_t ts, bool miner_tx, bool pool, bool double_spend_seen, const tx_cache_data &tx_cache_data, std::map<std::pair<uint64_t, uint64_t>, size_t> *output_tracker_cache, bool ignore_callbacks)
{
PERF_TIMER(process_new_transaction);
@@ -13007,18 +13106,14 @@ uint64_t wallet2::get_daemon_blockchain_target_height(string &err)
uint64_t wallet2::get_approximate_blockchain_height() const
{
// time of v2 fork
const time_t fork_time = m_nettype == TESTNET ? 1448285909 : m_nettype == STAGENET ? 1520937818 : 1458748658;
// v2 fork block
const uint64_t fork_block = m_nettype == TESTNET ? 624634 : m_nettype == STAGENET ? 32000 : 1009827;
// time of v1 fork
const time_t fork_time = 1719997643;
// v1 fork block
const uint64_t fork_block = 0;
// avg seconds per block
const int seconds_per_block = DIFFICULTY_TARGET_V2;
// Calculated blockchain height
uint64_t approx_blockchain_height = fork_block + (time(NULL) - fork_time)/seconds_per_block;
// testnet and stagenet got some huge rollbacks, so the estimation is way off
static const uint64_t approximate_rolled_back_blocks = m_nettype == TESTNET ? 342100 : 30000;
if ((m_nettype == TESTNET || m_nettype == STAGENET) && approx_blockchain_height > approximate_rolled_back_blocks)
approx_blockchain_height -= approximate_rolled_back_blocks;
LOG_PRINT_L2("Calculated blockchain height: " << approx_blockchain_height);
return approx_blockchain_height;
}
+9
View File
@@ -1747,6 +1747,15 @@ private:
bool get_pricing_record(oracle::pricing_record& pr, const uint64_t height);
bool get_circulating_supply(std::vector<std::pair<std::string, std::string>> &amounts);
bool get_yield_info(std::vector<cryptonote::yield_block_info>& ybi_data);
bool get_yield_summary_info(uint64_t &total_burnt,
uint64_t &total_supply,
uint64_t &total_locked,
uint64_t &total_yield,
uint64_t &yield_per_stake,
uint64_t &ybi_data_size,
std::vector<std::tuple<size_t, std::string, uint64_t, uint64_t>> &payouts
);
bool get_yield_payouts(std::vector<std::tuple<size_t, std::string, uint64_t, uint64_t>> &payouts);
private:
/*!
+1 -1
View File
@@ -462,7 +462,7 @@ namespace tools
std::string asset_type = req.asset_type.empty() ? "SAL" : boost::algorithm::to_upper_copy(req.asset_type);
// verify that the asset is in the list of in-wallet assets
if (std::find(assets_in_wallet.begin(), assets_in_wallet.end(), asset_type) == assets_in_wallet.end()) {
er.message = std::string("Invalid source asset specified: ") + asset_type;
er.message = std::string("Source asset '") + asset_type + "' not found in wallet";
return false;
}
std::vector<std::string> assets = req.all_assets ? assets_in_wallet : std::vector<std::string>{asset_type};
+8
View File
@@ -0,0 +1,8 @@
# Configuration for salviumd
# Syntax: any command line option may be specified as 'clioptionname=value'.
# Boolean options such as 'no-igd' are specified as 'no-igd=1'.
# See 'salviumd --help' for all available options.
data-dir=/var/lib/salvium
log-file=/var/log/salvium/salvium.log
log-level=0
+20
View File
@@ -0,0 +1,20 @@
[Unit]
Description=Salvium Full Node
After=network.target
[Service]
User=salvium
Group=salvium
WorkingDirectory=~
StateDirectory=salvium
LogsDirectory=salvium
Type=simple
ExecStart=/usr/bin/salviumd --config-file /etc/salviumd.conf --non-interactive
StandardOutput=null
StandardError=null
Restart=always
[Install]
WantedBy=multi-user.target