Skip to content

Commit

Permalink
Node farmer_ranking cache
Browse files Browse the repository at this point in the history
  • Loading branch information
madMAx43v3r committed Jul 7, 2024
1 parent d802cf7 commit a5c99af
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 39 deletions.
8 changes: 6 additions & 2 deletions include/mmx/Node.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,10 +198,10 @@ class Node : public NodeBase {
std::vector<std::shared_ptr<const BlockHeader>> get_farmed_blocks(
const std::vector<pubkey_t>& farmer_keys, const vnx::bool_t& full_blocks, const uint32_t& since = 0, const int32_t& limit = -1) const override;

std::map<pubkey_t, uint32_t> get_farmed_block_count(const uint32_t& since) const override;

farmed_block_summary_t get_farmed_block_summary(const std::vector<pubkey_t>& farmer_keys, const uint32_t& since = 0) const override;

std::vector<std::pair<pubkey_t, uint32_t>> get_farmer_ranking(const int32_t& limit) const override;

void on_stuck_timeout();

void start_sync(const vnx::bool_t& force) override;
Expand Down Expand Up @@ -386,6 +386,8 @@ class Node : public NodeBase {

void purge_tree();

void update_farmer_ranking();

void add_proof( const uint32_t height, const hash_t& challenge,
std::shared_ptr<const ProofOfSpace> proof, const vnx::Hash64 farmer_mac);

Expand Down Expand Up @@ -516,6 +518,8 @@ class Node : public NodeBase {
hash_multi_table<pubkey_t, addr_t> vplot_map; // [farmer key => contract]
hash_multi_table<pubkey_t, farmed_block_info_t> farmer_block_map; // [farmer key => info]

std::vector<std::pair<pubkey_t, uint32_t>> farmer_ranking; // sorted by count DSC [farmer key => num. blocks]

uint32_t sync_pos = 0; // current sync height
uint32_t sync_retry = 0;
int64_t sync_finish_ms = 0; // when peak was reached
Expand Down
4 changes: 2 additions & 2 deletions modules/Node.vni
Original file line number Diff line number Diff line change
Expand Up @@ -270,10 +270,10 @@ module Node implements vnx.addons.HttpComponent {
vector<BlockHeader*> get_farmed_blocks(vector<pubkey_t> farmer_keys, bool full_blocks, uint since, int limit = 100) const;

@Permission(permission_e.PUBLIC)
map<pubkey_t, uint> get_farmed_block_count(uint since) const;
farmed_block_summary_t get_farmed_block_summary(vector<pubkey_t> farmer_keys, uint since) const;

@Permission(permission_e.PUBLIC)
farmed_block_summary_t get_farmed_block_summary(vector<pubkey_t> farmer_keys, uint since) const;
vector<pair<pubkey_t, uint>> get_farmer_ranking(int limit = -1) const;

void start_sync(bool force);

Expand Down
51 changes: 48 additions & 3 deletions src/Node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,20 @@ void Node::main()
balance_count++;
return true;
});

{
std::map<pubkey_t, uint32_t> farmer_block_count;
farmer_block_map.scan([&farmer_block_count](const pubkey_t& key, const farmed_block_info_t& info) -> bool {
farmer_block_count[key]++;
return true;
});
for(const auto& entry : farmer_block_count) {
farmer_ranking.push_back(entry);
}
update_farmer_ranking();
}
if(height) {
log(INFO) << "Loaded DB at height " << (height - 1) << ", " << balance_count << " balances, " << mmx_address_count << " addresses"
<< ", took " << (vnx::get_wall_time_millis() - time_begin) / 1e3 << " sec";
log(INFO) << "Loaded DB at height " << (height - 1) << ", " << balance_count << " balances, " << mmx_address_count << " addresses, "
<< farmer_ranking.size() << " farmers, took " << (vnx::get_wall_time_millis() - time_begin) / 1e3 << " sec";
}
}
block_chain = std::make_shared<vnx::File>(storage_path + "block_chain.dat");
Expand Down Expand Up @@ -861,6 +871,14 @@ void Node::purge_tree()
}
}

void Node::update_farmer_ranking()
{
std::sort(farmer_ranking.begin(), farmer_ranking.end(),
[](const std::pair<pubkey_t, uint32_t>& L, const std::pair<pubkey_t, uint32_t>& R) -> bool {
return L.second > R.second;
});
}

