Skip to content

Commit

Permalink
Fix block creation (#28)
Browse files Browse the repository at this point in the history
* Working tests

* eos finality works

* log GrandpaNode

* fix broken add_stop_task logic
  • Loading branch information
justefg committed Apr 18, 2019
1 parent 1308391 commit 1924bd9
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 41 deletions.
3 changes: 3 additions & 0 deletions simulator/include/grandpa.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,19 @@ class GrandpaNode: public Node {
}

void on_receive(uint32_t from, void* msg) override {
cout << "[Node] #" << id << " on_receive " << endl;
auto data = *static_cast<grandpa_net_msg*>(msg);
data.ses_id = from;
in_net_ch->send(data);
}

void on_new_peer_event(uint32_t id) override {
cout << "[Node] #" << id << " on_new_peer_event " << endl;
ev_ch->send(grandpa_event { ::on_new_peer_event { id } });
}

void on_accepted_block_event(block_id_type id) override {
cout << "[Node] #" << id << " on_accepted_block_event " << endl;
ev_ch->send(grandpa_event { ::on_accepted_block_event { id } });
}

Expand Down
74 changes: 41 additions & 33 deletions simulator/include/simulator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ struct Task {
uint32_t at;
function<void(NodePtr)> cb;

bool operator<(const Task& m) const {
return at > m.at;
bool operator<(const Task& task) const {
return at > task.at || (at == task.at && to < task.to);
}
};

Expand Down Expand Up @@ -197,32 +197,20 @@ class TestRunner {
count_dist_matrix();
}

fork_db_chain_type create_blocks(NodePtr node) {
fork_db_chain_type create_block(NodePtr node) {
auto& db = node->db;
stringstream ss;
ss << "[Node] #" << node->id << " ";
auto node_id = ss.str();
cout << node_id << "Generating blocks node_id=" << " at " << clock.now() << endl;
cout << node_id << "Generating block" << " at " << clock.now() << endl;
cout << node_id << "LIB " << db.last_irreversible_block_id() << endl;
auto head = db.get_master_head();
auto head_block_height = fc::endian_reverse_u32(head->block_id._hash[0]);
cout << node_id << "Head block height: " << head_block_height << endl;

cout << node_id << "Building on top of " << head->block_id << endl;
cout << node_id << "New blocks: ";

vector<block_id_type> blocks(blocks_per_slot);
for (int i = 0; i < blocks_per_slot; i++) {
auto block_height = head_block_height + i + 1;
blocks[i] = generate_block(block_height);
cout << blocks[i] << ", ";
}
db.insert(head, blocks);
for (auto& block_id : blocks) {
node->on_accepted_block_event(block_id);
}
cout << endl;
return fork_db_chain_type{head->block_id, blocks};
auto new_block_id = generate_block(head_block_height + 1);
cout << node_id << "New block: " << new_block_id << endl;
return {head->block_id, {new_block_id}};
}

vector<int> get_ordering() {
Expand Down Expand Up @@ -253,29 +241,40 @@ class TestRunner {
add_task(std::move(task));
}

void schedule_producer(uint32_t start_ms, uint32_t producer_id) {
for (int i = 0; i < blocks_per_slot; i++) {
Task task;
task.at = start_ms + i * BLOCK_GEN_MS;
task.to = producer_id;
task.cb = [this](NodePtr node) {
auto block = create_block(node);
node->db.insert(block);
relay_block(node, block);
};
add_task(std::move(task));
}
}

void schedule_producers() {
cout << "[TaskRunner] Scheduling PRODUCERS " << endl;
cout << "[TaskRunner] Ordering: " << "[ " ;
auto ordering = get_ordering();
for (auto x : ordering) {
cout << x << " ";
}
cout << "]" << endl;
auto now = clock.now();
auto instances = get_instances();

for (int i = 0; i < instances; i++) {
int producer_id = ordering[i];
Task task;
task.at = now + i * SLOT_MS;
task.to = producer_id;
task.cb = [&](NodePtr node) {
auto chain = create_blocks(node);
relay_blocks(node, chain);
};
add_task(std::move(task));
schedule_producer(now + i * get_slot_ms(), ordering[i]);
}

schedule_time = now + instances * SLOT_MS;
schedule_time = now + instances * get_slot_ms();
add_schedule_task(schedule_time);
}

void relay_blocks(NodePtr node, const fork_db_chain_type& chain) {
void relay_block(NodePtr node, const fork_db_chain_type& chain) {
uint32_t from = node->id;
for (uint32_t to = 0; to < get_instances(); to++) {
if (from != to && dist_matrix[from][to] != -1) {
Expand All @@ -292,9 +291,13 @@ class TestRunner {
void run() {
init_nodes<TNode>(get_instances());
init_connections();

add_schedule_task(schedule_time);
run_loop();
}

void run_loop() {
cout << "[TaskRunner] " << "Run loop " << endl;
should_stop = false;
while (!should_stop) {
auto task = timeline.top();
cout << "[TaskRunner] " << "current_time=" << task.at << " schedule_time=" << schedule_time << endl;
Expand Down Expand Up @@ -348,11 +351,15 @@ class TestRunner {
return 2 * get_instances() / 3 + 1;
}

uint32_t get_slot_ms() {
return BLOCK_GEN_MS * blocks_per_slot;
}

const block_id_type genesys_block;
const uint32_t RUNNER_ID = 10000000;

static const uint32_t SLOT_MS = 500;
static const uint32_t DELAY_MS = 500;
static const uint32_t BLOCK_GEN_MS = 500;

size_t blocks_per_slot;
bool should_stop = false;
Expand All @@ -369,7 +376,8 @@ class TestRunner {
void init_nodes(uint32_t count) {
nodes.clear();
for (auto i = 0; i < count; ++i) {
auto conf_number = blocks_per_slot * bft_threshold();
// See https://bit.ly/2Wp3Nsf
auto conf_number = 2 * blocks_per_slot * bft_threshold();
auto node = std::make_shared<TNode>(i, Network(i, this), fork_db(genesys_block, conf_number));
nodes.push_back(std::static_pointer_cast<Node>(node));
}
Expand Down
76 changes: 68 additions & 8 deletions simulator/tests/no_byzantine_nodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ TEST(honest_nodes, eos_finality) {
vector<pair<int, int> > v0{{1, 2}, {2, 10}};
graph_type g{v0};
runner.load_graph(g);
runner.add_stop_task(4 * TestRunner::SLOT_MS);
runner.add_stop_task(7 * runner.get_slot_ms());
runner.run<Node>();
EXPECT_EQ(get_block_height(runner.get_db(0).last_irreversible_block_id()), 1);
EXPECT_EQ(get_block_height(runner.get_db(1).last_irreversible_block_id()), 1);
Expand All @@ -27,25 +27,85 @@ TEST(honest_nodes, eos_finality) {

TEST(honest_nodes, eos_master_chain_height) {
auto runner = TestRunner(3);
vector<pair<int, int> > v0{{1, 2}, {2, TestRunner::SLOT_MS}};
vector<pair<int, int> > v0{{1, 2}, {2, runner.get_slot_ms()}};
graph_type g{v0};
runner.load_graph(g);
runner.add_stop_task(TestRunner::SLOT_MS);
runner.add_stop_task(runner.get_slot_ms());
runner.run<Node>();
EXPECT_EQ(get_block_height(runner.get_db(0).get_master_block_id()), 1);
EXPECT_EQ(get_block_height(runner.get_db(1).get_master_block_id()), 1);
EXPECT_EQ(get_block_height(runner.get_db(2).get_master_block_id()), 0);
}

TEST(honest_nodes, eos_finality_multiple_blocks) {
auto runner = TestRunner(3, 2);
vector<pair<int, int> > v0{{1, 2}, {2, 10}};
graph_type g{v0};
runner.load_graph(g);
runner.add_stop_task(7 * runner.get_slot_ms());
runner.run<Node>();
EXPECT_EQ(get_block_height(runner.get_db(0).last_irreversible_block_id()), 2);
EXPECT_EQ(get_block_height(runner.get_db(1).last_irreversible_block_id()), 2);
EXPECT_EQ(get_block_height(runner.get_db(2).last_irreversible_block_id()), 2);

auto master = runner.get_db(0).get_master_head();
EXPECT_EQ(get_block_height(master->block_id), 14);
runner.add_stop_task(13 * runner.get_slot_ms());
runner.run_loop();
}

TEST(honest_nodes, grandpa_finality) {
auto runner = TestRunner(3);
vector<pair<int, int> > v0{{1, 2}, {2, 10}};
graph_type g;
g.push_back(v0);
runner.load_graph(g);
runner.add_stop_task(3 * TestRunner::SLOT_MS);
runner.add_stop_task(1 * runner.get_slot_ms());
runner.run<GrandpaNode>();
EXPECT_EQ(get_block_height(runner.get_db(0).last_irreversible_block_id()), 3);
EXPECT_EQ(get_block_height(runner.get_db(1).last_irreversible_block_id()), 3);
EXPECT_EQ(get_block_height(runner.get_db(2).last_irreversible_block_id()), 3);
}
EXPECT_EQ(get_block_height(runner.get_db(0).last_irreversible_block_id()), 1);
EXPECT_EQ(get_block_height(runner.get_db(1).last_irreversible_block_id()), 1);
EXPECT_EQ(get_block_height(runner.get_db(2).last_irreversible_block_id()), 1);
}

TEST(honest_nodes, eos_finality_many_nodes) {
size_t nodes_amount = 21;
auto runner = TestRunner(nodes_amount);
vector<pair<int, int> > v0{{1, 20}, {2, 10}, {3, 50}, {4, 30}, {5, 100}};
vector<pair<int, int> > v5{{6, 10}, {7, 30}, {8, 20}, {9, 10}, {10, 100}};
vector<pair<int, int> > v10{{11, 10}, {12, 10}, {13, 10}, {14, 10}, {15, 100}};
vector<pair<int, int> > v15{{16, 10}, {17, 10}, {18, 10}, {19, 10}, {20, 10}};
graph_type g(nodes_amount);
g[0] = v0;
g[5] = v5;
g[10] = v10;
g[15] = v15;
runner.load_graph(g);
runner.add_stop_task(31 * runner.get_slot_ms());
runner.run<Node>();
EXPECT_EQ(get_block_height(runner.get_db(0).last_irreversible_block_id()), 1);
EXPECT_EQ(get_block_height(runner.get_db(5).last_irreversible_block_id()), 1);
EXPECT_EQ(get_block_height(runner.get_db(10).last_irreversible_block_id()), 1);
EXPECT_EQ(get_block_height(runner.get_db(15).last_irreversible_block_id()), 1);
}
//
//TEST(honest_nodes, grandpa_finality_many_nodes) {
// size_t nodes_amount = 21;
// auto runner = TestRunner(nodes_amount);
// vector<pair<int, int> > v0{{1, 20}, {2, 10}, {3, 50}, {4, 30}, {5, 100}};
// vector<pair<int, int> > v5{{6, 10}, {7, 30}, {8, 20}, {9, 10}, {10, 100}};
// vector<pair<int, int> > v10{{11, 10}, {12, 10}, {13, 10}, {14, 10}, {15, 100}};
// vector<pair<int, int> > v15{{16, 10}, {17, 10}, {18, 10}, {19, 10}, {20, 10}};
// graph_type g(nodes_amount);
// g[0] = v0;
// g[5] = v5;
// g[10] = v10;
// g[15] = v15;
// runner.load_graph(g);
// runner.add_stop_task(16 * TestRunner::SLOT_MS);
// runner.run<GrandpaNode>();
//// cout << get_block_height(runner.get_db(0).last_irreversible_block_id()) << endl;
// EXPECT_EQ(get_block_height(runner.get_db(0).last_irreversible_block_id()), 16);
// EXPECT_EQ(get_block_height(runner.get_db(5).last_irreversible_block_id()), 16);
// EXPECT_EQ(get_block_height(runner.get_db(10).last_irreversible_block_id()), 16);
// EXPECT_EQ(get_block_height(runner.get_db(15).last_irreversible_block_id()), 16);
//}

0 comments on commit 1924bd9

Please sign in to comment.