updated to support propagation of the transaction type - this was necessary to distinguish between YIELD and TRANSFER type

This commit is contained in:
Some Random Crypto Guy
2023-11-17 17:43:21 +00:00
parent 7f6b8daa49
commit ef27f6380e
34 changed files with 445 additions and 78 deletions
+20
View File
@@ -277,6 +277,8 @@ uint64_t BlockchainDB::add_block( const std::pair<block, blobdata>& blck
oracle::asset_type_counts num_rct_outs_by_asset_type;
blobdata miner_bd = tx_to_blob(blk.miner_tx);
add_transaction(blk_hash, std::make_pair(blk.miner_tx, blobdata_ref(miner_bd)));
blobdata protocol_bd = tx_to_blob(blk.protocol_tx);
add_transaction(blk_hash, std::make_pair(blk.protocol_tx, blobdata_ref(protocol_bd)));
if (blk.miner_tx.version == 2)
{
@@ -291,6 +293,19 @@ uint64_t BlockchainDB::add_block( const std::pair<block, blobdata>& blck
}
}
if (blk.protocol_tx.version == 2)
{
num_rct_outs += blk.protocol_tx.vout.size();
// count the current block's rct outs by asset type
for (auto& vout: blk.protocol_tx.vout) {
std::string asset_type;
if (!get_output_asset_type(vout, asset_type))
throw std::runtime_error("Failed to get output asset type");
num_rct_outs_by_asset_type.add(asset_type, 1);
}
}
int tx_i = 0;
crypto::hash tx_hash = crypto::null_hash;
for (const std::pair<transaction, blobdata>& tx : txs)
@@ -344,6 +359,7 @@ void BlockchainDB::pop_block(block& blk, std::vector<transaction>& txs)
txs.push_back(std::move(tx));
remove_transaction(h);
}
remove_transaction(get_transaction_hash(blk.protocol_tx));
remove_transaction(get_transaction_hash(blk.miner_tx));
}
@@ -364,6 +380,10 @@ void BlockchainDB::remove_transaction(const crypto::hash& tx_hash)
}
}
// Check for yield_tx entries
if (tx.type == cryptonote::transaction_type::YIELD) {
}
const bool miner_tx = tx.vin.size() == 1 && tx.vin[0].type() == typeid(txin_gen);
// need tx as tx.vout has the tx outputs, and the output amounts are needed
+70 -1
View File
@@ -211,6 +211,8 @@ namespace
*
* alt_blocks block hash {block data, block blob}
*
* yield_txs 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"
* key is used when accessing the table; the Key listed above will be
@@ -249,6 +251,35 @@ const char* const LMDB_PROPERTIES = "properties";
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)
*
*
* 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.
*
* 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)
*
* 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.
*/
const char* const LMDB_YIELD_TXS = "yield_txs";
const char zerokey[8] = {0};
const MDB_val zerokval = { sizeof(zerokey), (void *)zerokey };
@@ -350,7 +381,13 @@ typedef struct circ_supply_tally {
uint64_t amount_hi;
uint64_t amount_lo;
} circ_supply_tally;
typedef struct yield_tx_data {
crypto::hash tx_hash;
crypto::public_key destination_address;
uint64_t amount;
} yield_tx_data;
std::atomic<uint64_t> mdb_txn_safe::num_active_txns{0};
std::atomic_flag mdb_txn_safe::creation_gate = ATOMIC_FLAG_INIT;
@@ -973,6 +1010,7 @@ uint64_t BlockchainLMDB::add_transaction_data(const crypto::hash& blk_hash, cons
CURSOR(tx_indices)
CURSOR(circ_supply)
CURSOR(circ_supply_tally)
CURSOR(yield_txs)
MDB_val_set(val_tx_id, tx_id);
MDB_val_set(val_h, tx_hash);
@@ -1085,6 +1123,20 @@ uint64_t BlockchainLMDB::add_transaction_data(const crypto::hash& blk_hash, cons
"\nDest tally before mint =" << dest_tally.str() << "\nDest tally after mint =" << final_dest_tally.str());
}
// Is there yield_tx data to add?
if (tx.type == cryptonote::transaction_type::YIELD) {
// Create the object we are going to write to the database
yield_tx_data yield_data;
yield_data.tx_hash = tx_hash;
yield_data.destination_address = tx.destination_address;
yield_data.amount = tx.amount_burnt; // SRCG - this feels as though we are bastardising the variable for an invalid purpose
MDB_val_set(val_height, m_height);
MDB_val_set(val_yield_tx_data, yield_data);
result = mdb_cursor_put(m_cur_yield_txs, &val_height, &val_yield_tx_data, MDB_APPEND);
if (result)
throw0(DB_ERROR( lmdb_error("Failed to add tx yield data to db transaction: ", result).c_str() ));
}
return tx_id;
}
@@ -1107,6 +1159,7 @@ void BlockchainLMDB::remove_transaction_data(const crypto::hash& tx_hash, const
CURSOR(tx_outputs)
CURSOR(circ_supply)
CURSOR(circ_supply_tally)
CURSOR(yield_txs)
MDB_val_set(val_h, tx_hash);
@@ -1213,6 +1266,22 @@ void BlockchainLMDB::remove_transaction_data(const crypto::hash& tx_hash, const
throw1(DB_ERROR(lmdb_error("Failed to add removal of tx outputs to db transaction: ", result).c_str()));
}
// Is there yield_tx data to remove?
if (tx.type == cryptonote::transaction_type::YIELD) {
// Remove any yield_tx data for this transaction
result = mdb_cursor_get(m_cur_yield_txs, &val_tx_id, NULL, MDB_SET);
if (result == MDB_NOTFOUND)
LOG_PRINT_L1("tx has no yield_tx data to remove: " << tx_hash);
else if (result)
throw1(DB_ERROR(lmdb_error("Failed to locate yield_tx data for removal: ", result).c_str()));
if (!result)
{
result = mdb_cursor_del(m_cur_yield_txs, 0);
if (result)
throw1(DB_ERROR(lmdb_error("Failed to add removal of yield_tx data to db transaction: ", result).c_str()));
}
}
// Don't delete the tx_indices entry until the end, after we're done with val_tx_id
if (mdb_cursor_del(m_cur_tx_indices, 0))
throw1(DB_ERROR("Failed to add removal of tx index to db transaction"));
+4 -1
View File
@@ -76,6 +76,7 @@ typedef struct mdb_txn_cursors
MDB_cursor *m_txc_circ_supply;
MDB_cursor *m_txc_circ_supply_tally;
MDB_cursor *m_txc_yield_txs;
} mdb_txn_cursors;
@@ -98,9 +99,9 @@ typedef struct mdb_txn_cursors
#define m_cur_alt_blocks m_cursors->m_txc_alt_blocks
#define m_cur_hf_versions m_cursors->m_txc_hf_versions
#define m_cur_properties m_cursors->m_txc_properties
#define m_cur_circ_supply m_cursors->m_txc_circ_supply
#define m_cur_circ_supply_tally m_cursors->m_txc_circ_supply_tally
#define m_cur_yield_txs m_cursors->m_txc_yield_txs
typedef struct mdb_rflags
{
@@ -126,6 +127,7 @@ typedef struct mdb_rflags
bool m_rf_properties;
bool m_rf_circ_supply;
bool m_rf_circ_supply_tally;
bool m_rf_yield_txs;
} mdb_rflags;
typedef struct mdb_threadinfo
@@ -484,6 +486,7 @@ private:
MDB_dbi m_circ_supply;
MDB_dbi m_circ_supply_tally;
MDB_dbi m_yield_txs;
mutable uint64_t m_cum_size; // used in batch size estimation
mutable unsigned int m_cum_count;