void Node::commit(std::shared_ptr<const Block> block)
{
if(!history.empty()) {
Expand Down Expand Up @@ -1029,6 +1047,14 @@ void Node::apply( std::shared_ptr<const Block> block,
info.reward = block->reward_amount;
info.reward_addr = (block->reward_addr ? *block->reward_addr : addr_t());
farmer_block_map.insert(proof->farmer_key, info);

for(auto& entry : farmer_ranking) {
if(entry.first == proof->farmer_key) {
entry.second++;
break;
}
}
update_farmer_ranking();
}
hash_index.insert(block->hash, block->height);

Expand Down Expand Up @@ -1140,6 +1166,25 @@ void Node::apply( std::shared_ptr<const Block> block,
void Node::revert(const uint32_t height)
{
const auto time_begin = vnx::get_wall_time_millis();

if(const auto peak = get_peak()) {
// revert farmer_ranking
for(int64_t i = peak->height; i >= int64_t(height); --i) {
if(const auto header = get_header_at(i)) {
if(const auto proof = header->proof) {
for(auto& entry : farmer_ranking) {
if(entry.first == proof->farmer_key) {
if(entry.second) {
entry.second--;
}
break;
}
}
}
}
}
update_farmer_ranking();
}
if(block_chain) {
block_index_t entry;
if(block_index.find(height, entry)) {
Expand Down
33 changes: 18 additions & 15 deletions src/Node_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
#include <mmx/Node_get_swap_equivalent_liquidity.hxx>
#include <mmx/Node_get_swap_liquidity_by.hxx>
#include <mmx/Node_get_farmed_blocks.hxx>
#include <mmx/Node_get_farmed_block_count.hxx>
#include <mmx/Node_get_farmer_ranking.hxx>
#include <mmx/Node_get_farmed_block_summary.hxx>
#include <mmx/Node_validate.hxx>

Expand Down Expand Up @@ -1341,19 +1341,6 @@ std::vector<std::shared_ptr<const BlockHeader>> Node::get_farmed_blocks(
return out;
}

std::map<pubkey_t, uint32_t> Node::get_farmed_block_count(const uint32_t& since) const
{
std::map<pubkey_t, uint32_t> out;
// TODO: optimize somehow
farmer_block_map.scan([&out, since](const pubkey_t& key, const farmed_block_info_t& info) -> bool {
if(info.height >= since) {
out[key]++;
}
return true;
});
return out;
}

farmed_block_summary_t Node::get_farmed_block_summary(const std::vector<pubkey_t>& farmer_keys, const uint32_t& since) const
{
farmed_block_summary_t out;
Expand All @@ -1372,6 +1359,22 @@ farmed_block_summary_t Node::get_farmed_block_summary(const std::vector<pubkey_t
return out;
}

std::vector<std::pair<pubkey_t, uint32_t>> Node::get_farmer_ranking(const int32_t& limit) const
{
if(limit < 0) {
return farmer_ranking;
}
std::vector<std::pair<pubkey_t, uint32_t>> out;
for(const auto& entry : farmer_ranking) {
if(out.size() < size_t(limit)) {
out.push_back(entry);
} else {
break;
}
}
return out;
}

void Node::http_request_async( std::shared_ptr<const vnx::addons::HttpRequest> request, const std::string& sub_path,
const vnx::request_id_t& request_id) const
{
Expand Down Expand Up @@ -1468,7 +1471,7 @@ std::shared_ptr<vnx::Value> Node::vnx_call_switch(std::shared_ptr<const vnx::Val
case Node_get_swap_equivalent_liquidity::VNX_TYPE_ID:
case Node_get_swap_liquidity_by::VNX_TYPE_ID:
case Node_get_farmed_blocks::VNX_TYPE_ID:
case Node_get_farmed_block_count::VNX_TYPE_ID:
case Node_get_farmer_ranking::VNX_TYPE_ID:
case Node_get_farmed_block_summary::VNX_TYPE_ID:
case Node_validate::VNX_TYPE_ID:
api_threads->add_task(std::bind(&Node::async_api_call, this, method, request_id));
Expand Down
23 changes: 6 additions & 17 deletions src/WebAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1559,30 +1559,19 @@ void WebAPI::http_request_async(std::shared_ptr<const vnx::addons::HttpRequest>
}
}
else if(sub_path == "/farmers") {
const auto iter_since = query.find("since");
const auto iter_limit = query.find("limit");
const auto iter_offset = query.find("offset");
uint32_t since = iter_since != query.end() ? vnx::from_string<int64_t>(iter_since->second) : 0;
const uint64_t limit = iter_limit != query.end() ? vnx::from_string<int64_t>(iter_limit->second) : 100;
const uint64_t offset = iter_offset != query.end() ? vnx::from_string<int64_t>(iter_offset->second) : 0;
const uint32_t limit = iter_limit != query.end() ? vnx::from_string<int64_t>(iter_limit->second) : 100;
const uint32_t offset = iter_offset != query.end() ? vnx::from_string<int64_t>(iter_offset->second) : 0;
if(is_public) {
if(offset + limit > 10000 || (offset >> 32) || (limit >> 32)) {
if(offset + limit > 10000 || (offset >> 30) || (limit >> 30)) {
throw std::logic_error("offset + limit > 10000");
}
const auto max_delta = 3153600u;
if(curr_height > max_delta) {
since = std::max(since, curr_height - max_delta);
}
}
node->get_farmed_block_count(since,
[this, request_id, limit, offset](const std::map<pubkey_t, uint32_t>& result) {
std::vector<std::pair<pubkey_t, uint32_t>> data(result.begin(), result.end());
std::sort(data.begin(), data.end(),
[](const std::pair<pubkey_t, uint32_t>& L, std::pair<pubkey_t, uint32_t>& R) -> bool {
return L.second > R.second;
});
node->get_farmer_ranking(offset + limit,
[this, request_id, limit, offset](const std::vector<std::pair<pubkey_t, uint32_t>>& result) {
std::vector<vnx::Object> out;
for(const auto& entry : get_page(data, limit, offset)) {
for(const auto& entry : get_page(result, limit, offset)) {
vnx::Object tmp;
tmp["farmer_key"] = entry.first.to_string();
tmp["block_count"] = entry.second;
Expand Down

0 comments on commit a5c99af

Please sign in to comment.