Drop integration test code.

This code is bitrotting, doesn't compile, and isn't being maintained
anymore.

The integration test suite was an interesting idea, in early Loki days,
but is no longer being maintained and is quite cumbersome to run (for
instance, it is not possible to run it via CI because it depends on
xterm to actually run).  The code to actually run it (in doy-lee's
loki-integration-testing repository) is also a large burden of "janky"
code that isn't worth maintaining.

Remove this from the code; if someone wants to pick it back up in the
future reverting this commit shouldn't be too difficult (though I'd
suggest that a much better approach to integration testing would be to
run different daemons/wallets via rpc commands, as the network-tests do,
rather than trying to feed stdin and parse stdout from running
individual oxends/wallets).
This commit is contained in:
Jason Rhinelander 2021-08-19 16:38:06 -03:00
parent c81cf6fd3b
commit 5f1bd2f1e4
23 changed files with 17 additions and 621 deletions

View File

@ -845,23 +845,19 @@ if (WIN32)
target_link_libraries(extra INTERFACE setupapi)
endif()
if (BUILD_INTEGRATION)
target_compile_definitions(extra INTERFACE OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
else()
option(USE_READLINE "Build with GNU readline support." ON)
if(USE_READLINE AND BUILD_STATIC_DEPS)
# readline target already set up
elseif(USE_READLINE)
find_package(Readline)
if(READLINE_FOUND AND GNU_READLINE_FOUND)
add_library(readline INTERFACE)
target_link_libraries(readline INTERFACE ${GNU_READLINE_LIBRARY})
target_include_directories(readline INTERFACE ${Readline_INCLUDE_DIR})
target_compile_definitions(readline INTERFACE HAVE_READLINE)
message(STATUS "Found readline library at: ${GNU_READLINE_LIBRARY}")
else()
message(STATUS "Could not find GNU readline library so building without readline support")
endif()
option(USE_READLINE "Build with GNU readline support." ON)
if(USE_READLINE AND BUILD_STATIC_DEPS)
# readline target already set up
elseif(USE_READLINE)
find_package(Readline)
if(READLINE_FOUND AND GNU_READLINE_FOUND)
add_library(readline INTERFACE)
target_link_libraries(readline INTERFACE ${GNU_READLINE_LIBRARY})
target_include_directories(readline INTERFACE ${Readline_INCLUDE_DIR})
target_compile_definitions(readline INTERFACE HAVE_READLINE)
message(STATUS "Found readline library at: ${GNU_READLINE_LIBRARY}")
else()
message(STATUS "Could not find GNU readline library so building without readline support")
endif()
endif()

View File

@ -60,10 +60,6 @@ debug-test:
mkdir -p $(builddir)/debug
cd $(builddir)/debug && cmake -D BUILD_TESTS=ON -D CMAKE_BUILD_TYPE=Debug $(topdir) && $(MAKE) && $(MAKE) ARGS="-E libwallet_api_tests" test
integration:
mkdir -p $(builddir)/integration
cd $(builddir)/integration && cmake -D CMAKE_BUILD_TYPE=Debug -D BUILD_INTEGRATION=ON $(topdir) && $(MAKE)
debug-test-asan:
mkdir -p $(builddir)/debug
cd $(builddir)/debug && cmake -D BUILD_TESTS=ON -D SANITIZE=ON -D CMAKE_BUILD_TYPE=Debug $(topdir) && $(MAKE) && $(MAKE) ARGS="-E libwallet_api_tests" test

View File

@ -71,10 +71,8 @@ add_subdirectory(daemonizer)
add_subdirectory(daemon)
add_subdirectory(simplewallet)
if (NOT BUILD_INTEGRATION)
add_subdirectory(gen_multisig)
add_subdirectory(blockchain_utilities)
endif()
add_subdirectory(gen_multisig)
add_subdirectory(blockchain_utilities)
# We'll always add, but with EXCLUDE_FROM_ALL if you didn't ask for them (but this lets you do a
# `make cn_deserialize` or whatever from a build dir without needing to reconfigure).

View File

@ -39,7 +39,6 @@
#include "blockchain_db/blockchain_db.h"
#include "cryptonote_basic/cryptonote_format_utils.h"
#include "common/oxen_integration_test_hooks.h"
#include "common/oxen.h"
#include "common/file.h"
#include "common/hex.h"
@ -309,7 +308,6 @@ namespace cryptonote
if (db->is_read_only())
return true;
#if !defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
if (nettype == MAINNET)
{
for (size_t i = 0; i < oxen::array_count(HARDCODED_MAINNET_CHECKPOINTS); ++i)
@ -318,7 +316,6 @@ namespace cryptonote
ADD_CHECKPOINT(checkpoint.height, checkpoint.hash);
}
}
#endif
return true;
}

View File

