Skip to content

Commit

Permalink
WIP: cloudabi changes
Browse files Browse the repository at this point in the history
First phase: simply #ifdef out everything that cannot compile with
CLOUDABI, and get something to compile and test.
  • Loading branch information
laanwj committed Mar 7, 2017
1 parent 21930e0 commit 1024183
Show file tree
Hide file tree
Showing 25 changed files with 339 additions and 43 deletions.
5 changes: 4 additions & 1 deletion src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ BITCOIN_TESTS =\
test/hash_tests.cpp \
test/key_tests.cpp \
test/limitedmap_tests.cpp \
test/dbwrapper_tests.cpp \
test/main_tests.cpp \
test/mempool_tests.cpp \
test/merkle_tests.cpp \
Expand Down Expand Up @@ -137,6 +136,10 @@ BITCOIN_TESTS =\
test/univalue_tests.cpp \
test/util_tests.cpp

# Disabled, need to figure out how to pass temporary directory
# to test first
# test/dbwrapper_tests.cpp \
#
if ENABLE_WALLET
BITCOIN_TESTS += \
wallet/test/wallet_test_fixture.cpp \
Expand Down
4 changes: 4 additions & 0 deletions src/bench/bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ void
benchmark::BenchRunner::RunAll(double elapsedTimeForOne)
{
perf_init();
#ifndef CLOUDABI
std::cout << "#Benchmark" << "," << "count" << "," << "min" << "," << "max" << "," << "average" << ","
<< "min_cycles" << "," << "max_cycles" << "," << "average_cycles" << "\n";
#endif

for (const auto &p: benchmarks()) {
State state(p.first, elapsedTimeForOne);
Expand Down Expand Up @@ -97,8 +99,10 @@ bool benchmark::State::KeepRunning()
// Output results
double average = (now-beginTime)/count;
int64_t averageCycles = (nowCycles-beginCycles)/count;
#ifndef CLOUDABI
std::cout << std::fixed << std::setprecision(15) << name << "," << count << "," << minTime << "," << maxTime << "," << average << ","
<< minCycles << "," << maxCycles << "," << averageCycles << "\n";
#endif

return false;
}
2 changes: 2 additions & 0 deletions src/bench/rollingbloom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ static void RollingBloom(benchmark::State& state)
int64_t b = GetTimeMicros();
filter.insert(data);
int64_t e = GetTimeMicros();
#ifndef CLOUDABI
std::cout << "RollingBloom-refresh,1," << (e-b)*0.000001 << "," << (e-b)*0.000001 << "," << (e-b)*0.000001 << "\n";
#endif
countnow = 0;
} else {
filter.insert(data);
Expand Down
126 changes: 107 additions & 19 deletions src/bitcoind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@
#include <boost/thread.hpp>

#include <stdio.h>
#ifdef CLOUDABI
#include <boost/algorithm/string/join.hpp>
#include <program.h>
#include <argdata.hpp>
#endif

/* Introduction text for doxygen: */

Expand Down Expand Up @@ -61,19 +66,13 @@ void WaitForShutdown(boost::thread_group* threadGroup)
//
// Start
//
bool AppInit(int argc, char* argv[])
bool AppInit()
{
boost::thread_group threadGroup;
CScheduler scheduler;

bool fRet = false;

//
// Parameters
//
// If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's main()
ParseParameters(argc, argv);

// Process help and version before taking care about datadir
if (IsArgSet("-?") || IsArgSet("-h") || IsArgSet("-help") || IsArgSet("-version"))
{
Expand All @@ -91,7 +90,9 @@ bool AppInit(int argc, char* argv[])
strUsage += "\n" + HelpMessage(HMM_BITCOIND);
}

#ifndef CLOUDABI
fprintf(stdout, "%s", strUsage.c_str());
#endif
return true;
}

Expand All @@ -117,17 +118,6 @@ bool AppInit(int argc, char* argv[])
return false;
}

// Command-line RPC
bool fCommandLine = false;
for (int i = 1; i < argc; i++)
if (!IsSwitchChar(argv[i][0]) && !boost::algorithm::istarts_with(argv[i], "bitcoin:"))
fCommandLine = true;

