Skip to content

Commit

Permalink
Add end-to-end integration test for 3PC EVM runner
Browse files Browse the repository at this point in the history
Signed-off-by: Alexander Jung <[email protected]>
  • Loading branch information
AlexRamRam committed May 1, 2023
1 parent 2835c32 commit e13f056
Show file tree
Hide file tree
Showing 9 changed files with 1,269 additions and 8 deletions.
8 changes: 4 additions & 4 deletions src/3pc/agent/runners/evm/http_server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
#ifndef CBDC_UNIVERSE0_SRC_3PC_AGENT_HTTP_SERVER_H_
#define CBDC_UNIVERSE0_SRC_3PC_AGENT_HTTP_SERVER_H_

#include "3pc/agent/impl.hpp"
#include "3pc/agent/runners/evm/impl.hpp"
#include "agent/impl.hpp"
#include "agent/server_interface.hpp"
#include "broker/interface.hpp"
#include "directory/interface.hpp"
#include "3pc/agent/server_interface.hpp"
#include "3pc/broker/interface.hpp"
#include "3pc/directory/interface.hpp"
#include "messages.hpp"
#include "util/common/blocking_queue.hpp"
#include "util/common/thread_pool.hpp"
Expand Down
6 changes: 3 additions & 3 deletions src/3pc/agent/server_interface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
#ifndef CBDC_UNIVERSE0_SRC_3PC_AGENT_SERVER_INTERFACE_H_
#define CBDC_UNIVERSE0_SRC_3PC_AGENT_SERVER_INTERFACE_H_

#include "agent/impl.hpp"
#include "broker/interface.hpp"
#include "directory/interface.hpp"
#include "3pc/agent/impl.hpp"
#include "3pc/broker/interface.hpp"
#include "3pc/directory/interface.hpp"
#include "interface.hpp"
#include "messages.hpp"
#include "util/common/blocking_queue.hpp"
Expand Down
4 changes: 3 additions & 1 deletion src/util/rpc/http/json_rpc_http_client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ namespace cbdc::rpc {
std::vector<std::string> m_endpoints;
long m_timeout;
std::unique_ptr<event_handler> m_ev_handler;
std::shared_ptr<cbdc::logging::log> m_log;

Json::StreamWriterBuilder m_builder;

Expand Down Expand Up @@ -109,6 +108,9 @@ namespace cbdc::rpc {
static auto timer_callback(CURLM* multi_handle,
long timeout_ms,
json_rpc_http_client* c) -> int;

protected:
std::shared_ptr<cbdc::logging::log> m_log;
};
}

Expand Down
14 changes: 14 additions & 0 deletions tests/integration/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ project(integration)
add_executable(run_integration_tests mock_system.cpp
atomizer_raft_integration_test.cpp
atomizer_end_to_end_test.cpp
gtest_evm_jsonrpc_client.cpp
sample_erc20_contract.cpp
sentinel_integration_test.cpp
sentinel_2pc_integration_test.cpp
shard_integration_test.cpp
replicated_shard_integration_tests.cpp
replicated_atomizer_integration_tests.cpp
threepc_evm_end_to_end_test.cpp
two_phase_end_to_end_test.cpp
watchtower_integration_test.cpp)