@ -1,229 +0,0 @@
#if defined(LOKI_ENABLE_INTEGRATION_TEST_HOOKS)
#if defined _WIN32
#error "Not implemented"
#endif
#ifndef LOKI_INTEGRATION_TEST_HOOKS_H
#define LOKI_INTEGRATION_TEST_HOOKS_H
//
// Header
//
#include <mutex>
#include <vector>
#include "command_line.h"
namespace integration_test
{
void init (std::string const &base_name);
void deinit ();
std::string read_from_pipe ();
void write_buffered_stdout();
void use_standard_cout ();
void use_redirected_cout ();
std::vector<std::string> space_delimit_input (std::string const &input);
extern const command_line::arg_descriptor<std::string, false> arg_hardforks_override;
extern const command_line::arg_descriptor<std::string, false> arg_pipe_name;
extern struct state_t
{
std::mutex mutex;
bool core_is_idle;
bool disable_checkpoint_quorum;
bool disable_obligation_quorum;
bool disable_obligation_uptime_proof;
bool disable_obligation_checkpointing;
} state;
}; // integration_test
#endif // LOKI_INTEGRATION_TEST_HOOKS_H
// -------------------------------------------------------------------------------------------------
//
// CPP Implementation
//
// -------------------------------------------------------------------------------------------------
#ifdef LOKI_INTEGRATION_TEST_HOOKS_IMPLEMENTATION
#include <string.h>
#include <assert.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <iostream>
namespace integration_test
{
const command_line::arg_descriptor<std::string, false> arg_hardforks_override = {
"integration-test-hardforks-override"
, "Specify custom hardfork heights and launch in regtest mode"
, ""
, false
};
const command_line::arg_descriptor<std::string, false> arg_pipe_name = {
"integration-test-pipe-name"
, "Specify the pipe name for stdin and stdout"
, "oxen-default-pipe-name"
, false
};
state_t state;
}; // namespace integration_test
struct ipc_pipe
{
int fd;
std::string file;
};
ipc_pipe read_pipe;
ipc_pipe write_pipe;
uint32_t const MSG_PACKET_MAGIC = 0x27befd93;
struct msg_packet
{
uint32_t magic = MSG_PACKET_MAGIC;
char buf[1024];
int len;
bool has_more;
};
static std::ostringstream global_redirected_cout;
static std::streambuf *global_std_cout;
void integration_test::use_standard_cout() { if (!global_std_cout) { global_std_cout = std::cout.rdbuf(); } std::cout.rdbuf(global_std_cout); }
void integration_test::use_redirected_cout() { if (!global_std_cout) { global_std_cout = std::cout.rdbuf(); } std::cout.rdbuf(global_redirected_cout.rdbuf()); }
void integration_test::init(const std::string &base_name)
{
read_pipe.file = base_name + "_stdin";
write_pipe.file = base_name + "_stdout";
read_pipe.fd = open(read_pipe.file.c_str(), O_RDONLY);
if (read_pipe.fd == -1)
{
perror("Failed to open read pipe");
assert(false);
}
else
{
fprintf(stdout, "---------- Opened read pipe: %.*s\n", (int)read_pipe.file.size(), read_pipe.file.c_str());
fprintf(stdout, "---------- Opened write pipe: %.*s\n", (int)write_pipe.file.size(), write_pipe.file.c_str());
}
}
void integration_test::deinit()
{
close(read_pipe.fd);
close(write_pipe.fd);
}
std::vector<std::string> integration_test::space_delimit_input(std::string const &input)
{
std::vector<std::string> args;
std::string::const_iterator start = input.begin();
for (auto it = input.begin(); it != input.end(); it++)
{
if (*it == ' ')
{
std::string result(start, it);
start = (it + 1);
args.push_back(result);
}
}
if (start != input.end())
{
std::string last(start, input.end());
args.push_back(last);
}
return args;
}
std::string integration_test::read_from_pipe()
{
std::unique_lock<std::mutex> scoped_lock(integration_test::state.mutex);
std::string result;
for (;;)
{
msg_packet packet = {};
int bytes_read = read(read_pipe.fd, reinterpret_cast<void *>(&packet), sizeof(packet));
if (bytes_read == -1)
{
perror("Error returned from read(...)");
return result;
}
if (bytes_read < static_cast<int>(sizeof(packet)))
{
fprintf(stderr, "Error reading packet from pipe expected=%zu, read=%d, possible that the pipe was cut mid-transmission\n", sizeof(packet), bytes_read);
return result;
}
if (packet.magic != MSG_PACKET_MAGIC)
{
fprintf(stderr, "Packet magic value=%x, does not match expected=%x\n", packet.magic, MSG_PACKET_MAGIC);
exit(-1);
}
fprintf(stdout, "---------- Read packet, len=%d msg=\"%.*s\"\n", packet.len, packet.len, packet.buf);
result.append(packet.buf, packet.len);
if (!packet.has_more) break;
}
return result;
}
static char const *make_msg_packet(char const *src, int *len, msg_packet *dest)
{
*dest = {};
int const max_size = static_cast<int>(sizeof(dest->buf));
int const bytes_to_copy = (*len > max_size) ? max_size : *len;
memcpy(dest->buf, src, bytes_to_copy);
dest->len = bytes_to_copy;
*len -= bytes_to_copy;
char const *result = (*len == 0) ? nullptr : src + bytes_to_copy;
dest->has_more = result != nullptr;
return result;
}
void integration_test::write_buffered_stdout()
{
std::unique_lock<std::mutex> scoped_lock(integration_test::state.mutex);
global_redirected_cout.flush();
std::string output = global_redirected_cout.str();
global_redirected_cout.str("");
global_redirected_cout.clear();
if (write_pipe.fd == 0)
{
write_pipe.fd = open(write_pipe.file.c_str(), O_WRONLY);
if (write_pipe.fd == -1)
{
perror("Failed to open write pipe");
assert(false);
}
}
char const *src = output.c_str();
int src_len = static_cast<int>(output.size());
while (src_len > 0)
{
msg_packet packet = {};
src = make_msg_packet(src, &src_len, &packet);
int num_bytes_written = write(write_pipe.fd, static_cast<void *>(&packet), sizeof(packet));
if (num_bytes_written == -1)
perror("Error returned from write(...)");
}
use_standard_cout();
std::cout << output << std::endl;
use_redirected_cout();
}
#endif // LOKI_INTEGRATION_TEST_HOOKS_IMPLEMENTATION
#endif // LOKI_ENABLE_INTEGRATION_TEST_HOOKS