if (fCommandLine)
{
fprintf(stderr, "Error: There is no RPC client functionality in bitcoind anymore. Use the bitcoin-cli utility instead.\n");
exit(EXIT_FAILURE);
}
// -server defaults to true for bitcoind but not for the GUI so do this here
SoftSetBoolArg("-server", true);
// Set this early so that parameter interactions go to console
Expand Down Expand Up @@ -186,12 +176,110 @@ bool AppInit(int argc, char* argv[])
return fRet;
}

#ifndef CLOUDABI
int main(int argc, char* argv[])
{
SetupEnvironment();

// Connect bitcoind signal handlers
noui_connect();

return (AppInit(argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE);
ParseParameters(argc, argv);

return (AppInit() ? EXIT_SUCCESS : EXIT_FAILURE);
}
#else
void program_main(const argdata_t *ad) {
mstd::optional<int> console_fd;
mstd::optional<int> datadir_fd;
mstd::optional<int> rpc_fd;
mstd::optional<int> p2p_fd;
mstd::optional<int> zmq_fd;
argdata_t::map args;
for (auto &i: ad->as_map()) {
auto key = i.first->as_str();
if (key == "console") {
console_fd = i.second->get_fd();
} else if(key == "datadir") {
datadir_fd = i.second->get_fd();
} else if(key == "args") {
args = i.second->as_map();
} else if(key == "rpc") {
rpc_fd = i.second->get_fd();
} else if(key == "p2p") {
p2p_fd = i.second->get_fd();
} else if(key == "zmq") {
zmq_fd = i.second->get_fd();
}
}
// Console fd is optional
if (console_fd) {
SetConsoleFD(console_fd.value());
}
// Datadir fd is mandatory
if (datadir_fd) {
SetDataDirFD(datadir_fd.value());
} else {
LogPrintf("Need to specify data directory\n");
std::exit(1);
}
// Log test message
fPrintToConsole = true;
LogPrintf("Welcome to cloudabi\n");

SetupEnvironment();
noui_connect();

// Process arguments
LogPrintf("Processing arguments\n");
for (const auto &entry: args) {
std::string key = "-" + std::string(entry.first->as_str());
mstd::optional<argdata_t::seq> seqval = entry.second->get_seq();
if (seqval) {
std::vector<std::string> values;
for (const auto &x: seqval.value()) {
values.push_back(std::string(x->as_str()));
}
LogPrintf("multiarg %s: %s\n", key, boost::algorithm::join(values, ", "));
SoftSetMultiArg(key, values);
} else { /* Convert any sensible kind of argument to string */
mstd::optional<mstd::string_view> strval = entry.second->get_str();
mstd::optional<bool> boolval = entry.second->get_bool();
mstd::optional<double> doubleval = entry.second->get_float();
mstd::optional<int64_t> intval = entry.second->get_int<int64_t>();
std::string value;
if (strval) {
value = strval.value();
} else if (boolval) {
value = boolval.value() ? "1" : "0";
} else if(doubleval) {
value = strprintf("%f", doubleval.value());
} else if(intval) {
value = strprintf("%d", intval.value());
}
LogPrintf("arg %s: %s\n", key, value);
SoftSetArg(key, value);
}
}
// Pass RPC and P2P fd as arguments
// TODO: should be able to accept mulitple of these to bind to multiple addresses,
// as well as associated bind/whitelist flags.
// TODO: this is a hack, these arguments should be passed in a configuration
// structure instead of magically enter the program through a global
// namespace.
if (rpc_fd) {
ForceSetArg("-rpcfd", itostr(rpc_fd.value()));
LogPrintf("rpcfd: %i\n", rpc_fd.value());
}
if (p2p_fd) {
ForceSetArg("-p2pfd", itostr(p2p_fd.value()));
LogPrintf("p2pfd: %i\n", p2p_fd.value());
}
if (zmq_fd) {
ForceSetArg("-zmqfd", itostr(zmq_fd.value()));
LogPrintf("zmqfd: %i\n", zmq_fd.value());
}

std::exit(AppInit() ? EXIT_SUCCESS : EXIT_FAILURE);
}
#endif
11 changes: 11 additions & 0 deletions src/compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,22 @@
#include <windows.h>
#include <ws2tcpip.h>
#else
#ifndef CLOUDABI
#include <sys/fcntl.h>
#endif
#include <sys/mman.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <net/if.h>
#include <netinet/in.h>
#ifndef CLOUDABI
#include <netinet/tcp.h>
#endif
#include <arpa/inet.h>
#ifndef CLOUDABI
#include <ifaddrs.h>
#endif
#include <limits.h>
#include <netdb.h>
#include <unistd.h>
Expand Down Expand Up @@ -84,4 +90,9 @@ bool static inline IsSelectableSocket(SOCKET s) {
#endif
}

#ifdef CLOUDABI
/* Define some constants that are not available on cloudabi */
#define INADDR_NONE ((unsigned long int) 0xffffffff)
#endif

#endif // BITCOIN_COMPAT_H
8 changes: 4 additions & 4 deletions src/dbwrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include <leveldb/cache.h>
#include <leveldb/env.h>
#include <leveldb/filter_policy.h>
#include <memenv.h>
#include <memenv/memenv.h>
#include <stdint.h>

static leveldb::Options GetOptions(size_t nCacheSize)
Expand All @@ -32,16 +32,15 @@ static leveldb::Options GetOptions(size_t nCacheSize)

CDBWrapper::CDBWrapper(const fs::path& path, size_t nCacheSize, bool fMemory, bool fWipe, bool obfuscate)
{
penv = NULL;
readoptions.verify_checksums = true;
iteroptions.verify_checksums = true;
iteroptions.fill_cache = false;
syncoptions.sync = true;
options = GetOptions(nCacheSize);
options.create_if_missing = true;
penv = leveldb::Env::DefaultWithDirectory(path.fd());
if (fMemory) {
penv = leveldb::NewMemEnv(leveldb::Env::Default());
options.env = penv;
penv = leveldb::NewMemEnv(penv);
} else {
if (fWipe) {
LogPrintf("Wiping LevelDB in %s\n", path.string());
Expand All @@ -51,6 +50,7 @@ CDBWrapper::CDBWrapper(const fs::path& path, size_t nCacheSize, bool fMemory, bo
TryCreateDirectory(path);
LogPrintf("Opening LevelDB in %s\n", path.string());
}
options.env = penv;
leveldb::Status status = leveldb::DB::Open(options, path.string(), &pdb);
dbwrapper_private::HandleError(status);
LogPrintf("Opened LevelDB successfully\n");
Expand Down
17 changes: 17 additions & 0 deletions src/httpserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <sys/stat.h>
#include <signal.h>
#include <future>
#include <deque>

#include <event2/event.h>
#include <event2/http.h>
Expand Down Expand Up @@ -318,6 +319,7 @@ static bool ThreadHTTP(struct event_base* base, struct evhttp* http)
/** Bind HTTP server to specified addresses */
static bool HTTPBindAddresses(struct evhttp* http)
{
#ifndef CLOUDABI
int defaultPort = GetArg("-rpcport", BaseParams().RPCPort());
std::vector<std::pair<std::string, uint16_t> > endpoints;

Expand Down Expand Up @@ -351,6 +353,21 @@ static bool HTTPBindAddresses(struct evhttp* http)
LogPrintf("Binding RPC on address %s port %i failed.\n", i->first, i->second);
}
}
#else
int fd = GetArg("-rpcfd", -1);
if (fd >= 0) {
LogPrintf("Binding RPC on fd %d.\n", fd);
/* Need to explicitly set the socket to non-blocking */
evutil_make_socket_nonblocking(fd);

evhttp_bound_socket *bind_handle = evhttp_accept_socket_with_handle(http, fd);
if (bind_handle) {
boundSockets.push_back(bind_handle);
} else {
LogPrintf("Binding RPC on fd %d failed.\n", fd);
}
}
#endif
return !boundSockets.empty();
}

Expand Down
Loading

0 comments on commit 1024183

Please sign in to comment.