Skip to content

Commit

Permalink
Merge pull request #165 from DLTcollab/develop
Browse files Browse the repository at this point in the history
Pre-release v0.4.0
  • Loading branch information
Wu Yu Wei committed Jun 19, 2019
2 parents aa27ed6 + 1624c2a commit 631d15c
Show file tree
Hide file tree
Showing 27 changed files with 1,466 additions and 36 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "deps/libtuv"]
path = deps/libtuv
url = https://github.com/DLTcollab/libtuv.git
[submodule "deps/rabbitmq-c"]
path = deps/rabbitmq-c
url = https://github.com/alanxz/rabbitmq-c.git
37 changes: 29 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
VERSION = 0.3.0
VERSION = 0.4.0

OUT ?= ./build
SRC := src
Expand Down Expand Up @@ -72,6 +72,10 @@ ifeq ("$(BUILD_FPGA_ACCEL)","1")
CFLAGS += -DENABLE_FPGA_ACCEL
endif

ifeq ("$(BUILD_REMOTE)","1")
CFLAGS += -DENABLE_REMOTE
endif

ifeq ("$(BUILD_JNI)","1")
include mk/java.mk
endif
Expand All @@ -84,7 +88,8 @@ TESTS = \
trinary \
curl \
dcurl \
pow
pow \
multi-pow

TESTS := $(addprefix $(OUT)/test-, $(TESTS))

Expand All @@ -98,6 +103,9 @@ PREQ := config $(TESTS) $(LIBS)
ifeq ("$(BUILD_JNI)","1")
PREQ += $(JARS)
endif
ifeq ("$(BUILD_REMOTE)", "1")
PREQ += $(OUT)/remote-worker
endif

all: $(PREQ)
.DEFAULT_GOAL := all
Expand Down Expand Up @@ -139,23 +147,36 @@ OBJS += \
pow_fpga_accel.o
endif

ifeq ("$(BUILD_REMOTE)", "1")
OBJS += \
remote_common.o \
remote_interface.o

WORKER_OBJS := $(addprefix $(OUT)/worker-,$(filter-out remote_interface.o, $(OBJS)))
WORKER_CFLAGS := $(filter-out -DENABLE_REMOTE, $(CFLAGS))
endif

OBJS := $(addprefix $(OUT)/, $(OBJS))

$(OUT)/test-%.o: tests/test-%.c $(LIBTUV_PATH)/include
$(VECHO) " CC\t$@\n"
$(Q)$(CC) -o $@ $(CFLAGS) -I $(SRC) $(LIBTUV_INCLUDE) -c -MMD -MF $@.d $<

$(OUT)/%.o: $(SRC)/%.c $(LIBTUV_PATH)/include
$(OUT)/%.o: $(SRC)/%.c $(LIBTUV_PATH)/include $(LIBRABBITMQ_PATH)/build/include
$(VECHO) " CC\t$@\n"
$(Q)$(CC) -o $@ $(CFLAGS) $(LIBTUV_INCLUDE) -c -MMD -MF $@.d $<
$(Q)$(CC) -o $@ $(CFLAGS) $(LIBTUV_INCLUDE) $(LIBRABBITMQ_INCLUDE) -c -MMD -MF $@.d $<

$(OUT)/test-%: $(OUT)/test-%.o $(OBJS) $(LIBTUV_LIBRARY)
$(OUT)/test-%: $(OUT)/test-%.o $(OBJS) $(LIBTUV_LIBRARY) $(LIBRABBITMQ_LIBRARY)
$(VECHO) " LD\t$@\n"
$(Q)$(CC) -o $@ $^ $(LDFLAGS)
$(Q)$(CC) -o $@ $^ $(LDFLAGS) $(LIBRABBITMQ_LINK)

$(OUT)/libdcurl.so: $(OBJS) $(LIBTUV_LIBRARY)
$(OUT)/libdcurl.so: $(OBJS) $(LIBTUV_LIBRARY) $(LIBRABBITMQ_LIBRARY)
$(VECHO) " LD\t$@\n"
$(Q)$(CC) -shared -o $@ $^ $(LDFLAGS)
$(Q)$(CC) -shared -o $@ $^ $(LDFLAGS) $(LIBRABBITMQ_LINK)

ifeq ("$(BUILD_REMOTE)", "1")
include mk/remote.mk
endif

include mk/common.mk

