Skip to content

Commit

Permalink
Merge pull request #955 from AntelopeIO/ship-fork-main
Browse files Browse the repository at this point in the history
[4.0 -> main] SHiP Fix forking behavior
  • Loading branch information
heifner authored Apr 3, 2023
2 parents d382d71 + d51a942 commit d278917
Show file tree
Hide file tree
Showing 6 changed files with 197 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,7 @@ struct session : session_base, std::enable_shared_from_this<session<Plugin, Sock

state_history::get_blocks_result_v0 result;
result.head = {block_state->block_num, block_state->id};
to_send_block_num = std::min(block_state->block_num, to_send_block_num);
send_update(std::move(result), block_state);
}

Expand Down
4 changes: 2 additions & 2 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ set_property(TEST ship_test PROPERTY LABELS nonparallelizable_tests)
add_test(NAME ship_test_unix COMMAND tests/ship_test.py -v --num-clients 10 --num-requests 5000 --clean-run ${UNSHARE} --unix-socket WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
set_property(TEST ship_test_unix PROPERTY LABELS nonparallelizable_tests)

add_test(NAME ship_streamer_test COMMAND tests/ship_streamer_test.py -v --num-clients 10 --num-blocks 50 --clean-run ${UNSHARE} WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
set_property(TEST ship_streamer_test PROPERTY LABELS nonparallelizable_tests)
add_test(NAME ship_streamer_test COMMAND tests/ship_streamer_test.py -v --num-clients 10 --clean-run ${UNSHARE} WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
set_property(TEST ship_streamer_test PROPERTY LABELS long_running_tests)

add_test(NAME p2p_dawn515_test COMMAND tests/p2p_tests/dawn_515/test.sh WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
set_property(TEST p2p_dawn515_test PROPERTY LABELS nonparallelizable_tests)
Expand Down
2 changes: 2 additions & 0 deletions tests/ship_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ int main(int argc, char* argv[]) {
eosio::check(result_doucment[1]["head"].IsObject(), "'head' is not an object");
eosio::check(result_doucment[1]["head"].HasMember("block_num"), "'head' does not contain 'block_num'");
eosio::check(result_doucment[1]["head"]["block_num"].IsUint(), "'head.block_num' isn't a number");
eosio::check(result_doucment[1]["head"].HasMember("block_id"), "'head' does not contain 'block_id'");
eosio::check(result_doucment[1]["head"]["block_id"].IsString(), "'head.block_id' isn't a string");

uint32_t this_block_num = result_doucment[1]["head"]["block_num"].GetUint();

Expand Down
63 changes: 47 additions & 16 deletions tests/ship_streamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,30 +111,61 @@ int main(int argc, char* argv[]) {
stream.write(boost::asio::buffer(request_type.json_to_bin(request_sb.GetString(), [](){})));
stream.read_message_max(0);

// block_num, block_id
std::map<uint32_t, std::string> block_ids;
bool is_first = true;
for(;;) {
boost::beast::flat_buffer buffer;
stream.read(buffer);

eosio::input_stream is((const char*)buffer.data().data(), buffer.data().size());
rapidjson::Document result_doucment;
result_doucment.Parse(result_type.bin_to_json(is).c_str());

eosio::check(!result_doucment.HasParseError(), "Failed to parse result JSON from abieos");
eosio::check(result_doucment.IsArray(), "result should have been an array (variant) but it's not");
eosio::check(result_doucment.Size() == 2, "result was an array but did not contain 2 items like a variant should");
eosio::check(std::string(result_doucment[0].GetString()) == "get_blocks_result_v0", "result type doesn't look like get_blocks_result_v0");
eosio::check(result_doucment[1].IsObject(), "second item in result array is not an object");
eosio::check(result_doucment[1].HasMember("head"), "cannot find 'head' in result");
eosio::check(result_doucment[1]["head"].IsObject(), "'head' is not an object");
eosio::check(result_doucment[1]["head"].HasMember("block_num"), "'head' does not contain 'block_num'");
eosio::check(result_doucment[1]["head"]["block_num"].IsUint(), "'head.block_num' isn't a number");
rapidjson::Document result_document;
result_document.Parse(result_type.bin_to_json(is).c_str());

eosio::check(!result_document.HasParseError(), "Failed to parse result JSON from abieos");
eosio::check(result_document.IsArray(), "result should have been an array (variant) but it's not");
eosio::check(result_document.Size() == 2, "result was an array but did not contain 2 items like a variant should");
eosio::check(std::string(result_document[0].GetString()) == "get_blocks_result_v0", "result type doesn't look like get_blocks_result_v0");
eosio::check(result_document[1].IsObject(), "second item in result array is not an object");
eosio::check(result_document[1].HasMember("head"), "cannot find 'head' in result");
eosio::check(result_document[1]["head"].IsObject(), "'head' is not an object");
eosio::check(result_document[1]["head"].HasMember("block_num"), "'head' does not contain 'block_num'");
eosio::check(result_document[1]["head"]["block_num"].IsUint(), "'head.block_num' isn't a number");
eosio::check(result_document[1]["head"].HasMember("block_id"), "'head' does not contain 'block_id'");
eosio::check(result_document[1]["head"]["block_id"].IsString(), "'head.block_id' isn't a string");

uint32_t this_block_num = 0;
if( result_doucment[1].HasMember("this_block") && result_doucment[1]["this_block"].IsObject() ) {
if( result_doucment[1]["this_block"].HasMember("block_num") && result_doucment[1]["this_block"]["block_num"].IsUint() ) {
this_block_num = result_doucment[1]["this_block"]["block_num"].GetUint();
if( result_document[1].HasMember("this_block") && result_document[1]["this_block"].IsObject() ) {
if( result_document[1]["this_block"].HasMember("block_num") && result_document[1]["this_block"]["block_num"].IsUint() ) {
this_block_num = result_document[1]["this_block"]["block_num"].GetUint();
}
std::string this_block_id;
if( result_document[1]["this_block"].HasMember("block_id") && result_document[1]["this_block"]["block_id"].IsString() ) {
this_block_id = result_document[1]["this_block"]["block_id"].GetString();
}
std::string prev_block_id;
if( result_document[1]["prev_block"].HasMember("block_id") && result_document[1]["prev_block"]["block_id"].IsString() ) {
prev_block_id = result_document[1]["prev_block"]["block_id"].GetString();
}
if( !irreversible_only && !this_block_id.empty() && !prev_block_id.empty() ) {
// verify forks were sent
if (block_ids.count(this_block_num-1)) {
if (block_ids[this_block_num-1] != prev_block_id) {
std::cerr << "Received block: << " << this_block_num << " that does not link to previous: " << block_ids[this_block_num-1] << std::endl;
return 1;
}
}
block_ids[this_block_num] = this_block_id;

if( result_document[1]["last_irreversible"].HasMember("block_num") && result_document[1]["last_irreversible"]["block_num"].IsUint() ) {
uint32_t lib_num = result_document[1]["last_irreversible"]["block_num"].GetUint();
auto i = block_ids.lower_bound(lib_num);
if (i != block_ids.end()) {
block_ids.erase(block_ids.begin(), i);
}
}
}

}

if(is_first) {
Expand All @@ -147,7 +178,7 @@ int main(int argc, char* argv[]) {

rapidjson::StringBuffer result_sb;
rapidjson::PrettyWriter<rapidjson::StringBuffer> result_writer(result_sb);
result_doucment[1].Accept(result_writer);
result_document[1].Accept(result_writer);
std::cout << result_sb.GetString() << std::endl << "}" << std::endl;

if( this_block_num == end_block_num ) break;
Expand Down
Loading

0 comments on commit d278917

Please sign in to comment.