forked from townforge/townforge
3413 lines
143 KiB
C++
3413 lines
143 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 "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 INITIAL_AUTO_FUNDING (35*COIN - CRYPTONOTE_CC_NEW_ACCOUNT_FEE)
|
|
#define BARE_TX_FEE 3000000
|
|
#define STARTING_BLOCK_1 400
|
|
#define STARTING_BLOCK_2 1200
|
|
#define STARTING_LABOUR 6000
|
|
#define N_LARGE_BALANCE_OUTS 350
|
|
#define PREDEFINED_BUILDINGS 1
|
|
#define FIRST_TEST_ACCOUNT 5
|
|
|
|
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;
|
|
|
|
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;
|
|
}
|
|
cryptonote::cc_command_game_update_t cg = cc::create_cc_game_update_command(c.get_blockchain_storage().get_db());
|
|
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;
|
|
|
|
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 * 35*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 + 140;
|
|
buy_land.y = oy + 20;
|
|
buy_land.wm1 = 5;
|
|
buy_land.hm1 = 5;
|
|
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(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);
|
|
}
|
|
|
|
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(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(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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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 = 35*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
|
|
{
|
|
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, 30*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, 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] - 30*COIN)
|
|
&& expect_cc_account(c, 1, FIRST_TEST_ACCOUNT + 1, initial_funding[1] + 50*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*35*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 + 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, 70*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),
|
|
90*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, 30*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, 34*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] - 34*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);
|
|
}
|
|
|
|
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, 34*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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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 = MIN_BUY_SIDE_SIZE-1;
|
|
cmd.hm1 = MIN_BUY_SIDE_SIZE-1;
|
|
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 + 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 = 33*COIN;
|
|
transfer.public_key = cc::get_cc_public_key(cc_test_accounts[0].get_keys().m_spend_secret_key);
|
|
transfer.out_amount = 33*COIN;
|
|
cmds.push_back(std::make_tuple("", transfer, BARE_TX_FEE));
|
|
transfer.cc_account = FIRST_TEST_ACCOUNT + 2;
|
|
transfer.in_amount = 33*COIN;
|
|
transfer.public_key = cc::get_cc_public_key(cc_test_accounts[0].get_keys().m_spend_secret_key);
|
|
transfer.out_amount = 33*COIN;
|
|
cmds.push_back(std::make_tuple("", transfer, BARE_TX_FEE));
|
|
transfer.cc_account = FIRST_TEST_ACCOUNT + 4;
|
|
transfer.in_amount = 33*COIN;
|
|
transfer.public_key = cc::get_cc_public_key(cc_test_accounts[0].get_keys().m_spend_secret_key);
|
|
transfer.out_amount = 33*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 * 33*COIN)
|
|
&& expect_cc_account(c, 1, FIRST_TEST_ACCOUNT + 1, initial_funding[1] - 33*COIN - BARE_TX_FEE)
|
|
&& expect_cc_account(c, 2, FIRST_TEST_ACCOUNT + 2, initial_funding[2] - 33*COIN - BARE_TX_FEE)
|
|
&& expect_cc_account(c, 3, FIRST_TEST_ACCOUNT + 3, initial_funding[3] + N_LARGE_BALANCE_OUTS * 35 * COIN - land_cost - BARE_TX_FEE)
|
|
&& expect_cc_account(c, 4, FIRST_TEST_ACCOUNT + 4, initial_funding[4] - 33*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 + 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 = 5;
|
|
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 = 4;
|
|
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));
|
|
|
|
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;
|
|
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;
|
|
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;
|
|
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 = 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;
|
|
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;
|
|
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;
|
|
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;
|
|
cmds.push_back(std::make_tuple("", settings, BARE_TX_FEE));
|
|
cryptonote::cc_command_build_t cmd;
|
|
for (int i = 0; i < 3; ++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(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(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(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(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(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 = MIN_BUY_SIDE_SIZE-1;
|
|
buy_land.hm1 = MIN_BUY_SIDE_SIZE-1;
|
|
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(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(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(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(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;
|
|
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(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;
|
|
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.active = false;
|
|
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});
|
|
cc::get_empty_packed_tiles(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(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;
|
|
int64_t gen_cc_tx_valid_cc_repair::game_update_account1_delta = 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;
|
|
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 = 5;
|
|
buy_land.hm1 = 5;
|
|
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;
|
|
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, 1500});
|
|
cmds.push_back(std::make_tuple("", repair, BARE_TX_FEE));
|
|
|
|
expected_repair = DEFAULT_REPAIR + 1500; // technically overflows, but the +1500 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;
|
|
|
|
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)
|
|
{
|
|
uint64_t balance;
|
|
account += adj.delta_account + 1;
|
|
if (account == FIRST_TEST_ACCOUNT - 1)
|
|
game_update_treasury_delta = adj.delta;
|
|
else if (account == FIRST_TEST_ACCOUNT)
|
|
game_update_account1_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;
|
|
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] - 3 * BARE_TX_FEE - money_cost + game_update_account1_delta)
|
|
&& 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 + 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 = 5;
|
|
buy_land.hm1 = 5;
|
|
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;
|
|
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 = 5;
|
|
buy_land.hm1 = 5;
|
|
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;
|
|
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 = 5;
|
|
buy_land.hm1 = 5;
|
|
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;
|
|
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 = 5;
|
|
buy_land.hm1 = 5;
|
|
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;
|
|
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);
|
|
}
|
|
|
|
int64_t gen_cc_tx_valid_huge_game_update::game_update_account1_delta = 0;
|
|
int64_t gen_cc_tx_valid_huge_game_update::game_update_treasury_delta = 0;
|
|
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));
|
|
|
|
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)
|
|
{
|
|
uint64_t balance;
|
|
account += adj.delta_account + 1;
|
|
if (account == FIRST_TEST_ACCOUNT - 1)
|
|
game_update_treasury_delta = adj.delta;
|
|
else if (account == FIRST_TEST_ACCOUNT)
|
|
game_update_account1_delta = adj.delta;
|
|
}
|
|
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] - cc::get_last_resort_price(ITEM_BASIC_STONE) - BARE_TX_FEE + game_update_account1_delta)
|
|
&& 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 + 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;
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
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(tx), pkey, skey, tx.cc_account_signature);
|
|
return true;
|
|
});
|
|
}
|