make blocks and labour items

This commit is contained in:
Crypto City 2019-09-07 17:26:01 +00:00
parent 0a2797fea5
commit 9b9aed1c56
46 changed files with 649 additions and 685 deletions

View File

@ -375,37 +375,25 @@ transaction BlockchainDB::get_pruned_tx(const crypto::hash& h) const
bool BlockchainDB::get_cc_account_transactional_data(uint32_t id, crypto::public_key &public_key, uint64_t &balance) const
{
uint32_t block_balances[256];
uint32_t labour_balance;
uint32_t item_balances[NUM_ITEMS];
std::vector<uint32_t> flags;
return get_cc_account_data(id, public_key, balance, block_balances, labour_balance, flags);
return get_cc_account_data(id, public_key, balance, item_balances, flags);
}
bool BlockchainDB::get_cc_account_balance(uint32_t id, uint64_t &balance) const
{
uint32_t block_balances[256];
uint32_t labour_balance;
uint32_t item_balances[NUM_ITEMS];
std::vector<uint32_t> flags;
crypto::public_key public_key;
return get_cc_account_data(id, public_key, balance, block_balances, labour_balance, flags);
return get_cc_account_data(id, public_key, balance, item_balances, flags);
}
bool BlockchainDB::get_cc_account_block_balances(uint32_t id, uint32_t block_balances[256]) const
bool BlockchainDB::get_cc_account_item_balances(uint32_t id, uint32_t item_balances[NUM_ITEMS]) const
{
uint64_t balance;
uint32_t labour_balance;
std::vector<uint32_t> flags;
crypto::public_key public_key;
return get_cc_account_data(id, public_key, balance, block_balances, labour_balance, flags);
}
bool BlockchainDB::get_cc_account_labour_balance(uint32_t id, uint32_t &labour_balance) const
{
uint64_t balance;
uint32_t block_balances[256];
std::vector<uint32_t> flags;
crypto::public_key public_key;
return get_cc_account_data(id, public_key, balance, block_balances, labour_balance, flags);
return get_cc_account_data(id, public_key, balance, item_balances, flags);
}
bool BlockchainDB::get_cc_city_treasury(uint32_t id, uint32_t &treasury) const

View File

