#include <iostream>
#include <cstring>
#include <cassert>
#include <algorithm>
#include <random>
#include <unistd.h>
#include <signal.h>
#include <event2/event.h>
#include "salticidae/stream.h"
#include "salticidae/util.h"
#include "salticidae/network.h"
#include "salticidae/msg.h"
#include "hotstuff/promise.hpp"
#include "hotstuff/type.h"
#include "hotstuff/entity.h"
#include "hotstuff/util.h"
#include "hotstuff/client.h"
#include "hotstuff/hotstuff.h"
using salticidae::MsgNetwork;
using salticidae::ClientNetwork;
using salticidae::ElapsedTime;
using salticidae::Config;
using salticidae::_1;
using salticidae::_2;
using salticidae::static_pointer_cast;
using salticidae::trim_all;
using salticidae::split;
using hotstuff::Event;
using hotstuff::EventContext;
using hotstuff::NetAddr;
using hotstuff::HotStuffError;
using hotstuff::CommandDummy;
using hotstuff::Finality;
using hotstuff::command_t;
using hotstuff::uint256_t;
using hotstuff::opcode_t;
using hotstuff::bytearray_t;
using hotstuff::DataStream;
using hotstuff::ReplicaID;
using hotstuff::MsgReqCmd;
using hotstuff::MsgRespCmd;
using hotstuff::get_hash;
using hotstuff::promise_t;
using HotStuff = hotstuff::HotStuffSecp256k1;
#define LOG_INFO HOTSTUFF_LOG_INFO
#define LOG_DEBUG HOTSTUFF_LOG_DEBUG
#define LOG_WARN HOTSTUFF_LOG_WARN
#define LOG_ERROR HOTSTUFF_LOG_ERROR
class HotStuffApp: public HotStuff {
double stat_period;
EventContext ec;
/** Network messaging between a replica and its client. */
ClientNetwork<opcode_t> cn;
/** Timer object to schedule a periodic printing of system statistics */
Event ev_stat_timer;
/** The listen address for client RPC */
NetAddr clisten_addr;
using Conn = ClientNetwork<opcode_t>::Conn;
void client_request_cmd_handler(MsgReqCmd &&, Conn &);
void print_stat_cb(evutil_socket_t, short);
command_t parse_cmd(DataStream &s) override {
auto cmd = new CommandDummy();
s >> *cmd;
return cmd;
}
void state_machine_execute(const Finality &fin) override {
#ifndef HOTSTUFF_ENABLE_BENCHMARK
LOG_INFO("replicated %s", std::string(fin).c_str());
#endif
}
public:
HotStuffApp(uint32_t blk_size,
double stat_period,
ReplicaID idx,
const bytearray_t &raw_privkey,
NetAddr plisten_addr,
NetAddr clisten_addr,
hotstuff::pacemaker_bt pmaker,
const EventContext &ec);
void start();
};
std::pair<std::string, std::string> split_ip_port_cport(const std::string &s) {
auto ret = trim_all(split(s, ";"));
if (ret.size() != 2)
throw std::invalid_argument("invalid cport format");
return std::make_pair(ret[0], ret[1]);
}
void signal_handler(int) {
throw HotStuffError("got terminal signal");
}
salticidae::BoxObj<HotStuffApp> papp = nullptr;
int main(int argc, char **argv) {
Config config("hotstuff.conf");
ElapsedTime elapsed;
elapsed.start();
signal(SIGTERM,