Use an empty vector instead of optional<vector>

We don't do anything differently for a nullopt versus an empty vector,
so just return an empty vector for both not-at-the-hf and no-payments
cases.

(This also fixes a segfault and/or chainsync bug in the previous commit
because the optional is dereferenced without checking when on hf19).
This commit is contained in:
Jason Rhinelander 2022-05-25 17:27:55 -03:00
parent fd4ca4a57c
commit 902d7afe55
No known key found for this signature in database
GPG key ID: C4992CE7A88D4262
12 changed files with 38 additions and 49 deletions

View file

@ -186,14 +186,14 @@ namespace cryptonote {
return true;
}
std::optional<std::vector<cryptonote::batch_sn_payment>> BlockchainSQLite::get_sn_payments(uint64_t block_height) {
std::vector<cryptonote::batch_sn_payment> BlockchainSQLite::get_sn_payments(uint64_t block_height) {
LOG_PRINT_L3("BlockchainDB_SQLITE::" << __func__);
// <= here because we might have crap in the db that we don't clear until we actually add the HF
// block later on. (This is a pretty slim edge case that happened on devnet and is probably
// virtually impossible on mainnet).
if (block_height <= cryptonote::get_hard_fork_heights(m_nettype, hf::hf19_reward_batching).first.value_or(0))
return std::nullopt;
return {};
const auto& conf = get_config(m_nettype);
@ -216,7 +216,6 @@ namespace cryptonote {
}
} else {
MERROR("Invalid address returned from batching database: " << address);
return std::nullopt;
}
}
@ -365,7 +364,7 @@ namespace cryptonote {
};
// Goes through the miner transactions vouts checks they are right and marks them as paid in the database
if (!validate_batch_payment(miner_tx_vouts, *calculated_rewards, block_height)) {
if (!validate_batch_payment(miner_tx_vouts, calculated_rewards, block_height)) {
return false;
}

View file

@ -72,7 +72,7 @@ private:
public:
// get_payments -> passing a block height will return an array of payments that should be created in a coinbase transaction on that block given the current batching DB state.
std::optional<std::vector<cryptonote::batch_sn_payment>> get_sn_payments(uint64_t block_height);
std::vector<cryptonote::batch_sn_payment> get_sn_payments(uint64_t block_height);
// calculate_rewards -> takes the list of contributors from sn_info with their SN contribution
// amounts and will calculate how much of the block rewards should be the allocated to the

View file

@ -1393,8 +1393,8 @@ bool Blockchain::validate_miner_transaction(const block& b, size_t cumulative_bl
// TODO(oxen): eliminate all floating point math in reward calculations.
uint64_t max_base_reward = reward_parts.governance_paid + 1;
if (version >= hf::hf19_reward_batching && batched_sn_payments.has_value()) {
max_base_reward += std::accumulate(batched_sn_payments->begin(), batched_sn_payments->end(), uint64_t{0}, [&](auto a, auto b){return a + b.amount;});
if (version >= hf::hf19_reward_batching) {
max_base_reward += std::accumulate(batched_sn_payments.begin(), batched_sn_payments.end(), uint64_t{0}, [&](auto a, auto b){return a + b.amount;});
} else {
max_base_reward += reward_parts.base_miner + reward_parts.service_node_total;
}
@ -1642,7 +1642,7 @@ bool Blockchain::create_block_template_internal(block& b, const crypto::hash *fr
}
// This will check the batching database for who is due to be paid out in this block
std::optional<std::vector<cryptonote::batch_sn_payment>> sn_rwds = std::nullopt;
std::vector<cryptonote::batch_sn_payment> sn_rwds;
if (hf_version >= hf::hf19_reward_batching)
{
sn_rwds = m_sqlite_db->get_sn_payments(height); //Rewards to pay out

View file

@ -249,7 +249,7 @@ namespace cryptonote
uint64_t fee,
transaction& tx,
const oxen_miner_tx_context &miner_tx_context,
const std::optional<std::vector<cryptonote::batch_sn_payment>>& sn_rwds,
const std::vector<cryptonote::batch_sn_payment>& sn_rwds,
const std::string& extra_nonce,
hf hard_fork_version)
{
@ -425,9 +425,10 @@ namespace cryptonote
uint64_t total_sn_rewards = 0;
// Add batched SN rewards to the block:
if (sn_rwds)
if (!sn_rwds.empty())
{
for (const auto& reward : *sn_rwds)
assert(hard_fork_version >= hf::hf19_reward_batching);
for (const auto& reward : sn_rwds)
{
assert(reward.amount % BATCH_REWARD_FACTOR == 0);
auto atomic_amt = reward.amount / BATCH_REWARD_FACTOR;

View file

@ -129,7 +129,7 @@ namespace cryptonote
uint64_t fee,
transaction& tx,
const oxen_miner_tx_context &miner_context,
const std::optional<std::vector<cryptonote::batch_sn_payment>>& sn_rwds,
const std::vector<cryptonote::batch_sn_payment>& sn_rwds,
const std::string& extra_nonce,
hf hard_fork_version);

View file

@ -221,9 +221,9 @@ bool gen_block_no_miner_tx::generate(std::vector<test_event_entry>& events) cons
0, \
TX, \
cryptonote::oxen_miner_tx_context::miner_block(cryptonote::network_type::FAKECHAIN, miner_account.get_keys().m_account_address), \
std::nullopt, \
{}, \
cryptonote::hf::none); \
{}, \
cryptonote::hf::none); \
if (!r) \
return false;

View file

@ -851,7 +851,6 @@ oxen_blockchain_entry oxen_chain_generator::create_genesis_block(const cryptonot
// TODO(doyle): Does this evaluate to 0? If so we can simplify this a lot more
size_t target_block_weight = get_transaction_weight(blk.miner_tx);
std::optional<std::vector<cryptonote::batch_sn_payment>> sn_rwds;
while (true)
{
@ -862,7 +861,7 @@ oxen_blockchain_entry oxen_chain_generator::create_genesis_block(const cryptonot
0 /*total_fee*/,
blk.miner_tx,
cryptonote::oxen_miner_tx_context::miner_block(cryptonote::network_type::FAKECHAIN, miner.get_keys().m_account_address),
sn_rwds,
{},
std::string(),
hf_version_);
assert(constructed);
@ -1010,11 +1009,9 @@ bool oxen_chain_generator::block_begin(oxen_blockchain_entry &entry, oxen_create
}
size_t target_block_weight = txs_weight + get_transaction_weight(blk.miner_tx);
std::optional<std::vector<cryptonote::batch_sn_payment>> sn_rwds;
if (hf_version_ >= hf::hf19_reward_batching)
{
sn_rwds = sqlite_db_->get_sn_payments(height); //Rewards to pay out
}
auto sn_rwds = sqlite_db_->get_sn_payments(height);
if (hf_version_ < hf::hf19_reward_batching)
CHECK_AND_ASSERT_MES(sn_rwds.empty(), false, "batch payments should be empty before hf19");
uint64_t block_rewards = 0;
bool r;
while (true)
@ -1340,7 +1337,6 @@ bool test_generator::construct_block(cryptonote::block &blk,
size_t target_block_weight = txs_weight + get_transaction_weight(blk.miner_tx);
manual_calc_batched_governance(*this, prev_id, miner_tx_context, m_hf_version, height);
std::optional<std::vector<cryptonote::batch_sn_payment>> sn_rwds;
while (true)
{
auto [r, block_rewards] = construct_miner_tx(height,
@ -1350,7 +1346,7 @@ bool test_generator::construct_block(cryptonote::block &blk,
total_fee,
blk.miner_tx,
miner_tx_context,
sn_rwds,
{},
std::string(),
m_hf_version);
if (!r)
@ -1464,9 +1460,8 @@ bool test_generator::construct_block_manually(
miner_tx_context.nettype = cryptonote::network_type::FAKECHAIN;
manual_calc_batched_governance(*this, prev_id, miner_tx_context, m_hf_version, height);
std::optional<std::vector<cryptonote::batch_sn_payment>> sn_rwds;
size_t current_block_weight = txs_weight + get_transaction_weight(blk.miner_tx);
auto [r, block_rewards] = construct_miner_tx(height, tools::median(block_weights.begin(), block_weights.end()), already_generated_coins, current_block_weight, miner_fee, blk.miner_tx, cryptonote::oxen_miner_tx_context::miner_block(cryptonote::network_type::FAKECHAIN, miner_acc.get_keys().m_account_address), sn_rwds, std::string(), m_hf_version);
auto [r, block_rewards] = construct_miner_tx(height, tools::median(block_weights.begin(), block_weights.end()), already_generated_coins, current_block_weight, miner_fee, blk.miner_tx, cryptonote::oxen_miner_tx_context::miner_block(cryptonote::network_type::FAKECHAIN, miner_acc.get_keys().m_account_address), {}, std::string(), m_hf_version);
if (!r)
return false;
}

View file

@ -3793,20 +3793,20 @@ bool oxen_batch_sn_rewards_pop_blocks_after_big_cycle::generate(std::vector<test
cryptonote::Blockchain& blockchain = c.get_blockchain_storage();
uint64_t curr_height = blockchain.get_current_blockchain_height();
auto sqliteDB = blockchain.sqlite_db();
CHECK_EQ((*sqliteDB).height, curr_height - 1);
CHECK_EQ(sqliteDB->height, curr_height - 1);
blockchain.pop_blocks(conf.BATCHING_INTERVAL * 3 + 1);
CHECK_EQ((*sqliteDB).height + 1, blockchain.get_current_blockchain_height());
CHECK_EQ((*sqliteDB).height + 1, curr_height - conf.BATCHING_INTERVAL * 3 - 1);
CHECK_EQ(sqliteDB->height + 1, blockchain.get_current_blockchain_height());
CHECK_EQ(sqliteDB->height + 1, curr_height - conf.BATCHING_INTERVAL * 3 - 1);
curr_height = blockchain.get_current_blockchain_height();
auto records = (*sqliteDB).get_sn_payments(curr_height);
CHECK_EQ((*records).size(), 1);
CHECK_EQ((*records)[0].amount, amount);
CHECK_EQ(tools::view_guts((*records)[0].address_info.address), tools::view_guts(alice.get_keys().m_account_address));
auto records = sqliteDB->get_sn_payments(curr_height);
CHECK_EQ(records.size(), 1);
CHECK_EQ(records[0].amount, amount);
CHECK_EQ(tools::view_guts(records[0].address_info.address), tools::view_guts(alice.get_keys().m_account_address));
return true;
});

View file

@ -58,18 +58,17 @@ bool test_transaction_generation_and_ring_signature()
account_base rv_acc2;
rv_acc2.generate();
transaction tx_mine_1;
std::optional<std::vector<cryptonote::batch_sn_payment>> sn_rwds;
construct_miner_tx(0, 0, 0, 10, 0, tx_mine_1, cryptonote::oxen_miner_tx_context::miner_block(network_type::FAKECHAIN, miner_acc1.get_keys().m_account_address),sn_rwds,{},hf_max);
construct_miner_tx(0, 0, 0, 10, 0, tx_mine_1, cryptonote::oxen_miner_tx_context::miner_block(network_type::FAKECHAIN, miner_acc1.get_keys().m_account_address),{},{},hf_max);
transaction tx_mine_2;
construct_miner_tx(0, 0, 0, 0, 0, tx_mine_2, cryptonote::oxen_miner_tx_context::miner_block(network_type::FAKECHAIN, miner_acc2.get_keys().m_account_address),sn_rwds,{},hf_max);
construct_miner_tx(0, 0, 0, 0, 0, tx_mine_2, cryptonote::oxen_miner_tx_context::miner_block(network_type::FAKECHAIN, miner_acc2.get_keys().m_account_address),{},{},hf_max);
transaction tx_mine_3;
construct_miner_tx(0, 0, 0, 0, 0, tx_mine_3, cryptonote::oxen_miner_tx_context::miner_block(network_type::FAKECHAIN, miner_acc3.get_keys().m_account_address),sn_rwds,{},hf_max);
construct_miner_tx(0, 0, 0, 0, 0, tx_mine_3, cryptonote::oxen_miner_tx_context::miner_block(network_type::FAKECHAIN, miner_acc3.get_keys().m_account_address),{},{},hf_max);
transaction tx_mine_4;
construct_miner_tx(0, 0, 0, 0, 0, tx_mine_4, cryptonote::oxen_miner_tx_context::miner_block(network_type::FAKECHAIN, miner_acc4.get_keys().m_account_address),sn_rwds,{},hf_max);
construct_miner_tx(0, 0, 0, 0, 0, tx_mine_4, cryptonote::oxen_miner_tx_context::miner_block(network_type::FAKECHAIN, miner_acc4.get_keys().m_account_address),{},{},hf_max);
transaction tx_mine_5;
construct_miner_tx(0, 0, 0, 0, 0, tx_mine_5, cryptonote::oxen_miner_tx_context::miner_block(network_type::FAKECHAIN, miner_acc5.get_keys().m_account_address),sn_rwds,{},hf_max);
construct_miner_tx(0, 0, 0, 0, 0, tx_mine_5, cryptonote::oxen_miner_tx_context::miner_block(network_type::FAKECHAIN, miner_acc5.get_keys().m_account_address),{},{},hf_max);
transaction tx_mine_6;
construct_miner_tx(0, 0, 0, 0, 0, tx_mine_6, cryptonote::oxen_miner_tx_context::miner_block(network_type::FAKECHAIN, miner_acc6.get_keys().m_account_address),sn_rwds,{},hf_max);
construct_miner_tx(0, 0, 0, 0, 0, tx_mine_6, cryptonote::oxen_miner_tx_context::miner_block(network_type::FAKECHAIN, miner_acc6.get_keys().m_account_address),{},{},hf_max);
//fill inputs entry
typedef tx_source_entry::output_entry tx_output_entry;
@ -140,9 +139,8 @@ bool test_block_creation()
bool r = get_account_address_from_str(info, network_type::MAINNET, "0099be99c70ef10fd534c43c88e9d13d1c8853213df7e362afbec0e4ee6fec4948d0c190b58f4b356cd7feaf8d9d0a76e7c7e5a9a0a497a6b1faf7a765882dd08ac2");
CHECK_AND_ASSERT_MES(r, false, "failed to import");
block b;
std::optional<std::vector<cryptonote::batch_sn_payment>> sn_rwds;
uint64_t block_rewards = 0;
std::tie(r, block_rewards) = construct_miner_tx(90, tools::median(std::move(szs)), 3553616528562147, 33094, 10000000, b.miner_tx, cryptonote::oxen_miner_tx_context::miner_block(network_type::FAKECHAIN, info.address), sn_rwds, {}, hf_max);
std::tie(r, block_rewards) = construct_miner_tx(90, tools::median(std::move(szs)), 3553616528562147, 33094, 10000000, b.miner_tx, cryptonote::oxen_miner_tx_context::miner_block(network_type::FAKECHAIN, info.address), {}, {}, hf_max);
return r;
}

View file

@ -51,14 +51,13 @@ public:
using namespace cryptonote;
std::vector<tx_source_entry::output_entry> output_entries;
std::optional<std::vector<cryptonote::batch_sn_payment>> sn_rwds;
for (size_t i = 0; i < ring_size; ++i)
{
m_miners[i].generate();
uint64_t block_rewards = 0;
bool r;
std::tie(r, block_rewards) = construct_miner_tx(0, 0, 0, 2, 0, m_miner_txs[1], cryptonote::oxen_miner_tx_context::miner_block(network_type::FAKECHAIN, m_miners[i].get_keys().m_account_address), sn_rwds, {}, hf::none);
std::tie(r, block_rewards) = construct_miner_tx(0, 0, 0, 2, 0, m_miner_txs[1], cryptonote::oxen_miner_tx_context::miner_block(network_type::FAKECHAIN, m_miners[i].get_keys().m_account_address), {}, {}, hf::none);
if (!r)
return false;

View file

@ -44,12 +44,11 @@ public:
m_bob.generate();
oxen_miner_tx_context miner_tx_context = {};
std::optional<std::vector<cryptonote::batch_sn_payment>> sn_rwds;
miner_tx_context.miner_block_producer = m_bob.get_keys().m_account_address;
uint64_t block_rewards = 0;
bool r;
std::tie(r, block_rewards) = construct_miner_tx(0, 0, 0, 2, 0, m_tx, cryptonote::oxen_miner_tx_context::miner_block(network_type::FAKECHAIN, m_bob.get_keys().m_account_address), sn_rwds, {}, hf::none);
std::tie(r, block_rewards) = construct_miner_tx(0, 0, 0, 2, 0, m_tx, cryptonote::oxen_miner_tx_context::miner_block(network_type::FAKECHAIN, m_bob.get_keys().m_account_address), {}, {}, hf::none);
if (!r)
return false;

View file

@ -141,10 +141,9 @@ TEST(parse_and_validate_tx_extra, is_valid_tx_extra_parsed)
cryptonote::account_base acc;
acc.generate();
std::string b = "dsdsdfsdfsf";
std::optional<std::vector<cryptonote::batch_sn_payment>> sn_rwds;
uint64_t block_rewards = 0;
bool r;
std::tie(r, block_rewards) = cryptonote::construct_miner_tx(0, 0, 10000000000000, 1000, TEST_FEE, tx, cryptonote::oxen_miner_tx_context::miner_block(cryptonote::network_type::FAKECHAIN, acc.get_keys().m_account_address), sn_rwds, b, cryptonote::hf::none);
std::tie(r, block_rewards) = cryptonote::construct_miner_tx(0, 0, 10000000000000, 1000, TEST_FEE, tx, cryptonote::oxen_miner_tx_context::miner_block(cryptonote::network_type::FAKECHAIN, acc.get_keys().m_account_address), {}, b, cryptonote::hf::none);
ASSERT_TRUE(r);
crypto::public_key tx_pub_key = cryptonote::get_tx_pub_key_from_extra(tx);
ASSERT_NE(tx_pub_key, crypto::null_pkey);
@ -154,11 +153,10 @@ TEST(parse_and_validate_tx_extra, fails_on_big_extra_nonce)
cryptonote::transaction tx{};
cryptonote::account_base acc;
acc.generate();
std::optional<std::vector<cryptonote::batch_sn_payment>> sn_rwds;
std::string b(cryptonote::TX_EXTRA_NONCE_MAX_COUNT + 1, 0);
uint64_t block_rewards = 0;
bool r;
std::tie(r,block_rewards) = cryptonote::construct_miner_tx(0, 0, 10000000000000, 1000, TEST_FEE, tx, cryptonote::oxen_miner_tx_context::miner_block(cryptonote::network_type::FAKECHAIN, acc.get_keys().m_account_address), sn_rwds, b, cryptonote::hf::none);
std::tie(r,block_rewards) = cryptonote::construct_miner_tx(0, 0, 10000000000000, 1000, TEST_FEE, tx, cryptonote::oxen_miner_tx_context::miner_block(cryptonote::network_type::FAKECHAIN, acc.get_keys().m_account_address), {}, b, cryptonote::hf::none);
ASSERT_FALSE(r);
}
TEST(parse_and_validate_tx_extra, fails_on_wrong_size_in_extra_nonce)