View File

@ -45,8 +45,6 @@
#define EOT 0x4
#include "common/oxen_integration_test_hooks.h"
namespace
{
#if defined(_WIN32)
@ -115,7 +113,6 @@ namespace
#else // end WIN32
#if !defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
bool is_cin_tty() noexcept
{
return 0 != isatty(fileno(stdin));
@ -177,11 +174,9 @@ namespace
return true;
}
#endif // !defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
#endif // end !WIN32
#if !defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
bool read_from_tty(const bool verify, const char *message, bool hide_input, epee::wipeable_string& pass1, epee::wipeable_string& pass2)
{
while (true)
@ -233,7 +228,6 @@ namespace
}
return true;
}
#endif // !defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
} // anonymous namespace
@ -250,9 +244,6 @@ namespace tools
std::optional<password_container> password_container::prompt(const bool verify, const char *message, bool hide_input)
{
#if defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
return password_container(std::string(""));
#else
is_prompting = true;
password_container pass1{};
password_container pass2{};
@ -264,7 +255,6 @@ namespace tools
is_prompting = false;
return std::nullopt;
#endif
}
std::optional<login> login::parse(std::string&& userpass, bool verify, const std::function<std::optional<password_container>(bool)> &prompt)

View File

@ -1,26 +1,11 @@
#include "scoped_message_writer.h"
#define OXEN_INTEGRATION_TEST_HOOKS_IMPLEMENTATION
#include "common/oxen_integration_test_hooks.h"
// NOTE(oxen): This file only exists because I need a way to hook into the
// message writer for integration tests. Originally this was a header only file,
// which means it needs to know the implementation of
// oxen_integration_test_hooks.h functions which isn't possible to expose in
// just the header because of the One Definition Rule.
// - doyle 2018-11-08
tools::scoped_message_writer::~scoped_message_writer()
{
if (m_flush)
{
m_flush = false;
#if defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
std::cout << m_oss.str() << "\n";
return;
#endif
MCLOG_FILE(m_log_level, "msgwriter", m_oss.str());
if (epee::console_color_default == m_color)
{

View File

@ -32,8 +32,6 @@
#include "epee/readline_suspend.h"
#include <iostream>
#include "common/oxen_integration_test_hooks.h"
namespace tools
{
@ -60,9 +58,6 @@ public:
, m_bright(bright)
, m_log_level(log_level)
{
#if defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
m_color = epee::console_color_default; // NOTE(oxen): No ANSI color codes in the output. Makes parsing harder.
#endif
m_oss << prefix;
}

View File

@ -429,17 +429,7 @@ bool Blockchain::init(BlockchainDB* db, sqlite3 *ons_db, const network_type nett
m_db = db;
#if defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
// NOTE(doyle): Passing in test options in integration mode means we're
// overriding fork heights for any nettype in our integration tests using
// a command line argument. So m_nettype should just be nettype. In
// non-integration test mode passing in test options means you started the
// daemon with --regtest OR you're running core_tests. So don't run core tests
// in integration mode or --regtest
m_nettype = nettype;
#else
m_nettype = test_options != NULL ? FAKECHAIN : nettype;
#endif
if (!m_checkpoints.init(m_nettype, m_db))
throw std::runtime_error("Failed to initialize checkpoints");
@ -447,7 +437,7 @@ bool Blockchain::init(BlockchainDB* db, sqlite3 *ons_db, const network_type nett
m_offline = offline;
m_fixed_difficulty = fixed_difficulty;
if (test_options) // Fakechain mode or in integration testing mode we're overriding hardfork heights
if (test_options) // Fakechain mode
fakechain_hardforks = test_options->hard_forks;
// if the blockchain is new, add the genesis block

View File

@ -73,8 +73,6 @@ extern "C" {
#include "common/i18n.h"
#include "epee/net/local_ip.h"
#include "common/oxen_integration_test_hooks.h"
#undef OXEN_DEFAULT_LOG_CATEGORY
#define OXEN_DEFAULT_LOG_CATEGORY "cn"
@ -359,10 +357,6 @@ namespace cryptonote
command_line::add_arg(desc, arg_keep_alt_blocks);
command_line::add_arg(desc, arg_store_quorum_history);
#if defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
command_line::add_arg(desc, integration_test::arg_hardforks_override);
command_line::add_arg(desc, integration_test::arg_pipe_name);
#endif
command_line::add_arg(desc, arg_omq_quorumnet_public);
miner::init_options(desc);
@ -566,40 +560,6 @@ namespace cryptonote
{
start_time = std::time(nullptr);
#if defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
const std::string arg_hardforks_override = command_line::get_arg(vm, integration_test::arg_hardforks_override);
std::vector<std::pair<uint8_t, uint64_t>> integration_test_hardforks;
if (!arg_hardforks_override.empty())
{
// Expected format: <fork_version>:<fork_height>, ...
// Example: 7:0, 8:10, 9:20, 10:100
char const *ptr = arg_hardforks_override.c_str();
while (ptr[0])
{
int hf_version = atoi(ptr);
while(ptr[0] != ':') ptr++;
++ptr;
int hf_height = atoi(ptr);
while(ptr[0] && ptr[0] != ',') ptr++;
integration_test_hardforks.push_back(std::make_pair(static_cast<uint8_t>(hf_version), static_cast<uint64_t>(hf_height)));
if (!ptr[0]) break;
ptr++;
}
}
cryptonote::test_options integration_hardfork_override = {integration_test_hardforks};
if (!arg_hardforks_override.empty())
test_options = &integration_hardfork_override;
{
const std::string arg_pipe_name = command_line::get_arg(vm, integration_test::arg_pipe_name);
integration_test::init(arg_pipe_name);
}
#endif
const bool regtest = command_line::get_arg(vm, arg_regtest_on);
if (test_options != NULL || regtest)
{
@ -659,7 +619,6 @@ namespace cryptonote
bool sync_on_blocks = true;
uint64_t sync_threshold = 1;
#if !defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS) // In integration mode, don't delete the DB. This should be explicitly done in the tests. Otherwise the more likely behaviour is persisting the DB across multiple daemons in the same test.
if (m_nettype == FAKECHAIN && !keep_fakechain)
{
// reset the db by removing the database file before opening it
@ -670,7 +629,6 @@ namespace cryptonote
}
fs::remove(ons_db_file_path);
}
#endif
try
{
@ -2405,10 +2363,6 @@ namespace cryptonote
m_miner.on_idle();
m_mempool.on_idle();
#if defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
integration_test::state.core_is_idle = true;
#endif
#ifdef ENABLE_SYSTEMD
m_systemd_notify_interval.do_call([this] { sd_notify(0, ("WATCHDOG=1\nSTATUS=" + get_status_string()).c_str()); });
#endif
@ -2467,11 +2421,6 @@ namespace cryptonote
return true;
}
#if defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
MDEBUG("Not checking block rate, integration test mode");
return true;
#endif
static constexpr double threshold = 1. / ((24h * 10) / TARGET_BLOCK_TIME); // one false positive every 10 days
static constexpr unsigned int max_blocks_checked = 150;

View File

@ -57,7 +57,6 @@
PUSH_WARNINGS
DISABLE_VS_WARNINGS(4355)
#include "common/oxen_integration_test_hooks.h"
namespace cryptonote
{
struct test_options {

View File

@ -1094,10 +1094,6 @@ namespace cryptonote
const blobdata bd = get_block_hashing_blob(b);
const uint8_t hf_version = b.major_version;
#if defined(OXEN_INTEGRATION_TESTS)
miners = 0;
#endif
crypto::cn_slow_hash_type cn_type = cn_slow_hash_type::heavy_v1;
if (nettype == FAKECHAIN)
{

View File

@ -39,8 +39,6 @@
#include "epee/net/local_ip.h"
#include <boost/endian/conversion.hpp>
#include "common/oxen_integration_test_hooks.h"
#undef OXEN_DEFAULT_LOG_CATEGORY
#define OXEN_DEFAULT_LOG_CATEGORY "quorum_cop"
@ -111,11 +109,6 @@ namespace service_nodes
bool check_uptime_obligation = true;
bool check_checkpoint_obligation = true;
#if defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
if (integration_test::state.disable_obligation_uptime_proof) check_uptime_obligation = false;
if (integration_test::state.disable_obligation_checkpointing) check_checkpoint_obligation = false;
#endif
if (check_uptime_obligation && time_since_last_uptime_proof > netconf.UPTIME_PROOF_VALIDITY)
{
LOG_PRINT_L1(
@ -262,11 +255,6 @@ namespace service_nodes
{
quorum_type const type = static_cast<quorum_type>(i);
#if defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
if (integration_test::state.disable_checkpoint_quorum && type == quorum_type::checkpointing) continue;
if (integration_test::state.disable_obligation_quorum && type == quorum_type::obligations) continue;
#endif
switch(type)
{
default:
@ -312,12 +300,10 @@ namespace service_nodes
}
}
#ifndef OXEN_ENABLE_INTEGRATION_TEST_HOOKS
// NOTE: Wait at least 2 hours before we're allowed to vote so that we collect necessary
// voting information from people on the network
if (live_time < m_core.get_net_config().UPTIME_PROOF_VALIDITY)
continue;
#endif
if (!m_core.service_node())
continue;

View File

@ -7,18 +7,6 @@
namespace service_nodes {
constexpr size_t PULSE_QUORUM_ENTROPY_LAG = 21; // How many blocks back from the tip of the Blockchain to source entropy for the Pulse quorums.
#if defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
constexpr auto PULSE_ROUND_TIME = 20s;
constexpr auto PULSE_WAIT_FOR_HANDSHAKES_DURATION = 3s;
constexpr auto PULSE_WAIT_FOR_OTHER_VALIDATOR_HANDSHAKES_DURATION = 3s;
constexpr auto PULSE_WAIT_FOR_BLOCK_TEMPLATE_DURATION = 3s;
constexpr auto PULSE_WAIT_FOR_RANDOM_VALUE_HASH_DURATION = 3s;
constexpr auto PULSE_WAIT_FOR_RANDOM_VALUE_DURATION = 3s;
constexpr auto PULSE_WAIT_FOR_SIGNED_BLOCK_DURATION = 5s;
constexpr size_t PULSE_QUORUM_NUM_VALIDATORS = 7;
constexpr size_t PULSE_BLOCK_REQUIRED_SIGNATURES = 6; // A block must have exactly N signatures to be considered properly
#else
constexpr auto PULSE_ROUND_TIME = 60s;
constexpr auto PULSE_WAIT_FOR_HANDSHAKES_DURATION = 10s;
constexpr auto PULSE_WAIT_FOR_OTHER_VALIDATOR_HANDSHAKES_DURATION = 10s;
@ -29,7 +17,6 @@ namespace service_nodes {
constexpr size_t PULSE_QUORUM_NUM_VALIDATORS = 11;
constexpr size_t PULSE_BLOCK_REQUIRED_SIGNATURES = 7; // A block must have exactly N signatures to be considered properly
#endif
constexpr auto PULSE_MIN_TARGET_BLOCK_TIME = TARGET_BLOCK_TIME - 30s;
constexpr auto PULSE_MAX_TARGET_BLOCK_TIME = TARGET_BLOCK_TIME + 30s;
@ -153,28 +140,17 @@ namespace service_nodes {
constexpr size_t STATE_CHANGE_MIN_NODES_TO_TEST = 50;
constexpr uint64_t VOTE_LIFETIME = BLOCKS_EXPECTED_IN_HOURS(2);
#if defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
constexpr size_t STATE_CHANGE_QUORUM_SIZE = 5;
constexpr size_t STATE_CHANGE_MIN_VOTES_TO_CHANGE_STATE = 1;
constexpr size_t CHECKPOINT_QUORUM_SIZE = 5;
constexpr size_t CHECKPOINT_MIN_VOTES = 1;
constexpr int BLINK_SUBQUORUM_SIZE = 5;
constexpr int BLINK_MIN_VOTES = 1;
#else
constexpr size_t STATE_CHANGE_MIN_VOTES_TO_CHANGE_STATE = 7;
constexpr size_t STATE_CHANGE_QUORUM_SIZE = 10;
constexpr size_t CHECKPOINT_QUORUM_SIZE = 20;
constexpr size_t CHECKPOINT_MIN_VOTES = 13;
constexpr int BLINK_SUBQUORUM_SIZE = 10;
constexpr int BLINK_MIN_VOTES = 7;
#endif
static_assert(STATE_CHANGE_MIN_VOTES_TO_CHANGE_STATE <= STATE_CHANGE_QUORUM_SIZE, "The number of votes required to kick can't exceed the actual quorum size, otherwise we never kick.");
static_assert(CHECKPOINT_MIN_VOTES <= CHECKPOINT_QUORUM_SIZE, "The number of votes required to add a checkpoint can't exceed the actual quorum size, otherwise we never add checkpoints.");
static_assert(BLINK_MIN_VOTES <= BLINK_SUBQUORUM_SIZE, "The number of votes required can't exceed the actual blink subquorum size, otherwise we never approve.");
#ifndef OXEN_ENABLE_INTEGRATION_TEST_HOOKS
static_assert(BLINK_MIN_VOTES > BLINK_SUBQUORUM_SIZE / 2, "Blink approvals must require a majority of quorum members to prevent conflicting, signed blinks.");
#endif
// NOTE: We can reorg up to last 2 checkpoints + the number of extra blocks before the next checkpoint is set
constexpr uint64_t REORG_SAFETY_BUFFER_BLOCKS_POST_HF12 = (CHECKPOINT_INTERVAL * CHECKPOINT_NUM_CHECKPOINTS_FOR_CHAIN_FINALITY) + (CHECKPOINT_INTERVAL - 1);

View File

@ -591,11 +591,7 @@ namespace service_nodes
std::unique_lock lock{m_lock};
// TODO(doyle): Rate-limiting: A better threshold value that follows suite with transaction relay time back-off
#if defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
constexpr uint64_t TIME_BETWEEN_RELAY = 0;
#else
constexpr uint64_t TIME_BETWEEN_RELAY = 60 * 2;
#endif
const uint64_t max_last_sent = static_cast<uint64_t>(time(nullptr)) - TIME_BETWEEN_RELAY;
const uint64_t min_height = height > VOTE_LIFETIME ? height - VOTE_LIFETIME : 0;

View File

@ -33,12 +33,6 @@
#include "epee/string_tools.h"
#include "daemon/command_server.h"
#include "common/oxen_integration_test_hooks.h"
#if defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
#include <thread>
#endif
#undef OXEN_DEFAULT_LOG_CATEGORY
#define OXEN_DEFAULT_LOG_CATEGORY "daemon"
@ -391,99 +385,12 @@ void command_server::init_commands(cryptonote::rpc::core_rpc_server* rpc_server)
},
"");
#if defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
m_command_lookup.set_handler(
"relay_votes_and_uptime", [rpc_server](const auto&) {
rpc_server->on_relay_uptime_and_votes();
return true;
}
, ""
);
m_command_lookup.set_handler(
"integration_test", [rpc_server](const auto& args) {
bool valid_cmd = false;
if (args.size() == 1)
{
valid_cmd = true;
if (args[0] == "toggle_checkpoint_quorum")
{
integration_test::state.disable_checkpoint_quorum = !integration_test::state.disable_checkpoint_quorum;
}
else if (args[0] == "toggle_obligation_quorum")
{
integration_test::state.disable_obligation_quorum = !integration_test::state.disable_obligation_quorum;
}
else if (args[0] == "toggle_obligation_uptime_proof")
{
integration_test::state.disable_obligation_uptime_proof = !integration_test::state.disable_obligation_uptime_proof;
}
else if (args[0] == "toggle_obligation_checkpointing")
{
integration_test::state.disable_obligation_checkpointing = !integration_test::state.disable_obligation_checkpointing;
}
else
{
valid_cmd = false;
}
if (valid_cmd) std::cout << args[0] << " toggled";
}
else if (args.size() == 3)
{
uint64_t num_blocks = 0;
if (args[0] == "debug_mine_n_blocks" && epee::string_tools::get_xtype_from_string(num_blocks, args[2]))
{
rpc_server->on_debug_mine_n_blocks(args[1], num_blocks);
valid_cmd = true;
}
}
if (!valid_cmd)
std::cout << "integration_test invalid command";
integration_test::write_buffered_stdout();
return true;
}
, ""
);
#endif
}
bool command_server::start_handling(std::function<void(void)> exit_handler)
{
if (m_is_rpc) return false;
#if defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
auto handle_pipe = [&]()
{
// TODO(doyle): Hack, don't hook into input until the daemon has completely initialised, i.e. you can print the status
while(!integration_test::state.core_is_idle) {}
mlog_set_categories(""); // TODO(doyle): We shouldn't have to do this.
for (;;)
{
integration_test::write_buffered_stdout();
std::string const input = integration_test::read_from_pipe();
std::vector<std::string> args = integration_test::space_delimit_input(input);
{
std::unique_lock<std::mutex> scoped_lock(integration_test::state.mutex);
integration_test::use_standard_cout();
std::cout << input << std::endl;
integration_test::use_redirected_cout();
}
process_command_and_log(args);
if (args.size() == 1 && args[0] == "exit")
{
integration_test::deinit();
break;
}
}
};
static std::thread handle_pipe_thread(handle_pipe);
#endif
m_command_lookup.start_handling("", get_commands_str(), std::move(exit_handler));
return true;
}

View File

@ -43,8 +43,6 @@
#include <boost/format.hpp>
#include <oxenmq/base32z.h>
#include "common/oxen_integration_test_hooks.h"
#include <fstream>
#include <ctime>
#include <string>
@ -65,13 +63,8 @@ namespace {
{
std::cout << prompt << std::flush;
std::string result;
#if defined (OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
integration_test::write_buffered_stdout();
result = integration_test::read_from_pipe();
#else
rdln::suspend_readline pause_readline;
std::cin >> result;
#endif
return result;
}
@ -1227,13 +1220,6 @@ bool rpc_command_executor::ban(const std::string &address, time_t seconds, bool
if (!invoke<SETBANS>(std::move(req), res, clear_ban ? "Failed to clear ban" : "Failed to set ban"))
return false;
// TODO(doyle): Work around because integration tests break when using
// mlog_set_categories(""), so emit the block message using msg writer
// instead of the logging system.
#if defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
tools::success_msg_writer() << "Host " << address << (clear_ban ? " unblocked." : " blocked.");
#endif
return true;
}
@ -1996,16 +1982,12 @@ bool rpc_command_executor::prepare_registration(bool force_registration)
uint64_t block_height = std::max(res.height, res.target_height);
uint8_t hf_version = hf_res.version;
#if defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
cryptonote::network_type const nettype = cryptonote::FAKECHAIN;
#else
cryptonote::network_type const nettype =
res.mainnet ? cryptonote::MAINNET :
res.devnet ? cryptonote::DEVNET :
res.testnet ? cryptonote::TESTNET :
res.nettype == "fakechain" ? cryptonote::FAKECHAIN :
cryptonote::UNDEFINED;
#endif
// Query the latest block we've synced and check that the timestamp is sensible, issue a warning if not
{

View File

@ -2252,14 +2252,12 @@ namespace nodetool
return 1;
}
#if !defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
if(has_too_many_connections(context.m_remote_address))
{
LOG_PRINT_CCONTEXT_L1("CONNECTION FROM " << context.m_remote_address.host_str() << " REFUSED, too many connections from the same address");
drop_connection(context);
return 1;
}
#endif
//associate peer_id with this connection
context.peer_id = arg.node_data.peer_id;

View File

@ -43,10 +43,6 @@
#include "p2p/net_node.h"
#include "cryptonote_protocol/cryptonote_protocol_handler.h"
#if defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
#include "common/oxen_integration_test_hooks.h"
#endif
#undef OXEN_DEFAULT_LOG_CATEGORY
#define OXEN_DEFAULT_LOG_CATEGORY "daemon.rpc"
@ -272,44 +268,6 @@ namespace cryptonote::rpc {
ONS_RESOLVE::response invoke(ONS_RESOLVE::request&& req, rpc_context context);
FLUSH_CACHE::response invoke(FLUSH_CACHE::request&& req, rpc_context);
#if defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
void on_relay_uptime_and_votes()
{
m_core.submit_uptime_proof();
m_core.relay_service_node_votes();
std::cout << "Votes and uptime relayed";
integration_test::write_buffered_stdout();
}
void on_debug_mine_n_blocks(std::string const &address, uint64_t num_blocks)
{
cryptonote::miner &miner = m_core.get_miner();
if (miner.is_mining())
{
std::cout << "Already mining";
return;
}
cryptonote::address_parse_info info;
if(!get_account_address_from_str(info, m_core.get_nettype(), address))
{
std::cout << "Failed, wrong address";
return;
}
uint64_t height = m_core.get_current_blockchain_height();
if (!miner.start(info.address, 1, num_blocks))
{
std::cout << "Failed, mining not started";
return;
}
while (m_core.get_current_blockchain_height() != (height + num_blocks))
std::this_thread::sleep_for(500ms);
std::cout << "Mining stopped in daemon";
}
#endif
private:
bool check_core_ready();

View File

@ -62,7 +62,6 @@
#include "common/dns_utils.h"
#include "common/base58.h"
#include "common/scoped_message_writer.h"
#include "common/oxen_integration_test_hooks.h"
#include "cryptonote_protocol/cryptonote_protocol_handler.h"
#include "cryptonote_core/service_node_voting.h"
#include "cryptonote_core/service_node_list.h"
@ -264,17 +263,6 @@ namespace
const char* USAGE_ONS_BY_OWNER("ons_by_owner [<owner> ...]");
const char* USAGE_ONS_LOOKUP("ons_lookup [type=session|wallet|lokinet] <name> [<name> ...]");
#if defined (OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
std::string input_line(const std::string &prompt, bool yesno = false)
{
if (yesno) std::cout << prompt << " (Y/Yes/N/No): ";
else std::cout << prompt << ": ";
integration_test::write_buffered_stdout();
std::string buf = integration_test::read_from_pipe();
epee::string_tools::trim(buf);
return buf;
}
#else // OXEN_ENABLE_INTEGRATION_TEST_HOOKS
std::string input_line(const std::string& prompt, bool yesno = false)
{
std::string buf;
@ -294,16 +282,9 @@ namespace
epee::string_tools::trim(buf);
return buf;
}
#endif // OXEN_ENABLE_INTEGRATION_TEST_HOOKS
epee::wipeable_string input_secure_line(const char *prompt)
{
#if defined (OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
std::cout << prompt;
integration_test::write_buffered_stdout();
epee::wipeable_string buf = integration_test::read_from_pipe();
#else
rdln::suspend_readline pause_readline;
auto pwd_container = tools::password_container::prompt(false, prompt, false);
if (!pwd_container)
@ -315,24 +296,17 @@ namespace
epee::wipeable_string buf = pwd_container->password();
buf.trim();
#endif
return buf;
}
std::optional<tools::password_container> password_prompter(const char *prompt, bool verify)
{
#if defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
std::cout << prompt << ": NOTE(oxen): Passwords not supported, defaulting to empty password";
integration_test::write_buffered_stdout();
tools::password_container pwd_container(std::string(""));
#else
rdln::suspend_readline pause_readline;
auto pwd_container = tools::password_container::prompt(verify, prompt);
if (!pwd_container)
{
tools::fail_msg_writer() << sw::tr("failed to read wallet password");
}
#endif
return pwd_container;
}
@ -8966,15 +8940,8 @@ std::string simple_wallet::get_prompt() const
}
//----------------------------------------------------------------------------------------------------
#if defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
#include <thread>
#endif
bool simple_wallet::run()
{
#if defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
integration_test::use_redirected_cout();
#endif
// check and display warning, but go on anyway
try_connect_to_daemon();
@ -9002,27 +8969,6 @@ bool simple_wallet::run()
message_writer(epee::console_color_green, false) << "Background refresh thread started";
#if defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
for (;;)
{
integration_test::write_buffered_stdout();
std::string const input = integration_test::read_from_pipe();
std::vector<std::string> args = integration_test::space_delimit_input(input);
{
std::unique_lock<std::mutex> scoped_lock(integration_test::state.mutex);
integration_test::use_standard_cout();
std::cout << input << std::endl;
integration_test::use_redirected_cout();
}
this->process_command_and_log(args);
if (args.size() == 1 && args[0] == "exit")
{
integration_test::deinit();
return true;
}
}
#endif
return m_cmd_binder.run_handling([this]() {return get_prompt(); }, "");
}
//----------------------------------------------------------------------------------------------------
@ -10189,7 +10135,7 @@ void simple_wallet::interrupt()
void simple_wallet::commit_or_save(std::vector<tools::wallet2::pending_tx>& ptx_vector, bool do_not_relay, bool blink)
{
size_t i = 0;
std::string msg_buf; // NOTE(oxen): Buffer output so integration tests read the entire output
std::string msg_buf;
msg_buf.reserve(128);
while (!ptx_vector.empty())

View File

@ -88,7 +88,6 @@
#include "cryptonote_core/service_node_list.h"
#include "cryptonote_core/service_node_rules.h"
#include "common/oxen.h"
#include "common/oxen_integration_test_hooks.h"
#include "oxen_economy.h"
#include "epee/string_coding.h"

View File

@ -72,7 +72,6 @@
#include "pending_tx.h"
#include "multisig_sig.h"
#include "common/oxen_integration_test_hooks.h"
#include "epee/wipeable_string.h"
#include "rpc/http_client.h"

View File

@ -36,8 +36,6 @@
#include "epee/string_tools.h"
#include "version.h"
#include "common/oxen_integration_test_hooks.h"
#if defined(WIN32)
#include <crtdbg.h>
#endif
@ -128,10 +126,6 @@ namespace wallet_args
command_line::add_arg(desc_params, arg_max_concurrency);
command_line::add_arg(desc_params, arg_config_file);
#if defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
command_line::add_arg(desc_params, integration_test::arg_pipe_name);
#endif
i18n_set_language("translations", "oxen", lang);
po::options_description desc_all, desc_visible;
@ -144,13 +138,6 @@ namespace wallet_args
auto parser = po::command_line_parser(argc, argv).options(desc_all).positional(positional_options);
po::store(parser.run(), vm);
#if defined(OXEN_ENABLE_INTEGRATION_TEST_HOOKS)
{
const std::string arg_pipe_name = command_line::get_arg(vm, integration_test::arg_pipe_name);
integration_test::init(arg_pipe_name);
}
#endif
if (command_line::get_arg(vm, command_line::arg_help))
{
Print(print) << "Oxen '" << OXEN_RELEASE_NAME << "' (v" << OXEN_VERSION_FULL << ")\n";