Expand All @@ -27,6 +30,14 @@ target_link_libraries(run_integration_tests ${GTEST_LIBRARY}
watchtower
coordinator
locking_shard
evm_runner
ticket_machine
runtime_locking_shard
runners
agent
broker
directory
json_rpc_http
raft
rpc
transaction
Expand All @@ -37,4 +48,7 @@ target_link_libraries(run_integration_tests ${GTEST_LIBRARY}
secp256k1
${LEVELDB_LIBRARY}
${NURAFT_LIBRARY}
${JSON_LIBRARY}
${CURL_LIBRARY}
${MHD_LIBRARY}
${CMAKE_THREAD_LIBS_INIT})
183 changes: 183 additions & 0 deletions tests/integration/gtest_evm_jsonrpc_client.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
// Copyright (c) 2023 MIT Digital Currency Initiative,
//
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "gtest_evm_jsonrpc_client.hpp"

#include "3pc/agent/runners/evm/address.hpp"
#include "3pc/agent/runners/evm/rlp.hpp"
#include "3pc/agent/runners/evm/serialization.hpp"
#include "3pc/agent/runners/evm/util.hpp"

#include <gtest/gtest.h>
#include <thread>

namespace cbdc::test {
static std::string gtest_descr() {
// e.g.: "GTEST: threepc_evm_end_to_end_test.native_transfer"
return std::string("GTEST: ")
+ ::testing::UnitTest::GetInstance()
->current_test_info()
->test_suite_name()
+ "."
+ ::testing::UnitTest::GetInstance()->current_test_info()->name();
}

gtest_evm_jsonrpc_client::gtest_evm_jsonrpc_client(
std::vector<std::string> endpoints,
long timeout,
std::shared_ptr<cbdc::logging::log> log)
: cbdc::rpc::json_rpc_http_client(std::move(endpoints),
timeout,
std::move(log)) {}

evmc::uint256be gtest_evm_jsonrpc_client::get_transaction_count(
const evmc::address& addr) {
std::string txcount_str;
get_transaction_count_str_(addr, txcount_str);
m_log->debug(gtest_descr(),
std::string(__FUNCTION__) + "()",
"0x" + cbdc::threepc::agent::runner::to_hex(addr),
txcount_str);
return cbdc::threepc::agent::runner::uint256be_from_hex(txcount_str)
.value();
}

void gtest_evm_jsonrpc_client::get_transaction_count_str_(
const evmc::address& addr,
std::string& out_txcount_str) {
auto params = Json::Value();
params.append("0x" + cbdc::threepc::agent::runner::to_hex(addr));
params.append("latest");

std::atomic<bool> tx_done{false};
call("eth_getTransactionCount",
std::move(params),
[&tx_done, &out_txcount_str](std::optional<Json::Value> res) {
ASSERT_TRUE(res.has_value());
const auto& v = res.value();
ASSERT_FALSE(v.isMember(m_json_error_key));
ASSERT_TRUE(v.isMember(m_json_result_key));
out_txcount_str = v[m_json_result_key].asString();
ASSERT_TRUE(out_txcount_str.length() > 0);

tx_done = true;
});

for(int cnt = 0; cnt < 20 && !tx_done; ++cnt) {
ASSERT_TRUE(pump());
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
ASSERT_TRUE(tx_done);
}

void gtest_evm_jsonrpc_client::send_transaction(
const cbdc::threepc::agent::runner::evm_tx& etx,
std::string& out_txid) {
const auto rlp_tx_buf = cbdc::threepc::agent::runner::tx_encode(etx);
const auto rlp_tx_hex = "0x" + rlp_tx_buf.to_hex();

auto params = Json::Value();
params.append(rlp_tx_hex);

std::atomic<bool> tx_done{false};
std::string txid{};
call("eth_sendRawTransaction",
std::move(params),
[&tx_done, &out_txid](std::optional<Json::Value> res) {
ASSERT_TRUE(res.has_value());
const auto& v = res.value();
ASSERT_FALSE(v.isMember(m_json_error_key));
ASSERT_TRUE(v.isMember(m_json_result_key));

ASSERT_TRUE(v.size() == 3);
ASSERT_TRUE(v.isMember("id"));
ASSERT_TRUE(v["id"].isInt());
ASSERT_TRUE(v.isMember("jsonrpc"));
ASSERT_TRUE(v["jsonrpc"].isString()); // e.g. "2.0"

ASSERT_TRUE(v[m_json_result_key].isString());
out_txid = v[m_json_result_key].asString();
ASSERT_TRUE(out_txid.length() > 0);

tx_done = true;
});

for(int cnt = 0; cnt < 20 && !tx_done; ++cnt) {
ASSERT_TRUE(pump());
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
ASSERT_TRUE(tx_done);
}

void gtest_evm_jsonrpc_client::get_transaction_receipt(
const std::string& txid,
Json::Value& out_tx_receipt,
std::shared_ptr<cbdc::logging::log> log) {
auto params = Json::Value();
params.append(txid);

std::atomic<bool> tx_done{false};
call("eth_getTransactionReceipt",
std::move(params),
[&out_tx_receipt, &tx_done, log](std::optional<Json::Value> res) {
ASSERT_TRUE(res.has_value());
auto& v = res.value();
ASSERT_FALSE(v.isMember(m_json_error_key));
ASSERT_TRUE(v.isMember(m_json_result_key));

out_tx_receipt = v[m_json_result_key];
ASSERT_TRUE(out_tx_receipt.isObject());

for(auto const& id : out_tx_receipt.getMemberNames()) {
log->debug(
"gtest_evm_jsonrpc_client::get_transaction_receipt() "
"json::value member:",
id,
out_tx_receipt[id].type(),
out_tx_receipt[id]);
}

tx_done = true;
});

for(int cnt = 0; cnt < 20 && !tx_done; ++cnt) {
ASSERT_TRUE(pump());
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
ASSERT_TRUE(tx_done);
}

void gtest_evm_jsonrpc_client::get_balance(
const evmc::address& addr,
std::optional<evmc::uint256be>& out_balance) {
auto params = Json::Value();
params.append("0x" + cbdc::threepc::agent::runner::to_hex(addr));

std::atomic<bool> tx_done{false};
call("eth_getBalance",
std::move(params),
[&tx_done, &out_balance](std::optional<Json::Value> res) {
ASSERT_TRUE(res.has_value());
const auto& v = res.value();
ASSERT_FALSE(v.isMember(m_json_error_key));
ASSERT_TRUE(v.isMember(m_json_result_key));

auto res_str = v[m_json_result_key].asString();
out_balance
= cbdc::threepc::agent::runner::uint256be_from_hex(
res_str);

tx_done = true;
});

for(int cnt = 0; cnt < 20 && !tx_done; ++cnt) {
ASSERT_TRUE(pump());
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}

ASSERT_TRUE(tx_done);
ASSERT_TRUE(out_balance.has_value());
}
}
43 changes: 43 additions & 0 deletions tests/integration/gtest_evm_jsonrpc_client.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (c) 2023 MIT Digital Currency Initiative,
//
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef OPENCBDC_TEST_INTEGRATION_GTEST_EVM_JSONRPC_CLIENT_H_
#define OPENCBDC_TEST_INTEGRATION_GTEST_EVM_JSONRPC_CLIENT_H_

#include "3pc/agent/runners/evm/messages.hpp"
#include "util/rpc/http/json_rpc_http_client.hpp"

namespace cbdc::test {

class gtest_evm_jsonrpc_client : public cbdc::rpc::json_rpc_http_client {
public:
gtest_evm_jsonrpc_client(std::vector<std::string> endpoints,
long timeout,
std::shared_ptr<cbdc::logging::log> log);

void send_transaction(const cbdc::threepc::agent::runner::evm_tx& tx,
std::string& out_txid);

void get_transaction_receipt(const std::string& txid,
Json::Value& out_tx_receipt,
std::shared_ptr<cbdc::logging::log> log);

void get_balance(const evmc::address& addr,
std::optional<evmc::uint256be>& out_balance);

[[nodiscard]] evmc::uint256be
get_transaction_count(const evmc::address& addr);

private:
static constexpr auto m_json_error_key = "error";
static constexpr auto m_json_result_key = "result";

void get_transaction_count_str_(const evmc::address& addr,
std::string& out_txcount_str);
};

}

#endif // OPENCBDC_TEST_INTEGRATION_GTEST_EVM_JSONRPC_CLIENT_H_
Loading

0 comments on commit e13f056

Please sign in to comment.