updated to support propagation of the transaction type - this was necessary to distinguish between YIELD and TRANSFER type
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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"));
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user