townforge/tests/core_tests/cc.cpp
Crypto City 6bfc447544 custom items may now have a prestige bonus
only the game account can add prestige bonuses
2022-08-04 08:36:31 +00:00

3505 lines
149 KiB
C++

// Copyright (c) 2014-2019, The Monero Project
//
// 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 <boost/algorithm/string.hpp>
#include "ringct/rctSigs.h"
#include "chaingen.h"
#include "ringct/rctTypes.h"
#include "cc.h"
#include "cc/cc_game_update.h"
#include "device/device.hpp"
using namespace epee;
using namespace crypto;
using namespace cryptonote;
#define BASE_TEST_FORK 14
#define INITIAL_AUTO_FUNDING (17*COIN - CRYPTONOTE_CC_NEW_ACCOUNT_FEE)
#define BARE_TX_FEE 3000000
#define STARTING_BLOCK_1 400
#define STARTING_BLOCK_2 1500
#define STARTING_LABOUR 8500
#define N_LARGE_BALANCE_OUTS 350
#define PREDEFINED_BUILDINGS 1
#define FIRST_TEST_ACCOUNT 5
#define CRYPTONOTE_CC_NEW_ACCOUNT_FEE_MINUS_NEWBIE_COIN_GOLD (CRYPTONOTE_CC_NEW_ACCOUNT_FEE - NEWBIE_COIN_GOLD_CONTENT)
#define PREP_BUY_LAND_X 140
#define PREP_BUY_LAND_Y 20
#define PREP_BUY_LAND_WM1 11
#define PREP_BUY_LAND_HM1 11
static cryptonote::account_base cc_test_accounts[8];
static const uint64_t initial_funding[8] = {
INITIAL_AUTO_FUNDING,
INITIAL_AUTO_FUNDING,
INITIAL_AUTO_FUNDING,
CRYPTONOTE_CC_NEW_ACCOUNT_FEE + 1,
INITIAL_AUTO_FUNDING,
INITIAL_AUTO_FUNDING,
INITIAL_AUTO_FUNDING,
INITIAL_AUTO_FUNDING
};
static uint64_t expected_balance[8] = {
0, 0, 0, 0, 0, 0, 0, 0
};
static uint64_t expected_treasury_balance = 0;
static cryptonote::account_base dummy_change_account;
static void init_cc_test_accounts()
{
static bool init = false;
if (init)
return;
init = true;
for (size_t i = 0; i < sizeof(cc_test_accounts) / sizeof(cc_test_accounts[0]); ++i)
{
cc_test_accounts[i].generate();
}
dummy_change_account.generate();
}
static bool log_test_accounts(cryptonote::core &c, const std::vector<test_event_entry> &events)
{
BlockchainDB &db = c.get_blockchain_storage().get_db();
uint64_t total_money_in_accounts = 0, total_money_in_blockchain = 0;
static const char *name[5] = { "invalid", "mayor", "game", "foreclosure", "treasury" };
for (uint32_t n = 0; n < sizeof(name) / sizeof(name[0]); ++n)
{
crypto::public_key public_key;
uint64_t balance;
if (db.get_cc_account_transactional_data(n, public_key, balance))
{
MDEBUG(" account " << n << " (" << name[n] << "): " << public_key << ", balance " << cryptonote::print_money(balance));
total_money_in_accounts += balance;
}
}
std::vector<block> block_list;
bool r = c.get_blocks(0, c.get_current_blockchain_height(), block_list);
if (!r)
{
MERROR("Failed to get blocks");
return false;
}
std::vector<block> blocks(block_list.begin(), block_list.end());
std::vector<cryptonote::block> chain;
map_hash2tx_t mtx;
const crypto::hash block_hash = get_block_hash(block_list.back());
r = find_block_chain(events, chain, mtx, block_hash);
if (!r)
{
MERROR("Failed to find blockchain");
return false;
}
for (uint32_t n = 0; n < sizeof(cc_test_accounts) / sizeof(cc_test_accounts[0]); ++n)
{
uint64_t account_balance, blockchain_balance;
const crypto::public_key spend_public_key = cc::get_cc_public_key(cc_test_accounts[n].get_keys().m_spend_secret_key);
uint32_t id;
if (!db.lookup_cc_account(spend_public_key, id) || !db.get_cc_account_balance(id, account_balance))
account_balance = 0;
std::map<uint32_t, uint32_t> item_balances;
if (db.get_cc_account_item_balances(id, item_balances))
{
for (const auto &e: item_balances)
{
if (e.first < ITEM_FIRST_USER || e.first > ITEM_LAST_USER)
continue;
cc::cc_custom_item_t cid;
if (!db.get_cc_custom_item_data(e.first, cid))
{
MERROR("Failed to get item data");
return false;
}
if (cid.is_group)
continue;
account_balance += e.second * cid.gold;
}
}
blockchain_balance = get_balance(cc_test_accounts[n], blocks, mtx);
MDEBUG(" account " << n << ": " << spend_public_key
<< ", game account balance " << cryptonote::print_money(account_balance)
<< ", blockchain balance " << cryptonote::print_money(blockchain_balance));
total_money_in_accounts += account_balance;
total_money_in_blockchain += blockchain_balance;
}
MDEBUG("Total money in game accounts: " << cryptonote::print_money(total_money_in_accounts));
MDEBUG("Total money in blockchain: " << cryptonote::print_money(total_money_in_blockchain));
MDEBUG("Total money in both: " << cryptonote::print_money(total_money_in_accounts + total_money_in_blockchain));
const auto coinbase_tx_sum = c.get_coinbase_tx_sum(0, c.get_current_blockchain_height());
const boost::multiprecision::uint128_t emission = std::get<0>(coinbase_tx_sum);
const boost::multiprecision::uint128_t subsidy = std::get<2>(coinbase_tx_sum);
MDEBUG("Total coinbase emission: " << cryptonote::print_money(emission));
MDEBUG("Total game subsidy: " << cryptonote::print_money(subsidy));
if (emission > std::numeric_limits<uint64_t>::max() || subsidy > std::numeric_limits<uint64_t>::max())
{
MERROR("emission or subsidy too high");
return false;
}
if (total_money_in_accounts + total_money_in_blockchain != emission + subsidy)
{
MERROR("Some money is unaccounted for");
if (total_money_in_accounts + total_money_in_blockchain < emission + subsidy)
MERROR("Some money was destroyed: " << cryptonote::print_money(emission + subsidy - (total_money_in_accounts + total_money_in_blockchain)));
else
MERROR("More money exists than mined: " << cryptonote::print_money(total_money_in_accounts + total_money_in_blockchain - emission - subsidy));
return false;
}
return true;
}
static bool expect_cc_account(cryptonote::core &c, int idx, uint32_t expected_id, uint64_t expected_balance)
{
BlockchainDB &db = c.get_blockchain_storage().get_db();
uint32_t id;
const crypto::public_key pkey = cc::get_cc_public_key(cc_test_accounts[idx].get_keys().m_spend_secret_key);
if (!db.lookup_cc_account(pkey, id))
{
MERROR("Account " << idx << " (" << pkey << ") not found in database");
return false;
}
if (id != expected_id)
{
MERROR("Account has unexpected id");
return false;
}
crypto::public_key public_key;
uint64_t balance;
if (!db.get_cc_account_transactional_data(id, public_key, balance))
{
MERROR("Account transactional data not found in database");
return false;
}
if (public_key != pkey)
{
MERROR("Account has unexpected spend public key");
return false;
}
if (balance != expected_balance)
{
MERROR("Account " << idx << " has unexpected balance: expected " << cryptonote::print_money(expected_balance) << ", got " << cryptonote::print_money(balance));
return false;
}
return true;
}
static bool expect_treasury_balance(cryptonote::core &c, uint64_t expected_balance)
{
BlockchainDB &db = c.get_blockchain_storage().get_db();
uint32_t treasury;
if (!db.get_cc_city_treasury(0, treasury))
{
MERROR("City 0 treasury not found");
return false;
}
uint64_t balance;
if (!db.get_cc_account_balance(treasury, balance))
{
MERROR("City 0 treasury account not found");
return false;
}
if (balance != expected_balance)
{
MERROR("City 0 treasury account has unexpected balance: " << cryptonote::print_money(balance) << ", expected " << cryptonote::print_money(expected_balance));
return false;
}
return true;
}
static uint64_t get_subsidy_total(cryptonote::core &c, const std::vector<test_event_entry> &events)
{
uint64_t subsidy = 0;
for (size_t i = 0; i < events.size(); ++i)
{
const auto &e = events[i];
if (e.type() != typeid(cryptonote::block))
continue;
const cryptonote::block &block = boost::get<cryptonote::block>(e);
const uint64_t height = cryptonote::get_block_height(block);
if (!cryptonote::is_game_update_block(height))
continue;
const cryptonote::cc_command_game_update_t &cmd = boost::get<cryptonote::cc_command_game_update_t>(block.miner_tx.cc_cmd);
for (const auto &city: cmd.cities)
subsidy += city.subsidy;
}
return subsidy;
}
static bool expect_flag_tiles(cryptonote::core &c, uint32_t flag, const std::vector<std::vector<uint8_t>> &expected_tiles)
{
BlockchainDB &db = c.get_blockchain_storage().get_db();
cryptonote::cc_flag_data_t fd;
if (!db.get_cc_flag_data(flag, fd))
{
MERROR("Flag " << flag << " not found");
return false;
}
std::vector<std::vector<uint8_t>> tiles;
if (!cc::unpack_tiles(tiles, fd.tiles, fd.x1 - fd.x0 + 1, fd.y1 - fd.y0 + 1))
{
MERROR("Flag " << flag << " filed to unpack tiles");
return false;
}
if (tiles.size() != expected_tiles.size())
{
MERROR("Flag " << flag << " tiles aren't the expected size: " << tiles.size() << ", expected " << expected_tiles.size());
return false;
}
for (size_t i = 0; i < tiles.size(); ++i)
{
if (tiles[i] != expected_tiles[i])
{
MERROR("Flag " << flag << " has unexpected tiles at index " << i << ": " << tiles[i].size() << ", expected " << expected_tiles[i].size());
std::stringstream s;
for (const auto &e: tiles[i]) s << std::to_string(e) << " ";
MERROR(" actual tiles: " << s.str());
s = std::stringstream();
for (const auto &e: expected_tiles[i]) s << std::to_string(e) << " ";
MERROR(" expected tiles: " << s.str());
return false;
}
}
return true;
}
static bool expect_item_balances(cryptonote::core &c, uint32_t account, const std::vector<std::pair<uint32_t, uint32_t>> &expected_item_balances)
{
BlockchainDB &db = c.get_blockchain_storage().get_db();
cryptonote::cc_account_data_t data;
if (!db.get_cc_account_data(account, data))
{
MERROR("Failed to get item balances for account " << account);
return false;
}
for (uint32_t i = 0; i < NUM_PREDEFINED_ITEMS; ++i)
{
uint32_t expected_balance = 0;
for (const auto &e: expected_item_balances)
if (e.first == i)
expected_balance = e.second;
if (data.item_balances[i] != expected_balance)
{
MERROR("Unexpected " << cc::get_predefined_item_name(i) << " balance: " << data.item_balances[i] << ", expected " << expected_balance);
return false;
}
}
return true;
}
//----------------------------------------------------------------------------------------------------------------------
// Tests
bool gen_cc_tx_validation_base::generate_game_update_command(cryptonote::core &c, size_t ev_index, const std::vector<test_event_entry> &events_)
{
std::vector<test_event_entry> &events = const_cast<std::vector<test_event_entry>&>(events_);
if (ev_index + 1 >= events.size())
{
MERROR("event index is out of range");
return false;
}
auto &e = events[ev_index + 1];
if (e.type() != typeid(cryptonote::block))
{
MERROR("Game update event is not a block");
return false;
}
game_events.clear();
cryptonote::cc_command_game_update_t cg = cc::create_cc_game_update_command(c.get_blockchain_storage().get_db(), BASE_TEST_FORK, game_events);
auto &b = boost::get<cryptonote::block>(e);
b.miner_tx.cc_cmd = cg;
return true;
}
bool gen_cc_tx_validation_base::generate_with_full(std::vector<test_event_entry>& events,
const boost::optional<cryptonote::cc_account_source> &cc_source, boost::optional<cryptonote::cc_account_dest> cc_dest,
preparation_t preparation, unsigned int n_txes, unsigned int mixin, uint64_t amount_paid,
bool bare, const std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> &bare_cmds,
bool pop_block, validity_t validity, bool update,
const std::function<void(std::vector<tx_source_entry> &sources, std::vector<tx_destination_entry> &destinations)> &pre_tx,
const std::function<void(transaction &tx)> &post_tx) const
{
uint64_t ts_start = 1338224400;
std::vector<block> blockchain;
auto miner_account = cc_test_accounts[0];
MAKE_CC_GENESIS_BLOCK(events, blk_0, miner_account, ts_start);
blockchain.push_back(blk_0);
for (size_t i = 0; i < sizeof(expected_balance) / sizeof(expected_balance[0]); ++i)
expected_balance[i] = 0;
expected_treasury_balance = 0;
// create 8 miner accounts, and have them mine the next 8 blocks
const cryptonote::block *prev_block = &blk_0;
cryptonote::block blocks[8];
for (size_t n = 0; n < 8; ++n) {
CHECK_AND_ASSERT_MES(generator.construct_block_manually(blocks[n], *prev_block, cc_test_accounts[n],
test_generator::bf_major_ver | test_generator::bf_minor_ver | test_generator::bf_timestamp | test_generator::bf_hf_version,
14, 14, prev_block->timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN * 2, // v2 has blocks twice as long
crypto::hash(), 0, transaction(), std::vector<crypto::hash>(), 0, 0, 14),
false, "Failed to generate block");
events.push_back(blocks[n]);
prev_block = blocks + n;
blockchain.push_back(blocks[n]);
}
// rewind
cryptonote::block blk_last;
{
blk_last = *prev_block;
const size_t nblocks = CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW + mixin + (preparation == prep_large_balance ? N_LARGE_BALANCE_OUTS : preparation == prep_buy_stuff ? 8 : 0);
for (size_t i = 0; i < nblocks; ++i) // unlock enough blocks to have enough fake outs
{
cryptonote::block blk;
CHECK_AND_ASSERT_MES(generator.construct_block_manually(blk, blk_last, miner_account,
test_generator::bf_major_ver | test_generator::bf_minor_ver | test_generator::bf_timestamp | test_generator::bf_hf_version,
14, 14, blk_last.timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN * 2, // v2 has blocks twice as long
crypto::hash(), 0, transaction(), std::vector<crypto::hash>(), 0, 0, 14),
false, "Failed to generate block");
if (cryptonote::is_game_update_block(cryptonote::get_block_height(blk)))
{
blk.miner_tx.minor_version = 1;
DO_CALLBACK(events, "generate_game_update_command");
}
events.push_back(blk);
blk_last = blk;
blockchain.push_back(blk);
}
}
if (preparation != prep_none)
{
std::vector<crypto::hash> tx_hashes;
uint64_t tx_fees = 0;
for (size_t i = 0; i < 8; ++i)
{
// create a rct tx
std::vector<tx_source_entry> sources;
sources.resize(sources.size()+1);
tx_source_entry& src = sources.back();
src.real_output = i+1;
src.amount = blockchain[src.real_output].miner_tx.vout[0].amount;
src.real_out_tx_key = get_tx_pub_key_from_extra(blockchain[src.real_output].miner_tx);
src.real_output_in_tx_index = 0;
src.mask = rct::identity();
src.rct = true;
for (unsigned int m = 0; m <= mixin; ++m) {
rct::ctkey ctkey;
ctkey.dest = rct::pk2rct(boost::get<txout_to_key>(blockchain[m].miner_tx.vout[0].target).key);
ctkey.mask = rct::zeroCommit(blockchain[m].miner_tx.vout[0].amount);
src.outputs.push_back(std::make_pair(m, ctkey));
}
//fill outputs entry
tx_destination_entry td;
td.addr = miner_account.get_keys().m_account_address;
td.amount = 1;
std::vector<tx_destination_entry> destinations;
destinations.push_back(td);
// dummy output required from v12
td.addr = dummy_change_account.get_keys().m_account_address;
td.amount = 0;
destinations.push_back(td);
transaction tx;
crypto::secret_key tx_key;
std::vector<crypto::secret_key> additional_tx_keys;
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
const auto &sending_account = src.real_output > 0 && src.real_output <= 8 ? cc_test_accounts[src.real_output - 1] : miner_account;
subaddresses[sending_account.get_keys().m_account_address.m_spend_public_key] = {0,0};
const rct::RCTConfig rct_config = { rct::RangeProofPaddedBulletproof, 0 };
cc_account_dest cc_create_account_dest = {true, cc::get_cc_public_key(sending_account.get_keys().m_spend_secret_key), CRYPTONOTE_CC_NEW_ACCOUNT_FEE + initial_funding[i], "player " + std::to_string(i), 0};
expected_balance[i] += initial_funding[i];
expected_treasury_balance += CRYPTONOTE_CC_NEW_ACCOUNT_FEE - NEWBIE_COIN_GOLD_CONTENT;
bool r = construct_tx_and_get_tx_key(sending_account.get_keys(), subaddresses, sources, boost::none, destinations, cc_create_account_dest, cryptonote::account_public_address{}, std::vector<uint8_t>(), tx, 0, tx_key, additional_tx_keys, true, rct_config);
CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction");
tx_hashes.push_back(get_transaction_hash(tx));
tx_fees += cryptonote::get_tx_fee(tx);
events.push_back(tx);
}
cryptonote::block blk;
CHECK_AND_ASSERT_MES(generator.construct_block_manually(blk, blk_last, miner_account,
test_generator::bf_major_ver | test_generator::bf_minor_ver | test_generator::bf_timestamp | test_generator::bf_hf_version | test_generator::bf_tx_hashes | test_generator::bf_tx_fees,
14, 14, blk_last.timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN * 2, // v2 has blocks twice as long
crypto::hash(), 0, transaction(), tx_hashes, 0, 0, 14, tx_fees),
false, "Failed to generate block");
events.push_back(blk);
blk_last = blk;
blockchain.push_back(blk);
}
if (preparation == prep_large_balance || preparation == prep_buy_stuff)
{
// send lots of balance to an account
std::vector<tx_source_entry> sources;
const size_t n_outs = preparation == prep_large_balance ? N_LARGE_BALANCE_OUTS : 8;
size_t n_outs_this_time = 0;
uint64_t tx_fees = 0;
std::vector<crypto::hash> tx_hashes;
for (size_t i = 0; i < n_outs; ++i)
{
sources.resize(sources.size()+1);
tx_source_entry& src = sources.back();
src.real_output = 9;
src.amount = blockchain[src.real_output+i].miner_tx.vout[0].amount;
src.real_out_tx_key = get_tx_pub_key_from_extra(blockchain[src.real_output+i].miner_tx);
src.real_output_in_tx_index = 0;
src.mask = rct::identity();
src.rct = true;
for (unsigned int m = 0; m <= mixin; ++m) {
rct::ctkey ctkey;
ctkey.dest = rct::pk2rct(boost::get<txout_to_key>(blockchain[m+i].miner_tx.vout[0].target).key);
ctkey.mask = rct::zeroCommit(blockchain[m+i].miner_tx.vout[0].amount);
src.outputs.push_back(std::make_pair(m+i, ctkey));
}
++n_outs_this_time;
if (n_outs_this_time == 128 || i == n_outs - 1)
{
//fill outputs entry
tx_destination_entry td;
td.addr = miner_account.get_keys().m_account_address;
td.amount = 1;
std::vector<tx_destination_entry> destinations;
destinations.push_back(td);
// dummy output required from v12
td.addr = dummy_change_account.get_keys().m_account_address;
td.amount = 0;
destinations.push_back(td);
transaction tx;
crypto::secret_key tx_key;
std::vector<crypto::secret_key> additional_tx_keys;
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
const auto &sending_account = miner_account;
subaddresses[sending_account.get_keys().m_account_address.m_spend_public_key] = {0,0};
const rct::RCTConfig rct_config = { rct::RangeProofPaddedBulletproof, 0 };
const int dest_idx = preparation == prep_large_balance ? 3 : 0;
cc_account_dest cc_account_dest = {false, cc::get_cc_public_key(cc_test_accounts[dest_idx].get_keys().m_spend_secret_key), n_outs_this_time * 17*COIN, {}, 0};
expected_balance[dest_idx] += cc_account_dest.amount;
bool r = construct_tx_and_get_tx_key(sending_account.get_keys(), subaddresses, sources, boost::none, destinations, cc_account_dest, cryptonote::account_public_address{}, std::vector<uint8_t>(), tx, 0, tx_key, additional_tx_keys, true, rct_config);
CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction");
tx_hashes.push_back(cryptonote::get_transaction_hash(tx));
tx_fees += cryptonote::get_tx_fee(tx);
events.push_back(tx);
n_outs_this_time = 0;
sources.clear();
}
}
cryptonote::block blk;
CHECK_AND_ASSERT_MES(generator.construct_block_manually(blk, blk_last, miner_account,
test_generator::bf_major_ver | test_generator::bf_minor_ver | test_generator::bf_timestamp | test_generator::bf_hf_version | test_generator::bf_tx_hashes | test_generator::bf_tx_fees,
14, 14, blk_last.timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN * 2, // v2 has blocks twice as long
crypto::hash(), 0, transaction(), tx_hashes, 0, 0, 14, tx_fees),
false, "Failed to generate block");
events.push_back(blk);
blk_last = blk;
blockchain.push_back(blk);
}
if (preparation == prep_buy_stuff)
{
std::vector<crypto::hash> txs_hashes;
const uint32_t cc_account = FIRST_TEST_ACCOUNT;
transaction tx;
uint64_t fee = 0, tx_fees = 0;
cryptonote::cc_command_buy_land_t buy_land;
buy_land.cc_nonce = 4000;
buy_land.cc_account = cc_account;
buy_land.city = 0;
uint32_t ox, oy;
cc::get_city_origin(0, ox, oy);
buy_land.x = ox + PREP_BUY_LAND_X;
buy_land.y = oy + PREP_BUY_LAND_Y;
buy_land.wm1 = PREP_BUY_LAND_WM1;
buy_land.hm1 = PREP_BUY_LAND_HM1;
uint64_t cost;
if (!cc::get_new_flag_cost(buy_land.x, buy_land.y, buy_land.x + buy_land.wm1, buy_land.y + buy_land.hm1, ox, oy, cost))
return false;
fee = BARE_TX_FEE;
tx_fees += fee;
const auto &sending_account = cc_test_accounts[cc_account - FIRST_TEST_ACCOUNT];
CHECK_AND_ASSERT_MES(cost + fee <= expected_balance[cc_account - FIRST_TEST_ACCOUNT], false, "Underflow");
expected_balance[cc_account - FIRST_TEST_ACCOUNT] -= cost + fee;
expected_treasury_balance += cost;
bool r = construct_bare_tx(sending_account.get_keys(), buy_land, fee, tx);
CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction");
events.push_back(tx);
txs_hashes.push_back(get_transaction_hash(tx));
cryptonote::cc_command_buy_items_t buy_blocks;
buy_blocks.cc_account = cc_account;
static const uint32_t buy_amounts[] = { ITEM_BASIC_STONE, STARTING_BLOCK_1, ITEM_BASIC_WOOD, STARTING_BLOCK_2, ITEM_LABOUR, STARTING_LABOUR };
for (size_t i = 0; i < sizeof(buy_amounts) / sizeof(buy_amounts[0]); i += 2)
{
cryptonote::cc_command_buy_items_t::entry_t e;
e.type = buy_amounts[i];
e.amount = buy_amounts[i + 1];
buy_blocks.entries.push_back(e);
CHECK_AND_ASSERT_MES(cc::get_last_resort_price(e.type) * e.amount + fee <= expected_balance[cc_account - FIRST_TEST_ACCOUNT], false, "Underflow");
expected_balance[cc_account - FIRST_TEST_ACCOUNT] -= cc::get_last_resort_price(e.type) * e.amount;
expected_treasury_balance += cc::get_last_resort_price(e.type) * e.amount;
}
fee = BARE_TX_FEE;
tx_fees += fee;
expected_balance[cc_account - FIRST_TEST_ACCOUNT] -= fee;
r = construct_bare_tx(sending_account.get_keys(), buy_blocks, fee, tx);
CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction");
events.push_back(tx);
txs_hashes.push_back(get_transaction_hash(tx));
cryptonote::block blk;
CHECK_AND_ASSERT_MES(generator.construct_block_manually(blk, blk_last, miner_account,
test_generator::bf_major_ver | test_generator::bf_minor_ver | test_generator::bf_timestamp | test_generator::bf_hf_version | test_generator::bf_tx_hashes | test_generator::bf_tx_fees,
14, 14, blk_last.timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN * 2, // v2 has blocks twice as long
crypto::hash(), 0, transaction(), txs_hashes, 0, 0, 14, tx_fees),
false, "Failed to generate block");
events.push_back(blk);
blk_last = blk;
blockchain.push_back(blk);
}
crypto::hash last_tx_hash;
uint64_t tx_fee = 0;
for (unsigned i = 0; i < n_txes; ++i)
{
if (i == n_txes - 1 && update)
{
while (1)
{
cryptonote::block blk;
CHECK_AND_ASSERT_MES(generator.construct_block_manually(blk, blk_last, miner_account,
test_generator::bf_major_ver | test_generator::bf_minor_ver | test_generator::bf_timestamp | test_generator::bf_hf_version,
14, 14, blk_last.timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN * 2, // v2 has blocks twice as long
crypto::hash(), 0, transaction(), std::vector<crypto::hash>(), 0, 0, 14),
false, "Failed to generate block");
if (cryptonote::is_game_update_block(cryptonote::get_block_height(blk)))
{
blk.miner_tx.minor_version = 1;
DO_CALLBACK(events, "generate_game_update_command");
}
events.push_back(blk);
blk_last = blk;
blockchain.push_back(blk);
if (cryptonote::is_game_update_block(cryptonote::get_block_height(blk)))
break;
}
}
transaction tx;
if (bare)
{
uint64_t fee = 0;
cryptonote::cc_command_t cmd;
cryptonote::cc_command_transfer_t transfer;
if (i < bare_cmds.size())
{
cmd = std::get<1>(bare_cmds[i]);
fee = std::get<2>(bare_cmds[i]);
if (!std::get<0>(bare_cmds[i]).empty())
DO_CALLBACK(events, std::get<0>(bare_cmds[i]));
}
else
{
transfer.cc_account = FIRST_TEST_ACCOUNT;
transfer.in_amount = cc_source ? cc_source->amount : 0;
transfer.public_key = cc_dest ? cc_dest->public_key : crypto::null_pkey;
transfer.out_amount = cc_dest ? cc_dest->amount : 0;
cmd = transfer;
fee = BARE_TX_FEE;
}
const cryptonote::cc_command_base_t *base = cryptonote::get_cc_command_base(cmd);
CHECK_AND_ASSERT_MES(base, false, "Command base not found");
const auto &sending_account = cc_test_accounts[base->cc_account - FIRST_TEST_ACCOUNT];
bool r = construct_bare_tx(sending_account.get_keys(), cmd, fee, tx);
CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction");
tx_fee += fee;
}
else
{
// create a rct tx
std::vector<tx_source_entry> sources;
sources.resize(sources.size()+1);
tx_source_entry& src = sources.back();
unsigned int output_to_send = i == 0 ? 0 : (i+9);
src.real_output = output_to_send;
src.amount = blockchain[src.real_output].miner_tx.vout[0].amount;
src.real_out_tx_key = get_tx_pub_key_from_extra(blockchain[src.real_output].miner_tx);
src.real_output_in_tx_index = 0;
src.mask = rct::identity();
src.rct = true;
for (unsigned int m = 0; m <= mixin; ++m) {
rct::ctkey ctkey;
ctkey.dest = rct::pk2rct(boost::get<txout_to_key>(blockchain[m].miner_tx.vout[0].target).key);
ctkey.mask = rct::zeroCommit(blockchain[m].miner_tx.vout[0].amount);
src.outputs.push_back(std::make_pair(m, ctkey));
}
//fill outputs entry
tx_destination_entry td;
td.addr = miner_account.get_keys().m_account_address;
td.amount = amount_paid;
std::vector<tx_destination_entry> destinations;
destinations.push_back(td);
// dummy output required from v12
td.addr = dummy_change_account.get_keys().m_account_address;
td.amount = 0;
destinations.push_back(td);
if (pre_tx)
pre_tx(sources, destinations);
crypto::secret_key tx_key;
std::vector<crypto::secret_key> additional_tx_keys;
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
const auto &sending_account = src.real_output > 0 && src.real_output <= 8 ? cc_test_accounts[src.real_output - 1] : miner_account;
subaddresses[sending_account.get_keys().m_account_address.m_spend_public_key] = {0,0};
const rct::RCTConfig rct_config = { rct::RangeProofPaddedBulletproof, 0 };
bool r = construct_tx_and_get_tx_key(sending_account.get_keys(), subaddresses, sources, cc_source, destinations, cc_dest, cryptonote::account_public_address{}, std::vector<uint8_t>(), tx, 0, tx_key, additional_tx_keys, true, rct_config);
CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction");
tx_fee += tx.rct_signatures.txnFee;
}
if (post_tx)
post_tx(tx);
if (validity == invalid && i == n_txes-1)
DO_CALLBACK(events, "mark_invalid_tx");
events.push_back(tx);
last_tx_hash = get_transaction_hash(tx);
LOG_PRINT_L0("Test tx: " << obj_to_json_str(tx));
if (i+1 < n_txes)
{
cryptonote::block blk;
CHECK_AND_ASSERT_MES(generator.construct_block_manually(blk, blk_last, miner_account,
test_generator::bf_major_ver | test_generator::bf_minor_ver | test_generator::bf_timestamp | test_generator::bf_hf_version | test_generator::bf_tx_hashes | test_generator::bf_tx_fees,
14, 14, blk_last.timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN * 2, // v2 has blocks twice as long
crypto::hash(), 0, transaction(), std::vector<crypto::hash>(1, last_tx_hash), 0, 0, 14, tx_fee),
false, "Failed to generate block");
events.push_back(blk);
blk_last = blk;
blockchain.push_back(blk);
tx_fee = 0;
}
}
if (validity == valid || validity == invalid_on_block)
{
// include the tx in a block so its actions get executed
cryptonote::block blk;
CHECK_AND_ASSERT_MES(generator.construct_block_manually(blk, blk_last, miner_account,
test_generator::bf_major_ver | test_generator::bf_minor_ver | test_generator::bf_timestamp | test_generator::bf_hf_version | test_generator::bf_tx_hashes | test_generator::bf_tx_fees,
14, 14, blk_last.timestamp + DIFFICULTY_BLOCKS_ESTIMATE_TIMESPAN * 2, // v2 has blocks twice as long
crypto::hash(), 0, transaction(), std::vector<crypto::hash>(1, last_tx_hash), 0, 0, 14, tx_fee),
false, "Failed to generate block");
if (validity == invalid_on_block)
DO_CALLBACK(events, "mark_invalid_block");
events.push_back(blk);
blk_last = blk;
blockchain.push_back(blk);
if (pop_block)
events.push_back(pop_blocks(1));
DO_CALLBACK(events, "mark_check_final_state");
}
return true;
}
bool gen_cc_tx_validation_base::generate_with(std::vector<test_event_entry>& events,
const boost::optional<cryptonote::cc_account_source> &cc_source, boost::optional<cryptonote::cc_account_dest> cc_dest,
preparation_t preparation, unsigned int n_txes, unsigned int mixin, uint64_t amount_paid,
bool bare, const std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> &bare_cmds,
bool pop_block, validity_t validity,
const std::function<void(std::vector<tx_source_entry> &sources, std::vector<tx_destination_entry> &destinations)> &pre_tx,
const std::function<void(transaction &tx)> &post_tx) const
{
return generate_with_full(events, cc_source, cc_dest, preparation, n_txes, mixin, amount_paid, bare, bare_cmds, pop_block, validity, false, pre_tx, post_tx);
}
bool gen_cc_tx_valid_non_cc::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 1*COIN;
return generate_with(events, boost::none, boost::none, prep_none, 1, mixin, amount_paid, false, {}, false, valid, NULL, NULL);
}
bool gen_cc_tx_valid_non_cc::check_final_state(cryptonote::core &c, const std::vector<test_event_entry> &events)
{
return log_test_accounts(c, events)
&& expect_treasury_balance(c, 0);
}
bool gen_cc_tx_valid_create_account::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 1*COIN;
const cryptonote::cc_account_dest dest = {
true,
cc::get_cc_public_key(cc_test_accounts[7].get_keys().m_spend_secret_key),
CRYPTONOTE_CC_NEW_ACCOUNT_FEE,
"test name",
0
};
return generate_with(events, boost::none, dest, prep_none, 1, mixin, amount_paid, false, {}, false, valid, NULL, [](cryptonote::transaction &tx) {
const crypto::public_key pkey = cc_test_accounts[7].get_keys().m_account_address.m_spend_public_key;
const crypto::secret_key skey = cc_test_accounts[7].get_keys().m_spend_secret_key;
cc::generate_signature(cryptonote::get_transaction_prefix_hash_with_tag(tx), pkey, skey, tx.cc_account_signature);
});
}
bool gen_cc_tx_valid_create_account::check_final_state(cryptonote::core &c, const std::vector<test_event_entry> &events)
{
return log_test_accounts(c, events)
&& expect_cc_account(c, 7, FIRST_TEST_ACCOUNT, 0) && expect_treasury_balance(c, CRYPTONOTE_CC_NEW_ACCOUNT_FEE_MINUS_NEWBIE_COIN_GOLD);
}
bool gen_cc_tx_invalid_create_account_low_fee::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 1*COIN;
const cryptonote::cc_account_dest dest = {
true,
cc::get_cc_public_key(cc_test_accounts[7].get_keys().m_spend_secret_key),
CRYPTONOTE_CC_NEW_ACCOUNT_FEE - 1,
"test name",
0
};
return generate_with(events, boost::none, dest, prep_none, 1, mixin, amount_paid, false, {}, false, invalid, NULL, [](cryptonote::transaction &tx) {
const crypto::public_key pkey = cc_test_accounts[7].get_keys().m_account_address.m_spend_public_key;
const crypto::secret_key skey = cc_test_accounts[7].get_keys().m_spend_secret_key;
cc::generate_signature(cryptonote::get_transaction_prefix_hash_with_tag(tx), pkey, skey, tx.cc_account_signature);
});
}
bool gen_cc_tx_valid_create_account_including_deposit::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 1*COIN;
const cryptonote::cc_account_dest dest = {
true,
cc::get_cc_public_key(cc_test_accounts[7].get_keys().m_spend_secret_key),
CRYPTONOTE_CC_NEW_ACCOUNT_FEE + 42,
"test name",
0
};
return generate_with(events, boost::none, dest, prep_none, 1, mixin, amount_paid, false, {}, false, valid, NULL, [](cryptonote::transaction &tx) {
const crypto::public_key pkey = cc_test_accounts[7].get_keys().m_account_address.m_spend_public_key;
const crypto::secret_key skey = cc_test_accounts[7].get_keys().m_spend_secret_key;
cc::generate_signature(cryptonote::get_transaction_prefix_hash_with_tag(tx), pkey, skey, tx.cc_account_signature);
});
}
bool gen_cc_tx_valid_create_account_including_deposit::check_final_state(cryptonote::core &c, const std::vector<test_event_entry> &events)
{
return log_test_accounts(c, events)
&& expect_cc_account(c, 7, FIRST_TEST_ACCOUNT, 42) && expect_treasury_balance(c, CRYPTONOTE_CC_NEW_ACCOUNT_FEE_MINUS_NEWBIE_COIN_GOLD);
}
bool gen_cc_tx_invalid_cc_one_in_no_out_invalid_cc_account::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 1*COIN;
const cryptonote::cc_account_source source = {8, 1};
return generate_with(events, source, boost::none, prep_none, 1, mixin, amount_paid, false, {}, false, invalid, NULL, NULL);
}
bool gen_cc_tx_invalid_cc_one_in_one_out_invalid_cc_account::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 1*COIN;
const cryptonote::cc_account_source source = {8, 1};
const cryptonote::cc_account_dest dest = {
true,
cc::get_cc_public_key(cc_test_accounts[7].get_keys().m_spend_secret_key),
CRYPTONOTE_CC_NEW_ACCOUNT_FEE,
"test name",
0
};
return generate_with(events, source, dest, prep_none, 1, mixin, amount_paid, false, {}, false, invalid, NULL, NULL);
}
bool gen_cc_tx_valid_cc_4_accounts::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 1*COIN;
return generate_with(events, boost::none, boost::none, prep_create_accounts, 1, mixin, amount_paid, false, {}, false, valid, NULL, NULL);
}
bool gen_cc_tx_valid_cc_4_accounts::check_final_state(cryptonote::core &c, const std::vector<test_event_entry> &events)
{
return log_test_accounts(c, events)
&& expect_cc_account(c, 0, FIRST_TEST_ACCOUNT, initial_funding[0])
&& expect_cc_account(c, 1, FIRST_TEST_ACCOUNT + 1, initial_funding[1])
&& expect_cc_account(c, 2, FIRST_TEST_ACCOUNT + 2, initial_funding[2])
&& expect_cc_account(c, 3, FIRST_TEST_ACCOUNT + 3, initial_funding[3])
&& expect_cc_account(c, 4, FIRST_TEST_ACCOUNT + 4, initial_funding[4])
&& expect_cc_account(c, 5, FIRST_TEST_ACCOUNT + 5, initial_funding[5])
&& expect_cc_account(c, 6, FIRST_TEST_ACCOUNT + 6, initial_funding[6])
&& expect_cc_account(c, 7, FIRST_TEST_ACCOUNT + 7, initial_funding[7])
&& expect_treasury_balance(c, 8 * CRYPTONOTE_CC_NEW_ACCOUNT_FEE_MINUS_NEWBIE_COIN_GOLD);
}
bool gen_cc_tx_valid_cc_one_in_one_out::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 1*COIN;
const cryptonote::cc_account_source source = {FIRST_TEST_ACCOUNT, 1}; // FIRST_TEST_ACCOUNT is cc_test_accounts[0]
const cryptonote::cc_account_dest dest = {
false,
cc::get_cc_public_key(cc_test_accounts[1].get_keys().m_spend_secret_key),
5000,
"test name",
0
};
return generate_with(events, source, dest, prep_create_accounts, 1, mixin, amount_paid, false, {}, false, valid, NULL, NULL);
}
bool gen_cc_tx_valid_cc_one_in_one_out::check_final_state(cryptonote::core &c, const std::vector<test_event_entry> &events)
{
return log_test_accounts(c, events)
&& expect_cc_account(c, 0, FIRST_TEST_ACCOUNT, initial_funding[0] - 1)
&& expect_cc_account(c, 1, FIRST_TEST_ACCOUNT + 1, initial_funding[1] + 5000)
&& expect_cc_account(c, 2, FIRST_TEST_ACCOUNT + 2, initial_funding[2])
&& expect_cc_account(c, 3, FIRST_TEST_ACCOUNT + 3, initial_funding[3])
&& expect_cc_account(c, 4, FIRST_TEST_ACCOUNT + 4, initial_funding[4])
&& expect_cc_account(c, 5, FIRST_TEST_ACCOUNT + 5, initial_funding[5])
&& expect_cc_account(c, 6, FIRST_TEST_ACCOUNT + 6, initial_funding[6])
&& expect_cc_account(c, 7, FIRST_TEST_ACCOUNT + 7, initial_funding[7])
&& expect_treasury_balance(c, 8 * CRYPTONOTE_CC_NEW_ACCOUNT_FEE_MINUS_NEWBIE_COIN_GOLD);
}
bool gen_cc_tx_invalid_cc_one_in_one_out_more_than_inputs::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 17*COIN;
const cryptonote::cc_account_source source = {FIRST_TEST_ACCOUNT, 1}; // FIRST_TEST_ACCOUNT is cc_test_accounts[0]
const cryptonote::cc_account_dest dest = {
false,
cc::get_cc_public_key(cc_test_accounts[1].get_keys().m_spend_secret_key),
1*COIN,
"test name",
0
};
if (generate_with(events, source, dest, prep_create_accounts, 1, mixin, amount_paid, false, {}, false, invalid, NULL, NULL))
return false;
return true;
}
bool gen_cc_tx_valid_cc_one_in_one_out_more_than_rct_inputs_but_balance_is_large_enough::generate(std::vector<test_event_entry>& events) const
{
// input: 30 from game, 35 from rct
// output: 1, 50
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 1*COIN;
const cryptonote::cc_account_source source = {FIRST_TEST_ACCOUNT, 15*COIN}; // FIRST_TEST_ACCOUNT is cc_test_accounts[0]
const cryptonote::cc_account_dest dest = {
false,
cc::get_cc_public_key(cc_test_accounts[1].get_keys().m_spend_secret_key),
30*COIN,
"test name",
0
};
return generate_with(events, source, dest, prep_large_balance, 1, mixin, amount_paid, false, {}, false, valid, NULL, NULL);
}
bool gen_cc_tx_valid_cc_one_in_one_out_more_than_rct_inputs_but_balance_is_large_enough::check_final_state(cryptonote::core &c, const std::vector<test_event_entry> &events)
{
uint64_t subsidy = get_subsidy_total(c, events);
subsidy -= subsidy * MAYOR_PAYOUT + subsidy * GAME_PAYOUT;
return log_test_accounts(c, events)
&& expect_cc_account(c, 0, FIRST_TEST_ACCOUNT, initial_funding[0] - 15*COIN)
&& expect_cc_account(c, 1, FIRST_TEST_ACCOUNT + 1, initial_funding[1] + 30*COIN)
&& expect_cc_account(c, 2, FIRST_TEST_ACCOUNT + 2, initial_funding[2])
&& expect_cc_account(c, 3, FIRST_TEST_ACCOUNT + 3, initial_funding[3] + N_LARGE_BALANCE_OUTS*17*COIN) // from the large amount prep
&& expect_cc_account(c, 4, FIRST_TEST_ACCOUNT + 4, initial_funding[4])
&& expect_cc_account(c, 5, FIRST_TEST_ACCOUNT + 5, initial_funding[5])
&& expect_cc_account(c, 6, FIRST_TEST_ACCOUNT + 6, initial_funding[6])
&& expect_cc_account(c, 7, FIRST_TEST_ACCOUNT + 7, initial_funding[7])
&& expect_treasury_balance(c, 8 * CRYPTONOTE_CC_NEW_ACCOUNT_FEE_MINUS_NEWBIE_COIN_GOLD + subsidy);
}
bool gen_cc_tx_invalid_cc_one_in_one_out_more_than_rct_inputs_but_balance_is_not_large_enough::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 1*COIN;
const cryptonote::cc_account_source source = {FIRST_TEST_ACCOUNT, 40*COIN}; // FIRST_TEST_ACCOUNT is cc_test_accounts[0]
const cryptonote::cc_account_dest dest = {
false,
cc::get_cc_public_key(cc_test_accounts[1].get_keys().m_spend_secret_key),
50*COIN,
"test name",
0
};
return generate_with(events, source, dest, prep_large_balance, 1, mixin, amount_paid, false, {}, false, invalid, NULL, NULL);
}
bool gen_cc_tx_invalid_cc_multiple_txes_spend_more_than_balance::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 1*COIN;
const cryptonote::cc_account_source source = {FIRST_TEST_ACCOUNT, 15*COIN}; // FIRST_TEST_ACCOUNT is cc_test_accounts[0]
const cryptonote::cc_account_dest dest = {
false,
cc::get_cc_public_key(cc_test_accounts[1].get_keys().m_spend_secret_key),
5000,
"test name",
0
};
return generate_with(events, source, dest, prep_create_accounts, 2, mixin, amount_paid, false, {}, false, invalid, NULL, NULL);
}
bool gen_cc_tx_invalid_cc_bad_signature::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 1*COIN;
const cryptonote::cc_account_source source = {FIRST_TEST_ACCOUNT, 1}; // FIRST_TEST_ACCOUNT is cc_test_accounts[0]
const cryptonote::cc_account_dest dest = {
false,
cc::get_cc_public_key(cc_test_accounts[1].get_keys().m_spend_secret_key),
5000,
"test name",
0
};
return generate_with(events, source, dest, prep_create_accounts, 1, mixin, amount_paid, false, {}, false, invalid, NULL, [](transaction &tx) {
const auto &sender_account_keys = cc_test_accounts[0].get_keys();
cc::generate_signature(crypto::null_hash, sender_account_keys.m_account_address.m_spend_public_key, sender_account_keys.m_spend_secret_key, tx.cc_account_signature);
});
}
bool gen_cc_tx_invalid_cc_signature_by_wrong_keys::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 1*COIN;
const cryptonote::cc_account_source source = {FIRST_TEST_ACCOUNT, 1}; // FIRST_TEST_ACCOUNT is cc_test_accounts[0]
const cryptonote::cc_account_dest dest = {
false,
cc::get_cc_public_key(cc_test_accounts[1].get_keys().m_spend_secret_key),
5000,
"test name",
0
};
return generate_with(events, source, dest, prep_create_accounts, 1, mixin, amount_paid, false, {}, false, invalid, NULL, [](transaction &tx) {
const auto &sender_account_keys = cc_test_accounts[7].get_keys();
const crypto::hash tx_prefix_hash = get_transaction_prefix_hash(tx);
cc::generate_signature(tx_prefix_hash, sender_account_keys.m_account_address.m_spend_public_key, sender_account_keys.m_spend_secret_key, tx.cc_account_signature);
});
}
bool gen_cc_tx_valid_cc_one_in_no_out::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 1*COIN;
const cryptonote::cc_account_source source = {FIRST_TEST_ACCOUNT, 16*COIN}; // FIRST_TEST_ACCOUNT is cc_test_accounts[0]
return generate_with(events, source, boost::none, prep_create_accounts, 1, mixin, amount_paid, false, {}, false, valid, NULL, NULL);
}
bool gen_cc_tx_valid_cc_one_in_no_out::check_final_state(cryptonote::core &c, const std::vector<test_event_entry> &events)
{
return log_test_accounts(c, events)
&& expect_cc_account(c, 0, FIRST_TEST_ACCOUNT, initial_funding[0] - 16*COIN)
&& expect_cc_account(c, 1, FIRST_TEST_ACCOUNT + 1, initial_funding[1])
&& expect_cc_account(c, 2, FIRST_TEST_ACCOUNT + 2, initial_funding[2])
&& expect_cc_account(c, 3, FIRST_TEST_ACCOUNT + 3, initial_funding[3])
&& expect_cc_account(c, 4, FIRST_TEST_ACCOUNT + 4, initial_funding[4])
&& expect_cc_account(c, 5, FIRST_TEST_ACCOUNT + 5, initial_funding[5])
&& expect_cc_account(c, 6, FIRST_TEST_ACCOUNT + 6, initial_funding[6])
&& expect_cc_account(c, 7, FIRST_TEST_ACCOUNT + 7, initial_funding[7])
&& expect_treasury_balance(c, 8 * CRYPTONOTE_CC_NEW_ACCOUNT_FEE_MINUS_NEWBIE_COIN_GOLD);
}
bool gen_cc_tx_valid_cc_pop_reverts::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 1*COIN;
const cryptonote::cc_account_source source = {FIRST_TEST_ACCOUNT, 16*COIN}; // FIRST_TEST_ACCOUNT is cc_test_accounts[0]
return generate_with(events, source, boost::none, prep_create_accounts, 1, mixin, amount_paid, false, {}, true, valid, NULL, NULL);
}
bool gen_cc_tx_valid_cc_pop_reverts::check_final_state(cryptonote::core &c, const std::vector<test_event_entry> &events)
{
return log_test_accounts(c, events)
&& expect_cc_account(c, 0, FIRST_TEST_ACCOUNT, initial_funding[0])
&& expect_cc_account(c, 1, FIRST_TEST_ACCOUNT + 1, initial_funding[1])
&& expect_cc_account(c, 2, FIRST_TEST_ACCOUNT + 2, initial_funding[2])
&& expect_cc_account(c, 3, FIRST_TEST_ACCOUNT + 3, initial_funding[3])
&& expect_cc_account(c, 4, FIRST_TEST_ACCOUNT + 4, initial_funding[4])
&& expect_cc_account(c, 5, FIRST_TEST_ACCOUNT + 5, initial_funding[5])
&& expect_cc_account(c, 6, FIRST_TEST_ACCOUNT + 6, initial_funding[6])
&& expect_cc_account(c, 7, FIRST_TEST_ACCOUNT + 7, initial_funding[7])
&& expect_treasury_balance(c, 8 * CRYPTONOTE_CC_NEW_ACCOUNT_FEE_MINUS_NEWBIE_COIN_GOLD);
}
bool gen_cc_tx_invalid_cc_bare_one_in_no_out::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
const cryptonote::cc_account_source source = {FIRST_TEST_ACCOUNT, 1}; // FIRST_TEST_ACCOUNT is cc_test_accounts[0]
return generate_with(events, source, boost::none, prep_create_accounts, 1, mixin, amount_paid, true, {}, false, invalid, NULL, NULL);
}
bool gen_cc_tx_invalid_cc_bare_no_in_one_out::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
const cryptonote::cc_account_dest dest = {
true,
cc::get_cc_public_key(cc_test_accounts[3].get_keys().m_spend_secret_key),
1,
"test name",
0
};
return generate_with(events, boost::none, dest, prep_create_accounts, 1, mixin, amount_paid, true, {}, false, invalid, NULL, NULL);
}
bool gen_cc_tx_valid_cc_bare_one_in_one_out::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
const cryptonote::cc_account_source source = {FIRST_TEST_ACCOUNT, 1234567890}; // FIRST_TEST_ACCOUNT is cc_test_accounts[0]
const cryptonote::cc_account_dest dest = {
true,
cc::get_cc_public_key(cc_test_accounts[3].get_keys().m_spend_secret_key),
1234567890,
"test name",
0
};
return generate_with(events, source, dest, prep_create_accounts, 1, mixin, amount_paid, true, {}, false, valid, NULL, NULL);
}
bool gen_cc_tx_valid_cc_bare_one_in_one_out::check_final_state(cryptonote::core &c, const std::vector<test_event_entry> &events)
{
return log_test_accounts(c, events)
&& expect_cc_account(c, 0, FIRST_TEST_ACCOUNT, initial_funding[0] - 1234567890 - BARE_TX_FEE)
&& expect_cc_account(c, 1, FIRST_TEST_ACCOUNT + 1, initial_funding[1])
&& expect_cc_account(c, 2, FIRST_TEST_ACCOUNT + 2, initial_funding[2])
&& expect_cc_account(c, 3, FIRST_TEST_ACCOUNT + 3, initial_funding[3] + 1234567890)
&& expect_cc_account(c, 4, FIRST_TEST_ACCOUNT + 4, initial_funding[4])
&& expect_cc_account(c, 5, FIRST_TEST_ACCOUNT + 5, initial_funding[5])
&& expect_cc_account(c, 6, FIRST_TEST_ACCOUNT + 6, initial_funding[6])
&& expect_cc_account(c, 7, FIRST_TEST_ACCOUNT + 7, initial_funding[7])
&& expect_treasury_balance(c, 8 * CRYPTONOTE_CC_NEW_ACCOUNT_FEE_MINUS_NEWBIE_COIN_GOLD);
}
bool gen_cc_tx_invalid_cc_bare_transfer_whole_balance_nothing_left_for_fee::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
uint64_t balance = 34*COIN;
const cryptonote::cc_account_source source = {FIRST_TEST_ACCOUNT, balance}; // FIRST_TEST_ACCOUNT is cc_test_accounts[0]
const cryptonote::cc_account_dest dest = {
true,
cc::get_cc_public_key(cc_test_accounts[3].get_keys().m_spend_secret_key),
balance,
"test name",
0
};
return generate_with(events, source, dest, prep_create_accounts, 1, mixin, amount_paid, true, {}, false, invalid, NULL, NULL);
}
uint64_t gen_cc_tx_valid_cc_bare_buy_land_min_size::land_cost = 0;
bool gen_cc_tx_valid_cc_bare_buy_land_min_size::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_buy_land_t cmd;
cmd.cc_account = FIRST_TEST_ACCOUNT;
cmd.city = 0;
uint32_t ox, oy;
cc::get_city_origin(0, ox, oy);
cmd.x = ox + 100;
cmd.y = oy + 200;
cmd.wm1 = 11;
cmd.hm1 = 11;
if (!cc::get_new_flag_cost(cmd.x, cmd.y, cmd.x + cmd.wm1, cmd.y + cmd.hm1, ox, oy, land_cost))
return false;
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_create_accounts, 1, mixin, amount_paid, true, cmds, false, valid, NULL, NULL);
}
bool gen_cc_tx_valid_cc_bare_buy_land_min_size::check_final_state(cryptonote::core &c, const std::vector<test_event_entry> &events)
{
return log_test_accounts(c, events)
&& expect_cc_account(c, 0, FIRST_TEST_ACCOUNT, initial_funding[0] - land_cost - BARE_TX_FEE)
&& expect_cc_account(c, 1, FIRST_TEST_ACCOUNT + 1, initial_funding[1])
&& expect_cc_account(c, 2, FIRST_TEST_ACCOUNT + 2, initial_funding[2])
&& expect_cc_account(c, 3, FIRST_TEST_ACCOUNT + 3, initial_funding[3])
&& expect_cc_account(c, 4, FIRST_TEST_ACCOUNT + 4, initial_funding[4])
&& expect_cc_account(c, 5, FIRST_TEST_ACCOUNT + 5, initial_funding[5])
&& expect_cc_account(c, 6, FIRST_TEST_ACCOUNT + 6, initial_funding[6])
&& expect_cc_account(c, 7, FIRST_TEST_ACCOUNT + 7, initial_funding[7])
&& expect_treasury_balance(c, 8 * CRYPTONOTE_CC_NEW_ACCOUNT_FEE_MINUS_NEWBIE_COIN_GOLD + land_cost);
}
uint64_t gen_cc_tx_valid_cc_bare_buy_land_max_size::land_cost = 0;
bool gen_cc_tx_valid_cc_bare_buy_land_max_size::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_transfer_t transfer;
transfer.cc_account = FIRST_TEST_ACCOUNT + 1;
transfer.in_amount = 15*COIN;
transfer.public_key = cc::get_cc_public_key(cc_test_accounts[0].get_keys().m_spend_secret_key);
transfer.out_amount = 15*COIN;
cmds.push_back(std::make_tuple("", transfer, BARE_TX_FEE));
transfer.cc_account = FIRST_TEST_ACCOUNT + 2;
transfer.in_amount = 15*COIN;
transfer.public_key = cc::get_cc_public_key(cc_test_accounts[0].get_keys().m_spend_secret_key);
transfer.out_amount = 15*COIN;
cmds.push_back(std::make_tuple("", transfer, BARE_TX_FEE));
transfer.cc_account = FIRST_TEST_ACCOUNT + 4;
transfer.in_amount = 15*COIN;
transfer.public_key = cc::get_cc_public_key(cc_test_accounts[0].get_keys().m_spend_secret_key);
transfer.out_amount = 15*COIN;
cmds.push_back(std::make_tuple("", transfer, BARE_TX_FEE));
uint32_t ox, oy;
cc::get_city_origin(0, ox, oy);
cryptonote::cc_command_buy_land_t cmd;
cmd.cc_account = FIRST_TEST_ACCOUNT + 3;
cmd.city = 0;
cmd.x = ox + 100;
cmd.y = oy + 200;
cmd.wm1 = 255;
cmd.hm1 = 255;
if (!cc::get_new_flag_cost(cmd.x, cmd.y, cmd.x + cmd.wm1, cmd.y + cmd.hm1, ox, oy, land_cost))
return false;
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_large_balance, 4, mixin, amount_paid, true, cmds, false, valid, NULL, NULL);
}
bool gen_cc_tx_valid_cc_bare_buy_land_max_size::check_final_state(cryptonote::core &c, const std::vector<test_event_entry> &events)
{
uint64_t subsidy = get_subsidy_total(c, events);
subsidy -= subsidy * MAYOR_PAYOUT + subsidy * GAME_PAYOUT;
return log_test_accounts(c, events)
&& expect_cc_account(c, 0, FIRST_TEST_ACCOUNT, initial_funding[0] + 3 * 15*COIN)
&& expect_cc_account(c, 1, FIRST_TEST_ACCOUNT + 1, initial_funding[1] - 15*COIN - BARE_TX_FEE)
&& expect_cc_account(c, 2, FIRST_TEST_ACCOUNT + 2, initial_funding[2] - 15*COIN - BARE_TX_FEE)
&& expect_cc_account(c, 3, FIRST_TEST_ACCOUNT + 3, initial_funding[3] + N_LARGE_BALANCE_OUTS * 17 * COIN - land_cost - BARE_TX_FEE)
&& expect_cc_account(c, 4, FIRST_TEST_ACCOUNT + 4, initial_funding[4] - 15*COIN - BARE_TX_FEE)
&& expect_cc_account(c, 5, FIRST_TEST_ACCOUNT + 5, initial_funding[5])
&& expect_cc_account(c, 6, FIRST_TEST_ACCOUNT + 6, initial_funding[6])
&& expect_cc_account(c, 7, FIRST_TEST_ACCOUNT + 7, initial_funding[7])
&& expect_treasury_balance(c, 8 * CRYPTONOTE_CC_NEW_ACCOUNT_FEE_MINUS_NEWBIE_COIN_GOLD + land_cost + subsidy);
}
bool gen_cc_tx_invalid_cc_bare_buy_land_too_small::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
uint64_t cost;
uint32_t ox, oy;
cc::get_city_origin(0, ox, oy);
cryptonote::cc_command_buy_land_t cmd;
cmd.cc_account = FIRST_TEST_ACCOUNT;
cmd.city = 0;
cmd.x = ox + 100;
cmd.y = ox + 200;
cmd.wm1 = MIN_BUY_SIDE_SIZE - 2;
cmd.hm1 = MIN_BUY_SIDE_SIZE - 2;
if (!cc::get_new_flag_cost(cmd.x, cmd.y, cmd.x + cmd.wm1, cmd.y + cmd.hm1, ox, oy, cost))
return false;
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_create_accounts, 1, mixin, amount_paid, true, cmds, false, invalid, NULL, NULL);
}
bool gen_cc_tx_invalid_cc_bare_buy_land_not_enough_balance::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
uint64_t cost;
uint32_t ox, oy;
cc::get_city_origin(0, ox, oy);
cryptonote::cc_command_buy_land_t cmd;
cmd.cc_account = FIRST_TEST_ACCOUNT + 3;
cmd.city = 0;
cmd.x = ox + 100;
cmd.y = oy + 200;
cmd.wm1 = 255;
cmd.hm1 = 255;
if (!cc::get_new_flag_cost(cmd.x, cmd.y, cmd.x + cmd.wm1, cmd.y + cmd.hm1, ox, oy, cost))
return false;
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_create_accounts, 1, mixin, amount_paid, true, cmds, false, invalid, NULL, NULL);
}
bool gen_cc_tx_invalid_cc_bare_buy_land_overlapping::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_buy_land_t cmd;
uint64_t cost;
uint32_t ox, oy;
cc::get_city_origin(0, ox, oy);
cmd.cc_account = FIRST_TEST_ACCOUNT;
cmd.city = 0;
cmd.x = ox + 134;
cmd.y = oy + 134;
cmd.wm1 = 11;
cmd.hm1 = 11;
if (!cc::get_new_flag_cost(cmd.x, cmd.y, cmd.x + cmd.wm1, cmd.y + cmd.hm1, ox, oy, cost))
return false;
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
cmd.cc_account = FIRST_TEST_ACCOUNT + 1;
cmd.city = 0;
cmd.x = ox + 133;
cmd.y = oy + 134;
cmd.wm1 = 6;
cmd.hm1 = 4;
if (!cc::get_new_flag_cost(cmd.x, cmd.y, cmd.x + cmd.wm1, cmd.y + cmd.hm1, ox, oy, cost))
return false;
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_create_accounts, 2, mixin, amount_paid, true, cmds, false, invalid, NULL, NULL);
}
bool gen_cc_tx_valid_cc_bare_build_whole_flag::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
// build a checker pattern
cryptonote::cc_command_building_settings_t settings;
settings.cc_account = FIRST_TEST_ACCOUNT;
settings.flag = 1 + PREDEFINED_BUILDINGS;
settings.role = ROLE_RESIDENTIAL1;
settings.economic_power = 100;
settings.construction_height = 89; // brittle
cmds.push_back(std::make_tuple("", settings, BARE_TX_FEE));
cryptonote::cc_command_assign_items_t assign;
assign.cc_account = FIRST_TEST_ACCOUNT;
assign.flag = 1 + PREDEFINED_BUILDINGS;
assign.items.push_back({ITEM_BASIC_STONE, 20});
assign.items.push_back({ITEM_BASIC_WOOD, 30});
cmds.push_back(std::make_tuple("", assign, BARE_TX_FEE));
cryptonote::cc_command_build_t cmd;
cmd.cc_account = FIRST_TEST_ACCOUNT;
cmd.flag = 1 + PREDEFINED_BUILDINGS;
cmd.dx = 0;
cmd.dy = 0;
cmd.wm1 = 3;
cmd.hm1 = 3;
cmd.height = 0;
cmd.remove = false;
static const uint8_t S = ITEM_BASIC_STONE;
static const uint8_t block_data[] = { 16-1, 0, S, 0, S, 0, S, 0, S, 0, S, 0, S, 0, S, 0, S };
cmd.block_data = std::vector<uint8_t>(block_data, block_data + sizeof(block_data));
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, valid, NULL, NULL);
}
bool gen_cc_tx_valid_cc_bare_build_whole_flag::check_final_state(cryptonote::core &c, const std::vector<test_event_entry> &events)
{
return log_test_accounts(c, events)
&& expect_cc_account(c, 0, FIRST_TEST_ACCOUNT, expected_balance[0] - 3 * BARE_TX_FEE)
&& expect_cc_account(c, 1, FIRST_TEST_ACCOUNT + 1, expected_balance[1])
&& expect_cc_account(c, 2, FIRST_TEST_ACCOUNT + 2, expected_balance[2])
&& expect_cc_account(c, 3, FIRST_TEST_ACCOUNT + 3, expected_balance[3])
&& expect_cc_account(c, 4, FIRST_TEST_ACCOUNT + 4, initial_funding[4])
&& expect_cc_account(c, 5, FIRST_TEST_ACCOUNT + 5, initial_funding[5])
&& expect_cc_account(c, 6, FIRST_TEST_ACCOUNT + 6, initial_funding[6])
&& expect_cc_account(c, 7, FIRST_TEST_ACCOUNT + 7, initial_funding[7])
&& expect_treasury_balance(c, expected_treasury_balance)
&& expect_flag_tiles(c, 1 + PREDEFINED_BUILDINGS, { {}, {1}, {}, {1}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {1}, {}, {1}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {1}, {}, {1}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {1}, {}, {1}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {} });
}
bool gen_cc_tx_valid_cc_bare_build_part_of_flag::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_building_settings_t settings;
settings.cc_account = FIRST_TEST_ACCOUNT;
settings.flag = 1 + PREDEFINED_BUILDINGS;
settings.role = ROLE_RESIDENTIAL1;
settings.economic_power = 100;
settings.construction_height = 89; // brittle
cmds.push_back(std::make_tuple("", settings, BARE_TX_FEE));
cryptonote::cc_command_assign_items_t assign;
assign.cc_account = FIRST_TEST_ACCOUNT;
assign.flag = 1 + PREDEFINED_BUILDINGS;
assign.items.push_back({ITEM_BASIC_STONE, 20});
assign.items.push_back({ITEM_BASIC_WOOD, 30});
cmds.push_back(std::make_tuple("", assign, BARE_TX_FEE));
// build a checker pattern
cryptonote::cc_command_build_t cmd;
cmd.cc_account = FIRST_TEST_ACCOUNT;
cmd.flag = 1 + PREDEFINED_BUILDINGS;
cmd.dx = 1;
cmd.dy = 2;
cmd.wm1 = 1;
cmd.hm1 = 1;
cmd.height = 0;
cmd.remove = false;
static const uint8_t S = ITEM_BASIC_STONE;
static const uint8_t block_data[] = { 4-1, 0, S, 0, S };
cmd.block_data = std::vector<uint8_t>(block_data, block_data + sizeof(block_data));
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, valid, NULL, NULL);
}
bool gen_cc_tx_valid_cc_bare_build_part_of_flag::check_final_state(cryptonote::core &c, const std::vector<test_event_entry> &events)
{
return log_test_accounts(c, events)
&& expect_cc_account(c, 0, FIRST_TEST_ACCOUNT, expected_balance[0] - 3 * BARE_TX_FEE)
&& expect_cc_account(c, 1, FIRST_TEST_ACCOUNT + 1, expected_balance[1])
&& expect_cc_account(c, 2, FIRST_TEST_ACCOUNT + 2, expected_balance[2])
&& expect_cc_account(c, 3, FIRST_TEST_ACCOUNT + 3, expected_balance[3])
&& expect_cc_account(c, 4, FIRST_TEST_ACCOUNT + 4, initial_funding[4])
&& expect_cc_account(c, 5, FIRST_TEST_ACCOUNT + 5, initial_funding[5])
&& expect_cc_account(c, 6, FIRST_TEST_ACCOUNT + 6, initial_funding[6])
&& expect_cc_account(c, 7, FIRST_TEST_ACCOUNT + 7, initial_funding[7])
&& expect_treasury_balance(c, expected_treasury_balance)
&& expect_flag_tiles(c, 1 + PREDEFINED_BUILDINGS, {{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {1}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {1}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {} });
}
bool gen_cc_tx_invalid_cc_bare_build_out_of_flag::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_building_settings_t settings;
settings.cc_account = FIRST_TEST_ACCOUNT;
settings.flag = 1 + PREDEFINED_BUILDINGS;
settings.role = ROLE_RESIDENTIAL1;
settings.economic_power = 100;
settings.construction_height = 89; // brittle
cmds.push_back(std::make_tuple("", settings, BARE_TX_FEE));
cryptonote::cc_command_build_t cmd;
cmd.cc_account = FIRST_TEST_ACCOUNT;
cmd.flag = 1 + PREDEFINED_BUILDINGS;
cmd.dx = 1;
cmd.dy = 12 - 3;
cmd.wm1 = 0;
cmd.hm1 = 5;
cmd.height = 0;
cmd.remove = false;
static const uint8_t S = ITEM_BASIC_STONE;
static const uint8_t block_data[] = { 6-1, 0, S, 0, S, 0, S };
cmd.block_data = std::vector<uint8_t>(block_data, block_data + sizeof(block_data));
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, NULL, NULL);
}
bool gen_cc_tx_invalid_cc_bare_build_invalid_flag::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_building_settings_t settings;
settings.cc_account = FIRST_TEST_ACCOUNT;
settings.flag = 1 + PREDEFINED_BUILDINGS;
settings.role = ROLE_RESIDENTIAL1;
settings.economic_power = 100;
settings.construction_height = 89; // brittle
cmds.push_back(std::make_tuple("", settings, BARE_TX_FEE));
cryptonote::cc_command_build_t cmd;
cmd.cc_account = FIRST_TEST_ACCOUNT;
cmd.flag = 20;
cmd.dx = 1;
cmd.dy = 2;
cmd.wm1 = 1;
cmd.hm1 = 1;
cmd.height = 0;
cmd.remove = false;
static const uint8_t S = ITEM_BASIC_STONE;
static const uint8_t block_data[] = { 4-1, 0, S, 0, S };
cmd.block_data = std::vector<uint8_t>(block_data, block_data + sizeof(block_data));
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, NULL, NULL);
}
bool gen_cc_tx_invalid_cc_bare_build_not_owned::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_build_t cmd;
cmd.cc_account = FIRST_TEST_ACCOUNT + 1;
cmd.flag = 1 + PREDEFINED_BUILDINGS;
cmd.dx = 1;
cmd.dy = 2;
cmd.wm1 = 1;
cmd.hm1 = 1;
cmd.height = 0;
cmd.remove = false;
static const uint8_t S = ITEM_BASIC_STONE;
static const uint8_t block_data[] = { 4-1, 0, S, 0, S };
cmd.block_data = std::vector<uint8_t>(block_data, block_data + sizeof(block_data));
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_buy_stuff, 1, mixin, amount_paid, true, cmds, false, invalid, NULL, NULL);
}
bool gen_cc_tx_invalid_cc_bare_build_too_long_decoded_block_data::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_building_settings_t settings;
settings.cc_account = FIRST_TEST_ACCOUNT;
settings.flag = 1 + PREDEFINED_BUILDINGS;
settings.role = ROLE_RESIDENTIAL1;
settings.economic_power = 100;
settings.construction_height = 89; // brittle
cmds.push_back(std::make_tuple("", settings, BARE_TX_FEE));
cryptonote::cc_command_build_t cmd;
cmd.cc_account = FIRST_TEST_ACCOUNT;
cmd.flag = 1 + PREDEFINED_BUILDINGS;
cmd.dx = 1;
cmd.dy = 2;
cmd.wm1 = 1;
cmd.hm1 = 1;
cmd.height = 0;
cmd.remove = false;
static const uint8_t S = ITEM_BASIC_STONE;
static const uint8_t block_data[] = { 5-1, 0, S, 0, S, 0 };
cmd.block_data = std::vector<uint8_t>(block_data, block_data + sizeof(block_data));
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, NULL, NULL);
}
bool gen_cc_tx_valid_cc_bare_build_stacked::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_building_settings_t settings;
settings.cc_account = FIRST_TEST_ACCOUNT;
settings.flag = 1 + PREDEFINED_BUILDINGS;
settings.role = ROLE_RESIDENTIAL1;
settings.economic_power = 100;
settings.construction_height = 89; // brittle
cmds.push_back(std::make_tuple("", settings, BARE_TX_FEE));
cryptonote::cc_command_assign_items_t assign;
assign.cc_account = FIRST_TEST_ACCOUNT;
assign.flag = 1 + PREDEFINED_BUILDINGS;
assign.items.push_back({ITEM_BASIC_STONE, 20});
assign.items.push_back({ITEM_BASIC_WOOD, 30});
cmds.push_back(std::make_tuple("", assign, BARE_TX_FEE));
// build a checker pattern
cryptonote::cc_command_build_t cmd;
cmd.cc_account = FIRST_TEST_ACCOUNT;
cmd.flag = 1 + PREDEFINED_BUILDINGS;
cmd.dx = 1;
cmd.dy = 2;
cmd.wm1 = 1;
cmd.hm1 = 1;
cmd.height = 0;
cmd.remove = false;
static const uint8_t S = ITEM_BASIC_STONE;
static const uint8_t W = ITEM_BASIC_WOOD;
static const uint8_t block_data0[] = { 4-1, 0, S, 0, S };
cmd.block_data = std::vector<uint8_t>(block_data0, block_data0 + sizeof(block_data0));
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
// build on top of some of them
static const uint8_t block_data1[] = { 4-1, S, 0, 0, 0 };
cmd.block_data = std::vector<uint8_t>(block_data1, block_data1 + sizeof(block_data1));
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
static const uint8_t block_data2[] = { 4-1, 0, 0, W, 0 };
cmd.block_data = std::vector<uint8_t>(block_data2, block_data2 + sizeof(block_data2));
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
// build on top of others
cmd.height = 1;
static const uint8_t block_data3[] = { 4-1, S, S, 0, W};
cmd.block_data = std::vector<uint8_t>(block_data3, block_data3 + sizeof(block_data3));
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
cmd.dy = 1;
static const uint8_t block_data4[] = { 4-1, S, S, 0, 0};
cmd.block_data = std::vector<uint8_t>(block_data4, block_data4 + sizeof(block_data4));
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
// build on another overlapping area
cmd.height = 2;
cmd.dx = 0;
static const uint8_t block_data5[] = { 4-1, 0, S, S, S };
cmd.block_data = std::vector<uint8_t>(block_data5, block_data5 + sizeof(block_data5));
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
// build under existing geometry
cmd.height = 1;
static const uint8_t block_data6[] = { 4-1, W, 0, W, 0 };
cmd.block_data = std::vector<uint8_t>(block_data6, block_data6 + sizeof(block_data6));
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, valid, NULL, NULL);
}
bool gen_cc_tx_valid_cc_bare_build_stacked::check_final_state(cryptonote::core &c, const std::vector<test_event_entry> &events)
{
static const uint8_t S = ITEM_BASIC_STONE;
static const uint8_t W = ITEM_BASIC_WOOD;
return log_test_accounts(c, events)
&& expect_cc_account(c, 0, FIRST_TEST_ACCOUNT, expected_balance[0] - 9 * BARE_TX_FEE)
&& expect_cc_account(c, 1, FIRST_TEST_ACCOUNT + 1, expected_balance[1])
&& expect_cc_account(c, 2, FIRST_TEST_ACCOUNT + 2, expected_balance[2])
&& expect_cc_account(c, 3, FIRST_TEST_ACCOUNT + 3, expected_balance[3])
&& expect_cc_account(c, 4, FIRST_TEST_ACCOUNT + 4, initial_funding[4])
&& expect_cc_account(c, 5, FIRST_TEST_ACCOUNT + 5, initial_funding[5])
&& expect_cc_account(c, 6, FIRST_TEST_ACCOUNT + 6, initial_funding[6])
&& expect_cc_account(c, 7, FIRST_TEST_ACCOUNT + 7, initial_funding[7])
&& expect_treasury_balance(c, expected_treasury_balance)
&& expect_flag_tiles(c, 1 + PREDEFINED_BUILDINGS,
{ {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},
{0,W}, {0,S,S}, {0,S}, {}, {}, {}, {}, {}, {}, {}, {}, {},
{0,W,S}, {S,S,S}, {S,S}, {}, {}, {}, {}, {}, {}, {}, {}, {},
{}, {W}, {S,W}, {}, {}, {}, {}, {}, {}, {}, {}, {},
{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},
{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},
{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},
{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},
{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},
{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},
{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {},
{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {} });
}
bool gen_cc_tx_invalid_cc_bare_build_not_enough_blocks::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_building_settings_t settings;
settings.cc_account = FIRST_TEST_ACCOUNT;
settings.flag = 1 + PREDEFINED_BUILDINGS;
settings.role = ROLE_RESIDENTIAL1;
settings.economic_power = 100;
settings.construction_height = 89; // brittle
cmds.push_back(std::make_tuple("", settings, BARE_TX_FEE));
cryptonote::cc_command_build_t cmd;
for (int i = 0; i < 23; ++i)
{
cmd.cc_account = FIRST_TEST_ACCOUNT;
cmd.flag = 1 + PREDEFINED_BUILDINGS;
cmd.dx = 0;
cmd.dy = 0;
cmd.wm1 = 5;
cmd.hm1 = 4;
cmd.height = i;
cmd.remove = false;
static const uint8_t S = ITEM_BASIC_STONE;
static const uint8_t block_data[] = { 30-1, S, S, S, S, S, S, S, S, S, S, S, S, S, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
cmd.block_data = std::vector<uint8_t>(block_data, block_data + sizeof(block_data));
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
}
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, NULL, NULL);
}
uint64_t gen_cc_tx_valid_cc_bare_buy_blocks::blocks_cost = 0;
bool gen_cc_tx_valid_cc_bare_buy_blocks::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
blocks_cost = 0;
cryptonote::cc_command_buy_items_t cmd;
cmd.cc_account = FIRST_TEST_ACCOUNT;
cryptonote::cc_command_buy_items_t::entry_t e;
e.type = ITEM_BASIC_STONE;
e.amount = 8;
cmd.entries.push_back(e);
blocks_cost += cc::get_last_resort_price(e.type) * e.amount;
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
e.type = ITEM_BASIC_WOOD;
e.amount = 18;
cmd.entries[0] = e;
blocks_cost += cc::get_last_resort_price(e.type) * e.amount;
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
e.type = ITEM_BASIC_STONE;
e.amount = 4;
cmd.entries[0] = e;
blocks_cost += cc::get_last_resort_price(e.type) * e.amount;
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_create_accounts, cmds.size(), mixin, amount_paid, true, cmds, false, valid, NULL, NULL);
}
bool gen_cc_tx_valid_cc_bare_buy_blocks::check_final_state(cryptonote::core &c, const std::vector<test_event_entry> &events)
{
return log_test_accounts(c, events)
&& expect_cc_account(c, 0, FIRST_TEST_ACCOUNT, expected_balance[0] - blocks_cost - 3 * BARE_TX_FEE)
&& expect_cc_account(c, 1, FIRST_TEST_ACCOUNT + 1, expected_balance[1])
&& expect_cc_account(c, 2, FIRST_TEST_ACCOUNT + 2, expected_balance[2])
&& expect_cc_account(c, 3, FIRST_TEST_ACCOUNT + 3, expected_balance[3])
&& expect_cc_account(c, 4, FIRST_TEST_ACCOUNT + 4, initial_funding[4])
&& expect_cc_account(c, 5, FIRST_TEST_ACCOUNT + 5, initial_funding[5])
&& expect_cc_account(c, 6, FIRST_TEST_ACCOUNT + 6, initial_funding[6])
&& expect_cc_account(c, 7, FIRST_TEST_ACCOUNT + 7, initial_funding[7])
&& expect_treasury_balance(c, expected_treasury_balance + blocks_cost)
&& expect_item_balances(c, FIRST_TEST_ACCOUNT, {std::make_pair(ITEM_BASIC_STONE, 12), std::make_pair(ITEM_BASIC_WOOD, 18)});
}
bool gen_cc_tx_invalid_cc_bare_buy_blocks_type_0::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_buy_items_t cmd;
cmd.cc_account = FIRST_TEST_ACCOUNT;
cryptonote::cc_command_buy_items_t::entry_t e;
e.type = 0;
e.amount = 1;
cmd.entries.push_back(e);
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_create_accounts, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, NULL, NULL);
}
bool gen_cc_tx_invalid_cc_bare_buy_blocks_amount_0::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_buy_items_t cmd;
cmd.cc_account = FIRST_TEST_ACCOUNT;
cryptonote::cc_command_buy_items_t::entry_t e;
e.type = ITEM_BASIC_STONE;
e.amount = 0;
cmd.entries.push_back(e);
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_create_accounts, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, NULL, NULL);
}
bool gen_cc_tx_invalid_cc_bare_buy_blocks_balance_overflow::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_buy_items_t cmd;
cmd.cc_account = FIRST_TEST_ACCOUNT;
cryptonote::cc_command_buy_items_t::entry_t e;
e.type = ITEM_BASIC_STONE;
e.amount = 0x1fffffff;
cmd.entries.push_back(e);
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_create_accounts, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, NULL, NULL);
}
bool gen_cc_tx_invalid_cc_bare_buy_blocks_balance_overflow_in_aggregate::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_buy_items_t cmd;
cmd.cc_account = FIRST_TEST_ACCOUNT;
cryptonote::cc_command_buy_items_t::entry_t e;
e.type = ITEM_BASIC_STONE;
e.amount = 30000000;
cmd.entries.push_back(e);
e.type = ITEM_BASIC_WOOD;
e.amount = 30000000;
cmd.entries.push_back(e);
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_create_accounts, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, NULL, NULL);
}
bool gen_cc_tx_invalid_cc_bare_buy_blocks_duplicate_type::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_buy_items_t cmd;
cmd.cc_account = FIRST_TEST_ACCOUNT;
cryptonote::cc_command_buy_items_t::entry_t e;
e.type = ITEM_BASIC_STONE;
e.amount = 0x100;
cmd.entries.push_back(e);
cmd.entries.push_back(e);
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_create_accounts, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, NULL, NULL);
}
bool gen_cc_tx_valid_cc_bare_trade_bid_blocks::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_trade_t trade;
trade.cc_account = FIRST_TEST_ACCOUNT;
trade.bid = true;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = ITEM_BASIC_STONE;
trade.amount = 20;
trade.price = 1000;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = 0;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = 0;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, valid, NULL, NULL);
}
bool gen_cc_tx_valid_cc_bare_trade_bid_blocks::check_final_state(cryptonote::core &c, const std::vector<test_event_entry> &events)
{
return log_test_accounts(c, events)
&& expect_cc_account(c, 0, FIRST_TEST_ACCOUNT, expected_balance[0] - 1 * BARE_TX_FEE)
&& expect_cc_account(c, 1, FIRST_TEST_ACCOUNT + 1, expected_balance[1])
&& expect_cc_account(c, 2, FIRST_TEST_ACCOUNT + 2, expected_balance[2])
&& expect_cc_account(c, 3, FIRST_TEST_ACCOUNT + 3, expected_balance[3])
&& expect_cc_account(c, 4, FIRST_TEST_ACCOUNT + 4, initial_funding[4])
&& expect_cc_account(c, 5, FIRST_TEST_ACCOUNT + 5, initial_funding[5])
&& expect_cc_account(c, 6, FIRST_TEST_ACCOUNT + 6, initial_funding[6])
&& expect_cc_account(c, 7, FIRST_TEST_ACCOUNT + 7, initial_funding[7])
&& expect_treasury_balance(c, expected_treasury_balance);
}
bool gen_cc_tx_valid_cc_bare_trade_offer_blocks::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_trade_t trade;
trade.cc_account = FIRST_TEST_ACCOUNT;
trade.bid = false;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = ITEM_BASIC_STONE;
trade.amount = 20;
trade.price = 1000;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = 0;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = 0;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, valid, NULL, NULL);
}
bool gen_cc_tx_valid_cc_bare_trade_offer_blocks::check_final_state(cryptonote::core &c, const std::vector<test_event_entry> &events)
{
return log_test_accounts(c, events)
&& expect_cc_account(c, 0, FIRST_TEST_ACCOUNT, expected_balance[0] - 1 * BARE_TX_FEE)
&& expect_cc_account(c, 1, FIRST_TEST_ACCOUNT + 1, expected_balance[1])
&& expect_cc_account(c, 2, FIRST_TEST_ACCOUNT + 2, expected_balance[2])
&& expect_cc_account(c, 3, FIRST_TEST_ACCOUNT + 3, expected_balance[3])
&& expect_cc_account(c, 4, FIRST_TEST_ACCOUNT + 4, initial_funding[4])
&& expect_cc_account(c, 5, FIRST_TEST_ACCOUNT + 5, initial_funding[5])
&& expect_cc_account(c, 6, FIRST_TEST_ACCOUNT + 6, initial_funding[6])
&& expect_cc_account(c, 7, FIRST_TEST_ACCOUNT + 7, initial_funding[7])
&& expect_treasury_balance(c, expected_treasury_balance);
}
bool gen_cc_tx_invalid_cc_bare_trade_bid_invalid_type::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_trade_t trade;
trade.cc_account = FIRST_TEST_ACCOUNT;
trade.bid = true;
trade.type = 0xffffff;
trade.id = ITEM_BASIC_STONE;
trade.amount = 20;
trade.price = 1000;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = 0;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = 0;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, NULL, NULL);
}
bool gen_cc_tx_invalid_cc_bare_trade_bid_block_id_0::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_trade_t trade;
trade.cc_account = FIRST_TEST_ACCOUNT;
trade.bid = true;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = 0;
trade.amount = 20;
trade.price = 1000;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = 0;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = 0;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, NULL, NULL);
}
bool gen_cc_tx_invalid_cc_bare_trade_bid_invalid_block_id::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_trade_t trade;
trade.cc_account = FIRST_TEST_ACCOUNT;
trade.bid = true;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = NUM_ITEMS;
trade.amount = 20;
trade.price = 1000;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = 0;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = 0;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, NULL, NULL);
}
bool gen_cc_tx_invalid_cc_bare_trade_bid_expired::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_trade_t trade;
trade.cc_account = FIRST_TEST_ACCOUNT;
trade.bid = true;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = ITEM_BASIC_STONE;
trade.amount = 20;
trade.price = 1000;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = 0;
trade.expiration = 10;
trade.cost = 0;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, NULL, NULL);
}
bool gen_cc_tx_invalid_cc_bare_trade_bid_not_enough_money::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_trade_t trade;
trade.cc_account = FIRST_TEST_ACCOUNT;
trade.bid = true;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = ITEM_BASIC_STONE;
trade.amount = 1;
trade.price = (uint64_t)1000*COIN;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = 0;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = 0;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, NULL, NULL);
}
bool gen_cc_tx_invalid_cc_bare_trade_bid_amount_0::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_trade_t trade;
trade.cc_account = FIRST_TEST_ACCOUNT;
trade.bid = true;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = ITEM_BASIC_STONE;
trade.amount = 0;
trade.price = 1000;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = 0;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = 0;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, NULL, NULL);
}
bool gen_cc_tx_invalid_cc_bare_trade_offer_amount_0::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_trade_t trade;
trade.cc_account = FIRST_TEST_ACCOUNT;
trade.bid = false;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = ITEM_BASIC_STONE;
trade.amount = 0;
trade.price = 1000;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = 0;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = 0;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, NULL, NULL);
}
bool gen_cc_tx_valid_cc_bare_match_blocks_matching_amounts::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_trade_t trade;
trade.bid = false;
trade.cc_account = FIRST_TEST_ACCOUNT;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = ITEM_BASIC_STONE;
trade.amount = 20;
trade.price = 1000;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = 0;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = 0;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
trade.bid = true;
trade.cc_account = FIRST_TEST_ACCOUNT + 1;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = ITEM_BASIC_STONE;
trade.amount = 20;
trade.price = 1000;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = 0;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = trade.amount * trade.price;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
std::vector<cryptonote::cc_command_trade_t::match_t> matches;
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, valid, NULL, [&](transaction &tx) {
if (tx.cc_cmd.type() != typeid(cryptonote::cc_command_trade_t))
return;
if (matches.size() < 1)
{
matches.push_back({boost::get<cryptonote::cc_command_trade_t>(tx.cc_cmd).cc_nonce, 20});
}
else
{
boost::get<cryptonote::cc_command_trade_t>(tx.cc_cmd).matches = matches;
const auto &sender_account_keys = cc_test_accounts[1].get_keys();
const crypto::hash h = cryptonote::get_transaction_prefix_hash_with_tag(tx);
cc::generate_signature(h, sender_account_keys.m_account_address.m_spend_public_key, sender_account_keys.m_spend_secret_key, tx.cc_account_signature);
}
});
}
bool gen_cc_tx_valid_cc_bare_match_blocks_matching_amounts::check_final_state(cryptonote::core &c, const std::vector<test_event_entry> &events)
{
return log_test_accounts(c, events)
&& expect_cc_account(c, 0, FIRST_TEST_ACCOUNT, expected_balance[0] - 1 * BARE_TX_FEE + 20 * 1000)
&& expect_cc_account(c, 1, FIRST_TEST_ACCOUNT + 1, expected_balance[1] - 1 * BARE_TX_FEE - 20 * 1000)
&& expect_cc_account(c, 2, FIRST_TEST_ACCOUNT + 2, expected_balance[2])
&& expect_cc_account(c, 3, FIRST_TEST_ACCOUNT + 3, expected_balance[3])
&& expect_cc_account(c, 4, FIRST_TEST_ACCOUNT + 4, initial_funding[4])
&& expect_cc_account(c, 5, FIRST_TEST_ACCOUNT + 5, initial_funding[5])
&& expect_cc_account(c, 6, FIRST_TEST_ACCOUNT + 6, initial_funding[6])
&& expect_cc_account(c, 7, FIRST_TEST_ACCOUNT + 7, initial_funding[7])
&& expect_treasury_balance(c, expected_treasury_balance)
&& expect_item_balances(c, FIRST_TEST_ACCOUNT, {std::make_pair(ITEM_BASIC_STONE, STARTING_BLOCK_1 - 20), std::make_pair(ITEM_BASIC_WOOD, STARTING_BLOCK_2), std::make_pair(ITEM_LABOUR, STARTING_LABOUR)})
&& expect_item_balances(c, FIRST_TEST_ACCOUNT + 1, {std::make_pair(ITEM_BASIC_STONE, 20)});
}
bool gen_cc_tx_valid_cc_bare_match_blocks_partial_buy::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_trade_t trade;
trade.bid = false;
trade.cc_account = FIRST_TEST_ACCOUNT;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = ITEM_BASIC_STONE;
trade.amount = 20;
trade.price = 1000;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = 0;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = 0;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
trade.bid = true;
trade.cc_account = FIRST_TEST_ACCOUNT + 1;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = ITEM_BASIC_STONE;
trade.amount = 12;
trade.price = 1000;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = 0;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = 12 * trade.price;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
std::vector<cryptonote::cc_command_trade_t::match_t> matches;
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, valid, NULL, [&](transaction &tx) {
if (tx.cc_cmd.type() != typeid(cryptonote::cc_command_trade_t))
return;
if (matches.size() < 1)
{
matches.push_back({boost::get<cryptonote::cc_command_trade_t>(tx.cc_cmd).cc_nonce, 12});
}
else
{
boost::get<cryptonote::cc_command_trade_t>(tx.cc_cmd).matches = matches;
const auto &sender_account_keys = cc_test_accounts[1].get_keys();
const crypto::hash h = cryptonote::get_transaction_prefix_hash_with_tag(tx);
cc::generate_signature(h, sender_account_keys.m_account_address.m_spend_public_key, sender_account_keys.m_spend_secret_key, tx.cc_account_signature);
}
});
}
bool gen_cc_tx_valid_cc_bare_match_blocks_partial_buy::check_final_state(cryptonote::core &c, const std::vector<test_event_entry> &events)
{
return log_test_accounts(c, events)
&& expect_cc_account(c, 0, FIRST_TEST_ACCOUNT, expected_balance[0] - 1 * BARE_TX_FEE + 12 * 1000)
&& expect_cc_account(c, 1, FIRST_TEST_ACCOUNT + 1, expected_balance[1] - 1 * BARE_TX_FEE - 12 * 1000)
&& expect_cc_account(c, 2, FIRST_TEST_ACCOUNT + 2, expected_balance[2])
&& expect_cc_account(c, 3, FIRST_TEST_ACCOUNT + 3, expected_balance[3])
&& expect_cc_account(c, 4, FIRST_TEST_ACCOUNT + 4, initial_funding[4])
&& expect_cc_account(c, 5, FIRST_TEST_ACCOUNT + 5, initial_funding[5])
&& expect_cc_account(c, 6, FIRST_TEST_ACCOUNT + 6, initial_funding[6])
&& expect_cc_account(c, 7, FIRST_TEST_ACCOUNT + 7, initial_funding[7])
&& expect_treasury_balance(c, expected_treasury_balance)
&& expect_item_balances(c, FIRST_TEST_ACCOUNT, {std::make_pair(ITEM_BASIC_STONE, STARTING_BLOCK_1 - 12), std::make_pair(ITEM_BASIC_WOOD, STARTING_BLOCK_2), std::make_pair(ITEM_LABOUR, STARTING_LABOUR)})
&& expect_item_balances(c, FIRST_TEST_ACCOUNT + 1, {std::make_pair(ITEM_BASIC_STONE, 12)});
}
bool gen_cc_tx_valid_cc_bare_match_blocks_partial_sell::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_trade_t trade;
trade.cc_account = FIRST_TEST_ACCOUNT;
trade.bid = false;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = ITEM_BASIC_STONE;
trade.amount = 20;
trade.price = 1000;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = 0;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = 0;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
trade.cc_account = FIRST_TEST_ACCOUNT + 1;
trade.bid = true;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = ITEM_BASIC_STONE;
trade.amount = 25;
trade.price = 1000;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = 0;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = 20 * trade.price;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
std::vector<cryptonote::cc_command_trade_t::match_t> matches;
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, valid, NULL, [&](transaction &tx) {
if (tx.cc_cmd.type() != typeid(cryptonote::cc_command_trade_t))
return;
if (matches.size() < 1)
{
matches.push_back({boost::get<cryptonote::cc_command_trade_t>(tx.cc_cmd).cc_nonce, 20});
}
else
{
boost::get<cryptonote::cc_command_trade_t>(tx.cc_cmd).matches = matches;
const auto &sender_account_keys = cc_test_accounts[1].get_keys();
const crypto::hash h = cryptonote::get_transaction_prefix_hash_with_tag(tx);
cc::generate_signature(h, sender_account_keys.m_account_address.m_spend_public_key, sender_account_keys.m_spend_secret_key, tx.cc_account_signature);
}
});
}
bool gen_cc_tx_valid_cc_bare_match_blocks_partial_sell::check_final_state(cryptonote::core &c, const std::vector<test_event_entry> &events)
{
return log_test_accounts(c, events)
&& expect_cc_account(c, 0, FIRST_TEST_ACCOUNT, expected_balance[0] - 1 * BARE_TX_FEE + 20 * 1000)
&& expect_cc_account(c, 1, FIRST_TEST_ACCOUNT + 1, expected_balance[1] - 1 * BARE_TX_FEE - 20 * 1000)
&& expect_cc_account(c, 2, FIRST_TEST_ACCOUNT + 2, expected_balance[2])
&& expect_cc_account(c, 3, FIRST_TEST_ACCOUNT + 3, expected_balance[3])
&& expect_cc_account(c, 4, FIRST_TEST_ACCOUNT + 4, initial_funding[4])
&& expect_cc_account(c, 5, FIRST_TEST_ACCOUNT + 5, initial_funding[5])
&& expect_cc_account(c, 6, FIRST_TEST_ACCOUNT + 6, initial_funding[6])
&& expect_cc_account(c, 7, FIRST_TEST_ACCOUNT + 7, initial_funding[7])
&& expect_treasury_balance(c, expected_treasury_balance)
&& expect_item_balances(c, FIRST_TEST_ACCOUNT, {std::make_pair(ITEM_BASIC_STONE, STARTING_BLOCK_1 - 20), std::make_pair(ITEM_BASIC_WOOD, STARTING_BLOCK_2), std::make_pair(ITEM_LABOUR, STARTING_LABOUR)})
&& expect_item_balances(c, FIRST_TEST_ACCOUNT + 1, {std::make_pair(ITEM_BASIC_STONE, 20)});
}
bool gen_cc_tx_invalid_cc_bare_match_0::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_trade_t trade;
trade.cc_account = FIRST_TEST_ACCOUNT;
trade.bid = false;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = ITEM_BASIC_STONE;
trade.amount = 20;
trade.price = 1000;
trade.accrual_start_height = 0;
trade.accrual_price_limit = 0;
trade.accrual = 0;
trade.flag_construction_height = 0;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = 0;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
trade.cc_account = FIRST_TEST_ACCOUNT + 1;
trade.bid = true;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = ITEM_BASIC_STONE;
trade.amount = 20;
trade.price = 1000;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = 0;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = trade.amount * trade.price;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
std::vector<cryptonote::cc_command_trade_t::match_t> matches;
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, NULL, [&](transaction &tx) {
if (tx.cc_cmd.type() != typeid(cryptonote::cc_command_trade_t))
return;
if (matches.size() < 1)
{
matches.push_back({boost::get<cryptonote::cc_command_trade_t>(tx.cc_cmd).cc_nonce, 0});
}
else
{
boost::get<cryptonote::cc_command_trade_t>(tx.cc_cmd).matches = matches;
const auto &sender_account_keys = cc_test_accounts[1].get_keys();
const crypto::hash h = cryptonote::get_transaction_prefix_hash_with_tag(tx);
cc::generate_signature(h, sender_account_keys.m_account_address.m_spend_public_key, sender_account_keys.m_spend_secret_key, tx.cc_account_signature);
}
});
}
bool gen_cc_tx_invalid_cc_bare_match_more_than_trade::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_trade_t trade;
trade.cc_account = FIRST_TEST_ACCOUNT;
trade.bid = false;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = ITEM_BASIC_STONE;
trade.amount = 20;
trade.price = 1000;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = 0;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = 0;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
trade.cc_account = FIRST_TEST_ACCOUNT + 1;
trade.bid = true;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = ITEM_BASIC_STONE;
trade.amount = 20;
trade.price = 1000;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = 0;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = trade.amount * trade.price;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
std::vector<cryptonote::cc_command_trade_t::match_t> matches;
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, NULL, [&](transaction &tx) {
if (tx.cc_cmd.type() != typeid(cryptonote::cc_command_trade_t))
return;
if (matches.size() < 1)
{
matches.push_back({boost::get<cryptonote::cc_command_trade_t>(tx.cc_cmd).cc_nonce, 25});
}
else
{
boost::get<cryptonote::cc_command_trade_t>(tx.cc_cmd).matches = matches;
const auto &sender_account_keys = cc_test_accounts[1].get_keys();
const crypto::hash h = cryptonote::get_transaction_prefix_hash_with_tag(tx);
cc::generate_signature(h, sender_account_keys.m_account_address.m_spend_public_key, sender_account_keys.m_spend_secret_key, tx.cc_account_signature);
}
});
}
bool gen_cc_tx_invalid_cc_bare_trade_from_account_0::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_trade_t trade;
trade.cc_account = FIRST_TEST_ACCOUNT;
trade.bid = false;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = ITEM_BASIC_STONE;
trade.amount = 20;
trade.price = 1000;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = 0;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = 0;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, NULL, [](transaction &tx) {
boost::get<cryptonote::cc_command_trade_t>(tx.cc_cmd).cc_account = 0;
});
}
bool gen_cc_tx_invalid_cc_bare_match_non_trade_tx::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_buy_land_t buy_land;
cryptonote::cc_command_trade_t trade;
uint32_t ox, oy;
cc::get_city_origin(0, ox, oy);
buy_land.cc_account = FIRST_TEST_ACCOUNT;
buy_land.city = 0;
buy_land.x = ox + 200;
buy_land.y = oy + 20;
buy_land.wm1 = 11;
buy_land.hm1 = 11;
cmds.push_back(std::make_tuple("", buy_land, BARE_TX_FEE));
trade.cc_account = FIRST_TEST_ACCOUNT + 1;
trade.bid = true;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = ITEM_BASIC_STONE;
trade.amount = 20;
trade.price = 1000;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = 0;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = 0;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
std::vector<cryptonote::cc_command_trade_t::match_t> matches;
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, NULL, [&](transaction &tx) {
if (tx.cc_cmd.type() == typeid(cryptonote::cc_command_buy_land_t))
{
matches.push_back({boost::get<cryptonote::cc_command_buy_land_t>(tx.cc_cmd).cc_nonce, 1});
}
else
{
boost::get<cryptonote::cc_command_trade_t>(tx.cc_cmd).matches = matches;
const auto &sender_account_keys = cc_test_accounts[1].get_keys();
const crypto::hash h = cryptonote::get_transaction_prefix_hash_with_tag(tx);
cc::generate_signature(h, sender_account_keys.m_account_address.m_spend_public_key, sender_account_keys.m_spend_secret_key, tx.cc_account_signature);
}
});
}
bool gen_cc_tx_invalid_cc_bare_match_duplicate_trade_tx::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_trade_t trade;
trade.cc_account = FIRST_TEST_ACCOUNT;
trade.bid = false;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = ITEM_BASIC_STONE;
trade.amount = 20;
trade.price = 1000;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = 0;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = 0;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
trade.cc_account = FIRST_TEST_ACCOUNT + 1;
trade.bid = false;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = ITEM_BASIC_STONE;
trade.amount = 40;
trade.price = 1000;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = 0;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = 0;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
std::vector<cryptonote::cc_command_trade_t::match_t> matches;
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, NULL, [&](transaction &tx) {
if (matches.size() < 1)
{
matches.push_back({boost::get<cryptonote::cc_command_trade_t>(tx.cc_cmd).cc_nonce, 20});
matches.push_back({boost::get<cryptonote::cc_command_trade_t>(tx.cc_cmd).cc_nonce, 20});
}
else
{
boost::get<cryptonote::cc_command_trade_t>(tx.cc_cmd).matches = matches;
const auto &sender_account_keys = cc_test_accounts[1].get_keys();
const crypto::hash h = cryptonote::get_transaction_prefix_hash_with_tag(tx);
cc::generate_signature(h, sender_account_keys.m_account_address.m_spend_public_key, sender_account_keys.m_spend_secret_key, tx.cc_account_signature);
}
});
}
bool gen_cc_tx_valid_cc_bare_match_two_buys_from_one_sell::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_trade_t trade;
trade.cc_account = FIRST_TEST_ACCOUNT;
trade.bid = false;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = ITEM_BASIC_STONE;
trade.amount = 20;
trade.price = 1000;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = 0;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = 0;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
trade.cc_account = FIRST_TEST_ACCOUNT + 1;
trade.bid = true;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = ITEM_BASIC_STONE;
trade.amount = 15;
trade.price = 1020;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = 0;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = 15 * 1000;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
trade.cc_account = FIRST_TEST_ACCOUNT + 2;
trade.bid = true;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = ITEM_BASIC_STONE;
trade.amount = 5;
trade.price = 1050;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = 0;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = 5 * 1000;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
uint32_t idx = 0;
uint64_t offer_nonce = 0;
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, valid, NULL, [&](transaction &tx) {
++idx;
switch (idx)
{
case 1:
offer_nonce = boost::get<cryptonote::cc_command_trade_t>(tx.cc_cmd).cc_nonce;
break;
case 2:
case 3:
{
boost::get<cryptonote::cc_command_trade_t>(tx.cc_cmd).matches.push_back({offer_nonce, 15 - 10 * (idx-2)});
const auto &sender_account_keys = cc_test_accounts[idx-1].get_keys();
const crypto::hash h = cryptonote::get_transaction_prefix_hash_with_tag(tx);
cc::generate_signature(h, sender_account_keys.m_account_address.m_spend_public_key, sender_account_keys.m_spend_secret_key, tx.cc_account_signature);
break;
}
}
});
}
bool gen_cc_tx_valid_cc_bare_match_two_buys_from_one_sell::check_final_state(cryptonote::core &c, const std::vector<test_event_entry> &events)
{
return log_test_accounts(c, events)
&& expect_cc_account(c, 0, FIRST_TEST_ACCOUNT, expected_balance[0] - 1 * BARE_TX_FEE + 20 * 1000)
&& expect_cc_account(c, 1, FIRST_TEST_ACCOUNT + 1, expected_balance[1] - 1 * BARE_TX_FEE - 15 * 1000)
&& expect_cc_account(c, 2, FIRST_TEST_ACCOUNT + 2, expected_balance[2] - 1 * BARE_TX_FEE - 5 * 1000)
&& expect_cc_account(c, 3, FIRST_TEST_ACCOUNT + 3, expected_balance[3])
&& expect_cc_account(c, 4, FIRST_TEST_ACCOUNT + 4, initial_funding[4])
&& expect_cc_account(c, 5, FIRST_TEST_ACCOUNT + 5, initial_funding[5])
&& expect_cc_account(c, 6, FIRST_TEST_ACCOUNT + 6, initial_funding[6])
&& expect_cc_account(c, 7, FIRST_TEST_ACCOUNT + 7, initial_funding[7])
&& expect_treasury_balance(c, expected_treasury_balance)
&& expect_item_balances(c, FIRST_TEST_ACCOUNT, {std::make_pair(ITEM_BASIC_STONE, STARTING_BLOCK_1 - 20), std::make_pair(ITEM_BASIC_WOOD, STARTING_BLOCK_2), std::make_pair(ITEM_LABOUR, STARTING_LABOUR)})
&& expect_item_balances(c, FIRST_TEST_ACCOUNT + 1, {std::make_pair(ITEM_BASIC_STONE, 15)})
&& expect_item_balances(c, FIRST_TEST_ACCOUNT + 2, {std::make_pair(ITEM_BASIC_STONE, 5)});
}
bool gen_cc_tx_valid_cc_bare_maker_no_fee::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_trade_t trade;
trade.bid = false;
trade.cc_account = FIRST_TEST_ACCOUNT;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = ITEM_BASIC_STONE;
trade.amount = 20;
trade.price = 1000;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = 0;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = 0;
cmds.push_back(std::make_tuple("", trade, 0));
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, valid, NULL, NULL);
}
bool gen_cc_tx_invalid_cc_bare_taker_no_fee::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_trade_t trade;
trade.bid = false;
trade.cc_account = FIRST_TEST_ACCOUNT;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = ITEM_BASIC_STONE;
trade.amount = 20;
trade.price = 1000;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = 0;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = 0;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
trade.bid = true;
trade.cc_account = FIRST_TEST_ACCOUNT + 1;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = ITEM_BASIC_STONE;
trade.amount = 20;
trade.price = 1000;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = 0;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = trade.amount * trade.price;
cmds.push_back(std::make_tuple("", trade, 0));
std::vector<cryptonote::cc_command_trade_t::match_t> matches;
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, NULL, [&](transaction &tx) {
if (tx.cc_cmd.type() != typeid(cryptonote::cc_command_trade_t))
return;
if (matches.size() < 1)
{
matches.push_back({boost::get<cryptonote::cc_command_trade_t>(tx.cc_cmd).cc_nonce, 20});
}
else
{
boost::get<cryptonote::cc_command_trade_t>(tx.cc_cmd).matches = matches;
const auto &sender_account_keys = cc_test_accounts[1].get_keys();
const crypto::hash h = cryptonote::get_transaction_prefix_hash_with_tag(tx);
cc::generate_signature(h, sender_account_keys.m_account_address.m_spend_public_key, sender_account_keys.m_spend_secret_key, tx.cc_account_signature);
}
});
}
uint64_t gen_cc_tx_valid_cc_bare_trade_flag::land_cost = 0;
uint64_t gen_cc_tx_valid_cc_bare_trade_flag::blocks_cost = 0;
bool gen_cc_tx_valid_cc_bare_trade_flag::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
uint32_t ox, oy;
cc::get_city_origin(0, ox, oy);
land_cost = 0;
blocks_cost = 0;
cryptonote::cc_command_buy_land_t buy_land;
buy_land.cc_account = FIRST_TEST_ACCOUNT;
buy_land.city = 0;
buy_land.x = ox + 240;
buy_land.y = oy + 20;
buy_land.wm1 = 63;
buy_land.hm1 = 63;
if (!cc::get_new_flag_cost(buy_land.x, buy_land.y, buy_land.x + buy_land.wm1, buy_land.y + buy_land.hm1, ox, oy, land_cost))
return false;
cmds.push_back(std::make_tuple("", buy_land, BARE_TX_FEE));
cryptonote::cc_command_buy_items_t cmd;
cmd.cc_account = FIRST_TEST_ACCOUNT;
cryptonote::cc_command_buy_items_t::entry_t e;
e.type = ITEM_BASIC_STONE;
e.amount = 1700;
cmd.entries.push_back(e);
blocks_cost += cc::get_last_resort_price(e.type) * e.amount;
e.type = ITEM_BASIC_WOOD;
e.amount = 3800;
cmd.entries.push_back(e);
blocks_cost += cc::get_last_resort_price(e.type) * e.amount;
e.type = ITEM_LABOUR;
e.amount = 31500;
cmd.entries.push_back(e);
blocks_cost += cc::get_last_resort_price(e.type) * e.amount;
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
cryptonote::cc_command_building_settings_t settings;
settings.cc_account = FIRST_TEST_ACCOUNT;
settings.flag = 2 + PREDEFINED_BUILDINGS;
settings.role = ROLE_AGRICULTURAL;
settings.economic_power = 100;
settings.construction_height = 90; // brittle
cmds.push_back(std::make_tuple("", settings, BARE_TX_FEE));
cryptonote::cc_command_trade_t trade;
trade.cc_account = FIRST_TEST_ACCOUNT;
trade.bid = false;
trade.type = cryptonote::cc_command_trade_t::type_flag;
trade.id = 2 + PREDEFINED_BUILDINGS;
trade.amount = 1;
trade.price = 10 * COIN;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = 0;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = 0;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
const uint64_t construction_height = 92; // brittle
trade.cc_account = FIRST_TEST_ACCOUNT + 1;
trade.bid = true;
trade.type = cryptonote::cc_command_trade_t::type_flag;
trade.id = 2 + PREDEFINED_BUILDINGS;
trade.amount = 1;
trade.price = 10 * COIN;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = construction_height;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = 10 * COIN;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
std::vector<cryptonote::cc_command_trade_t::match_t> matches;
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, valid, NULL, [&](transaction &tx) {
if (tx.cc_cmd.type() != typeid(cryptonote::cc_command_trade_t))
return;
if (matches.size() < 1)
{
matches.push_back({boost::get<cryptonote::cc_command_trade_t>(tx.cc_cmd).cc_nonce, 1});
}
else
{
boost::get<cryptonote::cc_command_trade_t>(tx.cc_cmd).matches = matches;
const auto &sender_account_keys = cc_test_accounts[1].get_keys();
const crypto::hash h = cryptonote::get_transaction_prefix_hash_with_tag(tx);
cc::generate_signature(h, sender_account_keys.m_account_address.m_spend_public_key, sender_account_keys.m_spend_secret_key, tx.cc_account_signature);
}
});
}
bool gen_cc_tx_valid_cc_bare_trade_flag::check_final_state(cryptonote::core &c, const std::vector<test_event_entry> &events)
{
return log_test_accounts(c, events)
&& expect_cc_account(c, 0, FIRST_TEST_ACCOUNT, expected_balance[0] - 4 * BARE_TX_FEE - land_cost - blocks_cost + 10 * COIN)
&& expect_cc_account(c, 1, FIRST_TEST_ACCOUNT + 1, expected_balance[1] - 10 * COIN - BARE_TX_FEE)
&& expect_cc_account(c, 2, FIRST_TEST_ACCOUNT + 2, expected_balance[2])
&& expect_cc_account(c, 3, FIRST_TEST_ACCOUNT + 3, expected_balance[3])
&& expect_cc_account(c, 4, FIRST_TEST_ACCOUNT + 4, initial_funding[4])
&& expect_cc_account(c, 5, FIRST_TEST_ACCOUNT + 5, initial_funding[5])
&& expect_cc_account(c, 6, FIRST_TEST_ACCOUNT + 6, initial_funding[6])
&& expect_cc_account(c, 7, FIRST_TEST_ACCOUNT + 7, initial_funding[7])
&& expect_treasury_balance(c, expected_treasury_balance + land_cost + blocks_cost);
}
bool gen_cc_tx_invalid_cc_bare_trade_flag_build_destroyed::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
uint32_t ox, oy;
cc::get_city_origin(0, ox, oy);
cryptonote::cc_command_buy_land_t buy_land;
buy_land.cc_account = FIRST_TEST_ACCOUNT;
buy_land.city = 0;
buy_land.x = ox + 240;
buy_land.y = oy + 20;
buy_land.wm1 = 63;
buy_land.hm1 = 63;
cmds.push_back(std::make_tuple("", buy_land, BARE_TX_FEE));
cryptonote::cc_command_buy_items_t cmd;
cmd.cc_account = FIRST_TEST_ACCOUNT;
cryptonote::cc_command_buy_items_t::entry_t e;
e.type = ITEM_BASIC_STONE;
e.amount = 1700;
cmd.entries.push_back(e);
e.type = ITEM_BASIC_WOOD;
e.amount = 3800;
cmd.entries.push_back(e);
e.type = ITEM_LABOUR;
e.amount = 31500;
cmd.entries.push_back(e);
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
cryptonote::cc_command_building_settings_t settings;
settings.cc_account = FIRST_TEST_ACCOUNT;
settings.flag = 2 + PREDEFINED_BUILDINGS;
settings.role = ROLE_AGRICULTURAL;
settings.economic_power = 100;
settings.construction_height = 90; // brittle
cmds.push_back(std::make_tuple("", settings, BARE_TX_FEE));
cryptonote::cc_command_trade_t trade;
trade.cc_account = FIRST_TEST_ACCOUNT;
trade.bid = false;
trade.type = cryptonote::cc_command_trade_t::type_flag;
trade.id = 2 + PREDEFINED_BUILDINGS;
trade.amount = 1;
trade.price = 10 * COIN;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = 0;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = 0;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
const uint64_t construction_height = 92; // brittle
cryptonote::cc_command_demolish_t demolish;
demolish.cc_account = FIRST_TEST_ACCOUNT;
demolish.flag = 2 + PREDEFINED_BUILDINGS;
demolish.role = settings.role;
demolish.economic_power = settings.economic_power;
demolish.repair = DEFAULT_REPAIR;
demolish.construction_height = construction_height;
demolish.last_service_height = construction_height;
demolish.service_price = 0;
demolish.active = false;
demolish.ignore = false;
demolish.crop = CROP_NONE;
demolish.sow_height = 0;
demolish.num_missed_ticks = 0;
demolish.num_fishing_ticks = 0;
demolish.fishing_distance = 0;
demolish.fishing_city = 0;
demolish.fish = 0;
std::map<uint32_t, uint32_t> budget;
cc::get_build_settings_requirements(buy_land.x, buy_land.y, buy_land.x + buy_land.wm1, buy_land.y + buy_land.hm1, settings.role, settings.economic_power, budget);
for (const auto &e: budget)
demolish.budget.push_back({e.first, e.second});
demolish.tiles = {};
cmds.push_back(std::make_tuple("", demolish, BARE_TX_FEE));
trade.cc_account = FIRST_TEST_ACCOUNT + 1;
trade.bid = true;
trade.type = cryptonote::cc_command_trade_t::type_flag;
trade.id = 2 + PREDEFINED_BUILDINGS;
trade.amount = 1;
trade.price = 10 * COIN;
trade.accrual_start_height = 0;
trade.accrual = 0;
trade.accrual_price_limit = 0;
trade.flag_construction_height = construction_height;
trade.expiration = (MIN_TRADE_EXPIRATION + MAX_TRADE_EXPIRATION) / 2;
trade.cost = 10 * COIN;
cmds.push_back(std::make_tuple("", trade, BARE_TX_FEE));
std::vector<cryptonote::cc_command_trade_t::match_t> matches;
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, NULL, [&](transaction &tx) {
if (tx.cc_cmd.type() != typeid(cryptonote::cc_command_trade_t))
return;
if (matches.size() < 1)
{
matches.push_back({boost::get<cryptonote::cc_command_trade_t>(tx.cc_cmd).cc_nonce, 1});
}
else
{
boost::get<cryptonote::cc_command_trade_t>(tx.cc_cmd).matches = matches;
const auto &sender_account_keys = cc_test_accounts[1].get_keys();
const crypto::hash h = cryptonote::get_transaction_prefix_hash_with_tag(tx);
cc::generate_signature(h, sender_account_keys.m_account_address.m_spend_public_key, sender_account_keys.m_spend_secret_key, tx.cc_account_signature);
}
});
}
uint64_t gen_cc_tx_valid_cc_repair::money_cost = 0;
std::map<uint32_t, uint32_t> gen_cc_tx_valid_cc_repair::item_balances;
uint64_t gen_cc_tx_valid_cc_repair::land_tax = 0;
int64_t gen_cc_tx_valid_cc_repair::game_update_treasury_delta = 0;
uint32_t gen_cc_tx_valid_cc_repair::expected_repair = 0;
std::map<uint32_t, uint64_t> gen_cc_tx_valid_cc_repair::prestige_bonuses;
bool gen_cc_tx_valid_cc_repair::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
uint64_t land_cost;
uint32_t ox, oy;
cc::get_city_origin(0, ox, oy);
item_balances[ITEM_BASIC_STONE] = STARTING_BLOCK_1;
item_balances[ITEM_BASIC_WOOD] = STARTING_BLOCK_2;
item_balances[ITEM_LABOUR] = STARTING_LABOUR;
cryptonote::cc_command_buy_land_t buy_land;
buy_land.cc_account = FIRST_TEST_ACCOUNT;
buy_land.city = 0;
buy_land.x = ox + 200;
buy_land.y = oy + 200;
buy_land.wm1 = 11;
buy_land.hm1 = 11;
if (!cc::get_new_flag_cost(buy_land.x, buy_land.y, buy_land.x + buy_land.wm1, buy_land.y + buy_land.hm1, ox, oy, land_cost))
return false;
money_cost += land_cost;
cmds.push_back(std::make_tuple("", buy_land, BARE_TX_FEE));
cryptonote::cc_command_building_settings_t settings;
settings.cc_account = FIRST_TEST_ACCOUNT;
settings.flag = 1 + PREDEFINED_BUILDINGS;
settings.role = ROLE_RESIDENTIAL1;
settings.economic_power = 100;
settings.construction_height = 89; // brittle
cmds.push_back(std::make_tuple("", settings, BARE_TX_FEE));
std::map<uint32_t, uint32_t> budget;
if (!cc::get_build_settings_requirements(buy_land.x, buy_land.y, buy_land.x + buy_land.wm1, buy_land.y + buy_land.hm1, settings.role, settings.economic_power, budget))
return false;
for (const auto &e: budget)
item_balances[e.first] -= e.second;
cryptonote::cc_command_repair_t repair;
repair.cc_account = FIRST_TEST_ACCOUNT;
repair.flags.push_back({1 + PREDEFINED_BUILDINGS, MIN_DECAY_RATE});
cmds.push_back(std::make_tuple("", repair, BARE_TX_FEE));
expected_repair = DEFAULT_REPAIR + MIN_DECAY_RATE; // technically overflows, but the +MIN_DECAY_RATE happens after the game update below
std::map<uint32_t, uint32_t> costs;
cc::get_repair_costs(buy_land.x, buy_land.y, buy_land.x + buy_land.wm1, buy_land.y + buy_land.hm1, settings.role, settings.economic_power, 1500, costs);
for (const auto &e: costs)
item_balances[e.first] -= e.second;
land_tax = 0;
uint64_t tax;
if (!cc::get_land_tax(ox + PREP_BUY_LAND_X, oy + PREP_BUY_LAND_Y, ox + PREP_BUY_LAND_X + PREP_BUY_LAND_WM1, oy + PREP_BUY_LAND_Y + PREP_BUY_LAND_HM1, ox, oy, 100, 0, 0, 0, 0, tax))
return false;
land_tax += tax;
if (!cc::get_land_tax(buy_land.x, buy_land.y, buy_land.x + buy_land.wm1, buy_land.y + buy_land.hm1, ox, oy, settings.economic_power, 0, 0, 0, 0, tax))
return false;
land_tax += tax;
return generate_with_full(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, valid, true, NULL, NULL);
}
bool gen_cc_tx_valid_cc_repair::generate_game_update_command(cryptonote::core &c, size_t ev_index, const std::vector<test_event_entry> &events_)
{
bool ret = gen_cc_tx_validation_base::generate_game_update_command(c, ev_index, events_);
if (!ret) return false;
std::vector<test_event_entry> &events = const_cast<std::vector<test_event_entry>&>(events_);
if (ev_index + 1 >= events.size())
{
MERROR("event index is out of range");
return false;
}
auto &e = events[ev_index + 1];
if (e.type() != typeid(cryptonote::block))
{
MERROR("Game update event is not a block");
return false;
}
auto &b = boost::get<cryptonote::block>(e);
auto &cg = boost::get<cryptonote::cc_command_game_update_t>(b.miner_tx.cc_cmd);
auto &city = cg.cities.back();
uint32_t account = 0xffffffffu;
for (const auto &adj: city.balances)
{
account += adj.delta_account + 1;
if (account == FIRST_TEST_ACCOUNT - 1)
game_update_treasury_delta = adj.delta;
}
if (city.repair.size() != 1 || city.repair[0].delta_id != 1 + PREDEFINED_BUILDINGS)
return false;
expected_repair += city.repair[0].delta_repair;
for (const auto &e: game_events)
{
if (e.cmd == get_cc_tag<uint8_t>(cryptonote::cc_command_game_update_t()))
if (boost::ends_with(e.event, " prestige bonus"))
prestige_bonuses[e.account] += e.balance;
}
return true;
}
bool gen_cc_tx_valid_cc_repair::check_final_state(cryptonote::core &c, const std::vector<test_event_entry> &events)
{
uint32_t repair = 0;
BlockchainDB &db = c.get_blockchain_storage().get_db();
if (!db.get_cc_flag_repair(1 + PREDEFINED_BUILDINGS, repair))
{
MERROR("Error in get_cc_flag_repair");
return false;
}
if (repair != expected_repair)
{
MERROR("Repair is not the expected value: expected " << expected_repair << ", got " << repair);
return false;
}
return log_test_accounts(c, events)
&& expect_cc_account(c, 0, FIRST_TEST_ACCOUNT, expected_balance[0] + prestige_bonuses[FIRST_TEST_ACCOUNT] - 3 * BARE_TX_FEE - money_cost - land_tax)
&& expect_cc_account(c, 1, FIRST_TEST_ACCOUNT + 1, expected_balance[1] + prestige_bonuses[FIRST_TEST_ACCOUNT + 1])
&& expect_cc_account(c, 2, FIRST_TEST_ACCOUNT + 2, expected_balance[2] + prestige_bonuses[FIRST_TEST_ACCOUNT + 2])
&& expect_cc_account(c, 3, FIRST_TEST_ACCOUNT + 3, expected_balance[3] + prestige_bonuses[FIRST_TEST_ACCOUNT + 3])
&& expect_cc_account(c, 4, FIRST_TEST_ACCOUNT + 4, initial_funding[4] + prestige_bonuses[FIRST_TEST_ACCOUNT + 4])
&& expect_cc_account(c, 5, FIRST_TEST_ACCOUNT + 5, initial_funding[5] + prestige_bonuses[FIRST_TEST_ACCOUNT + 5])
&& expect_cc_account(c, 6, FIRST_TEST_ACCOUNT + 6, initial_funding[6] + prestige_bonuses[FIRST_TEST_ACCOUNT + 6])
&& expect_cc_account(c, 7, FIRST_TEST_ACCOUNT + 7, initial_funding[7] + prestige_bonuses[FIRST_TEST_ACCOUNT + 7])
&& expect_treasury_balance(c, expected_treasury_balance + money_cost + game_update_treasury_delta)
&& expect_item_balances(c, FIRST_TEST_ACCOUNT, {std::make_pair(ITEM_BASIC_STONE, item_balances[ITEM_BASIC_STONE]), std::make_pair(ITEM_BASIC_WOOD, item_balances[ITEM_BASIC_WOOD]), std::make_pair(ITEM_LABOUR, item_balances[ITEM_LABOUR])});
}
bool gen_cc_tx_invalid_cc_repair_past_max::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
uint32_t ox, oy;
cc::get_city_origin(0, ox, oy);
cryptonote::cc_command_buy_land_t buy_land;
buy_land.cc_account = FIRST_TEST_ACCOUNT;
buy_land.city = 0;
buy_land.x = ox + 200;
buy_land.y = oy + 200;
buy_land.wm1 = 11;
buy_land.hm1 = 11;
cmds.push_back(std::make_tuple("", buy_land, BARE_TX_FEE));
cryptonote::cc_command_building_settings_t settings;
settings.cc_account = FIRST_TEST_ACCOUNT;
settings.flag = 1 + PREDEFINED_BUILDINGS;
settings.role = ROLE_RESIDENTIAL1;
settings.economic_power = 100;
settings.construction_height = 89; // brittle
cmds.push_back(std::make_tuple("", settings, BARE_TX_FEE));
cryptonote::cc_command_repair_t repair;
repair.cc_account = FIRST_TEST_ACCOUNT;
repair.flags.push_back({1 + PREDEFINED_BUILDINGS, 4501});
cmds.push_back(std::make_tuple("", repair, BARE_TX_FEE));
return generate_with_full(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, true, NULL, NULL);
}
bool gen_cc_tx_invalid_cc_repair_negative::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
uint32_t ox, oy;
cc::get_city_origin(0, ox, oy);
cryptonote::cc_command_buy_land_t buy_land;
buy_land.cc_account = FIRST_TEST_ACCOUNT;
buy_land.city = 0;
buy_land.x = ox + 200;
buy_land.y = oy + 200;
buy_land.wm1 = 11;
buy_land.hm1 = 11;
cmds.push_back(std::make_tuple("", buy_land, BARE_TX_FEE));
cryptonote::cc_command_building_settings_t settings;
settings.cc_account = FIRST_TEST_ACCOUNT;
settings.flag = 1 + PREDEFINED_BUILDINGS;
settings.role = ROLE_RESIDENTIAL1;
settings.economic_power = 100;
settings.construction_height = 89; // brittle
cmds.push_back(std::make_tuple("", settings, BARE_TX_FEE));
cryptonote::cc_command_repair_t repair;
repair.cc_account = FIRST_TEST_ACCOUNT;
repair.flags.push_back({1 + PREDEFINED_BUILDINGS, (uint32_t)-1});
cmds.push_back(std::make_tuple("", repair, BARE_TX_FEE));
return generate_with_full(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, true, NULL, NULL);
}
bool gen_cc_tx_invalid_cc_repair_invalid_flag::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
uint32_t ox, oy;
cc::get_city_origin(0, ox, oy);
cryptonote::cc_command_buy_land_t buy_land;
buy_land.cc_account = FIRST_TEST_ACCOUNT;
buy_land.city = 0;
buy_land.x = ox + 200;
buy_land.y = oy + 200;
buy_land.wm1 = 11;
buy_land.hm1 = 11;
cmds.push_back(std::make_tuple("", buy_land, BARE_TX_FEE));
cryptonote::cc_command_building_settings_t settings;
settings.cc_account = FIRST_TEST_ACCOUNT;
settings.flag = 1 + PREDEFINED_BUILDINGS;
settings.role = ROLE_RESIDENTIAL1;
settings.economic_power = 100;
settings.construction_height = 89; // brittle
cmds.push_back(std::make_tuple("", settings, BARE_TX_FEE));
cryptonote::cc_command_repair_t repair;
repair.cc_account = FIRST_TEST_ACCOUNT;
repair.flags.push_back({10, 4500});
cmds.push_back(std::make_tuple("", repair, BARE_TX_FEE));
return generate_with_full(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, true, NULL, NULL);
}
bool gen_cc_tx_invalid_cc_repair_unowned_flag::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
uint32_t ox, oy;
cc::get_city_origin(0, ox, oy);
cryptonote::cc_command_buy_land_t buy_land;
buy_land.cc_account = FIRST_TEST_ACCOUNT;
buy_land.city = 0;
buy_land.x = ox + 200;
buy_land.y = oy + 200;
buy_land.wm1 = 11;
buy_land.hm1 = 11;
cmds.push_back(std::make_tuple("", buy_land, BARE_TX_FEE));
cryptonote::cc_command_building_settings_t settings;
settings.cc_account = FIRST_TEST_ACCOUNT;
settings.flag = 1 + PREDEFINED_BUILDINGS;
settings.role = ROLE_RESIDENTIAL1;
settings.economic_power = 100;
settings.construction_height = 89; // brittle
cmds.push_back(std::make_tuple("", settings, BARE_TX_FEE));
cryptonote::cc_command_repair_t repair;
repair.cc_account = FIRST_TEST_ACCOUNT + 1;
repair.flags.push_back({1 + PREDEFINED_BUILDINGS, 4500});
cmds.push_back(std::make_tuple("", repair, BARE_TX_FEE));
return generate_with_full(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, true, NULL, NULL);
}
uint64_t gen_cc_tx_valid_huge_game_update::land_tax = 0;
int64_t gen_cc_tx_valid_huge_game_update::game_update_treasury_delta = 0;
std::map<uint32_t, uint64_t> gen_cc_tx_valid_huge_game_update::prestige_bonuses;
bool gen_cc_tx_valid_huge_game_update::generate(std::vector<test_event_entry>& events) const
{
cryptonote::cc_command_game_update_t::test_payload_template.resize(1024 * 1024, '\0');
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_buy_items_t buy_items;
buy_items.cc_account = FIRST_TEST_ACCOUNT;
cryptonote::cc_command_buy_items_t::entry_t e;
e.type = ITEM_BASIC_STONE;
e.amount = 1;
buy_items.entries.push_back(e);
cmds.push_back(std::make_tuple("", buy_items, BARE_TX_FEE));
uint32_t ox, oy;
cc::get_city_origin(0, ox, oy);
if (!cc::get_land_tax(ox + PREP_BUY_LAND_X, oy + PREP_BUY_LAND_Y, ox + PREP_BUY_LAND_X + PREP_BUY_LAND_WM1, oy + PREP_BUY_LAND_Y + PREP_BUY_LAND_HM1, ox, oy, 100, 0, 0, 0, 0, land_tax))
return false;
bool ret = generate_with_full(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, valid, true, NULL, NULL);
if (!ret)
{
cryptonote::cc_command_game_update_t::test_payload_template.clear();
return false;
}
return true;
}
bool gen_cc_tx_valid_huge_game_update::generate_game_update_command(cryptonote::core &c, size_t ev_index, const std::vector<test_event_entry> &events_)
{
epee::misc_utils::auto_scope_leave_caller scope_exit_handler = epee::misc_utils::create_scope_leave_handler([]() {
cryptonote::cc_command_game_update_t::test_payload_template.clear();
});
bool ret = gen_cc_tx_validation_base::generate_game_update_command(c, ev_index, events_);
if (!ret) return false;
std::vector<test_event_entry> &events = const_cast<std::vector<test_event_entry>&>(events_);
if (ev_index + 1 >= events.size())
{
MERROR("event index is out of range");
return false;
}
auto &e = events[ev_index + 1];
if (e.type() != typeid(cryptonote::block))
{
MERROR("Game update event is not a block");
return false;
}
auto &b = boost::get<cryptonote::block>(e);
auto &cg = boost::get<cryptonote::cc_command_game_update_t>(b.miner_tx.cc_cmd);
const size_t game_update_tx_size = cryptonote::tx_to_blob(b.miner_tx).size();
MINFO("Game update tx: " << game_update_tx_size);
MINFO("Game update block: " << cryptonote::block_to_blob(b).size());
if (game_update_tx_size <= 1024 * 1024)
{
MERROR("Game update tx is not as large as we want");
return false;
}
auto &city = cg.cities.back();
uint32_t account = 0xffffffffu;
for (const auto &adj: city.balances)
{
account += adj.delta_account + 1;
if (account == FIRST_TEST_ACCOUNT - 1)
game_update_treasury_delta = adj.delta;
}
for (const auto &e: game_events)
{
if (e.cmd == get_cc_tag<uint8_t>(cryptonote::cc_command_game_update_t()))
if (boost::ends_with(e.event, " prestige bonus"))
prestige_bonuses[e.account] += e.balance;
}
return true;
}
bool gen_cc_tx_valid_huge_game_update::check_final_state(cryptonote::core &c, const std::vector<test_event_entry> &events)
{
return log_test_accounts(c, events)
&& expect_cc_account(c, 0, FIRST_TEST_ACCOUNT, expected_balance[0] + prestige_bonuses[FIRST_TEST_ACCOUNT] - cc::get_last_resort_price(ITEM_BASIC_STONE) - BARE_TX_FEE - land_tax)
&& expect_cc_account(c, 1, FIRST_TEST_ACCOUNT + 1, expected_balance[1] + prestige_bonuses[FIRST_TEST_ACCOUNT + 1])
&& expect_cc_account(c, 2, FIRST_TEST_ACCOUNT + 2, expected_balance[2] + prestige_bonuses[FIRST_TEST_ACCOUNT + 2])
&& expect_cc_account(c, 3, FIRST_TEST_ACCOUNT + 3, expected_balance[3] + prestige_bonuses[FIRST_TEST_ACCOUNT + 3])
&& expect_cc_account(c, 4, FIRST_TEST_ACCOUNT + 4, initial_funding[4] + prestige_bonuses[FIRST_TEST_ACCOUNT + 4])
&& expect_cc_account(c, 5, FIRST_TEST_ACCOUNT + 5, initial_funding[5] + prestige_bonuses[FIRST_TEST_ACCOUNT + 5])
&& expect_cc_account(c, 6, FIRST_TEST_ACCOUNT + 6, initial_funding[6] + prestige_bonuses[FIRST_TEST_ACCOUNT + 6])
&& expect_cc_account(c, 7, FIRST_TEST_ACCOUNT + 7, initial_funding[7] + prestige_bonuses[FIRST_TEST_ACCOUNT + 7])
&& expect_treasury_balance(c, expected_treasury_balance + cc::get_last_resort_price(ITEM_BASIC_STONE) + game_update_treasury_delta);
}
bool gen_cc_tx_valid_cc_bare_new_item::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_new_item_t new_item;
new_item.cc_account = FIRST_TEST_ACCOUNT;
new_item.amount = 35;
new_item.name = "Test item";
new_item.primary_description = "Primary description";
new_item.secondary_description = "Secondary description";
new_item.is_group = false;
new_item.is_public = false;
new_item.group = 0;
new_item.gold = 0;
new_item.can_create_more = 0;
new_item.prestige_bonus = 0;
cmds.push_back(std::make_tuple("", new_item, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, valid, NULL, NULL);
}
bool gen_cc_tx_valid_cc_bare_new_item::check_final_state(cryptonote::core &c, const std::vector<test_event_entry> &events)
{
return log_test_accounts(c, events)
&& expect_cc_account(c, 0, FIRST_TEST_ACCOUNT, expected_balance[0] - 1 * BARE_TX_FEE - NEW_ITEM_FEE)
&& expect_cc_account(c, 1, FIRST_TEST_ACCOUNT + 1, expected_balance[1])
&& expect_cc_account(c, 2, FIRST_TEST_ACCOUNT + 2, expected_balance[2])
&& expect_cc_account(c, 3, FIRST_TEST_ACCOUNT + 3, expected_balance[3])
&& expect_cc_account(c, 4, FIRST_TEST_ACCOUNT + 4, initial_funding[4])
&& expect_cc_account(c, 5, FIRST_TEST_ACCOUNT + 5, initial_funding[5])
&& expect_cc_account(c, 6, FIRST_TEST_ACCOUNT + 6, initial_funding[6])
&& expect_cc_account(c, 7, FIRST_TEST_ACCOUNT + 7, initial_funding[7])
&& expect_treasury_balance(c, expected_treasury_balance + NEW_ITEM_FEE);
}
bool gen_cc_tx_invalid_cc_bare_new_item_zero_amount::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_new_item_t new_item;
new_item.cc_account = FIRST_TEST_ACCOUNT;
new_item.amount = 0;
new_item.name = "Test item";
new_item.primary_description = "Primary description";
new_item.secondary_description = "Secondary description";
new_item.is_group = false;
new_item.is_public = false;
new_item.group = 0;
new_item.gold = 0;
new_item.can_create_more = false;
new_item.prestige_bonus = 0;
cmds.push_back(std::make_tuple("", new_item, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, NULL, NULL);
}
bool gen_cc_tx_invalid_cc_bare_new_item_no_name::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_new_item_t new_item;
new_item.cc_account = FIRST_TEST_ACCOUNT;
new_item.amount = 35;
new_item.name = "";
new_item.primary_description = "Primary description";
new_item.secondary_description = "Secondary description";
new_item.is_group = false;
new_item.is_public = false;
new_item.group = 0;
new_item.gold = 0;
cmds.push_back(std::make_tuple("", new_item, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, NULL, NULL);
}
bool gen_cc_tx_invalid_cc_bare_new_item_invalid_name::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_new_item_t new_item;
new_item.cc_account = FIRST_TEST_ACCOUNT;
new_item.amount = 35;
new_item.name = "ABC\002D";
new_item.primary_description = "Primary description";
new_item.secondary_description = "Secondary description";
new_item.is_group = false;
new_item.is_public = false;
new_item.group = 0;
new_item.gold = 0;
cmds.push_back(std::make_tuple("", new_item, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, NULL, NULL);
}
bool gen_cc_tx_invalid_cc_bare_new_item_duplicate_name::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_new_item_t new_item;
new_item.cc_account = FIRST_TEST_ACCOUNT;
new_item.amount = 35;
new_item.name = "Test item";
new_item.primary_description = "Primary description";
new_item.secondary_description = "Secondary description";
new_item.is_group = false;
new_item.is_public = false;
new_item.group = 0;
new_item.gold = 0;
new_item.can_create_more = 0;
new_item.prestige_bonus = 0;
cmds.push_back(std::make_tuple("", new_item, BARE_TX_FEE));
cmds.push_back(std::make_tuple("", new_item, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, NULL, NULL);
}
bool gen_cc_tx_invalid_cc_bare_ignore_wrong_account::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_ignore_t ignore;
ignore.cc_account = FIRST_TEST_ACCOUNT;
ignore.type = cryptonote::cc_command_ignore_t::type_account;
ignore.id.push_back(FIRST_TEST_ACCOUNT);
ignore.ignore = true;
cmds.push_back(std::make_tuple("", ignore, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_none, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, NULL, NULL);
}
bool gen_cc_tx_invalid_cc_bare_new_event_badge_wrong_account::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_event_badge_t event_badge;
event_badge.cc_account = FIRST_TEST_ACCOUNT;
event_badge.badge_id = 0;
event_badge.name = "test badge";
event_badge.description = "test badge desc";
event_badge.instances.push_back({FIRST_TEST_ACCOUNT, 1});
cmds.push_back(std::make_tuple("", event_badge, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_none, cmds.size(), mixin, amount_paid, true, cmds, false, invalid, NULL, NULL);
}
bool gen_cc_tx_invalid_cc_bare_reused_nonce::generate(std::vector<test_event_entry>& events) const
{
init_cc_test_accounts();
const unsigned int mixin = 10;
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_buy_items_t cmd;
cmd.cc_account = FIRST_TEST_ACCOUNT;
cryptonote::cc_command_buy_items_t::entry_t e;
e.type = ITEM_BASIC_STONE;
e.amount = 1;
cmd.entries.push_back(e);
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
return generate_with(events, boost::none, boost::none, prep_buy_stuff, cmds.size(), mixin, amount_paid, true, cmds, false, invalid_on_block, NULL, [](transaction &tx) {
cryptonote::cc_command_basenonce_t *basenonce = cryptonote::get_cc_command_basenonce(tx.cc_cmd);
if (!basenonce)
return false;
basenonce->cc_nonce = 4000;
tx.invalidate_hashes();
const crypto::public_key pkey = cc_test_accounts[0].get_keys().m_account_address.m_spend_public_key;
const crypto::secret_key skey = cc_test_accounts[0].get_keys().m_spend_secret_key;
cc::generate_signature(cryptonote::get_transaction_prefix_hash_with_tag(tx), pkey, skey, tx.cc_account_signature);
return true;
});
}