From 6c2265f8c9c900b01b2907181c594125ba0a67a4 Mon Sep 17 00:00:00 2001 From: "Michael Bradley, Jr" Date: Mon, 10 Aug 2020 11:48:30 -0500 Subject: [PATCH] feat: introduce Nim impl of generateAlias Closes #32 --- .gitignore | 1 + .gitmodules | 3 + Makefile | 135 +- config.nims | 8 - nim_status.nimble | 7 +- src/nim_status.nim | 4 +- src/nim_status/c/lib.nim | 3 + src/nim_status/c/lib/shim.nim | 6 + src/nim_status/c/nim_status.nim | 2 +- src/nim_status/lib.nim | 21 +- src/nim_status/lib/alias.nim | 25 + src/nim_status/lib/alias/data.nim | 3102 +++++++++++++++++++++++++++++ src/nim_status/lib/shim.nim | 2 + src/nim_status/lib/util.nim | 14 +- tests/c/login.c | 6 - tests/c/shims.c | 28 + tests/c/shims.nim | 2 + tests/nim/login.nim | 17 +- tests/nim/shims.nim | 44 +- vendor/nim-secp256k1 | 1 + vendor/nim-stew | 2 +- vendor/nimbus-build-system | 2 +- vendor/status-go | 2 +- 23 files changed, 3377 insertions(+), 60 deletions(-) create mode 100644 src/nim_status/lib/alias.nim create mode 100644 src/nim_status/lib/alias/data.nim create mode 160000 vendor/nim-secp256k1 diff --git a/.gitignore b/.gitignore index 0640dfc..bad4363 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .vscode bin/ /bottles/ +/DLLs/ build/ vendor/.nimble tmp diff --git a/.gitmodules b/.gitmodules index 5eae78a..0d131f1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -28,3 +28,6 @@ [submodule "vendor/nim-json-serialization"] path = vendor/nim-json-serialization url = https://github.com/status-im/nim-json-serialization.git +[submodule "vendor/nim-secp256k1"] + path = vendor/nim-secp256k1 + url = https://github.com/status-im/nim-secp256k1.git diff --git a/Makefile b/Makefile index a42410b..017b11f 100644 --- a/Makefile +++ b/Makefile @@ -26,8 +26,8 @@ BUILD_SYSTEM_DIR := vendor/nimbus-build-system nim_status \ status-go \ test \ - test-shims-c \ - test-login-c \ + test-c-shims \ + test-c-login \ tests \ tests-c \ tests-nim \ @@ -67,8 +67,12 @@ ifeq ($(detected_OS),Darwin) export CGO_CFLAGS CFLAGS := -mmacosx-version-min=10.13 export CFLAGS + LIBSTATUS_EXT := dylib +else ifeq ($(detected_OS),Windows) + LIBSTATUS_EXT := dll else BOTTLES_TARGET := bottles-dummy + LIBSTATUS_EXT := so endif bottles: $(BOTTLES_TARGET) @@ -98,72 +102,144 @@ $(BOTTLE_PCRE): bottles-macos: | $(BOTTLE_OPENSSL) $(BOTTLE_PCRE) rm -rf bottles/Downloads -deps: | deps-common bottles +ifeq ($(detected_OS),Darwin) + NIM_DEP_LIBS := bottles/openssl/lib/libcrypto.a \ + bottles/openssl/lib/libssl.a \ + bottles/pcre/lib/libpcre.a +else ifeq ($(detected_OS),Linux) + NIM_DEP_LIBS := -lcrypto -lssl -lpcre +endif + +NIM_WINDOWS_PREBUILT_DLLS ?= DLLs/pcre.dll +NIM_WINDOWS_PREBUILT_DLLDIR := $(shell pwd)/$(shell dirname "$(NIM_WINDOWS_PREBUILT_DLLS)") + +$(NIM_WINDOWS_PREBUILT_DLLS): +ifeq ($(detected_OS),Windows) + echo -e "\e[92mFetching:\e[39m prebuilt DLLs from nim-lang.org" + rm -rf DLLs + mkdir -p DLLs + cd DLLs && \ + wget https://nim-lang.org/download/dlls.zip && \ + unzip dlls.zip +endif + +deps: | deps-common bottles $(NIM_WINDOWS_PREBUILT_DLLS) update: | update-common ifeq ($(detected_OS),Darwin) - NIM_PARAMS := $(NIM_PARAMS) -L:"-framework Foundation -framework Security -framework IOKit -framework CoreServices" + FRAMEWORKS := -framework CoreFoundation -framework CoreServices -framework IOKit -framework Security + NIM_PARAMS := $(NIM_PARAMS) -L:"$(FRAMEWORKS)" endif # TODO: control debug/release builds with a Make var # We need `-d:debug` to get Nim's default stack traces. NIM_PARAMS += -d:debug -STATUSGO := vendor/status-go/build/bin/libstatus.a +STATUSGO := vendor/status-go/build/bin/libstatus.$(LIBSTATUS_EXT) +STATUSGO_LIBDIR := $(shell pwd)/$(shell dirname "$(STATUSGO)") +export STATUSGO_LIBDIR status-go: $(STATUSGO) $(STATUSGO): | deps echo -e $(BUILD_MSG) "status-go" + cd vendor/status-go && \ - $(MAKE) statusgo-library $(HANDLE_OUTPUT) + $(MAKE) statusgo-shared-library $(HANDLE_OUTPUT) NIMSTATUS := build/nim_status.a nim_status: | $(NIMSTATUS) $(NIMSTATUS): | deps echo -e $(BUILD_MSG) "$@" && \ - $(ENV_SCRIPT) nim c $(NIM_PARAMS) --app:staticLib --header --noMain --nimcache:nimcache/nim_status -o:$@ src/nim_status/c/nim_status.nim - cp nimcache/nim_status/nim_status.h build/nim_status.h - mv nim_status.a build/ + $(ENV_SCRIPT) nim c \ + $(NIM_PARAMS) \ + --app:staticLib \ + --header \ + --noMain \ + -o:$@ \ + src/nim_status/c/nim_status.nim + cp nimcache/debug/nim_status/nim_status.h build/nim_status.h + mv nim_status.a build/ SHIMS := tests/c/build/shims.a shims: | $(SHIMS) $(SHIMS): | deps echo -e $(BUILD_MSG) "$@" && \ - $(ENV_SCRIPT) nim c $(NIM_PARAMS) --app:staticLib --header --noMain --nimcache:nimcache/nim_status -o:$@ tests/c/shims.nim - cp nimcache/nim_status/shims.h tests/c/build/shims.h + $(ENV_SCRIPT) nim c \ + $(NIM_PARAMS) \ + --app:staticLib \ + --header \ + --noMain \ + -o:$@ \ + tests/c/shims.nim + cp nimcache/debug/shims/shims.h tests/c/build/shims.h mv shims.a tests/c/build/ -test-shims-c: | $(STATUSGO) clean-data-dirs create-data-dirs $(SHIMS) +test-c-template: | $(STATUSGO) clean-data-dirs create-data-dirs mkdir -p tests/c/build - echo "Compiling 'tests/c/shims'" + echo "Compiling 'tests/c/$(TEST_NAME)'" + $(ENV_SCRIPT) $(CC) \ + $(TEST_INCLUDES) \ + -I"$(CURDIR)/vendor/nimbus-build-system/vendor/Nim/lib" \ + tests/c/$(TEST_NAME).c \ + $(TEST_DEPS) \ + $(NIM_DEP_LIBS) \ + -L$(STATUSGO_LIBDIR) \ + -lstatus \ + $(FRAMEWORKS) \ + -lm \ + -pthread \ + -o tests/c/build/$(TEST_NAME) + [[ $(detected_OS) = Darwin ]] && \ + install_name_tool -add_rpath \ + "$(STATUSGO_LIBDIR)" \ + tests/c/build/$(TEST_NAME) && \ + install_name_tool -change \ + libstatus.dylib \ + @rpath/libstatus.dylib \ + tests/c/build/$(TEST_NAME) || true + echo "Executing 'tests/c/build/$(TEST_NAME)'" ifeq ($(detected_OS),Darwin) - $(ENV_SCRIPT) $(CC) -I"$(CURDIR)/tests/c/build" -I"$(CURDIR)/vendor/nimbus-build-system/vendor/Nim/lib" tests/c/shims.c $(SHIMS) $(STATUSGO) -framework CoreFoundation -framework CoreServices -framework IOKit -framework Security -lm -pthread -o tests/c/build/shims + ./tests/c/build/$(TEST_NAME) +else ifeq ($(detected_OS),Windows) + PATH="$(STATUSGO_LIBDIR)":"$(NIM_WINDOWS_PREBUILT_DLLDIR)":/usr/bin:/bin:"$(PATH)" \ + ./tests/c/build/$(TEST_NAME) else - $(ENV_SCRIPT) $(CC) -I"$(CURDIR)/tests/c/build" -I"$(CURDIR)/vendor/nimbus-build-system/vendor/Nim/lib" tests/c/shims.c $(SHIMS) $(STATUSGO) -lm -pthread -o tests/c/build/shims + LD_LIBRARY_PATH="$(STATUSGO_LIBDIR)" \ + ./tests/c/build/$(TEST_NAME) endif - echo "Executing 'tests/c/build/shims'" - $(ENV_SCRIPT) ./tests/c/build/shims -test-login-c: | $(STATUSGO) clean-data-dirs create-data-dirs $(NIMSTATUS) - mkdir -p tests/c/build - echo "Compiling 'tests/c/login'" -ifeq ($(detected_OS),Darwin) - $(ENV_SCRIPT) $(CC) -I"$(CURDIR)/build" -I"$(CURDIR)/vendor/nimbus-build-system/vendor/Nim/lib" tests/c/login.c $(NIMSTATUS) $(STATUSGO) -framework CoreFoundation -framework CoreServices -framework IOKit -framework Security -lm -pthread -o tests/c/build/login -else - $(ENV_SCRIPT) $(CC) -I"$(CURDIR)/build" -I"$(CURDIR)/vendor/nimbus-build-system/vendor/Nim/lib" tests/c/login.c $(NIMSTATUS) $(STATUSGO) -lm -pthread -o tests/c/build/login -endif - echo "Executing 'tests/c/build/login'" - $(ENV_SCRIPT) ./tests/c/build/login +SHIMS_INCLUDES := -I\"$(CURDIR)/tests/c/build\" + +test-c-shims: | $(SHIMS) + $(MAKE) TEST_DEPS=$(SHIMS) \ + TEST_INCLUDES=$(SHIMS_INCLUDES) \ + TEST_NAME=shims \ + test-c-template + +LOGIN_INCLUDES := -I\"$(CURDIR)/build\" + +test-c-login: | $(NIMSTATUS) + $(MAKE) TEST_DEPS=$(NIMSTATUS) \ + TEST_INCLUDES=$(LOGIN_INCLUDES) \ + TEST_NAME=login \ + test-c-template tests-c: - $(MAKE) test-shims-c - $(MAKE) test-login-c + $(MAKE) test-c-shims + $(MAKE) test-c-login tests-nim: | $(STATUSGO) +ifeq ($(detected_OS),Darwin) $(ENV_SCRIPT) nimble test +else ifeq ($(detected_OS),Windows) + PATH="$(STATUSGO_LIBDIR)":"$(NIM_WINDOWS_PREBUILT_DLLDIR)":/usr/bin:/bin:"$(PATH)" \ + $(ENV_SCRIPT) nimble test +else + LD_LIBRARY_PATH="$(STATUSGO_LIBDIR)" \ + $(ENV_SCRIPT) nimble test +endif tests: tests-nim tests-c @@ -172,6 +248,7 @@ test: tests clean: | clean-common clean-build-dirs clean-data-dirs rm -rf $(STATUSGO) rm -rf bottles + rm -rf DLLs clean-build-dirs: rm -rf build/* diff --git a/config.nims b/config.nims index b90a45b..b109194 100644 --- a/config.nims +++ b/config.nims @@ -12,10 +12,6 @@ if defined(macosx): --dynliboverrideall # don't use dlopen() --tlsEmulation:off switch("passL", "-lstdc++") - # statically linke these libs - switch("passL", "bottles/openssl/lib/libcrypto.a") - switch("passL", "bottles/openssl/lib/libssl.a") - switch("passL", "bottles/pcre/lib/libpcre.a") # https://code.videolan.org/videolan/VLCKit/-/issues/232 switch("passL", "-Wl,-no_compact_unwind") # set the minimum supported macOS version to 10.13 @@ -25,9 +21,6 @@ elif defined(windows): switch("passL", "-Wl,-as-needed") else: --dynliboverrideall # don't use dlopen() - # dynamically link these libs, since we're opting out of dlopen() - switch("passL", "-lcrypto") - switch("passL", "-lssl") # don't link libraries we're not actually using switch("passL", "-Wl,-as-needed") @@ -39,4 +32,3 @@ switch("warning", "ObservableStores:off") # Too many false positives for "Warning: method has lock level , but another method has 0 [LockLevel]" switch("warning", "LockLevel:off") - diff --git a/nim_status.nimble b/nim_status.nimble index 9df91e1..176ede9 100644 --- a/nim_status.nimble +++ b/nim_status.nimble @@ -24,7 +24,12 @@ proc buildAndRunBinary(name: string, srcDir = "./", params = "", cmdParams = "", var extra_params = params for i in 2.. 2 and str[0..1] == "0x" + str.len > 2 and + str.len mod 2 == 0 and + str[0..1] == "0x" and + match(str[2..str.len-1], rePubKey) + +proc isPubKey*(str: string): bool = + str.len == 132 and + str[0..3] == "0x04" and + match(str[2..str.len-1], rePubKey) diff --git a/tests/c/login.c b/tests/c/login.c index 4b17cd1..48e3f57 100644 --- a/tests/c/login.c +++ b/tests/c/login.c @@ -15,12 +15,6 @@ int main(int argc, char* argv[]) { // in the compiled library NimMain(); - char* pubKey = "0x0441ccda1563d69ac6b2e53718973c4e7280b4a5d8b3a09bb8bce9ebc5f082778243f1a04ec1f7995660482ca4b966ab0044566141ca48d7cdef8b7375cd5b7af5"; - - const char* theIdenticon = identicon(pubKey); - - printf("Identicon: %s\n\n", theIdenticon); - printf("Create an account, login and receive signals:\n"); char* initKeystoreResult = initKeystore("./data"); diff --git a/tests/c/shims.c b/tests/c/shims.c index 7fb7b19..d71ccd2 100644 --- a/tests/c/shims.c +++ b/tests/c/shims.c @@ -15,11 +15,17 @@ void hashCmp(char* str1, char* str2, bool testSame) { } } +void generateAliasCmp(char* pubKey) { + assert(strcmp(nim_generateAlias(pubKey), go_generateAlias(pubKey)) == 0); +} + int main(int argc, char* argv[]) { // NimMain initializes Nim's garbage collector and runs top level statements // in the compiled library NimMain(); + // hashMessage + hashCmp("", "", true); hashCmp("a", "a", true); hashCmp("ab", "ab", true); @@ -44,5 +50,27 @@ int main(int argc, char* argv[]) { assert(strcmp(nim_hashMessage("0Xabcd"), nim_hashMessage("0xabcd")) != 0); assert(strcmp(go_hashMessage("0Xabcd"), go_hashMessage("0xabcd")) != 0); + char* pubKey_1 = "0x0441ccda1563d69ac6b2e53718973c4e7280b4a5d8b3a09bb8bce9ebc5f082778243f1a04ec1f7995660482ca4b966ab0044566141ca48d7cdef8b7375cd5b7af5"; + char* pubKey_2 = "0x04ee10b0d66ccb9e3da3a74f73f880e829332f2a649e759d7c82f08b674507d498d7837279f209444092625b2be691e607c5dc3da1c198d63e430c9c7810516a8f"; + char* pubKey_3 = "0x046ffe9547ebceda7696ef5a67dc28e330b6fc3911eb6b1996c9622b2d7f0e8493c46fbd07ab591d62244e36c0d051863f86b1d656361d347a830c4239ef8877f5"; + char* pubKey_4 = "0x049bdc0016c51ec7b788db9ab0c63a1fbf3f873d2f3e3b85bf1cf034ab5370858ff31894017f56705de03dbaabf3f9811193fd5323376ec38a688cc306a5bf3ef7"; + char* pubKey_5 = "0x04ffdb0fef8f8e3bd899250538bc3c651090aa5b579e9cefa38f6896d599dcd1f1326ec5cd8f749e0a7d3c0ce1c8f9126bd4be985004319769de1e83cbca9301bf"; + char* badKey_1 = "xyz"; + char* badKey_2 = "0x06abcd"; + char* badKey_3 = "0x06ffdb0fef8f8e3bd899250538bc3c651090aa5b579e9cefa38f6896d599dcd1f1326ec5cd8f749e0a7d3c0ce1c8f9126bd4be985004319769de1e83cbca9301bf"; + char* badKey_4 = "0x04ffdb0fef8f8e3bd899250538bc3c651090aa5b579e9cefa38f6896d599dcd1f1326ec5cd8f749e0a7d3c0ce1c8f9126bd4be985004319769de1e83cbca930xyz"; + + // generateAlias + + generateAliasCmp(pubKey_1); + generateAliasCmp(pubKey_2); + generateAliasCmp(pubKey_3); + generateAliasCmp(pubKey_4); + generateAliasCmp(pubKey_5); + generateAliasCmp(badKey_1); + generateAliasCmp(badKey_2); + generateAliasCmp(badKey_3); + generateAliasCmp(badKey_4); + return 0; } diff --git a/tests/c/shims.nim b/tests/c/shims.nim index b87b0cf..cfe3f44 100644 --- a/tests/c/shims.nim +++ b/tests/c/shims.nim @@ -1,7 +1,9 @@ import ../../src/nim_status/c/lib/shim as nim_shim let nim_hashMessage {.exportc.} = nim_shim.hashMessage +let nim_generateAlias {.exportc.} = nim_shim.generateAlias import ../../src/nim_status/c/go/shim as go_shim let go_hashMessage {.exportc.} = go_shim.hashMessage +let go_generateAlias {.exportc.} = go_shim.generateAlias diff --git a/tests/nim/login.nim b/tests/nim/login.nim index 9994487..f7768ec 100644 --- a/tests/nim/login.nim +++ b/tests/nim/login.nim @@ -1,9 +1,18 @@ -{.passL:"vendor/status-go/build/bin/libstatus.a"} +from os import getEnv +{.passL: "-L" & getEnv("STATUSGO_LIBDIR")} +{.passL: "-lstatus"} +when defined(linux): + {.passL: "-lcrypto"} + {.passL: "-lssl"} + {.passL: "-lpcre"} when defined(macosx): - {.passL: "-framework Foundation".} - {.passL: "-framework Security".} - {.passL: "-framework IOKit".} + {.passL: "bottles/openssl/lib/libcrypto.a"} + {.passL: "bottles/openssl/lib/libssl.a"} + {.passL: "bottles/pcre/lib/libpcre.a"} + {.passL: "-framework CoreFoundation".} {.passL: "-framework CoreServices".} + {.passL: "-framework IOKit".} + {.passL: "-framework Security".} import ../../src/nim_status import utils diff --git a/tests/nim/shims.nim b/tests/nim/shims.nim index 4f72d76..de058a6 100644 --- a/tests/nim/shims.nim +++ b/tests/nim/shims.nim @@ -1,14 +1,25 @@ -{.passL:"vendor/status-go/build/bin/libstatus.a"} +from os import getEnv +{.passL: "-L" & getEnv("STATUSGO_LIBDIR")} +{.passL: "-lstatus"} +when defined(linux): + {.passL: "-lcrypto"} + {.passL: "-lssl"} + {.passL: "-lpcre"} when defined(macosx): - {.passL: "-framework Foundation".} - {.passL: "-framework Security".} - {.passL: "-framework IOKit".} + {.passL: "bottles/openssl/lib/libcrypto.a"} + {.passL: "bottles/openssl/lib/libssl.a"} + {.passL: "bottles/pcre/lib/libpcre.a"} + {.passL: "-framework CoreFoundation".} {.passL: "-framework CoreServices".} + {.passL: "-framework IOKit".} + {.passL: "-framework Security".} import ../../src/nim_status/lib/shim as nim_shim import ../../src/nim_status/go/shim as go_shim import strutils +# hashMessage + proc hashCmp(str1: string, str2: string, testSame: bool): void = if testSame: assert nim_shim.hashMessage(str1) == go_shim.hashMessage(str2) @@ -40,3 +51,28 @@ hashCmp("0xabcd", "0Xabcd", false) hashCmp("0Xabcd", "0xabcd", false) assert nim_shim.hashMessage("0Xabcd") != nim_shim.hashMessage("0xabcd") assert go_shim.hashMessage("0Xabcd") != go_shim.hashMessage("0xabcd") + +const pubKey_1 = "0x0441ccda1563d69ac6b2e53718973c4e7280b4a5d8b3a09bb8bce9ebc5f082778243f1a04ec1f7995660482ca4b966ab0044566141ca48d7cdef8b7375cd5b7af5" +const pubKey_2 = "0x04ee10b0d66ccb9e3da3a74f73f880e829332f2a649e759d7c82f08b674507d498d7837279f209444092625b2be691e607c5dc3da1c198d63e430c9c7810516a8f" +const pubKey_3 = "0x046ffe9547ebceda7696ef5a67dc28e330b6fc3911eb6b1996c9622b2d7f0e8493c46fbd07ab591d62244e36c0d051863f86b1d656361d347a830c4239ef8877f5" +const pubKey_4 = "0x049bdc0016c51ec7b788db9ab0c63a1fbf3f873d2f3e3b85bf1cf034ab5370858ff31894017f56705de03dbaabf3f9811193fd5323376ec38a688cc306a5bf3ef7" +const pubKey_5 = "0x04ffdb0fef8f8e3bd899250538bc3c651090aa5b579e9cefa38f6896d599dcd1f1326ec5cd8f749e0a7d3c0ce1c8f9126bd4be985004319769de1e83cbca9301bf" +const badKey_1 = "xyz" +const badKey_2 = "0x06abcd" +const badKey_3 = "0x06ffdb0fef8f8e3bd899250538bc3c651090aa5b579e9cefa38f6896d599dcd1f1326ec5cd8f749e0a7d3c0ce1c8f9126bd4be985004319769de1e83cbca9301bf" +const badKey_4 = "0x04ffdb0fef8f8e3bd899250538bc3c651090aa5b579e9cefa38f6896d599dcd1f1326ec5cd8f749e0a7d3c0ce1c8f9126bd4be985004319769de1e83cbca930xyz" + +# generateAlias + +proc generateAliasCmp(pubKey: string): void = + assert nim_shim.generateAlias(pubKey) == go_shim.generateAlias(pubKey) + +generateAliasCmp(pubKey_1) +generateAliasCmp(pubKey_2) +generateAliasCmp(pubKey_3) +generateAliasCmp(pubKey_4) +generateAliasCmp(pubKey_5) +generateAliasCmp(badKey_1) +generateAliasCmp(badKey_2) +generateAliasCmp(badKey_3) +generateAliasCmp(badKey_4) diff --git a/vendor/nim-secp256k1 b/vendor/nim-secp256k1 new file mode 160000 index 0000000..fb96997 --- /dev/null +++ b/vendor/nim-secp256k1 @@ -0,0 +1 @@ +Subproject commit fb9699702b44f194b5926c8ab4a004cff676b435 diff --git a/vendor/nim-stew b/vendor/nim-stew index ec2f52b..4c695e5 160000 --- a/vendor/nim-stew +++ b/vendor/nim-stew @@ -1 +1 @@ -Subproject commit ec2f52b0cea1f1daa33f38ca4ba289d8f40f4104 +Subproject commit 4c695e59338d752c178934f4b215d43ba72244e4 diff --git a/vendor/nimbus-build-system b/vendor/nimbus-build-system index 4fe12e1..3842641 160000 --- a/vendor/nimbus-build-system +++ b/vendor/nimbus-build-system @@ -1 +1 @@ -Subproject commit 4fe12e1cfd7b4bce6d9802024342662f372bd5e5 +Subproject commit 384264142c93d5f47340fb91fd0a7fa851f5630f diff --git a/vendor/status-go b/vendor/status-go index 157f20a..4e9928a 160000 --- a/vendor/status-go +++ b/vendor/status-go @@ -1 +1 @@ -Subproject commit 157f20a7c826598ddd8f9be936ffca20a4c3bacd +Subproject commit 4e9928ab5fd4879d445d58c9cbe1aaa193e516d7