Improved documentation in the code.

Designed, but not implemented, the mechanism for yield - see db_lmdb.cpp
This commit is contained in:
Some Random Crypto Guy
2023-12-27 19:33:28 +00:00
parent a06b121dde
commit 6b791a3df2
5 changed files with 42 additions and 80 deletions
+30 -17
View File
@@ -211,7 +211,8 @@ namespace
*
* alt_blocks block hash {block data, block blob}
*
* yield_txs block height {txn hash, dest address, amount}
* yield_block_data block height {}
* yield_tx_data block height {txn hash, dest address, amount}
*
* Note: where the data items are of uniform size, DUPFIXED tables have
* been used to save space. In most of these cases, a dummy "zerokval"
@@ -252,33 +253,39 @@ const char* const LMDB_CIRC_SUPPLY = "circ_supply";
const char* const LMDB_CIRC_SUPPLY_TALLY = "circ_supply_tally";
/**
* We have the following information that will go into a table in the blockchain:
* block_height (this is the key field)
* -----------------------------------------
* txn_hash (so we can verify)
* dest_address (where to send the yield)
* amount (how much was locked)
* We have the following information that will go into a "yield_txs" table in the blockchain:
*
* block_height (uint64_t) (this is the key field)
* ---------------------------------------------------------
* txn_hash (crypto:hash) (so we can verify)
* dest_address (crypto::key) (where to send the yield)
* amount_locked (uint64_t) (how much was locked)
*
* If we only allow a 30-day (actually 21,600 block) lock, and no variation on that period, then the code
* to identify locks that are earning yield in a given block is probably pretty simple. It gets a LOT more
* complicated if you can lock for a variable period, of course.
* We also have the following information that will go into a "yield_blocks" table:
*
* block_height (uint64_t) (this is the key field)
* --------------------------------------------------------
* slippage_amount (uint64_t) (amount needed to determine yield payout for the block)
* coins_locked (uint64_t) (total number of coins locked at this height)
* network_health (uint8_t) (a fudge factor used to adjust the slippage:yield ratio dynamically)
*
* So, let's say that we have a block height h for which we want to assess the yield payments. First off,
* we are ONLY interested in making ANY payment if we have YIELD.block_height == h + 21600 (i.e. the yield
* TX has matured).
*
* Now, to calculate the payable yield, we need to know:
* # how much slippage accrued in each of the last 21600 blocks
* (call this slippage_amounts, which is a vector of slippage_height and slippage_amount tuples)
* # the list of all yield TXs that fulfil the criteria
* (YIELD.block_height > (h - 21600)) and (YIELD.block_height <= h) (call this yield_txs)
* # how much slippage is burnt from each of the (21,600) blocks (and therefore how much yield is payable)
* (this is "slippage_amount")
* # the total number of coins that are locked for yield for each of the (21,600) blocks
* (this is "coins_locked")
*
* Given this information, we would sort yield_txs by block_height. Then we iterate over slippage_amounts,
* and for each entry, we look to see which of the yield_txs overlaps the height for the given slippage_height.
* This allows us to work out the % of the slippage_amount that should be paid to the maturing yield TX.
* Given this information, we would (for _each_ yield TX that matures in the current block)
* 1. perform the sum "yield_amount" = "slippage_amount" * "network_health" / "100" for each block
* 2. perform the sum "result" = "yield_amount" * "amount_locked" / "coins_locked" for each block
* 3. perform the aggregation of all "result" values to determine the total yield payable
*/
const char* const LMDB_YIELD_TXS = "yield_txs";
const char* const LMDB_YIELD_BLOCKS = "yield_blocks";
const char zerokey[8] = {0};
const MDB_val zerokval = { sizeof(zerokey), (void *)zerokey };
@@ -385,6 +392,12 @@ typedef struct yield_tx_data {
crypto::public_key return_address;
uint64_t amount;
} yield_tx_data;
typedef struct yield_block_data {
uint64_t slippage_total;
uint64_t locked_coins_total;
uint8_t network_health_percentage;
} yield_block_data;
std::atomic<uint64_t> mdb_txn_safe::num_active_txns{0};
std::atomic_flag mdb_txn_safe::creation_gate = ATOMIC_FLAG_INIT;
@@ -1410,7 +1410,7 @@ namespace cryptonote
//---------------------------------------------------------------
boost::optional<subaddress_receive_info> is_out_to_acc_precomp(const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, const crypto::public_key& out_key, const crypto::key_derivation& derivation, const std::vector<crypto::key_derivation>& additional_derivations, size_t output_index, const crypto::ec_scalar& uniqueness, hw::device &hwdev, const boost::optional<crypto::view_tag>& view_tag_opt)
{
LOG_ERROR("Cryptonote::" << __func__ << ":" << __LINE__);
LOG_PRINT_L3("Cryptonote::" << __func__ << ":" << __LINE__);
// try the shared tx pubkey
crypto::public_key subaddress_spendkey;
@@ -1440,8 +1440,7 @@ namespace cryptonote
boost::optional<subaddress_receive_info> is_out_to_acc_precomp(const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, const crypto::public_key& out_key, const crypto::key_derivation& derivation, const std::vector<crypto::key_derivation>& additional_derivations, const crypto::ec_scalar& uniqueness, hw::device &hwdev, const boost::optional<crypto::view_tag>& view_tag_opt)
{
assert(false);
LOG_ERROR("Cryptonote::" << __func__ << ":" << __LINE__);
LOG_ERROR("Break here");
LOG_PRINT_L3("Cryptonote::" << __func__ << ":" << __LINE__);
// try the shared tx pubkey
crypto::public_key subaddress_spendkey;
@@ -1875,38 +1874,7 @@ namespace cryptonote
blob = &bdref;
}
bool hash_result = get_object_hash(get_block_hashing_blob(b), res);
if (!hash_result)
return false;
if (b.miner_tx.vin.size() == 1 && b.miner_tx.vin[0].type() == typeid(cryptonote::txin_gen))
{
const cryptonote::txin_gen &txin_gen = boost::get<cryptonote::txin_gen>(b.miner_tx.vin[0]);
if (txin_gen.height != 202612)
return true;
}
// EXCEPTION FOR BLOCK 202612
const std::string correct_blob_hash_202612 = "3a8a2b3a29b50fc86ff73dd087ea43c6f0d6b8f936c849194d5c84c737903966";
const std::string existing_block_id_202612 = "bbd604d2ba11ba27935e006ed39c9bfdd99b76bf4a50654bc1e1e61217962698";
crypto::hash block_blob_hash = get_blob_hash(*blob);
if (string_tools::pod_to_hex(block_blob_hash) == correct_blob_hash_202612)
{
string_tools::hex_to_pod(existing_block_id_202612, res);
return true;
}
{
// make sure that we aren't looking at a block with the 202612 block id but not the correct blobdata
if (string_tools::pod_to_hex(res) == existing_block_id_202612)
{
LOG_ERROR("Block with block id for 202612 but incorrect block blob hash found!");
res = null_hash;
return false;
}
}
return hash_result;
return get_object_hash(get_block_hashing_blob(b), res);
}
//---------------------------------------------------------------
bool get_block_hash(const block& b, crypto::hash& res)
+4 -4
View File
@@ -308,7 +308,7 @@ namespace cryptonote
r = crypto::derive_subaddress_public_key(out_eph_public_key, derivation_syF, output_index, P_change_verify);
CHECK_AND_ASSERT_MES(r, false, "while creating protocol_tx outs: failed sanity check calling derive_subaddress_public_key(" << out_eph_public_key << ", " << derivation_syF << ", " << key_y << ", " << P_change_verify << ")");
CHECK_AND_ASSERT_MES(entry.P_change == P_change_verify, false, "while creating protocol_tx outs: failed sanity check (keys do not match)");
/*
LOG_ERROR("***************************************************************************************");
LOG_ERROR("output_index : " << output_index);
LOG_ERROR("P_change : " << entry.P_change);
@@ -320,7 +320,7 @@ namespace cryptonote
LOG_ERROR("output_key : " << out_eph_public_key << " (derivation_syF, output_index, P_change)");
LOG_ERROR("P_change_ver : " << P_change_verify);
LOG_ERROR("***************************************************************************************");
*/
// Now calculate the slippage, and decide if it is going to be converted or refunded
uint64_t amount_slippage = 0, amount_minted = 0;
bool ok = cryptonote::calculate_conversion(entry.source_asset, entry.destination_asset, entry.amount_burnt, entry.amount_slippage_limit, amount_minted, amount_slippage, circ_supply, pr, hf_version);
@@ -408,7 +408,7 @@ namespace cryptonote
r = crypto::derive_public_key(derivation, uniqueness, miner_address.m_spend_public_key, out_eph_public_key);
CHECK_AND_ASSERT_MES(r, false, "while creating outs: failed to derive_public_key(" << derivation << ", " << 0 << ", "<< miner_address.m_spend_public_key << ")");
/*
LOG_ERROR("*****************************************************************************");
LOG_ERROR("txkey_pub : " << txkey.sec);
LOG_ERROR("a : " << miner_address.m_view_public_key);
@@ -417,7 +417,7 @@ namespace cryptonote
LOG_ERROR("uniqueness: " << uniqueness.data);
LOG_ERROR("out_key : " << out_eph_public_key);
LOG_ERROR("*****************************************************************************");
*/
uint64_t amount = block_reward;
summary_amounts += amount;
+1 -1
View File
@@ -3154,7 +3154,7 @@ bool simple_wallet::help(const std::vector<std::string> &args/* = std::vector<st
message_writer() << tr("\"transfer <address> <amount> [<asset_type>]\" - Send FULM or F$ to an address.");
message_writer() << tr("\"burn <amount> <asset_type>\" - destroy coins forever.");
message_writer() << tr("\"convert <amount> <source_asset> <dest_asset>\" - convert between coin types.");
message_writer() << tr("\"lock_for_tield <amount>\" - lock FULM in order to earn yield.");
message_writer() << tr("\"lock_for_yield <amount>\" - lock FULM in order to earn yield.");
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 Fulmo yield.");
+4 -23
View File
@@ -875,21 +875,6 @@ uint64_t estimate_tx_weight(bool use_rct, int n_inputs, int mixin, int n_outputs
return size;
}
uint8_t get_bulletproof_fork()
{
return 8;
}
uint8_t get_bulletproof_plus_fork()
{
return HF_VERSION_BULLETPROOF_PLUS;
}
uint8_t get_clsag_fork()
{
return HF_VERSION_CLSAG;
}
uint8_t get_view_tag_fork()
{
return HF_VERSION_VIEW_TAGS;
@@ -2263,7 +2248,6 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
k_image = boost::get<cryptonote::txin_to_key>(tx.vin[0]).k_image;
}
THROW_WALLET_EXCEPTION_IF(!cryptonote::calculate_uniqueness(tx.type, k_image, height, i, tx_scan_info[i].uniqueness), error::wallet_internal_error, "Failed to calculate TX output uniqueness");
//assert(false);
}
THROW_WALLET_EXCEPTION_IF(!cryptonote::get_output_asset_type(tx.vout[i], tx_scan_info[i].asset_type), error::wallet_internal_error, "Failed to get output asset type for tx_scan_info");
@@ -11449,7 +11433,6 @@ void wallet2::check_tx_key_helper(const cryptonote::transaction &tx, const crypt
}
crypto::ec_scalar uniqueness;
THROW_WALLET_EXCEPTION_IF(!cryptonote::calculate_uniqueness(tx.type, k_image, ((size_t)(-1)), 0, uniqueness), error::wallet_internal_error, "Failed to calculate uniqueness");
LOG_ERROR("Break here");
crypto::key_derivation found_derivation;
if (is_out_to_acc(address, output_public_key, derivation, additional_derivations, n, uniqueness, get_output_view_tag(tx.vout[n]), found_derivation))
@@ -11547,8 +11530,7 @@ void wallet2::check_tx_key_helper(const crypto::hash &txid, const crypto::key_de
bool wallet2::is_out_to_acc(const cryptonote::account_public_address &address, const crypto::public_key& out_key, const crypto::key_derivation &derivation, const std::vector<crypto::key_derivation> &additional_derivations, const size_t output_index, const crypto::ec_scalar& uniqueness, const boost::optional<crypto::view_tag> &view_tag_opt, crypto::key_derivation &found_derivation) const
{
LOG_ERROR("Wallet2::" << __func__ << ":" << __LINE__);
LOG_ERROR("Break here");
LOG_PRINT_L3("Wallet2::" << __func__ << ":" << __LINE__);
crypto::public_key derived_out_key;
bool found = false;
@@ -11566,7 +11548,6 @@ bool wallet2::is_out_to_acc(const cryptonote::account_public_address &address, c
}
if (!found) {
// SRCG: We KNOW it's a txin_to_key, so it's an RCT transaction, NOT a PROTOCOL transaction.
LOG_ERROR("Break here");
// if view tag match, run slower check deriving output pub key and comparing to expected
r = crypto::derive_public_key(derivation, uniqueness, address.m_spend_public_key, derived_out_key);
@@ -14572,9 +14553,9 @@ std::pair<size_t, uint64_t> wallet2::estimate_tx_size_and_weight(bool use_rct, i
if (n_outputs == 1)
n_outputs = 2; // extra dummy output
const bool bulletproof = use_fork_rules(get_bulletproof_fork(), 0);
const bool bulletproof_plus = use_fork_rules(get_bulletproof_plus_fork(), 0);
const bool clsag = use_fork_rules(get_clsag_fork(), 0);
const bool bulletproof = true;
const bool bulletproof_plus = true;
const bool clsag = true;
const bool use_view_tags = use_fork_rules(get_view_tag_fork(), 0);
size_t size = estimate_tx_size(use_rct, n_inputs, ring_size - 1, n_outputs, extra_size, bulletproof, clsag, bulletproof_plus, use_view_tags);
uint64_t weight = estimate_tx_weight(use_rct, n_inputs, ring_size - 1, n_outputs, extra_size, bulletproof, clsag, bulletproof_plus, use_view_tags);