@ -35,6 +35,7 @@
#include <boost/program_options.hpp>
#include "common/command_line.h"
#include "crypto/hash.h"
#include "cc/cc_config.h"
#include "cryptonote_basic/blobdatatype.h"
#include "cryptonote_basic/cryptonote_basic.h"
#include "cryptonote_basic/difficulty.h"
@ -161,8 +162,7 @@ struct cc_flag_data_t
uint32_t repair;
uint8_t stability;
uint32_t economic_power;
uint32_t block_budget[256];
uint32_t labour_budget;
uint32_t budget[NUM_ITEMS];
bool active;
};
@ -1811,10 +1811,9 @@ public:
virtual bool lookup_cc_account(const crypto::public_key &public_key, uint32_t &id) const = 0;
virtual void delete_cc_account(uint32_t id) = 0;
virtual uint32_t get_num_cc_accounts() const = 0;
virtual bool get_cc_account_data(uint32_t id, crypto::public_key &public_key, uint64_t &balance, uint32_t block_balances[256], uint32_t &labour_balance, std::vector<uint32_t> &flags) const = 0;
virtual bool get_cc_account_data(uint32_t id, crypto::public_key &public_key, uint64_t &balance, uint32_t item_balances[NUM_ITEMS], std::vector<uint32_t> &flags) const = 0;
virtual void set_cc_account_balance(uint32_t id, uint64_t balance) = 0;
virtual void set_cc_account_block_balances(uint32_t id, uint32_t block_balances[256]) = 0;
virtual void set_cc_account_labour_balance(uint32_t id, uint32_t labour_balance) = 0;
virtual void set_cc_account_item_balances(uint32_t id, uint32_t item_balances[NUM_ITEMS]) = 0;
virtual void add_cc_account_flag(uint32_t id, uint32_t flag_id) = 0;
virtual void remove_cc_account_flag(uint32_t id, uint32_t flag_id) = 0;
virtual void remove_last_cc_account_flag(uint32_t id) = 0;
@ -1832,7 +1831,7 @@ public:
virtual void set_cc_flag_repair(uint32_t id, uint32_t repair) = 0;
virtual void set_cc_flag_tiles(uint32_t id, const std::vector<std::vector<uint8_t>> &tiles) = 0;
virtual void set_cc_flag_role(uint32_t id, uint8_t role, uint32_t economic_power) = 0;
virtual void set_cc_flag_budget(uint32_t id, const uint32_t blocks[256], uint32_t labour) = 0;
virtual void set_cc_flag_budget(uint32_t id, const uint32_t budget[NUM_ITEMS]) = 0;
virtual void set_cc_flag_active(uint32_t id, bool active) = 0;
virtual uint32_t get_num_cc_flags() const = 0;
@ -1857,8 +1856,7 @@ public:
bool get_cc_account_transactional_data(uint32_t id, crypto::public_key &public_key, uint64_t &balance) const;
bool get_cc_city_treasury(uint32_t id, uint32_t &treasury) const;
bool get_cc_account_balance(uint32_t id, uint64_t &balance) const;
bool get_cc_account_block_balances(uint32_t id, uint32_t block_balances[256]) const;
bool get_cc_account_labour_balance(uint32_t id, uint32_t &labour_balance) const;
bool get_cc_account_item_balances(uint32_t id, uint32_t item_balances[NUM_ITEMS]) const;
bool transfer_cc_flag(uint32_t id, uint32_t new_owner);
/**

View File

@ -374,8 +374,7 @@ typedef struct mdb_cc_account_data
{
crypto::public_key public_key;
uint64_t balance;
uint32_t labour_balance;
uint32_t n_block_balances;
uint32_t n_item_balances;
uint32_t n_flags;
} mdb_cc_account_data;
@ -406,8 +405,7 @@ typedef struct mdb_cc_flag_data
uint8_t stability;
uint32_t economic_power;
uint32_t active: 1;
uint32_t block_budget[256];
uint32_t labour_budget;
uint32_t budget[NUM_ITEMS];
} mdb_cc_flag_data;
typedef struct mdb_cc_tile_data
@ -4444,24 +4442,24 @@ void BlockchainLMDB::drop_alt_blocks()
TXN_POSTFIX_SUCCESS();
}
static bool read_account_variable_size_data(const mdb_cc_account_data *ad, size_t bytes, uint32_t block_balances[256], std::vector<uint32_t> &flags)
static bool read_account_variable_size_data(const mdb_cc_account_data *ad, size_t bytes, uint32_t item_balances[NUM_ITEMS], std::vector<uint32_t> &flags)
{
memset(block_balances, 0, 256 * sizeof(uint32_t));
memset(item_balances, 0, NUM_ITEMS * sizeof(uint32_t));
flags.clear();
if (bytes < sizeof(mdb_cc_account_data) + (1 + sizeof(uint32_t)) * ad->n_block_balances + sizeof(uint32_t) * ad->n_flags)
if (bytes < sizeof(mdb_cc_account_data) + (1 + sizeof(uint32_t)) * ad->n_item_balances + sizeof(uint32_t) * ad->n_flags)
return false;
// variable size data
const uint8_t *ptr = ((const uint8_t*)ad) + sizeof(mdb_cc_account_data);
// read block balances
for (uint32_t i = 0; i < ad->n_block_balances; ++i)
for (uint32_t i = 0; i < ad->n_item_balances; ++i)
{
unsigned idx = *ptr++;
if (block_balances[idx] != 0)
MWARNING("Two non zero entries for block_balances[" << idx << "]");
block_balances[idx] = *(const uint32_t*)ptr;
if (item_balances[idx] != 0)
MWARNING("Two non zero entries for item_balances[" << idx << "]");
item_balances[idx] = *(const uint32_t*)ptr;
ptr += sizeof(uint32_t);
}
@ -4476,15 +4474,15 @@ static bool read_account_variable_size_data(const mdb_cc_account_data *ad, size_
return true;
}
static void write_account_variable_size_data(MDB_val &v, mdb_cc_account_data &ad, uint32_t block_balances[256], std::vector<uint32_t> &flags)
static void write_account_variable_size_data(MDB_val &v, mdb_cc_account_data &ad, uint32_t item_balances[NUM_ITEMS], std::vector<uint32_t> &flags)
{
ad.n_block_balances = 0;
for (int i = 0; i < 256; ++i)
if (block_balances[i])
++ad.n_block_balances;
ad.n_item_balances = 0;
for (int i = 0; i < NUM_ITEMS; ++i)
if (item_balances[i])
++ad.n_item_balances;
ad.n_flags = flags.size();
v.mv_size = sizeof(mdb_cc_account_data) + (1 + sizeof(uint32_t)) * ad.n_block_balances + sizeof(uint32_t) * ad.n_flags;
v.mv_size = sizeof(mdb_cc_account_data) + (1 + sizeof(uint32_t)) * ad.n_item_balances + sizeof(uint32_t) * ad.n_flags;
v.mv_data = malloc(v.mv_size);
memcpy(v.mv_data, &ad, sizeof(mdb_cc_account_data));
@ -4492,12 +4490,12 @@ static void write_account_variable_size_data(MDB_val &v, mdb_cc_account_data &ad
uint8_t *ptr = ((uint8_t*)v.mv_data) + sizeof(mdb_cc_account_data);
// write block balances
for (uint32_t i = 0; i < 256; ++i)
for (uint32_t i = 0; i < NUM_ITEMS; ++i)
{
if (!block_balances[i])
if (!item_balances[i])
continue;
*ptr++ = i;
*(uint32_t*)ptr = block_balances[i];
*(uint32_t*)ptr = item_balances[i];
ptr += sizeof(uint32_t);
}
@ -4548,8 +4546,7 @@ uint32_t BlockchainLMDB::allocate_new_cc_account(const crypto::public_key &publi
mdb_cc_account_data ad;
ad.public_key = public_key;
ad.balance = 0;
ad.labour_balance = 0;
ad.n_block_balances = 0;
ad.n_item_balances = 0;
ad.n_flags = 0;
k.mv_data = (void*)&account_id;
@ -4662,7 +4659,7 @@ void BlockchainLMDB::delete_cc_account(uint32_t id)
throw0(DB_ERROR(lmdb_error("Error deleting account keys for account " + std::to_string(id) + ": ", result).c_str()));
}
bool BlockchainLMDB::get_cc_account_data(uint32_t id, crypto::public_key &public_key, uint64_t &balance, uint32_t block_balances[256], uint32_t& labour_balance, std::vector<uint32_t> &flags) const
bool BlockchainLMDB::get_cc_account_data(uint32_t id, crypto::public_key &public_key, uint64_t &balance, uint32_t item_balances[NUM_ITEMS], std::vector<uint32_t> &flags) const
{
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
@ -4684,9 +4681,8 @@ bool BlockchainLMDB::get_cc_account_data(uint32_t id, crypto::public_key &public
memcpy(&public_key, &ad->public_key, 32);
balance = ad->balance;
labour_balance = ad->labour_balance;
if (!read_account_variable_size_data(ad, v.mv_size, block_balances, flags))
if (!read_account_variable_size_data(ad, v.mv_size, item_balances, flags))
throw0(DB_ERROR("Failed to read account variable size data"));
TXN_POSTFIX_RDONLY();
@ -4697,10 +4693,9 @@ bool BlockchainLMDB::does_cc_account_exist(uint32_t id) const
{
crypto::public_key public_key;
uint64_t balance;
uint32_t block_balances[256];
uint32_t labour_balance;
uint32_t item_balances[NUM_ITEMS];
std::vector<uint32_t> flags;
return get_cc_account_data(id, public_key, balance, block_balances, labour_balance, flags);
return get_cc_account_data(id, public_key, balance, item_balances, flags);
}
void BlockchainLMDB::set_cc_account_balance(uint32_t id, uint64_t balance)
@ -4723,45 +4718,12 @@ void BlockchainLMDB::set_cc_account_balance(uint32_t id, uint64_t balance)
mdb_cc_account_data ad = *(const mdb_cc_account_data*)v.mv_data;
ad.balance = balance;
uint32_t block_balances[256];
uint32_t item_balances[NUM_ITEMS];
std::vector<uint32_t> flags;
if (!read_account_variable_size_data((const mdb_cc_account_data*)v.mv_data, v.mv_size, block_balances, flags))
if (!read_account_variable_size_data((const mdb_cc_account_data*)v.mv_data, v.mv_size, item_balances, flags))
throw0(DB_ERROR("Failed to read account variable size data"));
write_account_variable_size_data(v, ad, block_balances, flags);
result = mdb_cursor_put(m_cur_cc_accounts, &k, &v, 0);
if (v.mv_data) free(v.mv_data);
if (result)
throw0(DB_ERROR(lmdb_error("Failed to add account data to db transaction: ", result).c_str()));
}
void BlockchainLMDB::set_cc_account_labour_balance(uint32_t id, uint32_t labour_balance)
{
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
mdb_txn_cursors *m_cursors = &m_wcursors;
CURSOR(cc_accounts)
// find account id
MDB_val_set(k, id);
MDB_val v;
int result = mdb_cursor_get(m_cur_cc_accounts, &k, &v, MDB_SET);
if (result)
throw0(DB_ERROR(lmdb_error("Account " + std::to_string(id) + " not found: ", result).c_str()));
if (v.mv_size < sizeof(mdb_cc_account_data))
throw0(DB_ERROR("Unexpected account data size"));
mdb_cc_account_data ad = *(const mdb_cc_account_data*)v.mv_data;
ad.labour_balance = labour_balance;
uint32_t block_balances[256];
std::vector<uint32_t> flags;
if (!read_account_variable_size_data((const mdb_cc_account_data*)v.mv_data, v.mv_size, block_balances, flags))
throw0(DB_ERROR("Failed to read account variable size data"));
write_account_variable_size_data(v, ad, block_balances, flags);
write_account_variable_size_data(v, ad, item_balances, flags);
result = mdb_cursor_put(m_cur_cc_accounts, &k, &v, 0);
if (v.mv_data) free(v.mv_data);
@ -4788,14 +4750,14 @@ void BlockchainLMDB::add_cc_account_flag(uint32_t id, uint32_t flag_id)
mdb_cc_account_data ad = *(const mdb_cc_account_data*)v.mv_data;
uint32_t block_balances[256];
uint32_t item_balances[NUM_ITEMS];
std::vector<uint32_t> flags;
if (!read_account_variable_size_data((const mdb_cc_account_data*)v.mv_data, v.mv_size, block_balances, flags))
if (!read_account_variable_size_data((const mdb_cc_account_data*)v.mv_data, v.mv_size, item_balances, flags))
throw0(DB_ERROR("Failed to read account variable size data"));
flags.push_back(flag_id);
write_account_variable_size_data(v, ad, block_balances, flags);
write_account_variable_size_data(v, ad, item_balances, flags);
result = mdb_cursor_put(m_cur_cc_accounts, &k, &v, 0);
if (v.mv_data) free(v.mv_data);
@ -4822,9 +4784,9 @@ void BlockchainLMDB::remove_cc_account_flag(uint32_t id, uint32_t flag_id)
mdb_cc_account_data ad = *(const mdb_cc_account_data*)v.mv_data;
uint32_t block_balances[256];
uint32_t item_balances[NUM_ITEMS];
std::vector<uint32_t> flags;
if (!read_account_variable_size_data((const mdb_cc_account_data*)v.mv_data, v.mv_size, block_balances, flags))
if (!read_account_variable_size_data((const mdb_cc_account_data*)v.mv_data, v.mv_size, item_balances, flags))
throw0(DB_ERROR("Failed to read account variable size data"));
bool found = false;
@ -4839,7 +4801,7 @@ void BlockchainLMDB::remove_cc_account_flag(uint32_t id, uint32_t flag_id)
if (!found)
throw0(DB_ERROR("Flag to remove not found"));
write_account_variable_size_data(v, ad, block_balances, flags);
write_account_variable_size_data(v, ad, item_balances, flags);
result = mdb_cursor_put(m_cur_cc_accounts, &k, &v, 0);
if (v.mv_data) free(v.mv_data);
@ -4866,16 +4828,16 @@ void BlockchainLMDB::remove_last_cc_account_flag(uint32_t id)
mdb_cc_account_data ad = *(const mdb_cc_account_data*)v.mv_data;
uint32_t block_balances[256];
uint32_t item_balances[NUM_ITEMS];
std::vector<uint32_t> flags;
if (!read_account_variable_size_data((const mdb_cc_account_data*)v.mv_data, v.mv_size, block_balances, flags))
if (!read_account_variable_size_data((const mdb_cc_account_data*)v.mv_data, v.mv_size, item_balances, flags))
throw0(DB_ERROR("Failed to read account variable size data"));
if (flags.empty())
throw0(DB_ERROR("Cannot remove from an empty flag list"));
flags.pop_back();
write_account_variable_size_data(v, ad, block_balances, flags);
write_account_variable_size_data(v, ad, item_balances, flags);
result = mdb_cursor_put(m_cur_cc_accounts, &k, &v, 0);
if (v.mv_data) free(v.mv_data);
@ -4883,7 +4845,7 @@ void BlockchainLMDB::remove_last_cc_account_flag(uint32_t id)
throw0(DB_ERROR(lmdb_error("Failed to add account data to db transaction: ", result).c_str()));
}
void BlockchainLMDB::set_cc_account_block_balances(uint32_t id, uint32_t block_balances[256])
void BlockchainLMDB::set_cc_account_item_balances(uint32_t id, uint32_t item_balances[NUM_ITEMS])
{
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
@ -4902,13 +4864,12 @@ void BlockchainLMDB::set_cc_account_block_balances(uint32_t id, uint32_t block_b
mdb_cc_account_data ad = *(mdb_cc_account_data*)v.mv_data;
uint32_t old_block_balances[256];
uint32_t old_item_balances[NUM_ITEMS];
std::vector<uint32_t> flags;
int asd;
if (!read_account_variable_size_data((mdb_cc_account_data*)v.mv_data, v.mv_size, old_block_balances, flags))
if (!read_account_variable_size_data((mdb_cc_account_data*)v.mv_data, v.mv_size, old_item_balances, flags))
throw0(DB_ERROR("Failed to read account variable size data"));
write_account_variable_size_data(v, ad, block_balances, flags);
write_account_variable_size_data(v, ad, item_balances, flags);
result = mdb_cursor_put(m_cur_cc_accounts, &k, &v, 0);
free(v.mv_data);
@ -5103,8 +5064,7 @@ uint32_t BlockchainLMDB::allocate_new_cc_flag(const uint32_t *id, uint32_t owner
fd.repair = repair;
fd.stability = stability;
fd.economic_power = 100;
memset(fd.block_budget, 0, sizeof(fd.block_budget));
fd.labour_budget = 0;
memset(fd.budget, 0, sizeof(fd.budget));
fd.active = true;
MDB_val k, v;
@ -5225,8 +5185,7 @@ bool BlockchainLMDB::for_all_cc_flags(std::function<bool(const cc_flag_data_t &f
cfd.repair = fd.repair;
cfd.stability = fd.stability;
cfd.economic_power = fd.economic_power;
memcpy(cfd.block_budget, fd.block_budget, sizeof(fd.block_budget));
cfd.labour_budget = fd.labour_budget;
memcpy(cfd.budget, fd.budget, sizeof(fd.budget));
cfd.active = fd.active;
if (!f(cfd))
{
@ -5274,8 +5233,7 @@ bool BlockchainLMDB::get_cc_flag_data(uint32_t id, cc_flag_data_t &cfd, std::vec
cfd.repair = fd.repair;
cfd.stability = fd.stability;
cfd.economic_power = fd.economic_power;
memcpy(cfd.block_budget, fd.block_budget, sizeof(fd.block_budget));
cfd.labour_budget = fd.labour_budget;
memcpy(cfd.budget, fd.budget, sizeof(fd.budget));
cfd.active = fd.active;
if (tiles)
@ -5400,7 +5358,7 @@ void BlockchainLMDB::set_cc_flag_role(uint32_t id, uint8_t role, uint32_t econom
throw0(DB_ERROR(lmdb_error("Failed to set flag role in db transaction: ", result).c_str()));
}
void BlockchainLMDB::set_cc_flag_budget(uint32_t id, const uint32_t blocks[256], uint32_t labour)
void BlockchainLMDB::set_cc_flag_budget(uint32_t id, const uint32_t budget[NUM_ITEMS])
{
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
@ -5418,8 +5376,7 @@ void BlockchainLMDB::set_cc_flag_budget(uint32_t id, const uint32_t blocks[256],
throw0(DB_ERROR("Unexpected flag data size"));
mdb_cc_flag_data fd = *(mdb_cc_flag_data*)v.mv_data;
memcpy(fd.block_budget, blocks, sizeof(fd.block_budget));
fd.labour_budget = labour;
memcpy(fd.budget, budget, sizeof(fd.budget));
v.mv_data = (void*)&fd;
v.mv_size = sizeof(fd);

View File

@ -450,11 +450,10 @@ private:
bool lookup_cc_account(const crypto::public_key &public_key, uint32_t &id) const;
void delete_cc_account(uint32_t id);
uint32_t get_num_cc_accounts() const;
bool get_cc_account_data(uint32_t id, crypto::public_key &public_key, uint64_t &balance, uint32_t block_balances[256], uint32_t &labour_balance, std::vector<uint32_t> &flags) const;
bool get_cc_account_data(uint32_t id, crypto::public_key &public_key, uint64_t &balance, uint32_t item_balances[NUM_ITEMS], std::vector<uint32_t> &flags) const;
bool does_cc_account_exist(uint32_t id) const;
void set_cc_account_balance(uint32_t id, uint64_t balance);
void set_cc_account_block_balances(uint32_t id, uint32_t block_balances[256]);
void set_cc_account_labour_balance(uint32_t id, uint32_t labour_balance);
void set_cc_account_item_balances(uint32_t id, uint32_t item_balances[NUM_ITEMS]);
void add_cc_account_flag(uint32_t id, uint32_t flag_id);
void remove_cc_account_flag(uint32_t id, uint32_t flag_id);
void remove_last_cc_account_flag(uint32_t id);
@ -473,7 +472,7 @@ private:
void set_cc_flag_repair(uint32_t id, uint32_t repair);
void set_cc_flag_tiles(uint32_t id, const std::vector<std::vector<uint8_t>> &tiles);
void set_cc_flag_role(uint32_t id, uint8_t role, uint32_t economic_power);
void set_cc_flag_budget(uint32_t id, const uint32_t blocks[256], uint32_t labour);
void set_cc_flag_budget(uint32_t id, const uint32_t budget[NUM_ITEMS]);
void set_cc_flag_active(uint32_t id, bool active);
uint32_t get_num_cc_flags() const;

View File

@ -170,10 +170,9 @@ public:
virtual bool lookup_cc_account(const crypto::public_key &spend_public_key, uint32_t &id) const { return false; }
virtual void delete_cc_account(uint32_t id) {}
uint32_t get_num_cc_accounts() const { return 0; }
virtual bool get_cc_account_data(uint32_t id, crypto::public_key &spend_public_key, uint64_t &balance, uint32_t block_balances[256], uint32_t &labour_balance, std::vector<uint32_t> &flags) const { return false; }
virtual bool get_cc_account_data(uint32_t id, crypto::public_key &spend_public_key, uint64_t &balance, uint32_t item_balances[NUM_ITEMS], std::vector<uint32_t> &flags) const { return false; }
virtual void set_cc_account_balance(uint32_t id, uint64_t balance) {}
virtual void set_cc_account_block_balances(uint32_t id, uint32_t block_balances[256]) {}
virtual void set_cc_account_labour_balance(uint32_t id, uint32_t labour_balance) {}
virtual void set_cc_account_item_balances(uint32_t id, uint32_t item_balances[NUM_ITEMS]) {}
virtual void add_cc_account_flag(uint32_t id, uint32_t flag_id) {}
virtual void remove_cc_account_flag(uint32_t id, uint32_t flag_id) {}
virtual void remove_last_cc_account_flag(uint32_t id) {}
@ -191,7 +190,7 @@ public:
virtual void set_cc_flag_repair(uint32_t id, uint32_t repair) {}
virtual void set_cc_flag_tiles(uint32_t id, const std::vector<std::vector<uint8_t>> &tiles) {}
virtual void set_cc_flag_role(uint32_t id, uint8_t role, uint32_t economic_power) {}
virtual void set_cc_flag_budget(uint32_t id, const uint32_t blocks[256], uint32_t labour) {}
virtual void set_cc_flag_budget(uint32_t id, const uint32_t budget[NUM_ITEMS]) {}
virtual void set_cc_flag_active(uint32_t id, bool active) {}
virtual uint32_t get_num_cc_flags() const { return 0; }

View File

@ -29,7 +29,7 @@
set(cc_sources
cc_command_handler_build.cpp
cc_command_handler_building_settings.cpp
cc_command_handler_buy_blocks.cpp
cc_command_handler_buy_items.cpp
cc_command_handler_buy_land.cpp
cc_command_handler_create_account.cpp
cc_command_handler_game_update.cpp
@ -44,7 +44,7 @@ set(cc_sources
set(cc_headers
cc_command_handler_build.h
cc_command_handler_building_settings.h
cc_command_handler_buy_blocks.h
cc_command_handler_buy_items.h
cc_command_handler_buy_land.h
cc_command_handler_create_account.h
cc_command_handler_game_update.h

View File

@ -34,7 +34,7 @@
#include "memwipe.h"
#include "cc_command_handler_build.h"
#include "cc_command_handler_building_settings.h"
#include "cc_command_handler_buy_blocks.h"
#include "cc_command_handler_buy_items.h"
#include "cc_command_handler_buy_land.h"
#include "cc_command_handler_create_account.h"
#include "cc_command_handler_game_update.h"
@ -51,6 +51,12 @@
using namespace cryptonote;
static const char *block_names[] = {
"<empty>",
"stone",
"wood",
};
namespace cc
{
@ -69,18 +75,38 @@ const char *get_role_name(uint8_t role)
}
}
bool get_build_settings_requirements(uint8_t role, uint32_t economic_power, std::vector<std::pair<uint8_t, uint32_t>> &blocks, uint32_t &labour)
const char *get_item_name(uint32_t idx)
{
blocks.clear();
labour = 0;
if (idx >= ITEM_FIRST_BLOCK && idx <= ITEM_LAST_BLOCK)
return block_names[idx] ? block_names[idx] : "<invalid block>";
if (idx == ITEM_LABOUR)
return "labour";
MERROR("No item name for index " << idx);
return "<invalid item>";
}
uint64_t get_last_resort_price(uint32_t idx)
{
#warning placeholders
if (idx >= ITEM_FIRST_BLOCK && idx <= ITEM_LAST_BLOCK && block_names[idx])
return 100;
if (idx == ITEM_LABOUR)
return 100;
return 0;
}
bool get_build_settings_requirements(uint8_t role, uint32_t economic_power, std::vector<std::pair<uint32_t, uint32_t>> &budget)
{
budget.clear();
switch (role)
{
case ROLE_EMPTY:
return true;
#warning TODO: placeholder
case ROLE_AGRICULTURAL:
blocks.push_back(std::make_pair(1, 20));
blocks.push_back(std::make_pair(2, 120));
budget.push_back(std::make_pair(1, 20));
budget.push_back(std::make_pair(2, 120));
budget.push_back(std::make_pair(ITEM_LABOUR, 80));
return true;
#warning TODO
default:
@ -396,7 +422,7 @@ static cc_command_handler &get_cc_command(const cryptonote::cc_command_t &cmd)
{
cc_command_handler &operator()(const cryptonote::cc_command_build_t &cmd) const { return cc_command_handler_build::instance; }
cc_command_handler &operator()(const cryptonote::cc_command_building_settings_t &cmd) const { return cc_command_handler_building_settings::instance; }
cc_command_handler &operator()(const cryptonote::cc_command_buy_blocks_t &cmd) const { return cc_command_handler_buy_blocks::instance; }
cc_command_handler &operator()(const cryptonote::cc_command_buy_items_t &cmd) const { return cc_command_handler_buy_items::instance; }
cc_command_handler &operator()(const cryptonote::cc_command_buy_land_t &cmd) const { return cc_command_handler_buy_land::instance; }
cc_command_handler &operator()(const cryptonote::cc_command_create_account_t &cmd) const { return cc_command_handler_create_account::instance; }
cc_command_handler &operator()(const cryptonote::cc_command_game_update_t &cmd) const { return cc_command_handler_game_update::instance; }

View File

@ -41,7 +41,9 @@ namespace cc
{
const char *get_role_name(uint8_t role);
bool get_build_settings_requirements(uint8_t role, uint32_t economic_power, std::vector<std::pair<uint8_t, uint32_t>> &blocks, uint32_t &labour);
const char *get_item_name(uint32_t idx);
uint64_t get_last_resort_price(uint32_t idx);
bool get_build_settings_requirements(uint8_t role, uint32_t economic_power, std::vector<std::pair<uint32_t, uint32_t>> &budget);
bool get_flag(const cryptonote::BlockchainDB &db, uint32_t x, uint32_t y, uint32_t &id);
bool has_flag(const cryptonote::BlockchainDB &db, uint32_t x, uint32_t y);
bool get_new_flag_cost(uint32_t ex0, uint32_t ey0, uint32_t ex1, uint32_t ey1, uint64_t &cost);

View File

@ -119,7 +119,7 @@ bool cc_command_handler_build::check(const cryptonote::BlockchainDB &db, const c
return false;
}
uint32_t blocks_needed[256] = {0};
uint32_t items_needed[NUM_ITEMS] = {0};
uint64_t cost = 0;
unsigned int idx = 0;
for (uint32_t y = ay0; y <= ay1; ++y)
@ -139,7 +139,7 @@ bool cc_command_handler_build::check(const cryptonote::BlockchainDB &db, const c
if (decoded[idx])
{
cost += get_build_cost_for_height(build_height);
++blocks_needed[decoded[idx]];
++items_needed[decoded[idx]];
}
++idx;
}
@ -152,11 +152,11 @@ bool cc_command_handler_build::check(const cryptonote::BlockchainDB &db, const c
}
// check block balances
for (int i = 0; i < 256; ++i)
for (int i = 0; i < NUM_ITEMS; ++i)
{
if (blocks_needed[i] == 0)
if (items_needed[i] == 0)
continue;
CHECK_AND_ASSERT_MES(blocks_needed[i] <= fd.block_budget[i], false, "Not enough blocks of type " << i << " in budget");
CHECK_AND_ASSERT_MES(items_needed[i] <= fd.budget[i], false, "Not enough items of type " << i << " in budget");
}
return true;
@ -200,7 +200,7 @@ bool cc_command_handler_build::execute(cryptonote::BlockchainDB &db, const crypt
const uint32_t ay1 = ay0 + build.hm1;
const uint32_t flag_width = fd.x1 - fd.x0 + 1;
uint32_t blocks_needed[256] = {0};
uint32_t items_needed[NUM_ITEMS] = {0};
unsigned int idx = 0;
for (uint32_t y = ay0; y <= ay1; ++y)
{
@ -222,7 +222,7 @@ bool cc_command_handler_build::execute(cryptonote::BlockchainDB &db, const crypt
while (tiles[tile_idx].size() < build_height)
tiles[tile_idx].push_back(0);
tiles[tile_idx].push_back(decoded[idx]);
++blocks_needed[decoded[idx]];
++items_needed[decoded[idx]];
}
++idx;
}
@ -231,14 +231,14 @@ bool cc_command_handler_build::execute(cryptonote::BlockchainDB &db, const crypt
try { db.set_cc_flag_tiles(build.flag, tiles); }
catch (const std::exception &e) { MERROR("Failed to set flag tiles"); return false; }
for (int i = 0; i < 256; ++i)
for (int i = 0; i < NUM_ITEMS; ++i)
{
if (blocks_needed[i] == 0)
if (items_needed[i] == 0)
continue;
CHECK_AND_ASSERT_MES(blocks_needed[i] <= fd.block_budget[i], false, "Not enough blocks of type " << i << " in budget");
fd.block_budget[i] -= blocks_needed[i];
CHECK_AND_ASSERT_MES(items_needed[i] <= fd.budget[i], false, "Not enough items of type " << i << " in budget");
fd.budget[i] -= items_needed[i];
}
db.set_cc_flag_budget(build.flag, fd.block_budget, fd.labour_budget);
db.set_cc_flag_budget(build.flag, fd.budget);
return true;
}
@ -272,7 +272,7 @@ bool cc_command_handler_build::revert(cryptonote::BlockchainDB &db, const crypto
const uint32_t ay1 = ay0 + build.hm1;
const uint32_t flag_width = fd.x1 - fd.x0 + 1;
uint32_t blocks_needed[256] = {0};
uint32_t items_needed[NUM_ITEMS] = {0};
unsigned int idx = 0;
for (uint32_t y = ay0; y <= ay1; ++y)
{
@ -304,7 +304,7 @@ bool cc_command_handler_build::revert(cryptonote::BlockchainDB &db, const crypto
tiles[tile_idx].pop_back();
while (!tiles[tile_idx].empty() && tiles[tile_idx].back() == 0)
tiles[tile_idx].pop_back();
++blocks_needed[decoded[idx]];
++items_needed[decoded[idx]];
}
++idx;
}
@ -323,14 +323,14 @@ bool cc_command_handler_build::revert(cryptonote::BlockchainDB &db, const crypto
CHECK_AND_ASSERT_MES(balance <= std::numeric_limits<uint64_t>::max() - build.cost, false, "Account balance would overflow");
db.set_cc_account_balance(build.cc_account, balance + build.cost);
for (int i = 0; i < 256; ++i)
for (int i = 0; i < NUM_ITEMS; ++i)
{
if (blocks_needed[i] == 0)
if (items_needed[i] == 0)
continue;
CHECK_AND_ASSERT_MES(blocks_needed[i] <= std::numeric_limits<uint32_t>::max() - fd.block_budget[i], false, "Block budget would overflow");
fd.block_budget[i] += blocks_needed[i];
CHECK_AND_ASSERT_MES(items_needed[i] <= std::numeric_limits<uint32_t>::max() - fd.budget[i], false, "Item budget would overflow");
fd.budget[i] += items_needed[i];
}
db.set_cc_flag_budget(build.cc_account, fd.block_budget, fd.labour_budget);
db.set_cc_flag_budget(build.flag, fd.budget);
return true;
}

View File

@ -95,22 +95,17 @@ bool cc_command_handler_building_settings::check(const cryptonote::BlockchainDB
}
}
std::vector<std::pair<uint8_t, uint32_t>> block_budget;
uint32_t labour_budget;
CHECK_AND_ASSERT_MES(cc::get_build_settings_requirements(building_settings.role, building_settings.economic_power, block_budget, labour_budget),
std::vector<std::pair<uint32_t, uint32_t>> budget;
CHECK_AND_ASSERT_MES(cc::get_build_settings_requirements(building_settings.role, building_settings.economic_power, budget),
false, "Failed to get building settings requirements");
uint32_t block_balances[256];
CHECK_AND_ASSERT_MES(db.get_cc_account_block_balances(building_settings.cc_account, block_balances), false, "Failed to get block balances");
for (const auto &e: block_budget)
uint32_t item_balances[NUM_ITEMS];
CHECK_AND_ASSERT_MES(db.get_cc_account_item_balances(building_settings.cc_account, item_balances), false, "Failed to get item balances");
for (const auto &e: budget)
{
CHECK_AND_ASSERT_MES(block_balances[e.first] >= e.second, false, "Not enough blocks of type " << (unsigned)e.first);
CHECK_AND_ASSERT_MES(fd.block_budget[e.first] <= std::numeric_limits<uint32_t>::max() - e.second, false, "Block budget overflow");
CHECK_AND_ASSERT_MES(item_balances[e.first] >= e.second, false, "Not enough items of type " << (unsigned)e.first);
CHECK_AND_ASSERT_MES(fd.budget[e.first] <= std::numeric_limits<uint32_t>::max() - e.second, false, "Budget overflow");
}
uint32_t labour_balance;
CHECK_AND_ASSERT_MES(db.get_cc_account_labour_balance(building_settings.cc_account, labour_balance), false, "Failed to get labour balances");
CHECK_AND_ASSERT_MES(labour_balance >= labour_budget, false, "Not enough labour balance");
CHECK_AND_ASSERT_MES(fd.labour_budget <= std::numeric_limits<uint32_t>::max() - labour_budget, false, "Labour budget overflow");
return true;
}
@ -118,65 +113,52 @@ bool cc_command_handler_building_settings::check(const cryptonote::BlockchainDB
bool cc_command_handler_building_settings::execute(cryptonote::BlockchainDB &db, const cryptonote::cc_command_t &cmd) const
{
const cryptonote::cc_command_building_settings_t &building_settings = boost::get<cryptonote::cc_command_building_settings_t>(cmd);
std::vector<std::pair<uint8_t, uint32_t>> block_budget;
uint32_t labour_budget;
std::vector<std::pair<uint32_t, uint32_t>> budget;
cryptonote::cc_flag_data_t fd;
CHECK_AND_ASSERT_MES(cc::get_build_settings_requirements(building_settings.role, building_settings.economic_power, block_budget, labour_budget),
CHECK_AND_ASSERT_MES(cc::get_build_settings_requirements(building_settings.role, building_settings.economic_power, budget),
false, "Failed to get building settings requirements");
CHECK_AND_ASSERT_MES(db.get_cc_flag_data(building_settings.flag, fd, NULL), false, "Failed to get flag data");
uint32_t block_balances[256];
uint32_t labour_balance;
CHECK_AND_ASSERT_MES(db.get_cc_account_block_balances(building_settings.cc_account, block_balances), false, "Failed to get block balances");
CHECK_AND_ASSERT_MES(db.get_cc_account_labour_balance(building_settings.cc_account, labour_balance), false, "Failed to get labour balance");
uint32_t item_balances[NUM_ITEMS];
CHECK_AND_ASSERT_MES(db.get_cc_account_item_balances(building_settings.cc_account, item_balances), false, "Failed to get item balances");
for (const auto &e: block_budget)
for (const auto &e: budget)
{
CHECK_AND_ASSERT_MES(block_balances[e.first] >= e.second, false, "Not enough blocks of type " << (unsigned)e.first);
block_balances[e.first] -= e.second;
fd.block_budget[e.first] += e.second;
CHECK_AND_ASSERT_MES(item_balances[e.first] >= e.second, false, "Not enough items of type " << (unsigned)e.first);
item_balances[e.first] -= e.second;
fd.budget[e.first] += e.second;
}
CHECK_AND_ASSERT_MES(labour_balance >= labour_budget, false, "Not enough labour balance");
labour_balance -= labour_budget;
fd.labour_budget += labour_budget;
db.set_cc_account_block_balances(building_settings.cc_account, block_balances);
db.set_cc_account_labour_balance(building_settings.cc_account, labour_balance);
db.set_cc_account_item_balances(building_settings.cc_account, item_balances);
db.set_cc_flag_role(building_settings.flag, building_settings.role, building_settings.economic_power);
db.set_cc_flag_budget(building_settings.flag, fd.block_budget, fd.labour_budget);
db.set_cc_flag_budget(building_settings.flag, fd.budget);
return true;
}
bool cc_command_handler_building_settings::revert(cryptonote::BlockchainDB &db, const cryptonote::cc_command_t &cmd) const
{
const cryptonote::cc_command_building_settings_t &building_settings = boost::get<cryptonote::cc_command_building_settings_t>(cmd);
std::vector<std::pair<uint8_t, uint32_t>> block_budget;
uint32_t labour_budget;
std::vector<std::pair<uint32_t, uint32_t>> budget;
cryptonote::cc_flag_data_t fd;
CHECK_AND_ASSERT_MES(cc::get_build_settings_requirements(building_settings.role, building_settings.economic_power, block_budget, labour_budget),
CHECK_AND_ASSERT_MES(cc::get_build_settings_requirements(building_settings.role, building_settings.economic_power, budget),
false, "Failed to get building settings requirements");
CHECK_AND_ASSERT_MES(db.get_cc_flag_data(building_settings.flag, fd, NULL), false, "Failed to get flag data");
uint32_t block_balances[256];
uint32_t labour_balance;
CHECK_AND_ASSERT_MES(db.get_cc_account_block_balances(building_settings.cc_account, block_balances), false, "Failed to get block balances");
CHECK_AND_ASSERT_MES(db.get_cc_account_labour_balance(building_settings.cc_account, labour_balance), false, "Failed to get labour balance");
uint32_t item_balances[NUM_ITEMS];
CHECK_AND_ASSERT_MES(db.get_cc_account_item_balances(building_settings.cc_account, item_balances), false, "Failed to get block balances");
for (const auto &e: block_budget)
for (const auto &e: budget)
{
block_balances[e.first] += e.second;
fd.block_budget[e.first] -= e.second;
item_balances[e.first] += e.second;
fd.budget[e.first] -= e.second;
}
labour_balance += labour_budget;
fd.labour_budget -= labour_budget;
db.set_cc_account_block_balances(building_settings.cc_account, block_balances);
db.set_cc_account_labour_balance(building_settings.cc_account, labour_balance);
db.set_cc_account_item_balances(building_settings.cc_account, item_balances);
db.set_cc_flag_role(building_settings.flag, ROLE_EMPTY, 0);
db.set_cc_flag_budget(building_settings.flag, fd.block_budget, fd.labour_budget);
db.set_cc_flag_budget(building_settings.flag, fd.budget);
return true;
}

View File

@ -28,29 +28,29 @@
#include "blockchain_db/blockchain_db.h"
#include "cc.h"
#include "cc_command_handler_buy_blocks.h"
#include "cc_command_handler_buy_items.h"
namespace cc
{
cc_command_handler_buy_blocks cc_command_handler_buy_blocks::instance;
cc_command_handler_buy_items cc_command_handler_buy_items::instance;
void cc_command_handler_buy_blocks::get_in_out(const cryptonote::cc_command_t &cmd, uint64_t &cc_in, uint64_t &cc_out) const
void cc_command_handler_buy_items::get_in_out(const cryptonote::cc_command_t &cmd, uint64_t &cc_in, uint64_t &cc_out) const
{
cc_in = 0;
cc_out = 0;
}
uint64_t cc_command_handler_buy_blocks::get_cost(const cryptonote::cc_command_t &cmd) const
uint64_t cc_command_handler_buy_items::get_cost(const cryptonote::cc_command_t &cmd) const
{
const cryptonote::cc_command_buy_blocks_t &buy_blocks = boost::get<cryptonote::cc_command_buy_blocks_t>(cmd);
const cryptonote::cc_command_buy_items_t &buy_items = boost::get<cryptonote::cc_command_buy_items_t>(cmd);
uint64_t cost = 0;
for (const auto &e: buy_blocks.entries)
for (const auto &e: buy_items.entries)
{
uint64_t entry_cost = last_resort_block_cost[e.type] * e.amount;
uint64_t entry_cost = cc::get_last_resort_price(e.type) * e.amount;
if (entry_cost > std::numeric_limits<uint64_t>::max() - cost)
{
MERROR("buy_blocks command cost overflow");
MERROR("buy_items command cost overflow");
return std::numeric_limits<uint64_t>::max();
}
cost += entry_cost;
@ -58,58 +58,57 @@ uint64_t cc_command_handler_buy_blocks::get_cost(const cryptonote::cc_command_t
return cost;
}
bool cc_command_handler_buy_blocks::check(const cryptonote::BlockchainDB &db, const cryptonote::cc_command_t &cmd) const
bool cc_command_handler_buy_items::check(const cryptonote::BlockchainDB &db, const cryptonote::cc_command_t &cmd) const
{
const cryptonote::cc_command_buy_blocks_t &buy_blocks = boost::get<cryptonote::cc_command_buy_blocks_t>(cmd);
for (const auto &e: buy_blocks.entries)
const cryptonote::cc_command_buy_items_t &buy_items = boost::get<cryptonote::cc_command_buy_items_t>(cmd);
for (const auto &e: buy_items.entries)
{
CHECK_AND_ASSERT_MES(e.type != 0, false, "Buy order for block type 0");
CHECK_AND_ASSERT_MES(e.amount > 0, false, "Buy order for 0 blocks");
CHECK_AND_ASSERT_MES(last_resort_block_cost[e.type] > 0, false, "Trying to buy unallocated block type " + std::to_string(e.type));
CHECK_AND_ASSERT_MES(e.type != 0 && e.type < NUM_ITEMS, false, "Buy order for invalid item type");
CHECK_AND_ASSERT_MES(e.amount > 0, false, "Buy order for 0 items");
CHECK_AND_ASSERT_MES(get_last_resort_price(e.type) > 0, false, "Trying to buy item " + std::to_string(e.type) + " which has no seller of last resort");
}
bool present[256] = {false};
for (const auto &e: buy_blocks.entries)
bool present[NUM_ITEMS] = {false};
for (const auto &e: buy_items.entries)
{
CHECK_AND_ASSERT_MES(!present[e.type], false, "Buy order for the same block more than once");
CHECK_AND_ASSERT_MES(e.type >= 0 && e.type < NUM_ITEMS, false, "Item type out of range");
CHECK_AND_ASSERT_MES(!present[e.type], false, "Buy order for the same item more than once");
present[e.type] = true;
}
crypto::public_key public_key;
uint64_t balance;
uint32_t block_balances[256];
uint32_t labour_balance;
uint32_t item_balances[NUM_ITEMS];
std::vector<uint32_t> flags;
CHECK_AND_ASSERT_MES(db.get_cc_account_data(buy_blocks.cc_account, public_key, balance, block_balances, labour_balance, flags), false, "Failed to get account data");
for (const auto &e: buy_blocks.entries)
CHECK_AND_ASSERT_MES(db.get_cc_account_data(buy_items.cc_account, public_key, balance, item_balances, flags), false, "Failed to get account data");
for (const auto &e: buy_items.entries)
{
CHECK_AND_ASSERT_MES(block_balances[e.type] <= std::numeric_limits<uint32_t>::max() - e.amount, false, "Balance would overflow");
CHECK_AND_ASSERT_MES(item_balances[e.type] <= std::numeric_limits<uint32_t>::max() - e.amount, false, "Balance would overflow");
}
return true;
}
bool cc_command_handler_buy_blocks::execute(cryptonote::BlockchainDB &db, const cryptonote::cc_command_t &cmd) const
bool cc_command_handler_buy_items::execute(cryptonote::BlockchainDB &db, const cryptonote::cc_command_t &cmd) const
{
const cryptonote::cc_command_buy_blocks_t &buy_blocks = boost::get<cryptonote::cc_command_buy_blocks_t>(cmd);
const cryptonote::cc_command_buy_items_t &buy_items = boost::get<cryptonote::cc_command_buy_items_t>(cmd);
crypto::public_key public_key;
uint64_t balance;
uint32_t block_balances[256];
uint32_t labour_balance;
uint32_t item_balances[NUM_ITEMS];
std::vector<uint32_t> flags;
uint32_t treasury;
uint64_t cost;
cost = 0;
for (const auto &e: buy_blocks.entries)
cost += last_resort_block_cost[e.type] * e.amount;
for (const auto &e: buy_items.entries)
cost += cc::get_last_resort_price(e.type) * e.amount;
CHECK_AND_ASSERT_MES(db.get_cc_account_data(buy_blocks.cc_account, public_key, balance, block_balances, labour_balance, flags), false, "Failed to get account data");
for (const auto &e: buy_blocks.entries)
CHECK_AND_ASSERT_MES(db.get_cc_account_data(buy_items.cc_account, public_key, balance, item_balances, flags), false, "Failed to get account data");
for (const auto &e: buy_items.entries)
{
CHECK_AND_ASSERT_MES(block_balances[e.type] <= std::numeric_limits<uint32_t>::max() - e.amount, false, "Balance would overflow");
block_balances[e.type] += e.amount;
CHECK_AND_ASSERT_MES(item_balances[e.type] <= std::numeric_limits<uint32_t>::max() - e.amount, false, "Balance would overflow");
item_balances[e.type] += e.amount;
}
db.set_cc_account_block_balances(buy_blocks.cc_account, block_balances);
db.set_cc_account_item_balances(buy_items.cc_account, item_balances);
balance -= cost;
db.set_cc_account_balance(buy_blocks.cc_account, balance);
db.set_cc_account_balance(buy_items.cc_account, balance);
CHECK_AND_ASSERT_MES(db.get_cc_city_treasury(0, treasury), false, "City treasury not found");
CHECK_AND_ASSERT_MES(db.get_cc_account_balance(treasury, balance), false, "Treasury account balance not found");
@ -119,32 +118,31 @@ bool cc_command_handler_buy_blocks::execute(cryptonote::BlockchainDB &db, const
return true;
}
bool cc_command_handler_buy_blocks::revert(cryptonote::BlockchainDB &db, const cryptonote::cc_command_t &cmd) const
bool cc_command_handler_buy_items::revert(cryptonote::BlockchainDB &db, const cryptonote::cc_command_t &cmd) const
{
const cryptonote::cc_command_buy_blocks_t &buy_blocks = boost::get<cryptonote::cc_command_buy_blocks_t>(cmd);
const cryptonote::cc_command_buy_items_t &buy_items = boost::get<cryptonote::cc_command_buy_items_t>(cmd);
crypto::public_key public_key;
uint64_t balance;
uint32_t block_balances[256];
uint32_t labour_balance;
uint32_t item_balances[NUM_ITEMS];
std::vector<uint32_t> flags;
uint32_t treasury;
uint64_t cost;
cost = 0;
for (const auto &e: buy_blocks.entries)
cost += last_resort_block_cost[e.type] * e.amount;
for (const auto &e: buy_items.entries)
cost += cc::get_last_resort_price(e.type) * e.amount;
CHECK_AND_ASSERT_MES(db.get_cc_account_data(buy_blocks.cc_account, public_key, balance, block_balances, labour_balance, flags), false, "Failed to get account data");
for (const auto &e: buy_blocks.entries)
CHECK_AND_ASSERT_MES(db.get_cc_account_data(buy_items.cc_account, public_key, balance, item_balances, flags), false, "Failed to get account data");
for (const auto &e: buy_items.entries)
{
CHECK_AND_ASSERT_MES(block_balances[e.type] >= e.amount, false, "Balance would underflow");
block_balances[e.type] -= e.amount;
CHECK_AND_ASSERT_MES(item_balances[e.type] >= e.amount, false, "Balance would underflow");
item_balances[e.type] -= e.amount;
}
db.set_cc_account_block_balances(buy_blocks.cc_account, block_balances);
db.set_cc_account_item_balances(buy_items.cc_account, item_balances);
CHECK_AND_ASSERT_MES(cost <= std::numeric_limits<uint64_t>::max() - balance, false, "Balance would overflow");
balance += cost;
db.set_cc_account_balance(buy_blocks.cc_account, balance);
db.set_cc_account_balance(buy_items.cc_account, balance);
CHECK_AND_ASSERT_MES(db.get_cc_city_treasury(0, treasury), false, "City treasury not found");
CHECK_AND_ASSERT_MES(db.get_cc_account_balance(treasury, balance), false, "Treasury account balance not found");

View File

@ -33,7 +33,7 @@
namespace cc
{
class cc_command_handler_buy_blocks: public cc_command_handler
class cc_command_handler_buy_items: public cc_command_handler
{
public:
virtual void get_in_out(const cryptonote::cc_command_t &cmd, uint64_t &cc_in, uint64_t &cc_out) const;
@ -42,7 +42,7 @@ public:
virtual bool execute(cryptonote::BlockchainDB &db, const cryptonote::cc_command_t &cmd) const;
virtual bool revert(cryptonote::BlockchainDB &db, const cryptonote::cc_command_t &cmd) const;
static cc_command_handler_buy_blocks instance;
static cc_command_handler_buy_items instance;
};
}

View File

@ -134,12 +134,11 @@ bool cc_command_handler_buy_land::revert(cryptonote::BlockchainDB &db, const cry
// find the right flag, it should be the last one from that account
crypto::public_key public_key;
uint64_t balance;
uint32_t block_balances[256];
uint32_t labour_balance;
uint32_t item_balances[NUM_ITEMS];
std::vector<uint32_t> flags;
uint32_t treasury;
if (!db.get_cc_account_data(buy_land.cc_account, public_key, balance, block_balances, labour_balance, flags))
if (!db.get_cc_account_data(buy_land.cc_account, public_key, balance, item_balances, flags))
{
MERROR("Failed to find last flag for account " << buy_land.cc_account);
return false;

View File

@ -30,6 +30,7 @@
#include "cryptonote_basic/cryptonote_format_utils.h"
#include "blockchain_db/blockchain_db.h"
#include "cc/cc_config.h"
#include "cc/cc.h"
#include "cc_command_handler_trade.h"
namespace cc
@ -95,14 +96,15 @@ bool cc_command_handler_trade::check(const cryptonote::BlockchainDB &db, const c
CHECK_AND_ASSERT_MES(db.does_cc_flag_exist(trade.id, owner), false, "Trade refers to unknown flag " << trade.id);
CHECK_AND_ASSERT_MES(trade.bid || owner == trade.cc_account, false, "Offer to sell flag " << trade.id << " which is not from the flag owner");
break;
case cryptonote::cc_command_trade_t::type_blocks:
CHECK_AND_ASSERT_MES(trade.id > 0 && trade.id < 256 && last_resort_block_cost[trade.id] != 0, false, "Trade for invalid block type " << trade.id);
case cryptonote::cc_command_trade_t::type_item:
CHECK_AND_ASSERT_MES(trade.id > 0 && trade.id < NUM_ITEMS, false, "Trade for invalid item type");
CHECK_AND_ASSERT_MES(trade.id > ITEM_LAST_BLOCK || cc::get_item_name(trade.id), false, "Trade for invalid block type " << trade.id);
if (!trade.bid)
{
uint32_t block_balances[256];
CHECK_AND_ASSERT_MES(db.get_cc_account_block_balances(trade.cc_account, block_balances), false, "Failed to get seller's block balances");
CHECK_AND_ASSERT_MES(block_balances[trade.id] >= trade.amount, false,
"Account " << trade.cc_account << " does not have that many blocks to sell: wanted " << trade.amount << ", has " << block_balances[trade.id]);
uint32_t item_balances[NUM_ITEMS];
CHECK_AND_ASSERT_MES(db.get_cc_account_item_balances(trade.cc_account, item_balances), false, "Failed to get seller's item balances");
CHECK_AND_ASSERT_MES(item_balances[trade.id] >= trade.amount, false,
"Account " << trade.cc_account << " does not have that many items to sell: wanted " << trade.amount << ", has " << item_balances[trade.id]);
}
break;
default:
@ -115,7 +117,7 @@ bool cc_command_handler_trade::check(const cryptonote::BlockchainDB &db, const c
CHECK_AND_ASSERT_MES(txes.size() == trade.matches.size(), false, "Database returned unexpected number of transactions");
std::map<uint32_t, uint64_t> account_balances;
std::map<uint32_t, std::vector<uint32_t>> account_block_balances;
std::map<uint32_t, std::vector<uint32_t>> account_item_balances;
// gets data from blockchain, but caches changes
auto get_account_balance = [&](const cryptonote::BlockchainDB &db, uint32_t account, uint64_t &balance)->bool
@ -137,24 +139,24 @@ bool cc_command_handler_trade::check(const cryptonote::BlockchainDB &db, const c
{
account_balances[account] = balance;
};
auto get_account_block_balances = [&](const cryptonote::BlockchainDB &db, uint32_t account, std::vector<uint32_t> &block_balances)->bool
auto get_account_item_balances = [&](const cryptonote::BlockchainDB &db, uint32_t account, std::vector<uint32_t> &item_balances)->bool
{
auto i = account_block_balances.find(account);
if (i != account_block_balances.end())
auto i = account_item_balances.find(account);
if (i != account_item_balances.end())
{
block_balances = i->second;
item_balances = i->second;
return true;
}
uint32_t bal[256];
if (!db.get_cc_account_block_balances(account, bal))
uint32_t bal[NUM_ITEMS];
if (!db.get_cc_account_item_balances(account, bal))
return false;
i = account_block_balances.insert(std::make_pair(account, std::vector<uint32_t>(bal, bal+256))).first;
block_balances = i->second;
i = account_item_balances.insert(std::make_pair(account, std::vector<uint32_t>(bal, bal+NUM_ITEMS))).first;
item_balances = i->second;
return true;
};
auto set_account_block_balances = [&](uint32_t account, const std::vector<uint32_t> &balances)
auto set_account_item_balances = [&](uint32_t account, const std::vector<uint32_t> &balances)
{
account_block_balances[account] = balances;
account_item_balances[account] = balances;
};
uint32_t amount_needed = trade.amount;
@ -177,7 +179,7 @@ bool cc_command_handler_trade::check(const cryptonote::BlockchainDB &db, const c
CHECK_AND_ASSERT_MES(used < matched_trade.amount, false, "Matching to a trade that's been fully matched already");
// check balances, they might place a cap on the matchable amount
std::vector<uint32_t> block_balances;
std::vector<uint32_t> item_balances;
uint64_t cap;
uint32_t matched_amount = std::min(amount_needed, matched_trade.amount - used);
if (trade.bid)
@ -197,11 +199,11 @@ bool cc_command_handler_trade::check(const cryptonote::BlockchainDB &db, const c
CHECK_AND_ASSERT_MES(db.does_cc_flag_exist(matched_trade.id, owner), false, "Match refers to unknown flag");
CHECK_AND_ASSERT_MES(matched_trade.bid || owner == matched_trade.cc_account, false, "Offer to sell a flag is not from the flag owner");
break;
case cryptonote::cc_command_trade_t::type_blocks:
CHECK_AND_ASSERT_MES(get_account_block_balances(db, trade.cc_account, block_balances), false, "Failed to get block balances");
matched_amount = std::min(matched_amount, std::numeric_limits<uint32_t>::max() - block_balances[trade.id]);
CHECK_AND_ASSERT_MES(get_account_block_balances(db, matched_trade.cc_account, block_balances), false, "Failed to get block balances");
matched_amount = std::min(matched_amount, block_balances[trade.id]);
case cryptonote::cc_command_trade_t::type_item:
CHECK_AND_ASSERT_MES(get_account_item_balances(db, trade.cc_account, item_balances), false, "Failed to get item balances");
matched_amount = std::min(matched_amount, std::numeric_limits<uint32_t>::max() - item_balances[trade.id]);
CHECK_AND_ASSERT_MES(get_account_item_balances(db, matched_trade.cc_account, item_balances), false, "Failed to get item balances");
matched_amount = std::min(matched_amount, item_balances[trade.id]);
break;
default:
MERROR("Invalid trade type");
@ -216,14 +218,14 @@ bool cc_command_handler_trade::check(const cryptonote::BlockchainDB &db, const c
set_account_balance(trade.cc_account, balance - matched_trade.price * matched_amount);
CHECK_AND_ASSERT_MES(get_account_balance(db, matched_trade.cc_account, balance), false, "Failed to get balance");
set_account_balance(matched_trade.cc_account, balance + matched_trade.price * matched_amount);
if (trade.type == cryptonote::cc_command_trade_t::type_blocks)
if (trade.type == cryptonote::cc_command_trade_t::type_item)
{
CHECK_AND_ASSERT_MES(get_account_block_balances(db, trade.cc_account, block_balances), false, "Failed to get block balances");
block_balances[trade.id] += matched_amount;
set_account_block_balances(trade.cc_account, block_balances);
CHECK_AND_ASSERT_MES(get_account_block_balances(db, matched_trade.cc_account, block_balances), false, "Failed to get block balances");
block_balances[trade.id] -= matched_amount;
set_account_block_balances(matched_trade.cc_account, block_balances);
CHECK_AND_ASSERT_MES(get_account_item_balances(db, trade.cc_account, item_balances), false, "Failed to get item balances");
item_balances[trade.id] += matched_amount;
set_account_item_balances(trade.cc_account, item_balances);
CHECK_AND_ASSERT_MES(get_account_item_balances(db, matched_trade.cc_account, item_balances), false, "Failed to get item balances");
item_balances[trade.id] -= matched_amount;
set_account_item_balances(matched_trade.cc_account, item_balances);
}
}
else
@ -241,9 +243,9 @@ bool cc_command_handler_trade::check(const cryptonote::BlockchainDB &db, const c
{
case cryptonote::cc_command_trade_t::type_flag:
break;
case cryptonote::cc_command_trade_t::type_blocks:
CHECK_AND_ASSERT_MES(get_account_block_balances(db, matched_trade.cc_account, block_balances), false, "Failed to get block balances");
matched_amount = std::min(matched_amount, std::numeric_limits<uint32_t>::max() - block_balances[trade.id]);
case cryptonote::cc_command_trade_t::type_item:
CHECK_AND_ASSERT_MES(get_account_item_balances(db, matched_trade.cc_account, item_balances), false, "Failed to get item balances");
matched_amount = std::min(matched_amount, std::numeric_limits<uint32_t>::max() - item_balances[trade.id]);
break;
default:
MERROR("Unsupported type");
@ -255,14 +257,14 @@ bool cc_command_handler_trade::check(const cryptonote::BlockchainDB &db, const c
set_account_balance(trade.cc_account, balance + matched_trade.price * matched_amount);
CHECK_AND_ASSERT_MES(get_account_balance(db, matched_trade.cc_account, balance), false, "Failed to get balance");
set_account_balance(matched_trade.cc_account, balance - matched_trade.price * matched_amount);
if (trade.type == cryptonote::cc_command_trade_t::type_blocks)
if (trade.type == cryptonote::cc_command_trade_t::type_item)
{
CHECK_AND_ASSERT_MES(get_account_block_balances(db, trade.cc_account, block_balances), false, "Failed to get block balances");
block_balances[trade.id] -= matched_amount;
set_account_block_balances(trade.cc_account, block_balances);
CHECK_AND_ASSERT_MES(get_account_block_balances(db, matched_trade.cc_account, block_balances), false, "Failed to get block balances");
block_balances[trade.id] += matched_amount;
set_account_block_balances(matched_trade.cc_account, block_balances);
CHECK_AND_ASSERT_MES(get_account_item_balances(db, trade.cc_account, item_balances), false, "Failed to get item balances");
item_balances[trade.id] -= matched_amount;
set_account_item_balances(trade.cc_account, item_balances);
CHECK_AND_ASSERT_MES(get_account_item_balances(db, matched_trade.cc_account, item_balances), false, "Failed to get item balances");
item_balances[trade.id] += matched_amount;
set_account_item_balances(matched_trade.cc_account, item_balances);
}
}
@ -294,7 +296,7 @@ bool cc_command_handler_trade::execute(cryptonote::BlockchainDB &db, const crypt
const uint32_t seller_account = trade.bid ? matched_trade.cc_account : trade.cc_account;
const uint32_t buyer_account = trade.bid ? trade.cc_account : matched_trade.cc_account;
uint64_t balance;
uint32_t block_balances[256];
uint32_t item_balances[NUM_ITEMS];
const uint32_t matched_amount = trade.matches[i].amount;
aggregate_amount += matched_amount;
@ -317,26 +319,26 @@ bool cc_command_handler_trade::execute(cryptonote::BlockchainDB &db, const crypt
db.set_cc_account_balance(seller_account, balance);
break;
case cryptonote::cc_command_trade_t::type_blocks:
case cryptonote::cc_command_trade_t::type_item:
db.get_cc_account_balance(buyer_account, balance);
CHECK_AND_ASSERT_MES(balance >= price * matched_amount, false, "Balance underflow");
balance -= price * matched_amount;
db.set_cc_account_balance(buyer_account, balance);
db.get_cc_account_block_balances(buyer_account, block_balances);
CHECK_AND_ASSERT_MES(block_balances[trade.id] <= std::numeric_limits<uint32_t>::max() - matched_amount, false, "Block balance overflow");
block_balances[trade.id] += matched_amount;
db.set_cc_account_block_balances(buyer_account, block_balances);
db.get_cc_account_item_balances(buyer_account, item_balances);
CHECK_AND_ASSERT_MES(item_balances[trade.id] <= std::numeric_limits<uint32_t>::max() - matched_amount, false, "Item balance overflow");
item_balances[trade.id] += matched_amount;
db.set_cc_account_item_balances(buyer_account, item_balances);
db.get_cc_account_balance(seller_account, balance);
CHECK_AND_ASSERT_MES(balance <= std::numeric_limits<uint64_t>::max() - price * matched_amount, false, "Balance overflow");
balance += price * matched_amount;
db.set_cc_account_balance(seller_account, balance);
db.get_cc_account_block_balances(seller_account, block_balances);
CHECK_AND_ASSERT_MES(block_balances[trade.id] >= matched_amount, false, "Block balance underflow");
block_balances[trade.id] -= matched_amount;
db.set_cc_account_block_balances(seller_account, block_balances);
db.get_cc_account_item_balances(seller_account, item_balances);
CHECK_AND_ASSERT_MES(item_balances[trade.id] >= matched_amount, false, "Item balance underflow");
item_balances[trade.id] -= matched_amount;
db.set_cc_account_item_balances(seller_account, item_balances);
break;
}
@ -364,7 +366,7 @@ bool cc_command_handler_trade::revert(cryptonote::BlockchainDB &db, const crypto
const uint32_t seller_account = trade.bid ? matched_trade.cc_account : trade.cc_account;
const uint32_t buyer_account = trade.bid ? trade.cc_account : matched_trade.cc_account;
uint64_t balance;
uint32_t block_balances[256];
uint32_t item_balances[NUM_ITEMS];
const uint32_t matched_amount = trade.matches[i].amount;
const uint64_t price = matched_trade.price;
@ -384,26 +386,26 @@ bool cc_command_handler_trade::revert(cryptonote::BlockchainDB &db, const crypto
db.set_cc_account_balance(buyer_account, balance);
break;
case cryptonote::cc_command_trade_t::type_blocks:
case cryptonote::cc_command_trade_t::type_item:
db.get_cc_account_balance(seller_account, balance);
CHECK_AND_ASSERT_MES(balance >= price * matched_amount, false, "Balance underflow");
balance -= price * matched_amount;
db.set_cc_account_balance(seller_account, balance);
db.get_cc_account_block_balances(seller_account, block_balances);
CHECK_AND_ASSERT_MES(block_balances[trade.id] <= std::numeric_limits<uint32_t>::max() - matched_amount, false, "Block balance overflow");
block_balances[trade.id] += matched_amount;
db.set_cc_account_block_balances(seller_account, block_balances);
db.get_cc_account_item_balances(seller_account, item_balances);
CHECK_AND_ASSERT_MES(item_balances[trade.id] <= std::numeric_limits<uint32_t>::max() - matched_amount, false, "Item balance overflow");
item_balances[trade.id] += matched_amount;
db.set_cc_account_item_balances(seller_account, item_balances);
db.get_cc_account_balance(buyer_account, balance);
CHECK_AND_ASSERT_MES(balance <= std::numeric_limits<uint64_t>::max() - price * matched_amount, false, "Balance overflow");
balance += price * matched_amount;
db.set_cc_account_balance(buyer_account, balance);
db.get_cc_account_block_balances(buyer_account, block_balances);
CHECK_AND_ASSERT_MES(block_balances[trade.id] >= matched_amount, false, "Block balance underflow");
block_balances[trade.id] -= matched_amount;
db.set_cc_account_block_balances(buyer_account, block_balances);
db.get_cc_account_item_balances(buyer_account, item_balances);
CHECK_AND_ASSERT_MES(item_balances[trade.id] >= matched_amount, false, "Item balance underflow");
item_balances[trade.id] -= matched_amount;
db.set_cc_account_item_balances(buyer_account, item_balances);
break;
}

View File

@ -61,3 +61,12 @@ enum BuildingRole
ROLE_CULTURAL,
NUM_ROLES
};
enum Item
{
ITEM_NONE = 0,
ITEM_FIRST_BLOCK = 1,
ITEM_LAST_BLOCK = 255,
ITEM_LABOUR,
NUM_ITEMS
};

View File

@ -45,7 +45,7 @@ const cc_command_base_t *get_cc_command_base(const cc_command_t &cmd)
{
const cc_command_base_t *operator()(const cryptonote::cc_command_build_t &cmd) const { return &cmd; }
const cc_command_base_t *operator()(const cryptonote::cc_command_building_settings_t &cmd) const { return &cmd; }
const cc_command_base_t *operator()(const cryptonote::cc_command_buy_blocks_t &cmd) const { return &cmd; }
const cc_command_base_t *operator()(const cryptonote::cc_command_buy_items_t &cmd) const { return &cmd; }
const cc_command_base_t *operator()(const cryptonote::cc_command_buy_land_t &cmd) const { return &cmd; }
const cc_command_base_t *operator()(const cryptonote::cc_command_create_account_t &cmd) const { return NULL; }
const cc_command_base_t *operator()(const cryptonote::cc_command_game_update_t &cmd) const { return NULL; }
@ -62,7 +62,7 @@ cc_command_base_t *get_cc_command_base(cc_command_t &cmd)
{
cc_command_base_t *operator()(cryptonote::cc_command_build_t &cmd) const { return &cmd; }
cc_command_base_t *operator()(cryptonote::cc_command_building_settings_t &cmd) const { return &cmd; }
cc_command_base_t *operator()(cryptonote::cc_command_buy_blocks_t &cmd) const { return &cmd; }
cc_command_base_t *operator()(cryptonote::cc_command_buy_items_t &cmd) const { return &cmd; }
cc_command_base_t *operator()(cryptonote::cc_command_buy_land_t &cmd) const { return &cmd; }
cc_command_base_t *operator()(cryptonote::cc_command_create_account_t &cmd) const { return NULL; }
cc_command_base_t *operator()(cryptonote::cc_command_game_update_t &cmd) const { return NULL; }

View File

@ -144,15 +144,15 @@ namespace cryptonote
END_SERIALIZE()
};
struct cc_command_buy_blocks_t: public cc_command_base_t
struct cc_command_buy_items_t: public cc_command_base_t
{
struct entry_t
{
uint8_t type;
uint32_t type;
uint32_t amount;
BEGIN_SERIALIZE_OBJECT()
FIELD(type)
VARINT_FIELD(type)
VARINT_FIELD(amount);
END_SERIALIZE()
};
@ -167,7 +167,7 @@ namespace cryptonote
struct cc_command_trade_t: public cc_command_base_t
{
enum { type_flag = 0, type_blocks, num_types };
enum { type_flag = 0, type_item, num_types };
struct match_t
{
@ -289,7 +289,7 @@ namespace cryptonote
cc_command_buy_land_t,
cc_command_building_settings_t,
cc_command_build_t,
cc_command_buy_blocks_t,
cc_command_buy_items_t,
cc_command_game_update_t,
cc_command_trade_t
> cc_command_t;
@ -369,7 +369,7 @@ CC_VARIANT_TAG(cryptonote::cc_command_create_account_t, 0x01);
CC_VARIANT_TAG(cryptonote::cc_command_transfer_t, 0x02);
CC_VARIANT_TAG(cryptonote::cc_command_buy_land_t, 0x03);
CC_VARIANT_TAG(cryptonote::cc_command_build_t, 0x04);
CC_VARIANT_TAG(cryptonote::cc_command_buy_blocks_t, 0x05);
CC_VARIANT_TAG(cryptonote::cc_command_buy_items_t, 0x05);
CC_VARIANT_TAG(cryptonote::cc_command_game_update_t, 0x06);
CC_VARIANT_TAG(cryptonote::cc_command_trade_t, 0x07);
CC_VARIANT_TAG(cryptonote::cc_command_building_settings_t, 0x08);
@ -379,7 +379,7 @@ VARIANT_TAG(json_archive, cryptonote::cc_command_create_account_t, "create_accou
VARIANT_TAG(json_archive, cryptonote::cc_command_transfer_t, "transfer");
VARIANT_TAG(json_archive, cryptonote::cc_command_buy_land_t, "buy_land");
VARIANT_TAG(json_archive, cryptonote::cc_command_build_t, "build");
VARIANT_TAG(json_archive, cryptonote::cc_command_buy_blocks_t, "buy_blocks");
VARIANT_TAG(json_archive, cryptonote::cc_command_buy_items_t, "buy_items");
VARIANT_TAG(json_archive, cryptonote::cc_command_game_update_t, "game_update");
VARIANT_TAG(json_archive, cryptonote::cc_command_trade_t, "trade");
VARIANT_TAG(json_archive, cryptonote::cc_command_building_settings_t, "building_settings");
@ -389,7 +389,7 @@ VARIANT_TAG(debug_archive, cryptonote::cc_command_create_account_t, "create_acco
VARIANT_TAG(debug_archive, cryptonote::cc_command_transfer_t, "transfer");
VARIANT_TAG(debug_archive, cryptonote::cc_command_buy_land_t, "buy_land");
VARIANT_TAG(debug_archive, cryptonote::cc_command_build_t, "build");
VARIANT_TAG(debug_archive, cryptonote::cc_command_buy_blocks_t, "buy_blocks");
VARIANT_TAG(debug_archive, cryptonote::cc_command_buy_items_t, "buy_items");
VARIANT_TAG(debug_archive, cryptonote::cc_command_game_update_t, "game_update");
VARIANT_TAG(debug_archive, cryptonote::cc_command_trade_t, "trade");
VARIANT_TAG(debug_archive, cryptonote::cc_command_building_settings_t, "building_settings");

View File

@ -45,9 +45,9 @@ struct cc_snapshot
END_KV_SERIALIZE_MAP()
};
struct blocks_t
struct item_t
{
uint8_t type;
uint32_t type;
uint32_t amount;
BEGIN_KV_SERIALIZE_MAP()
@ -68,8 +68,7 @@ struct cc_snapshot
uint32_t y1;
uint32_t repair;
uint32_t economic_power;
std::vector<blocks_t> block_budget;
uint32_t labour_budget;
std::vector<item_t> budget;
bool active;
std::vector<flag_tile_data_t> tiles;
@ -85,8 +84,7 @@ struct cc_snapshot
KV_SERIALIZE(repair)
KV_SERIALIZE(economic_power)
KV_SERIALIZE(active)
KV_SERIALIZE(block_budget)
KV_SERIALIZE(labour_budget)
KV_SERIALIZE(budget)
KV_SERIALIZE(tiles)
END_KV_SERIALIZE_MAP()
};

View File

@ -931,11 +931,11 @@ bool t_command_parser_executor::cc_debug_set_account_balance(const std::vector<s
return m_executor.cc_debug_set_account_balance(id, balance);
}
bool t_command_parser_executor::cc_debug_set_account_block_balance(const std::vector<std::string>& args)
bool t_command_parser_executor::cc_debug_set_account_item_balance(const std::vector<std::string>& args)
{
if (args.size() != 3)
{
std::cout << "cc_debug_set_account_block_balance <account> <index> <balance>" << std::endl;
std::cout << "cc_debug_set_account_item_balance <account> <index> <balance>" << std::endl;
return true;
}
@ -947,20 +947,20 @@ bool t_command_parser_executor::cc_debug_set_account_block_balance(const std::ve
}
unsigned idx;
if (!epee::string_tools::get_xtype_from_string(idx, args[1]) || idx > 255)
if (!epee::string_tools::get_xtype_from_string(idx, args[1]) || idx == 0 || idx >= NUM_ITEMS)
{
std::cout << "Invalid block index (0-255)" << std::endl;
std::cout << "Invalid block index" << std::endl;
return true;
}
uint64_t block_balance;
if (!epee::string_tools::get_xtype_from_string(block_balance, args[2]))
uint64_t item_balance;
if (!epee::string_tools::get_xtype_from_string(item_balance, args[2]))
{
std::cout << "Invalid balance" << std::endl;
return true;
}
return m_executor.cc_debug_set_account_block_balance(id, idx, block_balance);
return m_executor.cc_debug_set_account_item_balance(id, idx, item_balance);
}
bool t_command_parser_executor::cc_debug_allocate_new_city(const std::vector<std::string>& args)

View File

@ -162,7 +162,7 @@ public:
bool cc_debug_delete_account(const std::vector<std::string>& args);
bool cc_get_account(const std::vector<std::string>& args);
bool cc_debug_set_account_balance(const std::vector<std::string>& args);
bool cc_debug_set_account_block_balance(const std::vector<std::string>& args);
bool cc_debug_set_account_item_balance(const std::vector<std::string>& args);
bool cc_debug_allocate_new_city(const std::vector<std::string>& args);
bool cc_debug_delete_city(const std::vector<std::string>& args);
bool cc_get_city(const std::vector<std::string>& args);

View File

@ -344,9 +344,9 @@ t_command_server::t_command_server(
, "Set a Crypto City account's balance."
);
m_command_lookup.set_handler(
"cc_debug_set_account_block_balance"
, std::bind(&t_command_parser_executor::cc_debug_set_account_block_balance, &m_parser, p::_1)
, "Set a Crypto City account's block balance."
"cc_debug_set_account_item_balance"
, std::bind(&t_command_parser_executor::cc_debug_set_account_item_balance, &m_parser, p::_1)
, "Set a Crypto City account's item balance."
);
m_command_lookup.set_handler(
"cc_debug_allocate_new_city"

View File

@ -2468,11 +2468,10 @@ bool t_rpc_command_executor::cc_get_account(uint32_t id)
tools::success_msg_writer() << "Public key: " << res.public_key;
tools::success_msg_writer() << "Balance: " << cryptonote::print_money(res.balance);
std::stringstream ss;
for (int i = 0; i < 256; ++i)
if (res.block_balances[i])
ss << (ss.str().empty() ? "" : ", ") << i << ": " << res.block_balances[i];
tools::success_msg_writer() << "Block balances: " << ss.str();
tools::success_msg_writer() << "Labour balances: " << res.labour_balance;
for (int i = 0; i < NUM_ITEMS; ++i)
if (res.item_balances[i])
ss << (ss.str().empty() ? "" : ", ") << i << ": " << res.item_balances[i];
tools::success_msg_writer() << "Item balances: " << ss.str();
tools::success_msg_writer() << "Flags: " << boost::join(res.flags | boost::adaptors::transformed([](uint32_t id){return std::to_string(id);}), " ");
return true;
}
@ -2506,7 +2505,7 @@ bool t_rpc_command_executor::cc_debug_set_account_balance(uint32_t id, uint64_t
req_set.id = id;
req_set.balance = balance;
req_set.block_balances = res_get.block_balances;
req_set.item_balances = res_get.item_balances;
if (m_is_rpc)
{
@ -2527,7 +2526,7 @@ bool t_rpc_command_executor::cc_debug_set_account_balance(uint32_t id, uint64_t
return true;
}
bool t_rpc_command_executor::cc_debug_set_account_block_balance(uint32_t id, uint8_t idx, uint32_t block_balance)
bool t_rpc_command_executor::cc_debug_set_account_item_balance(uint32_t id, uint32_t idx, uint32_t item_balance)
{
cryptonote::COMMAND_RPC_CC_GET_ACCOUNT::request req_get;
cryptonote::COMMAND_RPC_CC_GET_ACCOUNT::response res_get;
@ -2556,8 +2555,8 @@ bool t_rpc_command_executor::cc_debug_set_account_block_balance(uint32_t id, uin
req_set.id = id;
req_set.balance = res_get.balance;
req_set.block_balances = res_get.block_balances;
req_set.block_balances[idx] = block_balance;
req_set.item_balances = res_get.item_balances;
req_set.item_balances[idx] = item_balance;
if (m_is_rpc)
{
@ -2765,11 +2764,10 @@ bool t_rpc_command_executor::cc_get_flag(uint32_t id, bool get_tiles)
tools::success_msg_writer() << "Role: " << (unsigned)res.role << " (" << cc::get_role_name(res.role) << ")";
tools::success_msg_writer() << "Economic power: " << res.economic_power << "%";
std::stringstream ss;
for (const auto &e: res.block_budget)
for (const auto &e: res.budget)
if (e.type > 0)
ss << std::to_string((unsigned)e.type) << ": " << std::to_string(e.amount) << ", ";
tools::success_msg_writer() << "Block budget: " << ss.str();
tools::success_msg_writer() << "Labour budget: " << res.labour_budget;
ss << cc::get_item_name(e.type) << ": " << std::to_string(e.amount) << ", ";
tools::success_msg_writer() << "Budget: " << ss.str();
tools::success_msg_writer() << "Extents: " << res.x0 << " " << res.y0 << " to " << res.x1 << " " << res.y1
<< " (" << (res.x1-res.x0+1) << " x " << (res.y1-res.y0+1) << ")";
if (get_tiles)

View File

@ -179,7 +179,7 @@ public:
bool cc_debug_delete_account(uint32_t id);
bool cc_get_account(uint32_t id);
bool cc_debug_set_account_balance(uint32_t id, uint64_t balance);
bool cc_debug_set_account_block_balance(uint32_t id, uint8_t idx, uint32_t balance);
bool cc_debug_set_account_item_balance(uint32_t id, uint32_t idx, uint32_t balance);
bool cc_debug_allocate_new_city(uint32_t ox, uint32_t oy, uint32_t mayor);
bool cc_debug_delete_city(uint32_t id);
bool cc_get_city(uint32_t id);

View File

@ -25,7 +25,7 @@ void PlayerState::update(const std::shared_ptr<tools::wallet2> &w)
id = w->get_cc_account();
if (id)
{
w->get_cc_account_data(id, balance, block_balances, flags);
w->get_cc_account_data(id, balance, item_balances, flags);
}
else
{
@ -86,12 +86,12 @@ bool GameState::process_build(const cryptonote::cc_command_build_t &cmd, Map &ma
{
if (decoded_types[i])
{
if (flag->block_budget[decoded_types[i]] < 1)
if (flag->budget[decoded_types[i]] < 1)
{
printf("Invalid block budget\n");
return false;
}
flag->block_budget[decoded_types[i]]--;
flag->budget[decoded_types[i]]--;
}
}
@ -107,15 +107,14 @@ bool GameState::process_building_settings(const cryptonote::cc_command_building_
return false;
}
std::vector<std::pair<uint8_t, uint32_t>> blocks;
uint32_t labour_cost;
cc::get_build_settings_requirements(cmd.role, cmd.economic_power, blocks, labour_cost);
std::vector<std::pair<uint32_t, uint32_t>> budget;
cc::get_build_settings_requirements(cmd.role, cmd.economic_power, budget);
flag->set_role(cmd.role, cmd.economic_power);
flag->set_budget(blocks, labour_cost);
flag->set_budget(budget);
return true;
}
bool GameState::process_buy_blocks(const cryptonote::cc_command_buy_blocks_t &cmd, Map &map)
bool GameState::process_buy_items(const cryptonote::cc_command_buy_items_t &cmd, Map &map)
{
return true;
}
@ -171,7 +170,7 @@ bool GameState::process_command(const cryptonote::cc_command_t &cmd, Map &map)
visitor(GameState &self, Map &map): self(self), map(map) {}
bool operator()(const cryptonote::cc_command_build_t &cmd) const { return self.process_build(cmd, map); }
bool operator()(const cryptonote::cc_command_building_settings_t &cmd) const { return self.process_building_settings(cmd, map); }
bool operator()(const cryptonote::cc_command_buy_blocks_t &cmd) const { return self.process_buy_blocks(cmd, map); }
bool operator()(const cryptonote::cc_command_buy_items_t &cmd) const { return self.process_buy_items(cmd, map); }
bool operator()(const cryptonote::cc_command_buy_land_t &cmd) const { return self.process_buy_land(cmd, map); }
bool operator()(const cryptonote::cc_command_create_account_t &cmd) const { return self.process_create_account(cmd, map); }
bool operator()(const cryptonote::cc_command_game_update_t &cmd) const { return self.process_game_update(cmd, map); }
@ -226,10 +225,10 @@ bool GameState::reset(Map &map, const cryptonote::cc_snapshot *snapshot)
tiles[i] = fs.tiles[i].data;
flag->set_tiles(tiles);
std::vector<std::pair<uint8_t, uint32_t>> block_budget;
for (const auto &e: fs.block_budget)
block_budget.push_back(std::make_pair(e.type, e.amount));
flag->set_budget(block_budget, fs.labour_budget);
std::vector<std::pair<uint32_t, uint32_t>> budget;
for (const auto &e: fs.budget)
budget.push_back(std::make_pair(e.type, e.amount));
flag->set_budget(budget);
}
}
return true;

View File

@ -33,7 +33,7 @@ struct PlayerState
uint64_t balance;
uint64_t wallet_balance;
const char *name;
std::vector<uint32_t> block_balances;
std::vector<uint32_t> item_balances;
std::vector<uint32_t> flags;
bool has_wallet;
@ -57,7 +57,7 @@ public:
private:
bool process_build(const cryptonote::cc_command_build_t &cmd, Map &map);
bool process_building_settings(const cryptonote::cc_command_building_settings_t &cmd, Map &map);
bool process_buy_blocks(const cryptonote::cc_command_buy_blocks_t &cmd, Map &map);
bool process_buy_items(const cryptonote::cc_command_buy_items_t &cmd, Map &map);
bool process_buy_land(const cryptonote::cc_command_buy_land_t &cmd, Map &map);
bool process_create_account(const cryptonote::cc_command_create_account_t &cmd, Map &map);
bool process_none(const cryptonote::cc_command_none_t &cmd, Map &map);

View File

@ -1011,12 +1011,12 @@ void CryptoCityUrho3D::HandleBuyBlocks(StringHash eventType, VariantMap& eventDa
new MessageBox(context_, "No wallet loaded - load a wallet to be able to buy blocks");
return;
}
cryptonote::cc_command_buy_blocks_t cmd;
cryptonote::cc_command_buy_items_t cmd;
cmd.cc_account = wallet->get_cc_account();
const std::vector<std::pair<uint8_t, uint32_t>> *v = (const std::vector<std::pair<uint8_t, uint32_t>>*)eventData[BuyBlocks::P_QUANTITIES].GetVoidPtr();
for (const auto &q: *v)
{
cryptonote::cc_command_buy_blocks_t::entry_t e;
cryptonote::cc_command_buy_items_t::entry_t e;
e.type = q.first;
e.amount = q.second;
cmd.entries.push_back(e);
@ -1071,13 +1071,13 @@ void CryptoCityUrho3D::HandleAddBlock(StringHash eventType, VariantMap& eventDat
raw_types[idx] = 0;
if (selection.is_selected(x, y))
{
if (flag->block_budget[currentMaterial] == 0)
if (flag->budget[currentMaterial] == 0)
{
new MessageBox(context_, String("Not enough ") + materials[currentMaterial].name + " blocks left in flag budget");
new MessageBox(context_, String("Not enough ") + cc::get_item_name(currentMaterial) + " blocks left in flag budget");
return;
}
raw_types[idx] = currentMaterial;
flag->block_budget[currentMaterial]--;
flag->budget[currentMaterial]--;
}
++idx;
}
@ -1184,7 +1184,7 @@ void CryptoCityUrho3D::HandleRemoveBlock(StringHash eventType, VariantMap& event
for (size_t i = 0; i < 256; ++i)
{
flag->block_budget[i] += blocks_recovered[i];
flag->budget[i] += blocks_recovered[i];
}
if (!flagUnderConstruction)

View File

@ -14,8 +14,7 @@
BlockMaterial materials[256] =
{
{
0,
"",
// empty
0, 0, 0, 0,
0,
0,
@ -24,8 +23,7 @@ BlockMaterial materials[256] =
0,
},
{
1,
"stone",
// stone
128, 128, 128, 1,
1,
1,
@ -34,8 +32,7 @@ BlockMaterial materials[256] =
4,
},
{
2,
"wood",
// wood
60, 40, 10, 1,
1,
1,
@ -43,9 +40,9 @@ BlockMaterial materials[256] =
1,
4,
},
#if 0
{
3,
"water",
// water
64, 64, 192, 1,
0,
1,
@ -53,6 +50,7 @@ BlockMaterial materials[256] =
4,
1,
},
#endif
};
bool encode_single_type(uint8_t src_type, uint16_t n_src_types, uint8_t *encoded_types, uint16_t *encoded_types_len)
@ -124,8 +122,7 @@ Flag::Flag(uint32_t id, uint32_t owner, uint8_t role, uint32_t x0, uint32_t y0,
const size_t h = y1 - y0 + 1;
const size_t ntiles = w * h;
tiles = new Tile[ntiles];
memset(block_budget, 0, sizeof(block_budget));
labour_budget = 0;
memset(budget, 0, sizeof(budget));
}
Flag::~Flag()
@ -203,12 +200,11 @@ void Flag::set_tiles(const std::vector<std::vector<uint8_t>> &new_tiles)
}
}
void Flag::set_budget(const std::vector<std::pair<uint8_t, uint32_t>> &block_budget, uint32_t labour_budget)
void Flag::set_budget(const std::vector<std::pair<uint32_t, uint32_t>> &budget)
{
memset(this->block_budget, 0, sizeof(this->block_budget));
for (const auto &e: block_budget)
this->block_budget[e.first] = e.second;
this->labour_budget = labour_budget;
memset(this->budget, 0, sizeof(this->budget));
for (const auto &e: budget)
this->budget[e.first] = e.second;
}
void Flag::get_min_max_neighbour_height(uint32_t x, uint32_t y, uint16_t &min_height, uint16_t &max_height) const
@ -374,9 +370,9 @@ bool Flag::push_tiles(PlayerState *player, uint32_t px0, uint32_t py0, uint32_t
}
for (uint32_t idx = 1; idx < 256; ++idx)
{
if (blocks_needed[idx] > player->block_balances[idx])
if (blocks_needed[idx] > player->item_balances[idx])
{
printf("Not enough blocks of type %u (%u, needs %u)\n", idx, player->block_balances[idx], blocks_needed[idx]);
printf("Not enough blocks of type %u (%u, needs %u)\n", idx, player->item_balances[idx], blocks_needed[idx]);
goto undo;
}
}
@ -397,7 +393,7 @@ bool Flag::push_tiles(PlayerState *player, uint32_t px0, uint32_t py0, uint32_t
{
player->balance -= cost;
for (uint32_t idx = 1; idx < 256; ++idx)
player->block_balances[idx] -= blocks_needed[idx];
player->item_balances[idx] -= blocks_needed[idx];
}
return true;

View File

@ -6,13 +6,12 @@
#include <deque>
#include <set>
#include "cc/quadtree.h"
#include "cc/cc.h"
class PlayerState;
struct BlockMaterial
{
uint8_t type;
const char *name;
uint8_t base_red;
uint8_t base_green;
uint8_t base_blue;
@ -71,8 +70,7 @@ public:
uint32_t y1;
uint32_t repair;
uint32_t economic_power;
uint32_t block_budget[256];
uint32_t labour_budget;
uint32_t budget[NUM_ITEMS];
Flag(uint32_t id, uint32_t owner, uint8_t role, uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1, uint32_t repair, uint32_t economic_power);
~Flag();
@ -91,7 +89,7 @@ public:
uint8_t get_role() const { return role; }
uint32_t get_economic_power() const { return economic_power; }
void set_role(uint8_t r, uint32_t ep) { role = r; economic_power = ep; }
void set_budget(const std::vector<std::pair<uint8_t, uint32_t>> &block_budget, uint32_t labour_budget);
void set_budget(const std::vector<std::pair<uint32_t, uint32_t>> &budget);
bool push_tiles(PlayerState *player, uint32_t px0, uint32_t py0, uint32_t px1, uint32_t py1, uint16_t min_height, const uint8_t *type_ptr, uint16_t type_len);
bool pop_tiles(PlayerState *player, uint32_t px0, uint32_t py0, uint32_t px1, uint32_t py1, const uint8_t *type_ptr, uint16_t type_len);

View File

@ -277,17 +277,16 @@ void UIBuildingSettingsDialog::HandleCancel(StringHash eventType, VariantMap& ev
ReleaseRef();
}
void UIBuildingSettingsDialog::SetBudget(uint32_t blocks[256], uint32_t labour)
void UIBuildingSettingsDialog::SetBudget(uint32_t budget[NUM_ITEMS])
{
auto* cache = context_->GetSubsystem<ResourceCache>();
auto* style = cache->GetResource<XMLFile>("UI/DefaultStyle.xml");
for (size_t i = 0; i < 256 + 1; ++i)
for (size_t i = 0; i < NUM_ITEMS; ++i)
{
const uint32_t value = i < 256 ? blocks[i] : labour;
if (value == 0)
if (budget[i] == 0)
continue;
const String name = i < 256 ? materials[i].name : "Labour";
const String name = cc::get_item_name(i);
UIElement *row = new UIElement(context_);
row->SetStyleAuto(style);
@ -302,7 +301,7 @@ void UIBuildingSettingsDialog::SetBudget(uint32_t blocks[256], uint32_t labour)
labelWidget->SetColor(Color(.5f, .5f, .5f));
auto *valueWidget = new Text(context_);
valueWidget->SetText(String(value));
valueWidget->SetText(String(budget[i]));
row->AddChild(valueWidget);
valueWidget->SetStyleAuto(style);
valueWidget->SetColor(Color(.5f, .5f, .5f));
@ -313,9 +312,8 @@ void UIBuildingSettingsDialog::HandleSettingsChanged(StringHash eventType, Varia
{
uint8_t role;
uint32_t economic_power;
std::vector<std::pair<uint8_t, uint32_t>> blocks;
uint32_t blocks256[256];
uint32_t labour;
std::vector<std::pair<uint32_t, uint32_t>> budget;
uint32_t budget_array[NUM_ITEMS];
while (rightLayout->GetNumChildren() > 1)
rightLayout->RemoveChildAtIndex(rightLayout->GetNumChildren() - 1);
@ -324,13 +322,13 @@ void UIBuildingSettingsDialog::HandleSettingsChanged(StringHash eventType, Varia
if (!s.Empty())
return;
if (!cc::get_build_settings_requirements(role, economic_power, blocks, labour))
if (!cc::get_build_settings_requirements(role, economic_power, budget))
return;
memset(blocks256, 0, sizeof(blocks256));
for (const auto &e: blocks)
memset(budget_array, 0, sizeof(budget_array));
for (const auto &e: budget)
if (e.first > 0)
blocks256[e.first] = e.second;
budget_array[e.first] = e.second;
SetBudget(blocks256, labour);
SetBudget(budget_array);
}

View File

@ -5,6 +5,7 @@
#include <Urho3D/Container/Str.h>
#include <Urho3D/Container/Ptr.h>
#include <Urho3D/Math/StringHash.h>
#include "cc/cc_config.h"
namespace Urho3D
{
@ -33,7 +34,7 @@ private:
void HandleSettingsChanged(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
Urho3D::String GetSettings(uint8_t &role, uint32_t &economic_power) const;
void SetBudget(uint32_t blocks[256], uint32_t labour);
void SetBudget(uint32_t budget[NUM_ITEMS]);
private:
Urho3D::SharedPtr<Urho3D::Window> window;

View File

@ -155,11 +155,12 @@ void UIBuyBlocksDialog::AddRow()
for (int i = 1; i < 256; ++i)
{
const BlockMaterial &m = materials[i];
if (!m.name)
const char *name = cc::get_item_name(i);
if (!name)
continue;
types[idx++] = i;
Text *t = new Text(context_);
t->SetText(m.name);
t->SetText(name);
t->SetStyleAuto(style);
typeWidget->AddItem(t);
}
@ -199,7 +200,7 @@ void UIBuyBlocksDialog::HandleOK(StringHash eventType, VariantMap& eventData)
return;
}
const uint8_t sel8 = types[sel];
if (sel8 == 0 || !materials[sel8].name)
if (sel8 == 0 || !cc::get_item_name(sel8))
{
new MessageBox(context_, "Internal error: bad item");
return;

View File

@ -166,26 +166,25 @@ void UIUrho3D::CreateFlagWindow()
AddText(w0, "Land tax");
flagLandTaxText = AddText(w1, "");
flagMaterialList = flagContents->CreateChild<ListView>();
flagMaterialList->SetStyleAuto();
indexToMaterialFlag[0] = 0;
flagItemTypeList = flagContents->CreateChild<ListView>();
flagItemTypeList->SetStyleAuto();
indexToItemTypeFlag[0] = 0;
auto list = flagMaterialList;
auto list = flagItemTypeList;
list->SetSelectOnClickEnd(true);
list->SetHighlightMode(HM_ALWAYS);
list->SetMinHeight(100);
for (int i = 1; i < 256; ++i)
for (int i = 1; i < NUM_ITEMS; ++i)
{
const BlockMaterial &m = materials[i];
flagMaterialItem[i] = new UIElement(context_);
flagMaterialItem[i]->SetLayout(LM_HORIZONTAL, 0, IntRect(0, 0, 0, 0));
flagMaterialItem[i]->SetStyleAuto();
flagMaterialItem[i]->SetName(ToString("%u", i));
AddText(flagMaterialItem[i], m.name);
flagMaterialText[i] = AddText(flagMaterialItem[i], "0");
flagMaterialList->AddItem(flagMaterialItem[i]);
indexToMaterialFlag[i] = i;
flagItemTypeItem[i] = new UIElement(context_);
flagItemTypeItem[i]->SetLayout(LM_HORIZONTAL, 0, IntRect(0, 0, 0, 0));
flagItemTypeItem[i]->SetStyleAuto();
flagItemTypeItem[i]->SetName(ToString("%u", i));
AddText(flagItemTypeItem[i], cc::get_item_name(i));
flagItemTypeText[i] = AddText(flagItemTypeItem[i], "0");
flagItemTypeList->AddItem(flagItemTypeItem[i]);
indexToItemTypeFlag[i] = i;
}
flagWindow->SetPosition(0, 0);
@ -240,24 +239,23 @@ void UIUrho3D::CreatePlayerWindow()
playerMaterialList = playerContents->CreateChild<ListView>();
playerMaterialList->SetStyleAuto();
indexToMaterialPlayer[0] = 0;
indexToItemTypePlayer[0] = 0;
auto list = playerMaterialList;
list->SetSelectOnClickEnd(true);
list->SetHighlightMode(HM_ALWAYS);
list->SetMinHeight(100);
for (int i = 1; i < 256; ++i)
for (int i = 1; i < NUM_ITEMS; ++i)
{
const BlockMaterial &m = materials[i];
playerMaterialItem[i] = new UIElement(context_);
playerMaterialItem[i]->SetLayout(LM_HORIZONTAL, 0, IntRect(0, 0, 0, 0));
playerMaterialItem[i]->SetStyleAuto();
playerMaterialItem[i]->SetName(ToString("%u", i));
AddText(playerMaterialItem[i], m.name);
AddText(playerMaterialItem[i], cc::get_item_name(i));
playerMaterialText[i] = AddText(playerMaterialItem[i], "0");
playerMaterialList->AddItem(playerMaterialItem[i]);
indexToMaterialPlayer[i] = i;
indexToItemTypePlayer[i] = i;
}
SharedPtr<UIElement> depositWithdraw(new UIElement(context_));
@ -271,7 +269,7 @@ void UIUrho3D::CreatePlayerWindow()
loadWalletButton = AddButton(playerWindow, "Load wallet");
SubscribeToEvent(playerMaterialList, E_ITEMSELECTED, URHO3D_HANDLER(UIUrho3D, HandlePlayerMaterialSelected));
SubscribeToEvent(flagMaterialList, E_ITEMSELECTED, URHO3D_HANDLER(UIUrho3D, HandleFlagMaterialSelected));
SubscribeToEvent(flagItemTypeList, E_ITEMSELECTED, URHO3D_HANDLER(UIUrho3D, HandleFlagMaterialSelected));
SubscribeToEvent(depositButton, E_RELEASED, URHO3D_HANDLER(UIUrho3D, HandleDepositInfo));
SubscribeToEvent(withdrawButton, E_RELEASED, URHO3D_HANDLER(UIUrho3D, HandleWithdrawInfo));
SubscribeToEvent(loadWalletButton, E_RELEASED, URHO3D_HANDLER(UIUrho3D, HandleLoadWallet));
@ -492,7 +490,7 @@ void UIUrho3D::UpdateFlag(const Map *map, const CityState *city, uint32_t mouse_
flagStabilityText->SetText("-");
flagEconomicPowerText->SetText("-");
flagLandTaxText->SetText("-");
flagMaterialList->RemoveAllItems();
flagItemTypeList->RemoveAllItems();
return;
}
@ -518,18 +516,18 @@ void UIUrho3D::UpdateFlag(const Map *map, const CityState *city, uint32_t mouse_
snprintf(s, sizeof(s), "error");
flagLandTaxText->SetText(s);
flagMaterialList->RemoveAllItems();
flagItemTypeList->RemoveAllItems();
int idx = 0;
for (size_t i = 1; i < 256; ++i)
for (size_t i = 1; i < NUM_ITEMS; ++i)
{
flagMaterialText[i]->SetText(String(flag->block_budget[i]));
if (!flag->block_budget[i])
flagItemTypeText[i]->SetText(String(flag->budget[i]));
if (!flag->budget[i])
continue;
flagMaterialList->AddItem(flagMaterialItem[i]);
indexToMaterialFlag[idx++] = i;
flagItemTypeList->AddItem(flagItemTypeItem[i]);
indexToItemTypeFlag[idx++] = i;
}
while (idx < 256)
indexToMaterialFlag[idx++] = -1;
while (idx < NUM_ITEMS)
indexToItemTypeFlag[idx++] = -1;
}
void UIUrho3D::UpdatePlayer(const PlayerState *player)
@ -542,19 +540,19 @@ void UIUrho3D::UpdatePlayer(const PlayerState *player)
int idx = 0;
if (player->has_wallet)
{
for (size_t i = 1; i < 256; ++i)
for (size_t i = 1; i < NUM_ITEMS; ++i)
{
if (i >= player->block_balances.size())
if (i >= player->item_balances.size())
continue;
playerMaterialText[i]->SetText(String(player->block_balances[i]));
if (!player->block_balances[i])
playerMaterialText[i]->SetText(String(player->item_balances[i]));
if (!player->item_balances[i])
continue;
playerMaterialList->AddItem(playerMaterialItem[i]);
indexToMaterialPlayer[idx++] = i;
indexToItemTypePlayer[idx++] = i;
}
}
while (idx < 256)
indexToMaterialPlayer[idx++] = -1;
while (idx < NUM_ITEMS)
indexToItemTypePlayer[idx++] = -1;
}
void UIUrho3D::HandleLoadWallet(StringHash eventType, VariantMap& eventData)
@ -644,12 +642,14 @@ void UIUrho3D::HandleDisplayShowFlags(StringHash eventType, VariantMap& eventDat
void UIUrho3D::HandleMaterialSelected(StringHash eventType, VariantMap& eventData, bool player)
{
int idx = eventData[ItemSelected::P_SELECTION].GetInt();
if (idx < 0 || idx >= 256)
if (idx < 0 || idx >= NUM_ITEMS)
{
printf("Invalid list index: %d\n", idx);
return;
}
int material = player ? indexToMaterialPlayer[idx] : indexToMaterialFlag[idx];
if (idx < ITEM_FIRST_BLOCK || idx > ITEM_LAST_BLOCK)
return;
int material = player ? indexToItemTypePlayer[idx] : indexToItemTypeFlag[idx];
if (material < 0 || material >= 256)
{
printf("Invalid material at list index %d: %d\n", idx, material);

View File

@ -100,23 +100,23 @@ private:
Urho3D::SharedPtr<Urho3D::Text> flagStabilityText;
Urho3D::SharedPtr<Urho3D::Text> flagEconomicPowerText;
Urho3D::SharedPtr<Urho3D::Text> flagLandTaxText;
Urho3D::SharedPtr<Urho3D::ListView> flagMaterialList;
Urho3D::SharedPtr<Urho3D::UIElement> flagMaterialItem[256];
Urho3D::SharedPtr<Urho3D::Text> flagMaterialText[256];
Urho3D::SharedPtr<Urho3D::ListView> flagItemTypeList;
Urho3D::SharedPtr<Urho3D::UIElement> flagItemTypeItem[NUM_ITEMS];
Urho3D::SharedPtr<Urho3D::Text> flagItemTypeText[NUM_ITEMS];
Urho3D::SharedPtr<ShadableWindow> playerWindow;
Urho3D::SharedPtr<Urho3D::Text> playerNameText;
Urho3D::SharedPtr<Urho3D::Text> playerBalanceText;
Urho3D::SharedPtr<Urho3D::Text> playerWalletBalanceText;
Urho3D::SharedPtr<Urho3D::ListView> playerMaterialList;
Urho3D::SharedPtr<Urho3D::UIElement> playerMaterialItem[256];
Urho3D::SharedPtr<Urho3D::Text> playerMaterialText[256];
Urho3D::SharedPtr<Urho3D::UIElement> playerMaterialItem[NUM_ITEMS];
Urho3D::SharedPtr<Urho3D::Text> playerMaterialText[NUM_ITEMS];
Urho3D::SharedPtr<Urho3D::Button> loadWalletButton;
Urho3D::SharedPtr<Urho3D::Button> depositButton;
Urho3D::SharedPtr<Urho3D::Button> withdrawButton;
Urho3D::SharedPtr<Urho3D::Window> depositWithdrawDialog;
int indexToMaterialPlayer[256];
int indexToMaterialFlag[256];
int indexToItemTypePlayer[NUM_ITEMS];
int indexToItemTypeFlag[NUM_ITEMS];
Urho3D::SharedPtr<ShadableWindow> displayWindow;

View File

@ -3284,18 +3284,17 @@ namespace cryptonote
try
{
crypto::public_key public_key;
uint32_t block_balances[256];
uint32_t labour_balance;
if (!m_core.get_blockchain_storage().get_db().get_cc_account_data(req.id, public_key, res.balance, block_balances, labour_balance, res.flags))
uint32_t item_balances[NUM_ITEMS];
if (!m_core.get_blockchain_storage().get_db().get_cc_account_data(req.id, public_key, res.balance, item_balances, res.flags))
{
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
error_resp.message = "Account not found";
return false;
}
res.public_key = epee::string_tools::pod_to_hex(public_key);
res.block_balances.resize(256);
for (int i = 0; i < 256; ++i)
res.block_balances[i] = block_balances[i];
res.item_balances.resize(NUM_ITEMS);
for (int i = 0; i < NUM_ITEMS; ++i)
res.item_balances[i] = item_balances[i];
}
catch (const std::exception &e)
{
@ -3312,12 +3311,12 @@ namespace cryptonote
{
try
{
uint32_t block_balances[256];
for (int i = 0; i < 256; ++i)
block_balances[i] = req.block_balances[i];
uint32_t item_balances[NUM_ITEMS];
for (int i = 0; i < NUM_ITEMS; ++i)
item_balances[i] = req.item_balances[i];
LockedTXN lock(m_core.get_blockchain_storage().get_db());
m_core.get_blockchain_storage().get_db().set_cc_account_balance(req.id, req.balance);
m_core.get_blockchain_storage().get_db().set_cc_account_block_balances(req.id, block_balances);
m_core.get_blockchain_storage().get_db().set_cc_account_item_balances(req.id, item_balances);
lock.commit();
}
catch (const std::exception &e)
@ -3462,10 +3461,9 @@ namespace cryptonote
res.y1 = fd.y1;
res.repair = fd.repair;
res.economic_power = fd.economic_power;
for (size_t i = 0; i < 256; ++i)
if (fd.block_budget[i])
res.block_budget.push_back({(uint8_t)i, fd.block_budget[i]});
res.labour_budget = fd.labour_budget;
for (size_t i = 0; i < NUM_ITEMS; ++i)
if (fd.budget[i])
res.budget.push_back({(uint32_t)i, fd.budget[i]});
res.active = fd.active;
if (req.get_tiles)
{
@ -3562,10 +3560,9 @@ namespace cryptonote
flag_state.y1 = fd.y1;
flag_state.repair = fd.repair;
flag_state.economic_power = fd.economic_power;
for (size_t i = 0; i < 256; ++i)
if (fd.block_budget[i] > 0)
flag_state.block_budget.push_back({(uint8_t)i, fd.block_budget[i]});
flag_state.labour_budget = fd.labour_budget;
for (size_t i = 0; i < NUM_ITEMS; ++i)
if (fd.budget[i] > 0)
flag_state.budget.push_back({(uint32_t)i, fd.budget[i]});
flag_state.active = fd.active;
flag_state.tiles.resize(tiles.size());
for (size_t i = 0; i < tiles.size(); ++i)

View File

@ -2653,16 +2653,14 @@ namespace cryptonote
{
std::string public_key;
uint64_t balance;
std::vector<uint32_t> block_balances;
uint32_t labour_balance;
std::vector<uint32_t> item_balances;
std::vector<uint32_t> flags;
std::string status;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(public_key)
KV_SERIALIZE(balance)
KV_SERIALIZE(block_balances)
KV_SERIALIZE(labour_balance)
KV_SERIALIZE(item_balances)
KV_SERIALIZE(flags)
KV_SERIALIZE(status)
END_KV_SERIALIZE_MAP()
@ -2703,12 +2701,12 @@ namespace cryptonote
{
uint32_t id;
uint64_t balance;
std::vector<uint32_t> block_balances;
std::vector<uint32_t> item_balances;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(id)
KV_SERIALIZE(balance)
KV_SERIALIZE(block_balances)
KV_SERIALIZE(item_balances)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<request_t> request;
@ -2888,9 +2886,9 @@ namespace cryptonote
END_KV_SERIALIZE_MAP()
};
struct blocks_t
struct item_t
{
uint8_t type;
uint32_t type;
uint32_t amount;
BEGIN_KV_SERIALIZE_MAP()
@ -2910,8 +2908,7 @@ namespace cryptonote
uint32_t y1;
uint32_t repair;
uint32_t economic_power;
std::vector<blocks_t> block_budget;
uint32_t labour_budget;
std::vector<item_t> budget;
bool active;
std::vector<tile_data_t> tiles;
std::string status;
@ -2926,8 +2923,7 @@ namespace cryptonote
KV_SERIALIZE(x1)
KV_SERIALIZE(y1)
KV_SERIALIZE(repair)
KV_SERIALIZE(block_budget)
KV_SERIALIZE(labour_budget)
KV_SERIALIZE(budget)
KV_SERIALIZE(active)
KV_SERIALIZE(tiles)
END_KV_SERIALIZE_MAP()

View File

@ -2645,13 +2645,14 @@ bool simple_wallet::cc_buy_blocks(const std::vector<std::string> &args_)
return true;
}
uint64_t cost = last_resort_block_cost[type] * amount;
const uint64_t price = cc::get_last_resort_price(type);
const uint64_t cost = price * amount;
message_writer() << tr("Total price: ") << cryptonote::print_money(cost);
message_writer() << tr("Price per block: ") << cryptonote::print_money(last_resort_block_cost[type]);
message_writer() << tr("Price per block: ") << cryptonote::print_money(price);
cryptonote::cc_command_buy_blocks_t cmd;
cryptonote::cc_command_buy_items_t cmd;
cmd.cc_account = m_wallet->get_cc_account();
cryptonote::cc_command_buy_blocks_t::entry_t e;
cryptonote::cc_command_buy_items_t::entry_t e;
e.type = type;
e.amount = amount;
cmd.entries.push_back(e);
@ -2866,9 +2867,9 @@ bool simple_wallet::cc_status(const std::vector<std::string> &args_)
}
uint64_t balance;
std::vector<uint32_t> block_balances;
std::vector<uint32_t> item_balances;
std::vector<uint32_t> flags;
m_wallet->get_cc_account_data(id, balance, block_balances, flags);
m_wallet->get_cc_account_data(id, balance, item_balances, flags);
message_writer() << tr("Account number: ") << id << " (" << tr("address: ") << m_wallet->get_cc_pkey() << ")";
@ -2876,18 +2877,18 @@ bool simple_wallet::cc_status(const std::vector<std::string> &args_)
std::stringstream ss;
bool first = true;
for (size_t i = 0; i < block_balances.size(); ++i)
for (size_t i = 0; i < item_balances.size(); ++i)
{
if (block_balances[i] > 0)
if (item_balances[i] > 0)
{
if (!first)
ss << ", ";
ss << i << ": " << block_balances[i];
ss << i << ": " << item_balances[i];
first = false;
}
}
std::string s = ss.str();
message_writer() << tr("Blocks: ") << (s.empty() ? "<none>" : s);
message_writer() << tr("Items: ") << (s.empty() ? "<none>" : s);
message_writer() << tr("Flags: ") << (flags.empty() ? "<none>" : std::to_string(flags.size()));
return true;

View File

@ -900,7 +900,7 @@ private:
// CC
bool get_new_cc_flag_cost(uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1, uint64_t &cost);
bool get_cc_build_cost(uint32_t flag, uint32_t dx, uint32_t dy, uint32_t width, uint32_t height, uint16_t min_height, const std::vector<uint8_t> &tiles, bool encoded, uint64_t &cost);
bool get_cc_account_data(uint32_t id, uint64_t &balance, std::vector<uint32_t> &block_balances, std::vector<uint32_t> &flags);
bool get_cc_account_data(uint32_t id, uint64_t &balance, std::vector<uint32_t> &item_balances, std::vector<uint32_t> &flags);
bool get_cc_city_data(uint32_t id, uint32_t &ox, uint32_t &oy, uint32_t &treasury, uint32_t &mayor);
bool get_cc_state(cryptonote::cc_snapshot &snapshot, uint64_t &height, crypto::hash &top_hash, std::vector<cryptonote::cc_command_t> &top_commands);
bool get_cc_order_book(std::vector<cryptonote::order_t<std::string>> *bids, std::vector<cryptonote::order_t<std::string>> *offers, const std::vector<uint32_t> &type, const std::vector<uint32_t> &id);

View File

@ -101,7 +101,7 @@ bool wallet2::get_cc_build_cost(uint32_t flag, uint32_t dx, uint32_t dy, uint32_
return true;
}
bool wallet2::get_cc_account_data(uint32_t id, uint64_t &balance, std::vector<uint32_t> &block_balances, std::vector<uint32_t> &flags)
bool wallet2::get_cc_account_data(uint32_t id, uint64_t &balance, std::vector<uint32_t> &item_balances, std::vector<uint32_t> &flags)
{
cryptonote::COMMAND_RPC_CC_GET_ACCOUNT::request req = AUTO_VAL_INIT(req);
cryptonote::COMMAND_RPC_CC_GET_ACCOUNT::response res;
@ -114,7 +114,7 @@ bool wallet2::get_cc_account_data(uint32_t id, uint64_t &balance, std::vector<ui
if (!r || res.status != CORE_RPC_STATUS_OK)
return false;
balance = res.balance;
block_balances = res.block_balances;
item_balances = res.item_balances;
flags = res.flags;
return true;
}

View File

@ -4233,9 +4233,9 @@ namespace tools
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
bool wallet_rpc_server::on_cc_buy_blocks(const wallet_rpc::COMMAND_RPC_CC_BUY_BLOCKS::request& req, wallet_rpc::COMMAND_RPC_CC_BUY_BLOCKS::response& res, epee::json_rpc::error& er, const connection_context *ctx)
bool wallet_rpc_server::on_cc_buy_items(const wallet_rpc::COMMAND_RPC_CC_BUY_ITEMS::request& req, wallet_rpc::COMMAND_RPC_CC_BUY_ITEMS::response& res, epee::json_rpc::error& er, const connection_context *ctx)
{
LOG_PRINT_L3("on_cc_buy_blocks starts");
LOG_PRINT_L3("on_cc_buy_items starts");
if (!m_wallet) return not_open(er);
if (m_restricted)
{
@ -4252,7 +4252,7 @@ namespace tools
}
for (const auto &e: req.entries)
{
if (e.type == 0 || e.amount == 0 || last_resort_block_cost[e.type] == 0)
if (e.type == 0 || e.type >= NUM_ITEMS || e.amount == 0 || cc::get_last_resort_price(e.type) == 0)
{
er.code = WALLET_RPC_ERROR_CODE_WRONG_INDEX;
er.message = "Bad type or amount";
@ -4262,9 +4262,9 @@ namespace tools
try
{
cryptonote::cc_command_buy_blocks_t cmd;
cryptonote::cc_command_buy_items_t cmd;
cmd.cc_account = m_wallet->get_cc_account();
cryptonote::cc_command_buy_blocks_t::entry_t e;
cryptonote::cc_command_buy_items_t::entry_t e;
for (const auto &re: req.entries)
{
e.type = re.type;
@ -4384,9 +4384,9 @@ namespace tools
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
bool wallet_rpc_server::on_cc_trade_blocks(const wallet_rpc::COMMAND_RPC_CC_TRADE_BLOCKS::request& req, wallet_rpc::COMMAND_RPC_CC_TRADE_BLOCKS::response& res, epee::json_rpc::error& er, const connection_context *ctx)
bool wallet_rpc_server::on_cc_trade_item(const wallet_rpc::COMMAND_RPC_CC_TRADE_ITEM::request& req, wallet_rpc::COMMAND_RPC_CC_TRADE_ITEM::response& res, epee::json_rpc::error& er, const connection_context *ctx)
{
LOG_PRINT_L3("on_cc_trade_blocks starts");
LOG_PRINT_L3("on_cc_trade_item starts");
if (!m_wallet) return not_open(er);
const uint32_t cc_account = m_wallet->get_cc_account();
@ -4396,13 +4396,19 @@ namespace tools
er.message = "No game account found.";
return false;
}
if (req.id == 0 || req.id >= NUM_ITEMS)
{
er.code = WALLET_RPC_ERROR_CODE_WRONG_INDEX;
er.message = "Invalid item id";
return false;
}
try
{
cryptonote::cc_command_trade_t cmd;
cmd.cc_account = cc_account;
cmd.bid = req.bid;
cmd.type = cryptonote::cc_command_trade_t::type_blocks;
cmd.type = cryptonote::cc_command_trade_t::type_item;
cmd.id = req.id;
cmd.amount = req.amount;
cmd.price = req.price;

View File

@ -158,10 +158,10 @@ namespace tools
MAP_JON_RPC_WE("cc_transfer", on_cc_transfer, wallet_rpc::COMMAND_RPC_CC_TRANSFER)
MAP_JON_RPC_WE("cc_buy_land", on_cc_buy_land, wallet_rpc::COMMAND_RPC_CC_BUY_LAND)
MAP_JON_RPC_WE("cc_build", on_cc_build, wallet_rpc::COMMAND_RPC_CC_BUILD)
MAP_JON_RPC_WE("cc_buy_blocks", on_cc_buy_blocks, wallet_rpc::COMMAND_RPC_CC_BUY_BLOCKS)
MAP_JON_RPC_WE("cc_buy_items", on_cc_buy_items, wallet_rpc::COMMAND_RPC_CC_BUY_ITEMS)
MAP_JON_RPC_WE("cc_get_info", on_cc_get_info, wallet_rpc::COMMAND_RPC_CC_GET_INFO)
MAP_JON_RPC_WE("cc_trade_flag", on_cc_trade_flag, wallet_rpc::COMMAND_RPC_CC_TRADE_FLAG)
MAP_JON_RPC_WE("cc_trade_blocks", on_cc_trade_blocks, wallet_rpc::COMMAND_RPC_CC_TRADE_BLOCKS)
MAP_JON_RPC_WE("cc_trade_item", on_cc_trade_item, wallet_rpc::COMMAND_RPC_CC_TRADE_ITEM)
END_JSON_RPC_MAP()
END_URI_MAP2()
@ -250,10 +250,10 @@ namespace tools
bool on_cc_transfer(const wallet_rpc::COMMAND_RPC_CC_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_CC_TRANSFER::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_cc_buy_land(const wallet_rpc::COMMAND_RPC_CC_BUY_LAND::request& req, wallet_rpc::COMMAND_RPC_CC_BUY_LAND::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_cc_build(const wallet_rpc::COMMAND_RPC_CC_BUILD::request& req, wallet_rpc::COMMAND_RPC_CC_BUILD::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_cc_buy_blocks(const wallet_rpc::COMMAND_RPC_CC_BUY_BLOCKS::request& req, wallet_rpc::COMMAND_RPC_CC_BUY_BLOCKS::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_cc_buy_items(const wallet_rpc::COMMAND_RPC_CC_BUY_ITEMS::request& req, wallet_rpc::COMMAND_RPC_CC_BUY_ITEMS::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_cc_get_info(const wallet_rpc::COMMAND_RPC_CC_GET_INFO::request& req, wallet_rpc::COMMAND_RPC_CC_GET_INFO::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_cc_trade_flag(const wallet_rpc::COMMAND_RPC_CC_TRADE_FLAG::request& req, wallet_rpc::COMMAND_RPC_CC_TRADE_FLAG::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_cc_trade_blocks(const wallet_rpc::COMMAND_RPC_CC_TRADE_BLOCKS::request& req, wallet_rpc::COMMAND_RPC_CC_TRADE_BLOCKS::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_cc_trade_item(const wallet_rpc::COMMAND_RPC_CC_TRADE_ITEM::request& req, wallet_rpc::COMMAND_RPC_CC_TRADE_ITEM::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
//json rpc v2
bool on_query_key(const wallet_rpc::COMMAND_RPC_QUERY_KEY::request& req, wallet_rpc::COMMAND_RPC_QUERY_KEY::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);

View File

@ -2722,11 +2722,11 @@ namespace wallet_rpc
typedef epee::misc_utils::struct_init<response_t> response;
};
struct COMMAND_RPC_CC_BUY_BLOCKS
struct COMMAND_RPC_CC_BUY_ITEMS
{
struct entry_t
{
uint8_t type;
uint32_t type;
uint32_t amount;
BEGIN_KV_SERIALIZE_MAP()
@ -2853,7 +2853,7 @@ namespace wallet_rpc
typedef epee::misc_utils::struct_init<response_t> response;
};
struct COMMAND_RPC_CC_TRADE_BLOCKS
struct COMMAND_RPC_CC_TRADE_ITEM
{
struct match_t
{

View File

@ -42,6 +42,7 @@ using namespace cryptonote;
#define BARE_TX_FEE 30000000000
#define STARTING_BLOCK_1 25
#define STARTING_BLOCK_2 125
#define STARTING_LABOUR 200
static cryptonote::account_base cc_test_accounts[8];
static const uint64_t initial_funding[8] = {
@ -236,29 +237,28 @@ static bool expect_flag_tiles(cryptonote::core &c, uint32_t flag, const std::vec
return true;
}
static bool expect_block_balances(cryptonote::core &c, uint32_t account, const std::vector<std::pair<uint8_t, uint32_t>> &expected_block_balances)
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();
crypto::public_key public_key;
uint64_t balance;
uint32_t block_balances[256];
uint32_t labour_balance;
uint32_t item_balances[NUM_ITEMS];
std::vector<uint32_t> flags;
if (!db.get_cc_account_data(account, public_key, balance, block_balances, labour_balance, flags))
if (!db.get_cc_account_data(account, public_key, balance, item_balances, flags))
{
MERROR("Failed to get block balances for account " << account);
return false;
}
for (int i = 0; i < 256; ++i)
for (uint32_t i = 0; i < NUM_ITEMS; ++i)
{
uint32_t expected_balance = 0;
for (const auto &e: expected_block_balances)
for (const auto &e: expected_item_balances)
if (e.first == i)
expected_balance = e.second;
if (block_balances[i] != expected_balance)
if (item_balances[i] != expected_balance)
{
MERROR("Unexpected block balance: " << block_balances[i] << ", expected " << expected_balance);
MERROR("Unexpected block balance: " << item_balances[i] << ", expected " << expected_balance);
return false;
}
}
@ -456,18 +456,18 @@ bool gen_cc_tx_validation_base::generate_with(std::vector<test_event_entry>& eve
events.push_back(tx);
txs_hashes.push_back(get_transaction_hash(tx));
cryptonote::cc_command_buy_blocks_t buy_blocks;
cryptonote::cc_command_buy_items_t buy_blocks;
buy_blocks.cc_account = cc_account;
static const uint32_t buy_amounts[] = { STARTING_BLOCK_1, STARTING_BLOCK_2 };
for (size_t i = 1; i <= sizeof(buy_amounts) / sizeof(buy_amounts[0]); ++i)
static const uint32_t buy_amounts[] = { 1, STARTING_BLOCK_1, 2, 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_blocks_t::entry_t e;
e.type = i;
e.amount = buy_amounts[i-1];
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(last_resort_block_cost[e.type] * e.amount + fee <= expected_balance[cc_account - 4], false, "Underflow");
expected_balance[cc_account - 4] -= last_resort_block_cost[e.type] * e.amount;
expected_treasury_balance += last_resort_block_cost[e.type] * e.amount;
CHECK_AND_ASSERT_MES(cc::get_last_resort_price(e.type) * e.amount + fee <= expected_balance[cc_account - 4], false, "Underflow");
expected_balance[cc_account - 4] -= 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;
expected_balance[cc_account - 4] -= fee;
@ -1486,25 +1486,25 @@ bool gen_cc_tx_valid_cc_bare_buy_blocks::generate(std::vector<test_event_entry>&
blocks_cost = 0;
cryptonote::cc_command_buy_blocks_t cmd;
cryptonote::cc_command_buy_items_t cmd;
cmd.cc_account = 4;
cryptonote::cc_command_buy_blocks_t::entry_t e;
cryptonote::cc_command_buy_items_t::entry_t e;
e.type = 1;
e.amount = 80;
cmd.entries.push_back(e);
blocks_cost += last_resort_block_cost[e.type] * e.amount;
blocks_cost += cc::get_last_resort_price(e.type) * e.amount;
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
e.type = 2;
e.amount = 180;
cmd.entries[0] = e;
blocks_cost += last_resort_block_cost[e.type] * e.amount;
blocks_cost += cc::get_last_resort_price(e.type) * e.amount;
cmds.push_back(std::make_tuple("", cmd, BARE_TX_FEE));
e.type = 1;
e.amount = 40;
cmd.entries[0] = e;
blocks_cost += last_resort_block_cost[e.type] * e.amount;
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);
@ -1522,7 +1522,7 @@ bool gen_cc_tx_valid_cc_bare_buy_blocks::check_final_state(cryptonote::core &c,
&& expect_cc_account(c, 6, 10, initial_funding[6])
&& expect_cc_account(c, 7, 11, initial_funding[7])
&& expect_treasury_balance(c, expected_treasury_balance + blocks_cost)
&& expect_block_balances(c, 4, {std::make_pair(1, 120), std::make_pair(2, 180)});
&& expect_item_balances(c, 4, {std::make_pair(1, 120), std::make_pair(2, 180)});
}
bool gen_cc_tx_invalid_cc_bare_buy_blocks_type_0::generate(std::vector<test_event_entry>& events) const
@ -1532,9 +1532,9 @@ bool gen_cc_tx_invalid_cc_bare_buy_blocks_type_0::generate(std::vector<test_even
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_buy_blocks_t cmd;
cryptonote::cc_command_buy_items_t cmd;
cmd.cc_account = 4;
cryptonote::cc_command_buy_blocks_t::entry_t e;
cryptonote::cc_command_buy_items_t::entry_t e;
e.type = 0;
e.amount = 1;
cmd.entries.push_back(e);
@ -1550,9 +1550,9 @@ bool gen_cc_tx_invalid_cc_bare_buy_blocks_amount_0::generate(std::vector<test_ev
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_buy_blocks_t cmd;
cryptonote::cc_command_buy_items_t cmd;
cmd.cc_account = 4;
cryptonote::cc_command_buy_blocks_t::entry_t e;
cryptonote::cc_command_buy_items_t::entry_t e;
e.type = 1;
e.amount = 0;
cmd.entries.push_back(e);
@ -1568,9 +1568,9 @@ bool gen_cc_tx_invalid_cc_bare_buy_blocks_balance_overflow::generate(std::vector
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_buy_blocks_t cmd;
cryptonote::cc_command_buy_items_t cmd;
cmd.cc_account = 4;
cryptonote::cc_command_buy_blocks_t::entry_t e;
cryptonote::cc_command_buy_items_t::entry_t e;
e.type = 1;
e.amount = 0x1fffffff;
cmd.entries.push_back(e);
@ -1586,9 +1586,9 @@ bool gen_cc_tx_invalid_cc_bare_buy_blocks_balance_overflow_in_aggregate::generat
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_buy_blocks_t cmd;
cryptonote::cc_command_buy_items_t cmd;
cmd.cc_account = 4;
cryptonote::cc_command_buy_blocks_t::entry_t e;
cryptonote::cc_command_buy_items_t::entry_t e;
e.type = 1;
e.amount = 30000000;
cmd.entries.push_back(e);
@ -1607,9 +1607,9 @@ bool gen_cc_tx_invalid_cc_bare_buy_blocks_duplicate_type::generate(std::vector<t
const uint64_t amount_paid = 0;
std::vector<std::tuple<std::string, cryptonote::cc_command_t, uint64_t>> cmds;
cryptonote::cc_command_buy_blocks_t cmd;
cryptonote::cc_command_buy_items_t cmd;
cmd.cc_account = 4;
cryptonote::cc_command_buy_blocks_t::entry_t e;
cryptonote::cc_command_buy_items_t::entry_t e;
e.type = 1;
e.amount = 0x100;
cmd.entries.push_back(e);
@ -1629,7 +1629,7 @@ bool gen_cc_tx_valid_cc_bare_trade_bid_blocks::generate(std::vector<test_event_e
cryptonote::cc_command_trade_t trade;
trade.cc_account = 4;
trade.bid = true;
trade.type = cryptonote::cc_command_trade_t::type_blocks;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = 1;
trade.amount = 20;
trade.price = 1000;
@ -1664,7 +1664,7 @@ bool gen_cc_tx_valid_cc_bare_trade_offer_blocks::generate(std::vector<test_event
cryptonote::cc_command_trade_t trade;
trade.cc_account = 4;
trade.bid = false;
trade.type = cryptonote::cc_command_trade_t::type_blocks;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = 1;
trade.amount = 20;
trade.price = 1000;
@ -1720,7 +1720,7 @@ bool gen_cc_tx_invalid_cc_bare_trade_bid_block_id_0::generate(std::vector<test_e
cryptonote::cc_command_trade_t trade;
trade.cc_account = 4;
trade.bid = true;
trade.type = cryptonote::cc_command_trade_t::type_blocks;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = 0;
trade.amount = 20;
trade.price = 1000;
@ -1741,8 +1741,8 @@ bool gen_cc_tx_invalid_cc_bare_trade_bid_invalid_block_id::generate(std::vector<
cryptonote::cc_command_trade_t trade;
trade.cc_account = 4;
trade.bid = true;
trade.type = cryptonote::cc_command_trade_t::type_blocks;
trade.id = 256;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = NUM_ITEMS;
trade.amount = 20;
trade.price = 1000;
trade.expiration = 1000;
@ -1762,7 +1762,7 @@ bool gen_cc_tx_invalid_cc_bare_trade_bid_expired::generate(std::vector<test_even
cryptonote::cc_command_trade_t trade;
trade.cc_account = 4;
trade.bid = true;
trade.type = cryptonote::cc_command_trade_t::type_blocks;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = 1;
trade.amount = 20;
trade.price = 1000;
@ -1783,7 +1783,7 @@ bool gen_cc_tx_invalid_cc_bare_trade_bid_not_enough_money::generate(std::vector<
cryptonote::cc_command_trade_t trade;
trade.cc_account = 4;
trade.bid = true;
trade.type = cryptonote::cc_command_trade_t::type_blocks;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = 1;
trade.amount = 1;
trade.price = (uint64_t)1000000000000000;
@ -1804,7 +1804,7 @@ bool gen_cc_tx_invalid_cc_bare_trade_bid_amount_0::generate(std::vector<test_eve
cryptonote::cc_command_trade_t trade;
trade.cc_account = 4;
trade.bid = true;
trade.type = cryptonote::cc_command_trade_t::type_blocks;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = 1;
trade.amount = 0;
trade.price = 1000;
@ -1825,7 +1825,7 @@ bool gen_cc_tx_invalid_cc_bare_trade_offer_amount_0::generate(std::vector<test_e
cryptonote::cc_command_trade_t trade;
trade.cc_account = 4;
trade.bid = false;
trade.type = cryptonote::cc_command_trade_t::type_blocks;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = 1;
trade.amount = 0;
trade.price = 1000;
@ -1846,7 +1846,7 @@ bool gen_cc_tx_valid_cc_bare_match_blocks_matching_amounts::generate(std::vector
trade.bid = false;
trade.cc_account = 4;
trade.type = cryptonote::cc_command_trade_t::type_blocks;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = 1;
trade.amount = 20;
trade.price = 1000;
@ -1856,7 +1856,7 @@ bool gen_cc_tx_valid_cc_bare_match_blocks_matching_amounts::generate(std::vector
trade.bid = true;
trade.cc_account = 5;
trade.type = cryptonote::cc_command_trade_t::type_blocks;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = 1;
trade.amount = 20;
trade.price = 1000;
@ -1894,8 +1894,8 @@ bool gen_cc_tx_valid_cc_bare_match_blocks_matching_amounts::check_final_state(cr
&& expect_cc_account(c, 6, 10, initial_funding[6])
&& expect_cc_account(c, 7, 11, initial_funding[7])
&& expect_treasury_balance(c, expected_treasury_balance)
&& expect_block_balances(c, 4, {std::make_pair(1, STARTING_BLOCK_1 - 20), std::make_pair(2, STARTING_BLOCK_2)})
&& expect_block_balances(c, 5, {std::make_pair(1, 20)});
&& expect_item_balances(c, 4, {std::make_pair(1, STARTING_BLOCK_1 - 20), std::make_pair(2, STARTING_BLOCK_2)})
&& expect_item_balances(c, 5, {std::make_pair(1, 20)});
}
bool gen_cc_tx_valid_cc_bare_match_blocks_partial_buy::generate(std::vector<test_event_entry>& events) const
@ -1908,7 +1908,7 @@ bool gen_cc_tx_valid_cc_bare_match_blocks_partial_buy::generate(std::vector<test
trade.bid = false;
trade.cc_account = 4;
trade.type = cryptonote::cc_command_trade_t::type_blocks;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = 1;
trade.amount = 20;
trade.price = 1000;
@ -1918,7 +1918,7 @@ bool gen_cc_tx_valid_cc_bare_match_blocks_partial_buy::generate(std::vector<test
trade.bid = true;
trade.cc_account = 5;
trade.type = cryptonote::cc_command_trade_t::type_blocks;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = 1;
trade.amount = 12;
trade.price = 1000;
@ -1956,8 +1956,8 @@ bool gen_cc_tx_valid_cc_bare_match_blocks_partial_buy::check_final_state(crypton
&& expect_cc_account(c, 6, 10, initial_funding[6])
&& expect_cc_account(c, 7, 11, initial_funding[7])
&& expect_treasury_balance(c, expected_treasury_balance)
&& expect_block_balances(c, 4, {std::make_pair(1, STARTING_BLOCK_1 - 12), std::make_pair(2, STARTING_BLOCK_2)})
&& expect_block_balances(c, 5, {std::make_pair(1, 12)});
&& expect_item_balances(c, 4, {std::make_pair(1, STARTING_BLOCK_1 - 12), std::make_pair(2, STARTING_BLOCK_2)})
&& expect_item_balances(c, 5, {std::make_pair(1, 12)});
}
bool gen_cc_tx_valid_cc_bare_match_blocks_partial_sell::generate(std::vector<test_event_entry>& events) const
@ -1970,7 +1970,7 @@ bool gen_cc_tx_valid_cc_bare_match_blocks_partial_sell::generate(std::vector<tes
trade.cc_account = 4;
trade.bid = false;
trade.type = cryptonote::cc_command_trade_t::type_blocks;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = 1;
trade.amount = 20;
trade.price = 1000;
@ -1980,7 +1980,7 @@ bool gen_cc_tx_valid_cc_bare_match_blocks_partial_sell::generate(std::vector<tes
trade.cc_account = 5;
trade.bid = true;
trade.type = cryptonote::cc_command_trade_t::type_blocks;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = 1;
trade.amount = 25;
trade.price = 1000;
@ -2018,8 +2018,8 @@ bool gen_cc_tx_valid_cc_bare_match_blocks_partial_sell::check_final_state(crypto
&& expect_cc_account(c, 6, 10, initial_funding[6])
&& expect_cc_account(c, 7, 11, initial_funding[7])
&& expect_treasury_balance(c, expected_treasury_balance)
&& expect_block_balances(c, 4, {std::make_pair(1, STARTING_BLOCK_1 - 20), std::make_pair(2, STARTING_BLOCK_2)})
&& expect_block_balances(c, 5, {std::make_pair(1, 20)});
&& expect_item_balances(c, 4, {std::make_pair(1, STARTING_BLOCK_1 - 20), std::make_pair(2, STARTING_BLOCK_2)})
&& expect_item_balances(c, 5, {std::make_pair(1, 20)});
}
bool gen_cc_tx_invalid_cc_bare_match_0::generate(std::vector<test_event_entry>& events) const
@ -2032,7 +2032,7 @@ bool gen_cc_tx_invalid_cc_bare_match_0::generate(std::vector<test_event_entry>&
trade.cc_account = 4;
trade.bid = false;
trade.type = cryptonote::cc_command_trade_t::type_blocks;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = 1;
trade.amount = 20;
trade.price = 1000;
@ -2042,7 +2042,7 @@ bool gen_cc_tx_invalid_cc_bare_match_0::generate(std::vector<test_event_entry>&
trade.cc_account = 5;
trade.bid = true;
trade.type = cryptonote::cc_command_trade_t::type_blocks;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = 1;
trade.amount = 20;
trade.price = 1000;
@ -2078,7 +2078,7 @@ bool gen_cc_tx_invalid_cc_bare_match_more_than_trade::generate(std::vector<test_
trade.cc_account = 4;
trade.bid = false;
trade.type = cryptonote::cc_command_trade_t::type_blocks;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = 1;
trade.amount = 20;
trade.price = 1000;
@ -2088,7 +2088,7 @@ bool gen_cc_tx_invalid_cc_bare_match_more_than_trade::generate(std::vector<test_
trade.cc_account = 5;
trade.bid = true;
trade.type = cryptonote::cc_command_trade_t::type_blocks;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = 1;
trade.amount = 20;
trade.price = 1000;
@ -2124,7 +2124,7 @@ bool gen_cc_tx_invalid_cc_bare_trade_from_account_0::generate(std::vector<test_e
trade.cc_account = 4;
trade.bid = false;
trade.type = cryptonote::cc_command_trade_t::type_blocks;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = 1;
trade.amount = 20;
trade.price = 1000;
@ -2158,7 +2158,7 @@ bool gen_cc_tx_invalid_cc_bare_match_non_trade_tx::generate(std::vector<test_eve
trade.cc_account = 5;
trade.bid = true;
trade.type = cryptonote::cc_command_trade_t::type_blocks;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = 1;
trade.amount = 20;
trade.price = 1000;
@ -2192,7 +2192,7 @@ bool gen_cc_tx_invalid_cc_bare_match_duplicate_trade_tx::generate(std::vector<te
trade.cc_account = 4;
trade.bid = false;
trade.type = cryptonote::cc_command_trade_t::type_blocks;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = 1;
trade.amount = 20;
trade.price = 1000;
@ -2202,7 +2202,7 @@ bool gen_cc_tx_invalid_cc_bare_match_duplicate_trade_tx::generate(std::vector<te
trade.cc_account = 5;
trade.bid = false;
trade.type = cryptonote::cc_command_trade_t::type_blocks;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = 1;
trade.amount = 40;
trade.price = 1000;
@ -2237,7 +2237,7 @@ bool gen_cc_tx_valid_cc_bare_match_two_buys_from_one_sell::generate(std::vector<
trade.cc_account = 4;
trade.bid = false;
trade.type = cryptonote::cc_command_trade_t::type_blocks;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = 1;
trade.amount = 20;
trade.price = 1000;
@ -2247,7 +2247,7 @@ bool gen_cc_tx_valid_cc_bare_match_two_buys_from_one_sell::generate(std::vector<
trade.cc_account = 5;
trade.bid = true;
trade.type = cryptonote::cc_command_trade_t::type_blocks;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = 1;
trade.amount = 15;
trade.price = 1020;
@ -2257,7 +2257,7 @@ bool gen_cc_tx_valid_cc_bare_match_two_buys_from_one_sell::generate(std::vector<
trade.cc_account = 6;
trade.bid = true;
trade.type = cryptonote::cc_command_trade_t::type_blocks;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = 1;
trade.amount = 5;
trade.price = 1050;
@ -2299,9 +2299,9 @@ bool gen_cc_tx_valid_cc_bare_match_two_buys_from_one_sell::check_final_state(cry
&& expect_cc_account(c, 6, 10, initial_funding[6])
&& expect_cc_account(c, 7, 11, initial_funding[7])
&& expect_treasury_balance(c, expected_treasury_balance)
&& expect_block_balances(c, 4, {std::make_pair(1, STARTING_BLOCK_1 - 20), std::make_pair(2, STARTING_BLOCK_2)})
&& expect_block_balances(c, 5, {std::make_pair(1, 15)})
&& expect_block_balances(c, 6, {std::make_pair(1, 5)});
&& expect_item_balances(c, 4, {std::make_pair(1, STARTING_BLOCK_1 - 20), std::make_pair(2, STARTING_BLOCK_2)})
&& expect_item_balances(c, 5, {std::make_pair(1, 15)})
&& expect_item_balances(c, 6, {std::make_pair(1, 5)});
}
bool gen_cc_tx_valid_cc_bare_maker_no_fee::generate(std::vector<test_event_entry>& events) const
@ -2314,7 +2314,7 @@ bool gen_cc_tx_valid_cc_bare_maker_no_fee::generate(std::vector<test_event_entry
trade.bid = false;
trade.cc_account = 4;
trade.type = cryptonote::cc_command_trade_t::type_blocks;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = 1;
trade.amount = 20;
trade.price = 1000;
@ -2335,7 +2335,7 @@ bool gen_cc_tx_invalid_cc_bare_taker_no_fee::generate(std::vector<test_event_ent
trade.bid = false;
trade.cc_account = 4;
trade.type = cryptonote::cc_command_trade_t::type_blocks;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = 1;
trade.amount = 20;
trade.price = 1000;
@ -2345,7 +2345,7 @@ bool gen_cc_tx_invalid_cc_bare_taker_no_fee::generate(std::vector<test_event_ent
trade.bid = true;
trade.cc_account = 5;
trade.type = cryptonote::cc_command_trade_t::type_blocks;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = 1;
trade.amount = 20;
trade.price = 1000;

View File

@ -37,6 +37,7 @@ import json
from framework.daemon import Daemon
from framework.wallet import Wallet
NUM_ITEMS = 257
account_creation_fee = 1000000000000
class CCTest():
@ -214,7 +215,7 @@ class CCTest():
res = self.wallet[i].cc_get_info()
assert res.cc_balance == cc_balance[i]
assert not 'flags' in res or len(res.flags) == 0
assert not 'block_balances' in res or res.block_balances == [0]*256
assert not 'item_balances' in res or res.item_balances == [0]*NUM_ITEMS
def test_buy_land(self):
daemon = Daemon()
@ -311,19 +312,19 @@ class CCTest():
account_id = res.account_id
res = daemon.cc_get_account(account_id)
block_balances = res.block_balances
assert len(block_balances) == 256
item_balances = res.item_balances
assert len(item_balances) == NUM_ITEMS
res = self.wallet[2].cc_buy_blocks(entries = [{'type': 1, 'amount': 15}, {'type': 2, 'amount': 40}])
block_balances[1] += 15
block_balances[2] += 40
item_balances[1] += 15
item_balances[2] += 40
daemon.generateblocks('CC1MM8HqWBathu8hS5mwMNHm1da3cZCzg2rkqWLKCxpUarKtPszP3MjiocrJeLvph4AghgYu1AXonCmckfEuyE8Q2FFm8jNdiz3', 1)
res = daemon.cc_get_account(account_id)
assert len(res.block_balances) == 256
for i in range(256):
assert(res.block_balances[i] == block_balances[i])
assert len(res.item_balances) == NUM_ITEMS
for i in range(NUM_ITEMS
assert(res.item_balances[i] == item_balances[i])
ok = False
try: res = self.wallet[2].cc_buy_blocks(entries = [{'type': 0, 'amount': 15}])
@ -346,14 +347,14 @@ class CCTest():
assert ok
res = self.wallet[2].cc_buy_blocks(entries = [{'type': 1, 'amount': 20}])
block_balances[1] += 20
item_balances[1] += 20
daemon.generateblocks('CC1MM8HqWBathu8hS5mwMNHm1da3cZCzg2rkqWLKCxpUarKtPszP3MjiocrJeLvph4AghgYu1AXonCmckfEuyE8Q2FFm8jNdiz3', 1)
res = daemon.cc_get_account(account_id)
assert len(res.block_balances) == 256
for i in range(256):
assert(res.block_balances[i] == block_balances[i])
assert len(res.item_balances) == NUM_ITEMS
for i in range(NUM_ITEMS):
assert(res.item_balances[i] == item_balances[i])
def test_build(self):
daemon = Daemon()
@ -478,7 +479,7 @@ class CCTest():
print("Testing trading")
expected_balances = [None, None, None]
expected_block_balances = [[None]*256, [None]*256, [None]*256]
expected_item_balances = [[None]*NUM_ITEMS, [None]*NUM_ITEMS, [None]*NUM_ITEMS]
account_id = [None, None, None]
for i in range(3):
self.wallet[i].refresh()
@ -486,14 +487,14 @@ class CCTest():
account_id[i] = res.account_id
res = daemon.cc_get_account(account_id[i])
expected_balances[i] = res.balance
expected_block_balances[i] = res.block_balances
expected_item_balances[i] = res.item_balances
res = daemon.cc_get_order_book(True, True)
assert not 'offers' in res or len(res.offers) == 0
assert not 'bids' in res or len(res.bids) == 0
# 2 has blocks, set some of them up for sale
res = self.wallet[2].cc_trade_blocks(False, 1, 5, 80, 1500)
res = self.wallet[2].cc_trade_item(False, 1, 5, 80, 1500)
assert len(res.tx_hash) == 64
offer_1_5_80_nonce = res.cc_nonce
assert offer_1_5_80_nonce > 0
@ -523,7 +524,7 @@ class CCTest():
assert not trade.mined # not matched, stays in the txpool
# add a compatible bid, but do not match, they'll coexist
res = self.wallet[1].cc_trade_blocks(True, 1, 2, 80, 1500)
res = self.wallet[1].cc_trade_item(True, 1, 2, 80, 1500)
assert len(res.tx_hash) == 64
bid_1_2_80_a_nonce = res.cc_nonce
assert bid_1_2_80_a_nonce > 0
@ -545,12 +546,12 @@ class CCTest():
# add a matching one - first matching too few
ok = False
try: self.wallet[1].cc_trade_blocks(True, 1, 2, 80, 1500, matches = [{'nonce': offer_1_5_80_nonce, 'amount': 1}], cost = 80 * 1)
try: self.wallet[1].cc_trade_item(True, 1, 2, 80, 1500, matches = [{'nonce': offer_1_5_80_nonce, 'amount': 1}], cost = 80 * 1)
except: ok = True
assert ok
# then matching enough
res = self.wallet[1].cc_trade_blocks(True, 1, 2, 80, 1500, matches = [{'nonce': offer_1_5_80_nonce, 'amount': 2}], cost = 80 * 2)
res = self.wallet[1].cc_trade_item(True, 1, 2, 80, 1500, matches = [{'nonce': offer_1_5_80_nonce, 'amount': 2}], cost = 80 * 2)
assert len(res.tx_hash) == 64
bid_1_2_80_b_nonce = res.cc_nonce
assert bid_1_2_80_b_nonce > 0
@ -606,9 +607,9 @@ class CCTest():
matched_amount = 2
matched_price = 80
expected_balances[1] -= matched_amount * matched_price
expected_block_balances[1][1] += matched_amount
expected_item_balances[1][1] += matched_amount
expected_balances[2] += matched_amount * matched_price
expected_block_balances[2][1] -= matched_amount
expected_item_balances[2][1] -= matched_amount
# the offer should still be around, with 2 used and 3 left, and the last bid is gone
res = daemon.cc_get_order_book(True, True)
@ -629,7 +630,7 @@ class CCTest():
for i in range(3):
res = daemon.cc_get_account(account_id[i])
assert res.balance == expected_balances[i]
assert res.block_balances == expected_block_balances[i]
assert res.item_balances == expected_item_balances[i]
# current orders
# 2 sells 3 at 80
@ -637,7 +638,7 @@ class CCTest():
# matching to a non existing tx
ok = False
try: self.wallet[0].cc_trade_blocks(True, 1, 1, 80, 1500, matches = [{'txid': "4"*64, 'amount': 1}], cost = 80)
try: self.wallet[0].cc_trade_item(True, 1, 1, 80, 1500, matches = [{'txid': "4"*64, 'amount': 1}], cost = 80)
except: ok = True
assert ok
@ -645,56 +646,56 @@ class CCTest():
res = daemon.getblockheaderbyheight(50)
miner_tx_hash = res.block_header.miner_tx_hash
ok = False
try: self.wallet[0].cc_trade_blocks(True, 1, 1, 80, 1500, matches = [{'nonce': miner_tx_hash, 'amount': 1}], cost = 80)
try: self.wallet[0].cc_trade_item(True, 1, 1, 80, 1500, matches = [{'nonce': miner_tx_hash, 'amount': 1}], cost = 80)
except: ok = True
assert ok
# matching with non matching price
ok = False
try: self.wallet[0].cc_trade_blocks(True, 1, 1, 79, 1500, matches = [{'nonce': offer_1_5_80_nonce, 'amount': 1}], cost = 80)
try: self.wallet[0].cc_trade_item(True, 1, 1, 79, 1500, matches = [{'nonce': offer_1_5_80_nonce, 'amount': 1}], cost = 80)
except: ok = True
assert ok
# matching too much
ok = False
try: self.wallet[0].cc_trade_blocks(True, 1, 5, 80, 1500, matches = [{'nonce': offer_1_5_80_nonce, 'amount': 5}], cost = 800)
try: self.wallet[0].cc_trade_item(True, 1, 5, 80, 1500, matches = [{'nonce': offer_1_5_80_nonce, 'amount': 5}], cost = 800)
except: ok = True
assert ok
# matching nothing
ok = False
try: self.wallet[0].cc_trade_blocks(True, 1, 1, 80, 1500, matches = [{'nonce': offer_1_5_80_nonce, 'amount': 0}], cost = 1)
try: self.wallet[0].cc_trade_item(True, 1, 1, 80, 1500, matches = [{'nonce': offer_1_5_80_nonce, 'amount': 0}], cost = 1)
except: ok = True
assert ok
# matching the same tx twice
ok = False
try: self.wallet[0].cc_trade_blocks(True, 1, 2, 80, 1500, matches = [{'nonce': offer_1_5_80_nonce, 'amount': 1}, {'nonce': offer_1_5_80_nonce, 'amount': 1}], cost = 160)
try: self.wallet[0].cc_trade_item(True, 1, 2, 80, 1500, matches = [{'nonce': offer_1_5_80_nonce, 'amount': 1}, {'nonce': offer_1_5_80_nonce, 'amount': 1}], cost = 160)
except: ok = True
assert ok
# matching with oneself's order
ok = False
try: self.wallet[2].cc_trade_blocks(True, 1, 1, 80, 1500, matches = [{'nonce': offer_1_5_80_nonce, 'amount': 1}], cost = 80)
try: self.wallet[2].cc_trade_item(True, 1, 1, 80, 1500, matches = [{'nonce': offer_1_5_80_nonce, 'amount': 1}], cost = 80)
except: ok = True
assert ok
# matching with a better price uses the matched trade's price
res = self.wallet[0].cc_trade_blocks(True, 1, 1, 140, 1500, matches = [{'nonce': offer_1_5_80_nonce, 'amount': 1}], cost = 80)
res = self.wallet[0].cc_trade_item(True, 1, 1, 140, 1500, matches = [{'nonce': offer_1_5_80_nonce, 'amount': 1}], cost = 80)
assert len(res.tx_hash) == 64
expected_balances[0] -= res.fee
expected_balances[0] -= 80
expected_balances[2] += 80
expected_block_balances[0][1] += 1
expected_block_balances[2][1] -= 1
expected_item_balances[0][1] += 1
expected_item_balances[2][1] -= 1
res = self.wallet[2].cc_trade_blocks(False, 1, 1, 40, 1500, matches = [{'nonce': bid_1_2_80_a_nonce, 'amount': 1}], cost = 0)
res = self.wallet[2].cc_trade_item(False, 1, 1, 40, 1500, matches = [{'nonce': bid_1_2_80_a_nonce, 'amount': 1}], cost = 0)
assert len(res.tx_hash) == 64
expected_balances[2] -= res.fee
expected_balances[2] += 80
expected_balances[1] -= 80
expected_block_balances[2][1] -= 1
expected_block_balances[1][1] += 1
expected_item_balances[2][1] -= 1
expected_item_balances[1][1] += 1
daemon.generateblocks('CC1MM8HqWBathu8hS5mwMNHm1da3cZCzg2rkqWLKCxpUarKtPszP3MjiocrJeLvph4AghgYu1AXonCmckfEuyE8Q2FFm8jNdiz3', 1)
expected_balances[1] -= bid_1_2_80_a_fee # finally!
@ -704,7 +705,7 @@ class CCTest():
for i in range(3):
res = daemon.cc_get_account(account_id[i])
assert res.balance == expected_balances[i]
assert res.block_balances == expected_block_balances[i]
assert res.item_balances == expected_item_balances[i]
# the offer should still be around, with 2 used and 3 left, and the last bid is gone
res = daemon.cc_get_order_book(True, True)
@ -724,17 +725,17 @@ class CCTest():
# 1 buys 1 at 80
# add several offers in a ladder
res = self.wallet[2].cc_trade_blocks(False, 1, 1, 100, 1500)
res = self.wallet[2].cc_trade_item(False, 1, 1, 100, 1500)
assert len(res.tx_hash) == 64
offer_1_1_100_nonce = res.cc_nonce
assert offer_1_1_100_nonce > 0
offer_1_1_100_fee = res.fee
res = self.wallet[1].cc_trade_blocks(False, 1, 3, 85, 1500)
res = self.wallet[1].cc_trade_item(False, 1, 3, 85, 1500)
assert len(res.tx_hash) == 64
offer_1_3_85_nonce = res.cc_nonce
assert offer_1_3_85_nonce > 0
offer_1_3_85_fee = res.fee
res = self.wallet[2].cc_trade_blocks(False, 1, 2, 90, 1500)
res = self.wallet[2].cc_trade_item(False, 1, 2, 90, 1500)
assert len(res.tx_hash) == 64
offer_1_2_90_nonce = res.cc_nonce
assert offer_1_2_90_nonce > 0
@ -772,36 +773,36 @@ class CCTest():
# we can't match more than one unmined tx
ok = False
try: self.wallet[0].cc_trade_blocks(True, 1, 4, 100, 1500, matches = [{'nonce': offer_1_3_85_nonce, 'amount': 3}, {'nonce': offer_1_2_90_nonce, 'amount': 1}], cost = 85 * 3 + 90 * 1)
try: self.wallet[0].cc_trade_item(True, 1, 4, 100, 1500, matches = [{'nonce': offer_1_3_85_nonce, 'amount': 3}, {'nonce': offer_1_2_90_nonce, 'amount': 1}], cost = 85 * 3 + 90 * 1)
except: ok = True
assert ok
# we can't grab only part of one while leaving some for another
ok = False
try: self.wallet[0].cc_trade_blocks(True, 1, 4, 100, 1500, matches = [{'nonce': offer_1_5_80_nonce, 'amount': 1}, {'nonce': offer_1_2_90_nonce, 'amount': 1}], cost = 85 + 90)
try: self.wallet[0].cc_trade_item(True, 1, 4, 100, 1500, matches = [{'nonce': offer_1_5_80_nonce, 'amount': 1}, {'nonce': offer_1_2_90_nonce, 'amount': 1}], cost = 85 + 90)
except: ok = True
assert ok
# nibble at offer_1_3_85_nonce so it gets mined
res = self.wallet[0].cc_trade_blocks(True, 1, 1, 100, 1500, matches = [{'nonce': offer_1_3_85_nonce, 'amount': 1}], cost = 85)
res = self.wallet[0].cc_trade_item(True, 1, 1, 100, 1500, matches = [{'nonce': offer_1_3_85_nonce, 'amount': 1}], cost = 85)
expected_balances[0] -= res.fee
expected_balances[0] -= 85
expected_block_balances[0][1] += 1
expected_item_balances[0][1] += 1
expected_balances[1] -= offer_1_3_85_fee
expected_balances[1] += 85
expected_block_balances[1][1] -= 1
expected_item_balances[1][1] -= 1
daemon.generateblocks('CC1MM8HqWBathu8hS5mwMNHm1da3cZCzg2rkqWLKCxpUarKtPszP3MjiocrJeLvph4AghgYu1AXonCmckfEuyE8Q2FFm8jNdiz3', 1)
# match several txes, once of them partially
res = self.wallet[0].cc_trade_blocks(True, 1, 5, 100, 1500, matches = [{'nonce': offer_1_5_80_nonce, 'amount': 2}, {'nonce': offer_1_2_90_nonce, 'amount': 2}, {'nonce': offer_1_3_85_nonce, 'amount': 1}], cost = 2 * 80 + 2 * 90 + 1 * 85)
res = self.wallet[0].cc_trade_item(True, 1, 5, 100, 1500, matches = [{'nonce': offer_1_5_80_nonce, 'amount': 2}, {'nonce': offer_1_2_90_nonce, 'amount': 2}, {'nonce': offer_1_3_85_nonce, 'amount': 1}], cost = 2 * 80 + 2 * 90 + 1 * 85)
expected_balances[0] -= res.fee
expected_balances[0] -= 2 * 80 + 2 * 90 + 1 * 85
expected_block_balances[0][1] += 5
expected_item_balances[0][1] += 5
expected_balances[2] -= offer_1_2_90_fee
expected_balances[2] += 2 * 80 + 2 * 90
expected_block_balances[2][1] -= 4
expected_item_balances[2][1] -= 4
expected_balances[1] += 1 * 85
expected_block_balances[1][1] -= 1
expected_item_balances[1][1] -= 1
daemon.generateblocks('CC1MM8HqWBathu8hS5mwMNHm1da3cZCzg2rkqWLKCxpUarKtPszP3MjiocrJeLvph4AghgYu1AXonCmckfEuyE8Q2FFm8jNdiz3', 1)
daemon.generateblocks('CC1MM8HqWBathu8hS5mwMNHm1da3cZCzg2rkqWLKCxpUarKtPszP3MjiocrJeLvph4AghgYu1AXonCmckfEuyE8Q2FFm8jNdiz3', 1)
@ -810,23 +811,23 @@ class CCTest():
for i in range(3):
res = daemon.cc_get_account(account_id[i])
assert res.balance == expected_balances[i]
assert res.block_balances == expected_block_balances[i]
assert res.item_balances == expected_item_balances[i]
# expiration too high
ok = False
try: self.wallet[2].cc_trade_blocks(False, 1, 1, 80, 221500)
try: self.wallet[2].cc_trade_item(False, 1, 1, 80, 221500)
except: ok = True
assert ok
# expiration in the past
ok = False
try: self.wallet[2].cc_trade_blocks(False, 1, 1, 80, 10)
try: self.wallet[2].cc_trade_item(False, 1, 1, 80, 10)
except: ok = True
assert ok
# expiration too low
ok = False
try: self.wallet[2].cc_trade_blocks(False, 1, 1, 80, 100)
try: self.wallet[2].cc_trade_item(False, 1, 1, 80, 100)
except: ok = True
assert ok
@ -869,7 +870,7 @@ class CCTest():
assert res.balance == 0
ok = False
try: res = self.wallet[2].cc_trade_blocks(False, 1, 1, 80, 1500, matches = [{'nonce': bid_1_2_80_a_nonce, 'amount': 1}], cost = 0)
try: res = self.wallet[2].cc_trade_item(False, 1, 1, 80, 1500, matches = [{'nonce': bid_1_2_80_a_nonce, 'amount': 1}], cost = 0)
except: ok = True
assert ok
@ -883,23 +884,23 @@ class CCTest():
assert res.balance == expected_balances[1]
# matching a tx from an account that does not have the blocks anymore
res = self.wallet[1].cc_trade_blocks(False, 1, 1, 90, 1500)
res = self.wallet[1].cc_trade_item(False, 1, 1, 90, 1500)
assert len(res.tx_hash) == 64
nonce = res.cc_nonce
assert nonce > 0
expected_balances[1] -= res.fee
res = self.wallet[0].cc_trade_blocks(True, 1, 1, 90, 1500, matches = [{'nonce': nonce, 'amount': 1}], cost = 90)
res = self.wallet[0].cc_trade_item(True, 1, 1, 90, 1500, matches = [{'nonce': nonce, 'amount': 1}], cost = 90)
assert len(res.tx_hash) == 64
expected_balances[0] -= res.fee
daemon.generateblocks('CC1MM8HqWBathu8hS5mwMNHm1da3cZCzg2rkqWLKCxpUarKtPszP3MjiocrJeLvph4AghgYu1AXonCmckfEuyE8Q2FFm8jNdiz3', 1)
daemon.generateblocks('CC1MM8HqWBathu8hS5mwMNHm1da3cZCzg2rkqWLKCxpUarKtPszP3MjiocrJeLvph4AghgYu1AXonCmckfEuyE8Q2FFm8jNdiz3', 1)
expected_balances[1] += 90
expected_balances[0] -= 90
expected_block_balances[1][1] -= 1
expected_block_balances[0][1] += 1
expected_item_balances[1][1] -= 1
expected_item_balances[0][1] += 1
ok = False
try: self.wallet[2].cc_trade_blocks(True, 1, 1, 85, 1500, matches = [{'nonce': offer_1_3_85_nonce, 'amount': 1}], cost = 85)
try: self.wallet[2].cc_trade_item(True, 1, 1, 85, 1500, matches = [{'nonce': offer_1_3_85_nonce, 'amount': 1}], cost = 85)
except: ok = True
assert ok
@ -907,7 +908,7 @@ class CCTest():
for i in range(3):
res = daemon.cc_get_account(account_id[i])
assert res.balance == expected_balances[i]
assert res.block_balances == expected_block_balances[i]
assert res.item_balances == expected_item_balances[i]
# sell a flag we do not have
res = daemon.cc_get_account(account_id[2])
@ -960,7 +961,7 @@ class CCTest():
for i in range(3):
res = daemon.cc_get_account(account_id[i])
assert res.balance == expected_balances[i]
assert res.block_balances == expected_block_balances[i]
assert res.item_balances == expected_item_balances[i]
def test_interacting_trades(self):
daemon = Daemon()
@ -997,10 +998,10 @@ class CCTest():
self.wallet[i].refresh()
res = self.wallet[i].cc_get_info()
res = daemon.cc_get_account(res.account_id)
res = self.wallet[2].cc_trade_blocks(False, 1, 10, 80, 1500)
res = self.wallet[2].cc_trade_item(False, 1, 10, 80, 1500)
nonce = res.cc_nonce
res = self.wallet[1].cc_trade_blocks(True, 1, 8, 80, 1500, matches = [{'nonce': nonce, 'amount': 8}], cost = 8*80)
res = self.wallet[0].cc_trade_blocks(True, 1, 4, 80, 1500, matches = [{'nonce': nonce, 'amount': 4}], cost = 4*80)
res = self.wallet[1].cc_trade_item(True, 1, 8, 80, 1500, matches = [{'nonce': nonce, 'amount': 8}], cost = 8*80)
res = self.wallet[0].cc_trade_item(True, 1, 4, 80, 1500, matches = [{'nonce': nonce, 'amount': 4}], cost = 4*80)
daemon.generateblocks('CC1MM8HqWBathu8hS5mwMNHm1da3cZCzg2rkqWLKCxpUarKtPszP3MjiocrJeLvph4AghgYu1AXonCmckfEuyE8Q2FFm8jNdiz3', 1)
daemon.generateblocks('CC1MM8HqWBathu8hS5mwMNHm1da3cZCzg2rkqWLKCxpUarKtPszP3MjiocrJeLvph4AghgYu1AXonCmckfEuyE8Q2FFm8jNdiz3', 1)

View File

@ -55,11 +55,10 @@ private:
{
crypto::public_key public_key;
uint64_t balance;
uint32_t block_balances[256];
uint32_t labour_balance;
uint32_t item_balances[NUM_ITEMS];
std::vector<uint32_t> flags;
bool operator==(const account_t &other) const { return public_key == other.public_key && balance == other.balance && !memcmp(block_balances, other.block_balances, 256 * sizeof(uint32_t)) && labour_balance == other.labour_balance && flags == other.flags; }
bool operator==(const account_t &other) const { return public_key == other.public_key && balance == other.balance && !memcmp(item_balances, other.item_balances, NUM_ITEMS * sizeof(uint32_t)) && flags == other.flags; }
};
struct city_t
@ -86,11 +85,10 @@ private:
uint32_t repair;
uint8_t stability;
uint32_t economic_power;
uint32_t block_budget[256];
uint32_t labour_budget;
uint32_t budget[NUM_ITEMS];
uint32_t active: 1;
bool operator==(const flag_t &other) const { return owner == other.owner && city == other.city && role == other.role && x0 == other.x0 && y0 == other.y0 && x1 == other.x1 && y1 == other.y1 && repair == other.repair && stability == other.stability && economic_power == other.economic_power && !memcmp(block_budget, other.block_budget, sizeof(block_budget)) && labour_budget == other.labour_budget && active == other.active; }
bool operator==(const flag_t &other) const { return owner == other.owner && city == other.city && role == other.role && x0 == other.x0 && y0 == other.y0 && x1 == other.x1 && y1 == other.y1 && repair == other.repair && stability == other.stability && economic_power == other.economic_power && !memcmp(budget, other.budget, sizeof(budget)) && active == other.active; }
};
struct tile_t
@ -176,7 +174,7 @@ public:
// CC
virtual uint32_t allocate_new_cc_account(const crypto::public_key &public_key) override
{
state.accounts.push_back({public_key, 0, {}, 0, {}});
state.accounts.push_back({public_key, 0, {}, {}});
return state.accounts.size() - 1;
}
@ -210,14 +208,13 @@ public:
return c;
}
virtual bool get_cc_account_data(uint32_t id, crypto::public_key &public_key, uint64_t &balance, uint32_t block_balances[256], uint32_t &labour_balance, std::vector<uint32_t> &flags) const override
virtual bool get_cc_account_data(uint32_t id, crypto::public_key &public_key, uint64_t &balance, uint32_t item_balances[NUM_ITEMS], std::vector<uint32_t> &flags) const override
{
if (id == 0 || id >= state.accounts.size() || state.accounts[id].public_key == DEAD_PKEY)
return false;
public_key = state.accounts[id].public_key;
balance = state.accounts[id].balance;
memcpy(block_balances, state.accounts[id].block_balances, 256 * sizeof(uint32_t));
labour_balance = state.accounts[id].labour_balance;
memcpy(item_balances, state.accounts[id].item_balances, NUM_ITEMS * sizeof(uint32_t));
flags = state.accounts[id].flags;
return true;
}
@ -227,14 +224,9 @@ public:
state.accounts[id].balance = balance;
}
virtual void set_cc_account_labour_balance(uint32_t id, uint32_t labour_balance) override
virtual void set_cc_account_item_balances(uint32_t id, uint32_t item_balances[NUM_ITEMS]) override
{
state.accounts[id].labour_balance = labour_balance;
}
virtual void set_cc_account_block_balances(uint32_t id, uint32_t block_balances[256]) override
{
memcpy(state.accounts[id].block_balances, block_balances, 256 * sizeof(uint32_t));
memcpy(state.accounts[id].item_balances, item_balances, NUM_ITEMS * sizeof(uint32_t));
}
virtual void add_cc_account_flag(uint32_t id, uint32_t flag_id) override
@ -298,7 +290,7 @@ public:
{
actual_id = *id;
}
state.flags[actual_id] = {true, owner_id, city_id, ROLE_EMPTY, x0, y0, x1, y1, repair, stability, 0, {}, 0, true};
state.flags[actual_id] = {true, owner_id, city_id, ROLE_EMPTY, x0, y0, x1, y1, repair, stability, 0, {}, true};
return actual_id;
}
@ -335,8 +327,7 @@ public:
fd.repair = flag.repair;
fd.stability = flag.stability;
fd.economic_power = flag.economic_power;
memcpy(fd.block_budget, flag.block_budget, sizeof(flag.block_budget));
fd.labour_budget = flag.labour_budget;
memcpy(fd.budget, flag.budget, sizeof(flag.budget));
fd.active = flag.active;
if (!f(fd))
return false;
@ -359,8 +350,7 @@ public:
fd.repair = state.flags[id].repair;
fd.stability = state.flags[id].stability;
fd.economic_power = state.flags[id].economic_power;
memcpy(fd.block_budget, state.flags[id].block_budget, sizeof(fd.block_budget));
fd.labour_budget = state.flags[id].labour_budget;
memcpy(fd.budget, state.flags[id].budget, sizeof(fd.budget));
fd.active = state.flags[id].active;
if (tiles)
{
@ -396,10 +386,9 @@ public:
state.flags[id].repair = repair;
}
virtual void set_cc_flag_budget(uint32_t id, const uint32_t blocks[256], uint32_t labour) override
virtual void set_cc_flag_budget(uint32_t id, const uint32_t budget[NUM_ITEMS]) override
{
memcpy(state.flags[id].block_budget, blocks, 256 * sizeof(uint32_t));
state.flags[id].labour_budget = labour;
memcpy(state.flags[id].budget, budget, NUM_ITEMS * sizeof(uint32_t));
}
virtual void set_cc_flag_active(uint32_t id, bool active) override
@ -639,7 +628,7 @@ TEST(cc_command, build)
TEST(cc_command, buy_blocks)
{
cryptonote::cc_command_buy_blocks_t cmd;
cryptonote::cc_command_buy_items_t cmd;
cmd.entries.resize(1);
cmd.entries[0].type = 1;
cmd.entries[0].amount = 1;
@ -948,9 +937,9 @@ TEST(cc_command, execute_build)
buy_land.hm1 = 3;
ASSERT_TRUE(cc::get_new_flag_cost(buy_land.x, buy_land.y, buy_land.x + buy_land.wm1, buy_land.y + buy_land.hm1, buy_land.cost));
setup.push_back(buy_land);
cryptonote::cc_command_buy_blocks_t buy_blocks;
cryptonote::cc_command_buy_items_t buy_blocks;
buy_blocks.cc_account = 4;
cryptonote::cc_command_buy_blocks_t::entry_t e;
cryptonote::cc_command_buy_items_t::entry_t e;
e.type = 1;
e.amount = 100;
buy_blocks.entries.push_back(e);
@ -981,7 +970,7 @@ TEST(cc_command, execute_build)
TEST(cc_command, execute_buy_blocks)
{
cryptonote::cc_command_buy_blocks_t buy_blocks;
cryptonote::cc_command_buy_items_t buy_blocks;
std::vector<cryptonote::cc_command_t> setup;
cryptonote::keypair keys = cryptonote::keypair::generate(hw::get_device("default"));
@ -1010,6 +999,32 @@ TEST(cc_command, execute_buy_blocks)
test_commands(false, setup, buy_blocks, "0 blocks");
}
TEST(cc_command, execute_buy_labour)
{
cryptonote::cc_command_buy_items_t buy_labour;
std::vector<cryptonote::cc_command_t> setup;
cryptonote::keypair keys = cryptonote::keypair::generate(hw::get_device("default"));
// setup
cryptonote::cc_command_create_account_t create_account;
create_account.public_key = keys.pub;
create_account.amount = CRYPTONOTE_CC_NEW_ACCOUNT_FEE + 1000000000000;
setup.push_back(create_account);
buy_labour.entries.resize(1);
// good
buy_labour.cc_account = 4;
buy_labour.entries[0].type = ITEM_LABOUR;
buy_labour.entries[0].amount = 12;
test_commands(true, setup, buy_labour, "valid");
// cannot buy 0 labour
buy_labour.entries[0].type = ITEM_LABOUR;
buy_labour.entries[0].amount = 0;
test_commands(false, setup, buy_labour, "0 items");
}
TEST(cc_command, execute_trade_maker)
{
cryptonote::cc_command_trade_t trade;
@ -1022,9 +1037,9 @@ TEST(cc_command, execute_trade_maker)
create_account.public_key = keys.pub;
create_account.amount = CRYPTONOTE_CC_NEW_ACCOUNT_FEE + 1000000000000;
setup.push_back(create_account);
cryptonote::cc_command_buy_blocks_t buy_blocks;
cryptonote::cc_command_buy_items_t buy_blocks;
buy_blocks.cc_account = 4;
cryptonote::cc_command_buy_blocks_t::entry_t e;
cryptonote::cc_command_buy_items_t::entry_t e;
e.type = 1;
e.amount = 100;
buy_blocks.entries.push_back(e);
@ -1036,7 +1051,7 @@ TEST(cc_command, execute_trade_maker)
// good bid
trade.cc_account = 4;
trade.bid = true;
trade.type = cryptonote::cc_command_trade_t::type_blocks;
trade.type = cryptonote::cc_command_trade_t::type_item;
trade.id = 1;
trade.amount = 10;
trade.price = 10;
@ -1051,7 +1066,7 @@ TEST(cc_command, execute_trade_maker)
// bad type
trade.type = 0xff;
test_commands(false, setup, trade, "bad type");
trade.type = cryptonote::cc_command_trade_t::type_blocks;
trade.type = cryptonote::cc_command_trade_t::type_item;
// bad id
trade.id = 0;
@ -1067,7 +1082,7 @@ TEST(cc_command, execute_trade_maker)
TEST(cc_command, execute_building_settings)
{
cryptonote::cc_command_buy_land_t buy_land;
cryptonote::cc_command_buy_blocks_t buy_blocks;
cryptonote::cc_command_buy_items_t buy_blocks;
cryptonote::cc_command_building_settings_t building_settings;
std::vector<cryptonote::cc_command_t> setup;
@ -1778,7 +1793,7 @@ TEST(cc, type_tags)
ASSERT_EQ(get_cc_tag(cmd), 0x03);
cmd = cryptonote::cc_command_build_t();
ASSERT_EQ(get_cc_tag(cmd), 0x04);
cmd = cryptonote::cc_command_buy_blocks_t();
cmd = cryptonote::cc_command_buy_items_t();
ASSERT_EQ(get_cc_tag(cmd), 0x05);
cmd = cryptonote::cc_command_game_update_t();
ASSERT_EQ(get_cc_tag(cmd), 0x06);

View File

@ -669,13 +669,13 @@ class Daemon(object):
}
return self.rpc.send_json_rpc_request(cc_get_account)
def cc_debug_set_account(self, id, balance, block_balances = []):
def cc_debug_set_account(self, id, balance, item_balances = []):
cc_debug_set_account = {
'method': 'cc_debug_set_account',
'params': {
'id': id,
'balance': balance,
'block_balances': block_balances,
'item_balances': item_balances,
},
'jsonrpc': '2.0',
'id': '0'

View File

@ -1167,9 +1167,9 @@ class Wallet(object):
}
return self.rpc.send_json_rpc_request(cc_trade_flag)
def cc_trade_blocks(self, bid, id, amount, price, expiration, matches = [], cost = 0, priority = 0, do_not_relay = False, get_tx_hex = False, get_tx_metadata = False):
cc_trade_blocks = {
'method': 'cc_trade_blocks',
def cc_trade_item(self, bid, id, amount, price, expiration, matches = [], cost = 0, priority = 0, do_not_relay = False, get_tx_hex = False, get_tx_metadata = False):
cc_trade_item = {
'method': 'cc_trade_item',
'params': {
'bid': bid,
'id': id,
@ -1186,5 +1186,5 @@ class Wallet(object):
'jsonrpc': '2.0',
'id': '0'
}
return self.rpc.send_json_rpc_request(cc_trade_blocks)
return self.rpc.send_json_rpc_request(cc_trade_item)