Expand Down
13 changes: 3 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,10 @@ After integrating dcurl into IRI, performance of [attachToTangle](https://iota.r
[Modified IRI accepting external PoW Library](https://github.com/DLTcollab/iri)
Supported IRI version: 1.7.0

* ```$ cd ~/iri && mvn compile && mvn package```
* ```$ java -jar target/iri.jar -p <port> --pearldiver-exlib dcurl```

or with the **deprecated** commands

* ```$ cd ~/iri && mvn compile && mvn package```
* ```$ cp ~/dcurl/build/libdcurl.so ~/iri```
* ```$ cd ~/iri && java -Djava.library.path=./ -jar target/iri.jar -p <port> --pearldiver-exlib dcurl```
Load the external dcurl shared library from the installed JAR file

* ```$ cd ~/iri && make check```
* ```$ java -jar target/iri.jar -p <port> --pearldiver-exlib dcurl```

## Adoptions
Here is a partial list of open source projects that have adopted dcurl. If you
Expand Down Expand Up @@ -68,8 +63,6 @@ pull requests to dcurl.
it faciliates dcurl to perform hardware-accelerated PoW operations on
edge devices.

5. [remotepow](https://github.com/tylerw1369/remotepow/tree/Dcurl): delegate PoW to remote servers


## Licensing
`dcurl` is freely redistributable under the MIT License.
Expand Down
2 changes: 1 addition & 1 deletion deps/libtuv
1 change: 1 addition & 0 deletions deps/rabbitmq-c
Submodule rabbitmq-c added at 75a21e
4 changes: 2 additions & 2 deletions docs/build-n-test.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# Building and Testing

## Prerequisites
* Check JDK installation and set environment variable `JAVA_HOME` if you wish to specify.
* Check JDK 8 installation and set environment variable `JAVA_HOME` if you wish to specify.
* If target platform lacks of Intel SSE instructions, multi-threaded pure C implementation would be used as the fallback.
* Install the OpenCL and GPU driver before calculating the PoW with GPU.
* For FPGA-based hardware accelerator, [Lampa Lab's Cyclone V FPGA PoW](https://github.com/LampaLab/iota_fpga) is taken as the basis.
- File `soc_system.rbf` is only valid for DE10-nano board, and you have to synthesize to get appropriate `soc_system.rbf` for Arrow SoCKit board.
- [RBF file](https://github.com/DLTcollab/iota_fpga/releases/tag/v0.3-sockit) can be downloaded from our release.
- Moreover, you need to download [Lampa Lab-provided Linux image](https://github.com/LampaLab/iota_fpga/releases/tag/v0.1) to flash into the micro-SD card. The root password is `123456`.

* Install `CMake` for building git submodules.

## Build Instructions
* dcurl allows various combinations of build configurations to fit final use scenarios.
Expand Down
67 changes: 67 additions & 0 deletions docs/remote-interface.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Remote interface
## Introduction

```
+-----------------------------------------------+
| remote interface |
| +----------------------------------------+ |
| +----------------------------------------+| |
| +----------------------------------------+|+ |
| | RabbitMQ-provided RPC |+ |
| +----------------------------------------+ |
| | ^ |
+------------|---------------------|------------+
+------------|---------------------|------------+
| | RabbitMQ broker | |
| | | |
| | +------------------+ |
| v +------------------+| |
| +------------------+ +------------------+|| |
| | incoming queue | | private queue ||| |
| | | | ||| |
| | - trytes | | - PoW result ||| |
| | - mwm | | ||+ |
| | | | |+ |
| +------------------+ +------------------+ |
| | ^ |
+------------|---------------------|------------+
v |
+---------------------------------------------+
+---------------------------------------------+|
+---------------------------------------------+|+
| remote worker |+
+---------------------------------------------+
```
To support asynchronous remote procedure call, remote interface in dcurl provides an interface named as `Remote_ImplContext` to implement it. dcurl currently uses RabbitMQ C client to implement asynchronous RPC in remote interface. Remote interface provides thread management to support an asynchronous RPC per thread.

Here are detailed implementations of the RabbitMQ-provided RPC pattern as follows:
* Asynchronous RPC requests are inserted into the message queue, `incoming_queue`, in RabbitMQ broker
* Asynchronous RPCs with exclusive private queues (callback queues) with TTL = 10s property
* Correlation ID is not used
* An asynchronous RPC uses a connection to RabbitMQ broker
* Remote workers can obtain requests from `incoming_queue` by default exchange of RabbitMQ broker

## How to test remote interface in localhost
You need to open three terminals

Terminal 1: Run the RabbitMQ broker You can quickly use docker to run the RabbitMQ broker, rabbitmq
```
$ sudo docker run -d rabbitmq
```

Terminal 2: Run remote workers
```
$ ./build/remote-worker
```
How to build remote worker on FPGA board
```
$ make BUILD_REMOTE=1 BUILD_FPGA_ACCEL=1 BOARD=de10nano
```

Terminal 3: Run check
```
$ make BUILD_REMOTE=1 BUILD_DEBUG=1 check
```

## Requirements
Remote interface requires RabbitMQ broker
3 changes: 3 additions & 0 deletions mk/defs.mk
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ BUILD_GPU ?= 0
# Build FPGA backend or not
BUILD_FPGA_ACCEL ?= 0

# Build facilities of remote procedure calls
BUILD_REMOTE ?= 0

# Build JNI glue as the bridge between dcurl and IRI
BUILD_JNI ?= 0

Expand Down
8 changes: 8 additions & 0 deletions mk/remote.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Build remote-worker
$(OUT)/worker-%.o: $(SRC)/%.c $(LIBTUV_PATH)/include $(LIBRABBITMQ_PATH)/build/include
$(VECHO) " CC\t$@\n"
$(Q)$(CC) -o $@ $(WORKER_CFLAGS) $(LIBTUV_INCLUDE) $(LIBRABBITMQ_INCLUDE) -c -MMD -MF $@.d $<

$(OUT)/remote-worker: $(OUT)/remote_worker.o $(WORKER_OBJS) $(LIBTUV_LIBRARY) $(LIBRABBITMQ_LIBRARY)
$(VECHO) " LD\t$@\n"
$(Q)$(CC) -o $@ $^ $(LDFLAGS) $(LIBRABBITMQ_LINK)
3 changes: 3 additions & 0 deletions mk/sanitizers.mk
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,8 @@ ifeq ("$(LOWER_VER)","$(SANITIZER_MIN_GCC_VER)")
ifneq ("$(SANITIZER)","")
CFLAGS += -fsanitize=$(SANITIZER)
LDFLAGS += -fsanitize=$(SANITIZER)
ifeq ("$(SANITIZER)","undefined")
CFLAGS += -fno-sanitize-recover
endif
endif
endif
33 changes: 32 additions & 1 deletion mk/submodule.mk
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ endif
LIBTUV_PATH = deps/libtuv
LIBTUV_INCLUDE := -I $(LIBTUV_PATH)/include
LIBTUV_PLATFORM := $(UNAME_M)-$(UNAME_S)
LIBTUV_BOARD := $(BUILD_BOARD)
LIBTUV_BOARD := $(BOARD)
# PIC (Position-Independent-Code) library
LIBTUV_LIBRARY := $(LIBTUV_PATH)/build/$(LIBTUV_PLATFORM)/release/lib/libtuv.o

Expand All @@ -26,3 +26,34 @@ $(LIBTUV_PATH)/include:

$(LIBTUV_LIBRARY):
$(MAKE) -C $(LIBTUV_PATH) TUV_BUILD_TYPE=release TUV_CREATE_PIC_LIB=yes TUV_PLATFORM=$(LIBTUV_PLATFORM) TUV_BOARD=$(LIBTUV_BOARD)

# librabbitmq related variables
LIBRABBITMQ_PATH = deps/rabbitmq-c
LIBRABBITMQ_INCLUDE := -I $(LIBRABBITMQ_PATH)/build/include
LIBRABBITMQ_LIB_PATH := $(LIBRABBITMQ_PATH)/build/librabbitmq/
ifeq ($(UNAME_S),darwin)
# macOS
LIBRABBITMQ_LINK := -Wl,-rpath,$(LIBRABBITMQ_LIB_PATH) -L$(LIBRABBITMQ_LIB_PATH) -lrabbitmq
LIBRABBITMQ_LIBRARY := $(LIBRABBITMQ_LIB_PATH)/librabbitmq.dylib
else
LIBRABBITMQ_LINK := -Wl,-rpath=$(LIBRABBITMQ_LIB_PATH) -L$(LIBRABBITMQ_LIB_PATH) -lrabbitmq
LIBRABBITMQ_LIBRARY := $(LIBRABBITMQ_LIB_PATH)/librabbitmq.so
endif

$(LIBRABBITMQ_PATH)/build/include:
git submodule update --init $(LIBRABBITMQ_PATH)
mkdir $(LIBRABBITMQ_PATH)/build
ifeq ($(UNAME_S),darwin)
# macOS
cd $(LIBRABBITMQ_PATH)/build && \
cmake -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl/ -DCMAKE_INSTALL_PREFIX=. .. && \
cmake --build . --target install
else
cd $(LIBRABBITMQ_PATH)/build && \
cmake -DCMAKE_INSTALL_PREFIX=. .. && \
cmake --build . --target install
endif

$(LIBRABBITMQ_LIBRARY):
cd $(LIBRABBITMQ_PATH)/build && \
cmake --build .
13 changes: 12 additions & 1 deletion src/common.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
#ifndef COMMON_H_
#define COMMON_H_

#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <time.h>

#define __DCURL_MAJOR__ 0
#define __DCURL_MINOR__ 1
#define __DCURL_MINOR__ 4
#define __DCURL_PATCH__ 0

double diff_in_second(struct timespec t1, struct timespec t2);

static inline void ddprintf(const char *format, ...) {
#if defined(ENABLE_DEBUG)
va_list ap;
va_start(ap, format);
vprintf(format, ap);
va_end(ap);
#endif
}

typedef struct _pow_info PoW_Info;

struct _pow_info {
Expand Down
39 changes: 39 additions & 0 deletions src/dcurl.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
#if defined(ENABLE_FPGA_ACCEL)
#include "pow_fpga_accel.h"
#endif
#if defined(ENABLE_REMOTE)
#include "remote_interface.h"
#endif
#include "implcontext.h"
#include "trinary.h"
#include "uv.h"
Expand Down Expand Up @@ -48,6 +51,11 @@ extern ImplContext PoWCL_Context;
extern ImplContext PoWFPGAAccel_Context;
#endif

#if defined(ENABLE_REMOTE)
extern RemoteImplContext Remote_Context;
static uv_sem_t notify_remote;
#endif

bool dcurl_init()
{
bool ret = true;
Expand All @@ -68,6 +76,11 @@ bool dcurl_init()
ret &= registerImplContext(&PoWFPGAAccel_Context);
#endif

#if defined(ENABLE_REMOTE)
ret &= initializeRemoteContext(&Remote_Context);
uv_sem_init(&notify_remote, 0);
#endif

uv_sem_init(&notify, 0);
return isInitialized = ret;
}
Expand All @@ -77,6 +90,10 @@ void dcurl_destroy()
ImplContext *impl = NULL;
struct list_head *p;

#if defined(ENABLE_REMOTE)
destroyRemoteContext(&Remote_Context);
#endif

list_for_each (p, &IMPL_LIST) {
impl = list_entry(p, ImplContext, list);
destroyImplContext(impl);
Expand All @@ -96,6 +113,28 @@ int8_t *dcurl_entry(int8_t *trytes, int mwm, int threads)
if (!isInitialized)
return NULL;

#if defined(ENABLE_REMOTE)
do {
if (enterRemoteContext(&Remote_Context)) {
pow_ctx = getRemoteContext(&Remote_Context, trytes, mwm);
goto remote_pow;
}
uv_sem_wait(&notify_remote);
} while (1);

remote_pow:
if (!doRemoteContext(&Remote_Context, pow_ctx)) {
goto local_pow;
} else {
res = getRemoteResult(&Remote_Context, pow_ctx);
}
freeRemoteContext(&Remote_Context, pow_ctx);
exitRemoteContext(&Remote_Context);
uv_sem_post(&notify_remote);
return res;

local_pow:
#endif
do {
list_for_each (p, &IMPL_LIST) {
impl = list_entry(p, ImplContext, list);
Expand Down
6 changes: 2 additions & 4 deletions src/implcontext.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,10 @@ bool registerImplContext(ImplContext *impl_ctx)
bool initializeImplContext(ImplContext *impl_ctx)
{
bool res = impl_ctx->initialize(impl_ctx);
#if defined(ENABLE_DEBUG)
if (res) {
printf(MSG_PREFIX "Implementation %s is initialized successfully\n",
impl_ctx->description);
ddprintf(MSG_PREFIX "Implementation %s is initialized successfully\n",
impl_ctx->description);
}
#endif
return res;
}

Expand Down
Loading

0 comments on commit 631d15c

Please sign in to comment.