Compare commits

..

No commits in common. "dev" and "main" have entirely different histories.
dev ... main

53 changed files with 1287 additions and 873 deletions

@ -1 +0,0 @@
Subproject commit 9c9346d5494688a78ea573f3bc0547ad12b9be2a

View file

@ -1,83 +0,0 @@
# Lethean Blockchain Build Configuration
# Used by: core compile
version: 1
project:
name: blockchain
type: cpp
description: "Lethean Blockchain - SASE infrastructure chain"
version: "6.0.1"
cpp:
standard: 17
build_type: Release
static: false
conan:
version: "2.21.0"
requires:
- zlib/1.3.1
- boost/1.85.0
- openssl/3.2.0
- miniupnpc/2.2.5
- jwt-cpp/0.7.1
- oatpp/1.3.0.latest
- oatpp-swagger/1.3.0.latest
tool_requires:
- cmake/3.31.9
options:
boost/*:without_test: true
registry:
url: http://forge.snider.dev:4000/api/packages/host-uk/conan
remote: conan_build
cmake:
minimum_version: "3.16"
variables:
USE_CCACHE: "ON"
options:
testnet: false
targets:
- os: linux
arch: x86_64
profile: gcc-linux-x86_64
- os: linux
arch: arm64
profile: gcc-linux-armv8
- os: darwin
arch: arm64
profile: apple-clang-armv8
- os: darwin
arch: x86_64
profile: apple-clang-x86_64
- os: windows
arch: x86_64
profile: msvc-194-x86_64
package:
generators:
- TGZ
- ZIP
- NSIS
- DEB
- RPM
vendor: Lethean
contact: support@lt.hn
website: https://lt.hn
docker:
dockerfile: utils/docker/lthn-chain/Dockerfile
image: lthn/chain
platforms:
- linux/amd64
tags:
- testnet
- "{{.Version}}"
build_args:
BUILD_THREADS: auto
BUILD_TESTNET: "1"
BUILD_STATIC: "0"
BUILD_TYPE: Release

View file

@ -1,234 +0,0 @@
name: Build & Release
on:
workflow_dispatch:
push:
branches:
- dev
- main
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
FORGEJO_URL: ${{ github.server_url }}
jobs:
# ──────────────────────────────────────────────
# Linux x86_64 — native build on snider-linux
# ──────────────────────────────────────────────
build-linux:
name: Linux x86_64
runs-on: linux-native
env:
CPU_CORES: "24"
steps:
- name: Checkout
uses: https://code.forgejo.org/actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
submodules: false
- name: Init submodules
run: |
git config --global url."${{ env.FORGEJO_URL }}/".insteadOf "http://forge.snider.dev:4000/"
git -c http.extraHeader="Authorization: token ${{ secrets.RELEASE_TOKEN }}" submodule update --init --recursive
git submodule foreach --recursive 'git fetch --tags origin 2>/dev/null || true'
- name: Build dependencies
run: |
make build-deps \
CPU_CORES=${{ env.CPU_CORES }} \
CONAN_URL=${{ env.FORGEJO_URL }}/api/packages/host-uk/conan \
CONAN_USER=claude \
CONAN_PASSWORD=${{ secrets.RELEASE_TOKEN }}
- name: Compile
run: |
make ${{ github.ref_name == 'main' && 'mainnet' || 'testnet' }} \
CPU_CORES=${{ env.CPU_CORES }} \
CONAN_URL=${{ env.FORGEJO_URL }}/api/packages/host-uk/conan \
CONAN_USER=claude \
CONAN_PASSWORD=${{ secrets.RELEASE_TOKEN }}
- name: Upload artifacts
uses: https://code.forgejo.org/forgejo/upload-artifact@v4
with:
name: linux-x86_64
path: build/packages/lethean-*
retention-days: 7
# ──────────────────────────────────────────────
# macOS ARM64 — native build on M3 Ultra
# ──────────────────────────────────────────────
build-macos:
name: macOS ARM64
runs-on: macos-native
env:
CPU_CORES: "24"
steps:
- name: Checkout
uses: https://code.forgejo.org/actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true
submodules: false
- name: Init submodules
run: |
git config --global url."${{ env.FORGEJO_URL }}/".insteadOf "http://forge.snider.dev:4000/"
git -c http.extraHeader="Authorization: token ${{ secrets.RELEASE_TOKEN }}" submodule update --init --recursive
git submodule foreach --recursive 'git fetch --tags origin 2>/dev/null || true'
- name: Build dependencies
run: |
export PATH="/opt/homebrew/bin:$PATH"
make build-deps \
CPU_CORES=${{ env.CPU_CORES }} \
CONAN_URL=${{ env.FORGEJO_URL }}/api/packages/host-uk/conan \
CONAN_USER=claude \
CONAN_PASSWORD=${{ secrets.RELEASE_TOKEN }}
- name: Compile
run: |
export PATH="/opt/homebrew/bin:$PATH"
make ${{ github.ref_name == 'main' && 'mainnet' || 'testnet' }} \
CPU_CORES=${{ env.CPU_CORES }} \
CONAN_URL=${{ env.FORGEJO_URL }}/api/packages/host-uk/conan \
CONAN_USER=claude \
CONAN_PASSWORD=${{ secrets.RELEASE_TOKEN }}
- name: Upload artifacts
uses: https://code.forgejo.org/forgejo/upload-artifact@v4
with:
name: macos-arm64
path: build/packages/lethean-*
retention-days: 7
# ──────────────────────────────────────────────
# Aggregate artifacts and create release
# ──────────────────────────────────────────────
release:
name: Create Release
needs: [build-linux, build-macos]
runs-on: linux-native
steps:
- name: Checkout
uses: https://code.forgejo.org/actions/checkout@v4
with:
fetch-depth: 1
submodules: false
- name: Download Linux artifacts
uses: https://code.forgejo.org/forgejo/download-artifact@v4
with:
name: linux-x86_64
path: artifacts/linux
- name: Download macOS artifacts
uses: https://code.forgejo.org/forgejo/download-artifact@v4
with:
name: macos-arm64
path: artifacts/macos
- name: List artifacts
run: find artifacts/ -type f | sort
- name: Compute release tag
id: release
run: |
VERSION=$(grep '^BUILD_VERSION:=' Makefile | cut -d'=' -f2)
if [ "${{ github.ref_name }}" = "main" ]; then
TAG="v${VERSION}+${{ github.run_number }}"
PRERELEASE=false
TITLE="v${VERSION} (build ${{ github.run_number }})"
else
TAG="v${VERSION}-beta+${{ github.run_number }}"
PRERELEASE=true
TITLE="v${VERSION}-beta (build ${{ github.run_number }})"
fi
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
echo "prerelease=${PRERELEASE}" >> "$GITHUB_OUTPUT"
echo "title=${TITLE}" >> "$GITHUB_OUTPUT"
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
- name: Create release
id: create_release
run: |
RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \
"${{ env.FORGEJO_URL }}/api/v1/repos/${{ github.repository }}/releases" \
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" \
-H "Content-Type: application/json" \
-d "{
\"tag_name\": \"${{ steps.release.outputs.tag }}\",
\"target_commitish\": \"${{ github.sha }}\",
\"name\": \"${{ steps.release.outputs.title }}\",
\"body\": \"Automated build from \`${{ github.ref_name }}\` branch (run #${{ github.run_number }})\n\n## Platforms\n- Linux x86_64\n- macOS ARM64 (Apple Silicon)\",
\"draft\": false,
\"prerelease\": ${{ steps.release.outputs.prerelease }}
}")
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
BODY=$(echo "$RESPONSE" | sed '$d')
if [ "$HTTP_CODE" -ge 400 ]; then
echo "Failed to create release (HTTP ${HTTP_CODE}):"
echo "$BODY"
exit 1
fi
RELEASE_ID=$(echo "$BODY" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
echo "id=${RELEASE_ID}" >> "$GITHUB_OUTPUT"
echo "Created release ID: ${RELEASE_ID}"
- name: Upload release assets
run: |
for dir in artifacts/linux artifacts/macos; do
for file in "$dir"/lethean-*; do
[ -f "$file" ] || continue
FILENAME=$(basename "$file")
echo "Uploading: ${FILENAME}"
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST \
"${{ env.FORGEJO_URL }}/api/v1/repos/${{ github.repository }}/releases/${{ steps.create_release.outputs.id }}/assets?name=${FILENAME}" \
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" \
-H "Content-Type: application/octet-stream" \
--data-binary "@${file}")
if [ "$HTTP_CODE" -ge 400 ]; then
echo "Failed to upload ${FILENAME} (HTTP ${HTTP_CODE})"
exit 1
fi
echo "Uploaded ${FILENAME} (HTTP ${HTTP_CODE})"
done
done
- name: Prune old releases
run: |
TAG_PREFIX="${{ github.ref_name == 'main' && 'v6' || 'v6.*-beta' }}"
CURRENT_ID="${{ steps.create_release.outputs.id }}"
echo "Keeping release ${CURRENT_ID}, pruning older ${TAG_PREFIX} releases..."
PAGE=1
while true; do
RELEASES=$(curl -s "${{ env.FORGEJO_URL }}/api/v1/repos/${{ github.repository }}/releases?limit=50&page=${PAGE}" \
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}")
COUNT=$(echo "$RELEASES" | python3 -c "import sys,json; print(len(json.load(sys.stdin)))" 2>/dev/null || echo 0)
[ "$COUNT" = "0" ] && break
echo "$RELEASES" | python3 -c "
import sys, json, fnmatch
for r in json.load(sys.stdin):
rid = r['id']
tag = r['tag_name']
if rid == ${CURRENT_ID}:
continue
if fnmatch.fnmatch(tag, '${TAG_PREFIX}*'):
print(f'{rid} {tag}')
" | while read -r RID RTAG; do
echo "Deleting release ${RTAG} (id=${RID})"
curl -s -o /dev/null -X DELETE \
"${{ env.FORGEJO_URL }}/api/v1/repos/${{ github.repository }}/releases/${RID}" \
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}"
curl -s -o /dev/null -X DELETE \
"${{ env.FORGEJO_URL }}/api/v1/repos/${{ github.repository }}/tags/${RTAG}" \
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}"
done
PAGE=$((PAGE + 1))
done
echo "Prune complete"

6
.gitmodules vendored
View file

@ -10,9 +10,3 @@
[submodule "docs"]
path = docs
url = https://github.com/letheanVPN/documentation.git
[submodule "contrib/randomx"]
path = contrib/randomx
url = https://github.com/tevador/RandomX.git
[submodule ".core/build"]
path = .core/build
url = http://forge.snider.dev:4000/host-uk/build.git

View file

@ -10,7 +10,7 @@ set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
list(INSERT CMAKE_MODULE_PATH 0
"${CMAKE_CURRENT_SOURCE_DIR}/.core/build/cmake")
"${CMAKE_CURRENT_SOURCE_DIR}/cmake")
if(POLICY CMP0043)
cmake_policy(SET CMP0043 NEW)

View file

@ -18,7 +18,7 @@
"cacheVariables": {
"TESTNET": "ON",
"CMAKE_BUILD_TYPE": "Release",
"CMAKE_PROJECT_TOP_LEVEL_INCLUDES":".core/build/cmake/ConanProvider.cmake"
"CMAKE_PROJECT_TOP_LEVEL_INCLUDES":"cmake/ConanProvider.cmake"
}
},
{
@ -30,7 +30,7 @@
"cacheVariables": {
"TESTNET": "OFF",
"CMAKE_BUILD_TYPE": "Release",
"CMAKE_PROJECT_TOP_LEVEL_INCLUDES":".core/build/cmake/ConanProvider.cmake"
"CMAKE_PROJECT_TOP_LEVEL_INCLUDES":"cmake/ConanProvider.cmake"
}
}
],

View file

@ -4,6 +4,6 @@
"conan": {}
},
"include": [
"build/release/generators/CMakePresets.json"
"build/release/conan/build/debug/generators/CMakePresets.json"
]
}

View file

@ -4,15 +4,12 @@
# Distributed under the MIT/X11 software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
# ============================================================
# Build system from host-uk/build submodule
# ============================================================
BUILD_SYS := .core/build
CMAKE_DIR := $(BUILD_SYS)/cmake
# ------------------------------------------------------------
# Detect the number of logical CPU cores works on Linux,
# macOS, BSD, and Windows (both cmd.exe and PowerShell).
# ------------------------------------------------------------
# ============================================================
# Project Configuration
# ============================================================
# Default to “unknown” will be overwritten below.
CPU_CORES := 1
TESTNET:= 0
STATIC:= 0
@ -22,22 +19,21 @@ BUILD_FOLDER:=build/release
PRESET_BUILD:=conan-release
PRESET_CONFIGURE:=conan-release
# ------------------------------------------------------------
# Detect the number of logical CPU cores works on Linux,
# macOS, BSD, and Windows (both cmd.exe and PowerShell).
# ------------------------------------------------------------
UNAME_S := $(shell uname -s 2>/dev/null || echo Unknown)
ifeq ($(UNAME_S),Linux)
# Linux: try nproc first, fall back to /proc
CPU_CORES := $(shell nproc 2>/dev/null || \
grep -c ^processor /proc/cpuinfo 2>/dev/null || echo 1)
endif
ifeq ($(UNAME_S),Darwin)
# macOS: sysctl reports the number of logical CPUs
CPU_CORES := $(shell sysctl -n hw.logicalcpu 2>/dev/null || echo 1)
endif
ifeq ($(filter %BSD,$(UNAME_S)),%BSD)
# *BSD: also sysctl, but the key differs on some variants
CPU_CORES := $(shell sysctl -n hw.ncpu 2>/dev/null || echo 1)
endif
@ -45,27 +41,29 @@ ifeq ($(OS),Windows_NT)
PRESET_CONFIGURE:=conan-default
# Prefer the environment variable that Windows sets for us.
# It works in both cmd.exe and PowerShell.
CPU_CORES := $(NUMBER_OF_PROCESSORS)
# If for some reason the env var is empty, fall back to PowerShell.
ifeq ($(CPU_CORES),)
CPU_CORES := $(shell powershell -NoProfile -Command ^ "[Environment]::ProcessorCount")
endif
endif
# Safety net
# -----------------------------------------------------------------
# Safety net ensure we always have a positive integer.
# -----------------------------------------------------------------
CPU_CORES := $(or $(CPU_CORES),1)
CPU_CORES := $(shell expr $(CPU_CORES) + 0 2>/dev/null || echo 1)
CONAN_CPU_COUNT=$(CPU_CORES)
# ============================================================
# Paths — profiles and cmake modules from .build submodule
# ============================================================
PROFILES :=$(patsubst $(CMAKE_DIR)/profiles/%,%,$(wildcard $(CMAKE_DIR)/profiles/*))
PROFILES :=$(patsubst cmake/profiles/%,%,$(wildcard cmake/profiles/*))
SORTED_PROFILES :=$(sort $(PROFILES))
CONAN_CACHE :=$(CURDIR)/build/sdk
CONAN_URL :=http://forge.snider.dev:4000/api/packages/host-uk/conan
CONAN_USER ?=$(shell echo $$CONAN_USER)
CONAN_PASSWORD ?=$(shell echo $$CONAN_PASSWORD)
CONAN_URL :=https://artifacts.host.uk.com/artifactory/api/conan/conan-build
CONAN_USER :=public
CONAN_PASSWORD :=Lethean1234
CONAN_EXECUTABLE :=$(CURDIR)/build/bin/conan
CC_DOCKER_FILE ?=utils/docker/images/lthn-chain/Dockerfile
SDK_PACKAGES_JSON :=$(wildcard utils/sdk/packages/*.json)
@ -113,10 +111,10 @@ docs: configure
sdk:
$(MAKE) -C utils/sdk $(filter-out $@,$(MAKECMDGOALS)) PACKAGE_VERSION=$(BUILD_VERSION)
# Rule for each profile — uses .build/cmake/profiles/
# Rule for each profile
$(PROFILES): conan-profile-detect
@echo "Building profile: $@"
CONAN_HOME=$(CONAN_CACHE) $(CONAN_EXECUTABLE) install . -pr:h=$(CMAKE_DIR)/profiles/$@ --build=missing -s build_type=$(BUILD_TYPE)
CONAN_HOME=$(CONAN_CACHE) $(CONAN_EXECUTABLE) install . -pr:h=cmake/profiles/$@ --build=missing -s build_type=$(BUILD_TYPE)
cmake -S . -B $(BUILD_FOLDER) -DCMAKE_TOOLCHAIN_FILE=$(BUILD_FOLDER)/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) -DSTATIC=$(STATIC) -DTESTNET=$(TESTNET) -DBUILD_VERSION=$(BUILD_VERSION)
cmake --build $(BUILD_FOLDER) --config=$(BUILD_TYPE) --parallel=$(CPU_CORES)
(cd $(BUILD_FOLDER) && cpack)
@ -130,10 +128,10 @@ help:
@echo ""
@echo "Available targets:"
@printf " %-42s %s\n" "make clean" "Clean all build directories"
@printf " %-42s %s\n" "make conan-get" "Download and install conan locally"
@printf " %-42s %s\n" "make get-conan" "Download and install conan locally"
@printf " %-42s %s\n" "make release" "Build release"
@printf " %-42s %s\n" "make testnet" "Build testnet"
@printf " %-42s %s\n" "make mainnet" "Build mainnet"
@printf " %-42s %s\n" "make static" "Build static release"
@printf " %-42s %s\n" "make debug" "Build debug"
@printf " %-42s %s\n" "make test" "Build & run tests"
@printf " %-42s %s\n" "make docs" "Builds offline documentation website"
@printf " %-42s %s\n" "make docs-dev" "Runs local doc server, for editing/adding docs"
@ -163,19 +161,17 @@ test-debug:
cmake --build build/test-debug --config=Debug --parallel=$(CPU_CORES)
$(MAKE) test
# Conan management — cmake modules from .build submodule
# allowing this target to error quietly saves cross brwoser file detection
conan-get:
cmake -P $(CMAKE_DIR)/ConanGet.cmake
ifneq ($(CONAN_USER),)
cmake -P cmake/ConanGet.cmake
(CONAN_HOME=$(CONAN_CACHE) $(CONAN_EXECUTABLE) remote add conan_build $(CONAN_URL) && \
CONAN_HOME=$(CONAN_CACHE) $(CONAN_EXECUTABLE) remote login conan_build $(CONAN_USER) -p $(CONAN_PASSWORD)) || true
endif
conan-upload:
CONAN_HOME=$(CONAN_CACHE) $(CONAN_EXECUTABLE) upload "*" -r=conan_build --confirm
conan-profile-detect: conan-get
cmake -P $(CMAKE_DIR)/ConanProfileSetup.cmake
cmake -P cmake/ConanProfileSetup.cmake
docs-dev: configure
@echo "Building Documentation"
@ -185,7 +181,7 @@ $(SDK_TARGETS):
@# This is a proxy target. Handled by the 'sdk' rule.
clean:
@cmake -P $(CMAKE_DIR)/CleanBuild.cmake
@cmake -P cmake/CleanBuild.cmake
clean-build: clean
rm -rf build
@ -193,4 +189,5 @@ clean-build: clean
tags:
ctags -R --sort=1 --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ src contrib tests/gtest
.PHONY: all release upload-conan-cache docs docs-dev configure static static-release test test-release test-debug clean tags conan-profile-detect conan-get $(PROFILES) sdk $(SDK_TARGETS)
.PHONY: all release upload-conan-cache docs docs-dev configure static static-release test test-release test-debug clean tags conan-profile-detect get-conan $(PROFILES) sdk $(SDK_TARGETS)
.PHONY: go-client

88
cmake/CPackConfig.cmake Normal file
View file

@ -0,0 +1,88 @@
if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo" OR CMAKE_BUILD_TYPE STREQUAL "MinSizeRel" OR CMAKE_BUILD_TYPE STREQUAL "")
set(CPACK_PACKAGE_NAME "${package_name}")
set(CPACK_PACKAGE_VENDOR "${package_vendor}")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${package_description}")
set(CPACK_PACKAGE_VERSION "${BUILD_VERSION}")
set(CPACK_PACKAGE_CONTACT "${package_contact}")
set(CPACK_PACKAGE_HOMEPAGE_URL "${package_website}")
#set(CPACK_PACKAGING_INSTALL_PREFIX "/usr/local") # Linux/macOS default
#if(WIN32)
# set(CPACK_PACKAGING_INSTALL_PREFIX "C:/Program Files/${PROJECT_NAME}")
#endif()
if(APPLE)
if("${package_macos_installer}" STREQUAL "DMG")
# set(CPACK_GENERATOR "DragNDrop")
# set(CPACK_DMG_BACKGROUND_IMAGE "${CMAKE_SOURCE_DIR}/resources/dmg_background.png")
# set(CPACK_DMG_VOLUME_NAME "${CPACK_PACKAGE_NAME} ${CPACK_PACKAGE_VERSION}")
# message(STATUS "Registered CPACK_GENERATOR: DragNDrop")
else ()
# set(CPACK_GENERATOR "productbuild")
# set(CPACK_PRODUCTBUILD_IDENTIFIER "${package_macos_pkg_productbuild_identifier}")
# set(CPACK_PRODUCTBUILD_SIGNING_IDENTITY "Developer ID Installer: Your Company (TEAMID)")
# message(STATUS "Registered CPACK_GENERATOR: productbuild")
endif ()
elseif(WIN32)
set(CPACK_GENERATOR "NSIS")
set(CPACK_NSIS_MODIFY_PATH ON)
set(CPACK_NSIS_HELP_LINK "https://lt.hn/getting-started/chain.html")
set(CPACK_NSIS_URL_INFO_ABOUT "https://lt.hn")
set(CPACK_NSIS_CONTACT "support@lt.hn")
set(CPACK_NSIS_UNINSTALL_NAME "Lethean CLI")
set(CPACK_NSIS_BRANDING_TEXT "Lethean Community")
set(CPACK_NSIS_MUI_FINISHPAGE_RUN "lethean-testnet-chain-node.exe")
message(STATUS "Registered CPACK_GENERATOR: Inno exe")
# set(CPACK_WIX_PRODUCT_ICON "${CMAKE_SOURCE_DIR}/resources/windows_icon.ico")
# set(CPACK_WIX_LICENSE_RTF "${CMAKE_SOURCE_DIR}/LICENSE.rtf")
# set(CPACK_WIX_UPGRADE_GUID "D3F5A9C1-4B2E-4F5A-9C71-123456789ABC") # change once per major version
else()
set(CPACK_GENERATOR "DEB")
set(CPACK_GENERATOR "RPM")
message(STATUS "Registered CPACK_GENERATOR: deb")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "${package_contact}")
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.28)")
set(CPACK_DEBIAN_PACKAGE_SECTION "utils")
set(CPACK_DEBIAN_ARCHITECTURE "${CMAKE_SYSTEM_PROCESSOR}")
# postinstall script (e.g., to register a systemd service)
# set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
# "${CMAKE_SOURCE_DIR}/scripts/postinstall.sh")
endif()
list(APPEND CPACK_GENERATOR "TXZ" "ZIP")
message(STATUS "Registered CPACK_GENERATOR: tgz")
message(STATUS "Registered CPACK_GENERATOR: zip")
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY OFF)
set(CPACK_ARCHIVE_COMPONENT_INSTALL OFF)
set(CPACK_COMPONENTS_ALL)
set(CPACK_MONOLITHIC_INSTALL OFF)
set(CPACK_PACKAGE_CHECKSUM SHA256)
message(STATUS "Using SHA256 Checksums")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE.txt")
set(CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/README.md")
set(CPACK_PACKAGE_DIRECTORY "${CMAKE_SOURCE_DIR}/build/packages")
install(FILES README.md LICENSE.txt
DESTINATION "share/doc/${PROJECT_NAME}"
)
set(_arch "${CMAKE_SYSTEM_PROCESSOR}")
if(_arch MATCHES "AMD64|x86_64")
set(_arch "x86_64")
elseif(_arch MATCHES "arm64|aarch64")
set(_arch "arm64")
endif()
string(TOLOWER "${CMAKE_SYSTEM_NAME}" _sys_name_lc)
set(CPACK_PACKAGE_FILE_NAME
"${package_name}-${CPACK_PACKAGE_VERSION}-${_sys_name_lc}-${_arch}")
include(CPack)
endif()

76
cmake/CleanBuild.cmake Normal file
View file

@ -0,0 +1,76 @@
# cmake/CleanBuild.cmake
# Function to selectively clean the build directory.
#
# This function will remove most of the generated build files from the build
# directory, while preserving specific directories that contain downloaded
# tools or generated documentation.
#
# Golden Rules:
# - never delete build/
# - never delete build/bin
# - never delete build/docs
# - never delete build/sdk (non cache)
#
# It will:
# - purge build files
# - clean up conan build files, cached sources can always remain.
function(selective_clean_build_dir)
if(EXISTS "${CMAKE_SOURCE_DIR}/build")
message(STATUS "Selectively cleaning build directory: ${CMAKE_SOURCE_DIR}/build")
# List of top-level items in the build directory to keep.
set(golden_items
"${CMAKE_SOURCE_DIR}/build/.ccache"
"${CMAKE_SOURCE_DIR}/build/bin"
"${CMAKE_SOURCE_DIR}/build/docs"
"${CMAKE_SOURCE_DIR}/build/sdk"
)
# Get all top-level items in the build directory.
file(GLOB top_level_items "${CMAKE_SOURCE_DIR}/build/*")
foreach(item ${top_level_items})
list(FIND golden_items "${item}" is_golden)
if(is_golden STREQUAL "-1")
string(FIND "${item}" "${CMAKE_SOURCE_DIR}/build" is_prefixed)
if(is_prefixed EQUAL 0)
message(STATUS "Removing: ${item}")
if(IS_DIRECTORY "${item}")
file(REMOVE_RECURSE "${item}")
else()
file(REMOVE "${item}")
endif()
else()
message(WARNING "Safety check failed: Will not remove '${item}' because it is not prefixed with CMAKE_SOURCE_DIR/build.")
endif()
else()
message(STATUS "Keeping golden item: ${item}")
endif()
endforeach()
message(STATUS "Selective clean complete.")
else()
message(STATUS "Build directory not found, skipping clean.")
endif()
endfunction()
function(reset_conan_presets)
set(CONAN_PRESETS_FILE "${CMAKE_SOURCE_DIR}/ConanPresets.json")
set(NEW_CONTENT [[{
"version": 4,
"vendor": {
"conan": {}
},
"include": [
]
}]])
message(STATUS "Resetting ${CONAN_PRESETS_FILE} to a clean state.")
file(WRITE "${CONAN_PRESETS_FILE}" "${NEW_CONTENT}")
message(STATUS "${CONAN_PRESETS_FILE} has been successfully reset.")
endfunction()
selective_clean_build_dir()
reset_conan_presets()

102
cmake/ConanGet.cmake Normal file
View file

@ -0,0 +1,102 @@
# cmake/ConanGet.cmake
# This module downloads and installs Conan if it's not found.
# Set the Conan version
set(CONAN_VERSION 2.21.0)
# Set the download URLs
set(CONAN_URL_MACOS_ARM "https://github.com/conan-io/conan/releases/download/${CONAN_VERSION}/conan-${CONAN_VERSION}-macos-arm64.tgz")
set(CONAN_URL_MACOS_INTEL "https://github.com/conan-io/conan/releases/download/${CONAN_VERSION}/conan-${CONAN_VERSION}-macos-x86_64.tgz")
set(CONAN_URL_WINDOWS_X86_64 "https://github.com/conan-io/conan/releases/download/${CONAN_VERSION}/conan-${CONAN_VERSION}-windows-x86_64.zip")
set(CONAN_URL_WINDOWS_ARM64 "https://github.com/conan-io/conan/releases/download/${CONAN_VERSION}/conan-${CONAN_VERSION}-windows-arm64.zip")
set(CONAN_URL_LINUX_X86_64 "https://github.com/conan-io/conan/releases/download/${CONAN_VERSION}/conan-${CONAN_VERSION}-linux-x86_64.tgz")
set(CONAN_URL_LINUX_AARCH64 "https://github.com/conan-io/conan/releases/download/${CONAN_VERSION}/conan-${CONAN_VERSION}-linux-aarch64.tgz")
# Set the installation directory
if(NOT CMAKE_BINARY_DIR)
set(CMAKE_BINARY_DIR "${CONAN_INSTALL_DIR}")
endif()
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
set(CONAN_INSTALL_DIR "${CMAKE_SOURCE_DIR}/build/bin")
set(CONAN_EXECUTABLE "${CMAKE_SOURCE_DIR}/build/bin/conan.exe")
else ()
set(CONAN_INSTALL_DIR "${CMAKE_SOURCE_DIR}/build")
set(CONAN_EXECUTABLE "${CONAN_INSTALL_DIR}/bin/conan")
endif ()
# Check if Conan is already installed
if(NOT EXISTS "${CONAN_EXECUTABLE}")
message(STATUS "Conan not found. Downloading and installing...")
file(MAKE_DIRECTORY "${CONAN_INSTALL_DIR}")
# Determine the processor architecture, with a fallback
if(CMAKE_HOST_SYSTEM_PROCESSOR)
set(HOST_PROCESSOR ${CMAKE_HOST_SYSTEM_PROCESSOR})
else()
cmake_host_system_information(RESULT HOST_PROCESSOR QUERY OS_PLATFORM)
endif()
# Detect the operating system and architecture
message(STATUS "Detecting OS and architecture: ${HOST_PROCESSOR} on ${CMAKE_HOST_SYSTEM_NAME}")
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
if(HOST_PROCESSOR MATCHES "arm64")
set(CONAN_URL ${CONAN_URL_MACOS_ARM})
set(CONAN_ARCHIVE_TYPE "tgz")
else()
set(CONAN_URL ${CONAN_URL_MACOS_INTEL})
set(CONAN_ARCHIVE_TYPE "tgz")
endif()
elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
if(HOST_PROCESSOR MATCHES "ARM64")
set(CONAN_URL ${CONAN_URL_WINDOWS_ARM64})
set(CONAN_ARCHIVE_TYPE "zip")
else()
set(CONAN_URL ${CONAN_URL_WINDOWS_X86_64})
set(CONAN_ARCHIVE_TYPE "zip")
endif()
elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
if(HOST_PROCESSOR MATCHES "aarch64|arm64|ARM64")
set(CONAN_URL ${CONAN_URL_LINUX_AARCH64})
set(CONAN_ARCHIVE_TYPE "tgz")
else()
set(CONAN_URL ${CONAN_URL_LINUX_X86_64})
set(CONAN_ARCHIVE_TYPE "tgz")
endif()
else()
message(FATAL_ERROR "Unsupported operating system: ${CMAKE_HOST_SYSTEM_NAME}")
endif()
# Download and extract Conan
set(CONAN_ARCHIVE "${CMAKE_BINARY_DIR}/conan.${CONAN_ARCHIVE_TYPE}")
message(STATUS "Downloading ${CONAN_URL} to ${CONAN_ARCHIVE}")
file(DOWNLOAD "${CONAN_URL}" "${CONAN_ARCHIVE}" SHOW_PROGRESS)
message(STATUS "Extracting ${CONAN_ARCHIVE} to ${CONAN_INSTALL_DIR}")
if(CONAN_ARCHIVE_TYPE STREQUAL "tgz")
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar xzf "${CONAN_ARCHIVE}"
WORKING_DIRECTORY "${CONAN_INSTALL_DIR}"
RESULT_VARIABLE result
)
elseif(CONAN_ARCHIVE_TYPE STREQUAL "zip")
# CMake -E tar can handle zip files
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar xf "${CONAN_ARCHIVE}"
WORKING_DIRECTORY "${CONAN_INSTALL_DIR}"
RESULT_VARIABLE result
)
endif()
if(NOT result EQUAL 0)
message(FATAL_ERROR "Failed to extract Conan archive.")
endif()
# Clean up the archive
file(REMOVE "${CONAN_ARCHIVE}")
message(STATUS "Conan installed successfully at ${CONAN_EXECUTABLE}")
else()
message(STATUS "Conan already installed at ${CONAN_EXECUTABLE}")
endif()

View file

@ -0,0 +1,38 @@
set(CONAN_HOME "${CMAKE_SOURCE_DIR}/build/sdk")
set(DEFAULT_PROFILE "${CONAN_HOME}/profiles/default")
if(WIN32)
set(CONAN_EXECUTABLE "${CMAKE_SOURCE_DIR}/build/bin/conan.exe")
else()
set(CONAN_EXECUTABLE "${CMAKE_SOURCE_DIR}/build/bin/conan")
endif()
if(NOT EXISTS "${DEFAULT_PROFILE}")
message(STATUS "Conan default profile not found. Detecting a new one...")
set(ENV{CONAN_HOME} "${CONAN_HOME}")
execute_process(
COMMAND "${CONAN_EXECUTABLE}" profile detect --name=default --force
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
RESULT_VARIABLE return_code
)
unset(ENV{CONAN_HOME})
if(NOT return_code EQUAL 0)
message(FATAL_ERROR "Conan profile detection failed with exit code: ${return_code}")
endif()
endif()
message(STATUS "Appending custom settings to Conan default profile...")
set(CUSTOM_SETTINGS "
compiler.cppstd=17
")
#if(WIN32)
# message(STATUS "Windows detected. Appending static runtime setting.")
# string(APPEND CUSTOM_SETTINGS "
#compiler.runtime=static
#")
#endif()
file(APPEND "${DEFAULT_PROFILE}" "${CUSTOM_SETTINGS}")
message(STATUS "Conan profile setup is complete.")

698
cmake/ConanProvider.cmake Normal file
View file

@ -0,0 +1,698 @@
# The MIT License (MIT)
#
# Copyright (c) 2024 JFrog
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
set(CONAN_MINIMUM_VERSION 2.0.5)
# Create a new policy scope and set the minimum required cmake version so the
# features behind a policy setting like if(... IN_LIST ...) behaves as expected
# even if the parent project does not specify a minimum cmake version or a minimum
# version less than this module requires (e.g. 3.0) before the first project() call.
# (see: https://cmake.org/cmake/help/latest/variable/CMAKE_PROJECT_TOP_LEVEL_INCLUDES.html)
#
# The policy-affecting calls like cmake_policy(SET...) or `cmake_minimum_required` only
# affects the current policy scope, i.e. between the PUSH and POP in this case.
#
# https://cmake.org/cmake/help/book/mastering-cmake/chapter/Policies.html#the-policy-stack
cmake_policy(PUSH)
cmake_minimum_required(VERSION 3.24)
function(detect_os os os_api_level os_sdk os_subsystem os_version)
# it could be cross compilation
message(STATUS "CMake-Conan: cmake_system_name=${CMAKE_SYSTEM_NAME}")
if(CMAKE_SYSTEM_NAME AND NOT CMAKE_SYSTEM_NAME STREQUAL "Generic")
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(${os} Macos PARENT_SCOPE)
elseif(CMAKE_SYSTEM_NAME STREQUAL "QNX")
set(${os} Neutrino PARENT_SCOPE)
elseif(CMAKE_SYSTEM_NAME STREQUAL "CYGWIN")
set(${os} Windows PARENT_SCOPE)
set(${os_subsystem} cygwin PARENT_SCOPE)
elseif(CMAKE_SYSTEM_NAME MATCHES "^MSYS")
set(${os} Windows PARENT_SCOPE)
set(${os_subsystem} msys2 PARENT_SCOPE)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
# https://github.com/emscripten-core/emscripten/blob/4.0.6/cmake/Modules/Platform/Emscripten.cmake#L17C1-L17C34
set(${os} Emscripten PARENT_SCOPE)
else()
set(${os} ${CMAKE_SYSTEM_NAME} PARENT_SCOPE)
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Android")
if(DEFINED ANDROID_PLATFORM)
string(REGEX MATCH "[0-9]+" _os_api_level ${ANDROID_PLATFORM})
elseif(DEFINED CMAKE_SYSTEM_VERSION)
set(_os_api_level ${CMAKE_SYSTEM_VERSION})
endif()
message(STATUS "CMake-Conan: android api level=${_os_api_level}")
set(${os_api_level} ${_os_api_level} PARENT_SCOPE)
endif()
if(CMAKE_SYSTEM_NAME MATCHES "Darwin|iOS|tvOS|watchOS")
# CMAKE_OSX_SYSROOT contains the full path to the SDK for MakeFile/Ninja
# generators, but just has the original input string for Xcode.
if(NOT IS_DIRECTORY ${CMAKE_OSX_SYSROOT})
set(_os_sdk ${CMAKE_OSX_SYSROOT})
else()
if(CMAKE_OSX_SYSROOT MATCHES Simulator)
set(apple_platform_suffix simulator)
else()
set(apple_platform_suffix os)
endif()
if(CMAKE_OSX_SYSROOT MATCHES AppleTV)
set(_os_sdk "appletv${apple_platform_suffix}")
elseif(CMAKE_OSX_SYSROOT MATCHES iPhone)
set(_os_sdk "iphone${apple_platform_suffix}")
elseif(CMAKE_OSX_SYSROOT MATCHES Watch)
set(_os_sdk "watch${apple_platform_suffix}")
endif()
endif()
if(DEFINED os_sdk)
message(STATUS "CMake-Conan: cmake_osx_sysroot=${CMAKE_OSX_SYSROOT}")
set(${os_sdk} ${_os_sdk} PARENT_SCOPE)
endif()
if(DEFINED CMAKE_OSX_DEPLOYMENT_TARGET)
message(STATUS "CMake-Conan: cmake_osx_deployment_target=${CMAKE_OSX_DEPLOYMENT_TARGET}")
set(${os_version} ${CMAKE_OSX_DEPLOYMENT_TARGET} PARENT_SCOPE)
endif()
endif()
endif()
endfunction()
function(detect_arch arch)
# CMAKE_OSX_ARCHITECTURES can contain multiple architectures, but Conan only supports one.
# Therefore this code only finds one. If the recipes support multiple architectures, the
# build will work. Otherwise, there will be a linker error for the missing architecture(s).
if(DEFINED CMAKE_OSX_ARCHITECTURES)
string(REPLACE " " ";" apple_arch_list "${CMAKE_OSX_ARCHITECTURES}")
list(LENGTH apple_arch_list apple_arch_count)
if(apple_arch_count GREATER 1)
message(WARNING "CMake-Conan: Multiple architectures detected, this will only work if Conan recipe(s) produce fat binaries.")
endif()
endif()
if(CMAKE_SYSTEM_NAME MATCHES "Darwin|iOS|tvOS|watchOS" AND NOT CMAKE_OSX_ARCHITECTURES STREQUAL "")
set(host_arch ${CMAKE_OSX_ARCHITECTURES})
elseif(MSVC)
set(host_arch ${CMAKE_CXX_COMPILER_ARCHITECTURE_ID})
else()
set(host_arch ${CMAKE_SYSTEM_PROCESSOR})
endif()
if(host_arch MATCHES "aarch64|arm64|ARM64")
set(_arch armv8)
elseif(host_arch MATCHES "armv7|armv7-a|armv7l|ARMV7")
set(_arch armv7)
elseif(host_arch MATCHES armv7s)
set(_arch armv7s)
elseif(host_arch MATCHES "i686|i386|X86")
set(_arch x86)
elseif(host_arch MATCHES "AMD64|amd64|x86_64|x64")
set(_arch x86_64)
endif()
if(EMSCRIPTEN)
# https://github.com/emscripten-core/emscripten/blob/4.0.6/cmake/Modules/Platform/Emscripten.cmake#L294C1-L294C80
set(_arch wasm)
endif()
message(STATUS "CMake-Conan: cmake_system_processor=${_arch}")
set(${arch} ${_arch} PARENT_SCOPE)
endfunction()
function(detect_cxx_standard cxx_standard)
set(${cxx_standard} ${CMAKE_CXX_STANDARD} PARENT_SCOPE)
if(CMAKE_CXX_EXTENSIONS)
set(${cxx_standard} "gnu${CMAKE_CXX_STANDARD}" PARENT_SCOPE)
endif()
endfunction()
macro(detect_gnu_libstdcxx)
# _conan_is_gnu_libstdcxx true if GNU libstdc++
check_cxx_source_compiles("
#include <cstddef>
#if !defined(__GLIBCXX__) && !defined(__GLIBCPP__)
static_assert(false);
#endif
int main(){}" _conan_is_gnu_libstdcxx)
# _conan_gnu_libstdcxx_is_cxx11_abi true if C++11 ABI
check_cxx_source_compiles("
#include <string>
static_assert(sizeof(std::string) != sizeof(void*), \"using libstdc++\");
int main () {}" _conan_gnu_libstdcxx_is_cxx11_abi)
set(_conan_gnu_libstdcxx_suffix "")
if(_conan_gnu_libstdcxx_is_cxx11_abi)
set(_conan_gnu_libstdcxx_suffix "11")
endif()
unset (_conan_gnu_libstdcxx_is_cxx11_abi)
endmacro()
macro(detect_libcxx)
# _conan_is_libcxx true if LLVM libc++
check_cxx_source_compiles("
#include <cstddef>
#if !defined(_LIBCPP_VERSION)
static_assert(false);
#endif
int main(){}" _conan_is_libcxx)
endmacro()
function(detect_lib_cxx lib_cxx)
if(CMAKE_SYSTEM_NAME STREQUAL "Android")
message(STATUS "CMake-Conan: android_stl=${CMAKE_ANDROID_STL_TYPE}")
set(${lib_cxx} ${CMAKE_ANDROID_STL_TYPE} PARENT_SCOPE)
return()
endif()
include(CheckCXXSourceCompiles)
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
detect_gnu_libstdcxx()
set(${lib_cxx} "libstdc++${_conan_gnu_libstdcxx_suffix}" PARENT_SCOPE)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "AppleClang")
set(${lib_cxx} "libc++" PARENT_SCOPE)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_SYSTEM_NAME MATCHES "Windows")
# Check for libc++
detect_libcxx()
if(_conan_is_libcxx)
set(${lib_cxx} "libc++" PARENT_SCOPE)
return()
endif()
# Check for libstdc++
detect_gnu_libstdcxx()
if(_conan_is_gnu_libstdcxx)
set(${lib_cxx} "libstdc++${_conan_gnu_libstdcxx_suffix}" PARENT_SCOPE)
return()
endif()
# TODO: it would be an error if we reach this point
elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
# Do nothing - compiler.runtime and compiler.runtime_type
# should be handled separately: https://github.com/conan-io/cmake-conan/pull/516
return()
else()
# TODO: unable to determine, ask user to provide a full profile file instead
endif()
endfunction()
function(detect_compiler compiler compiler_version compiler_runtime compiler_runtime_type)
if(DEFINED CMAKE_CXX_COMPILER_ID)
set(_compiler ${CMAKE_CXX_COMPILER_ID})
set(_compiler_version ${CMAKE_CXX_COMPILER_VERSION})
else()
if(NOT DEFINED CMAKE_C_COMPILER_ID)
message(FATAL_ERROR "C or C++ compiler not defined")
endif()
set(_compiler ${CMAKE_C_COMPILER_ID})
set(_compiler_version ${CMAKE_C_COMPILER_VERSION})
endif()
message(STATUS "CMake-Conan: CMake compiler=${_compiler}")
message(STATUS "CMake-Conan: CMake compiler version=${_compiler_version}")
if(_compiler MATCHES MSVC)
set(_compiler "msvc")
string(SUBSTRING ${MSVC_VERSION} 0 3 _compiler_version)
# Configure compiler.runtime and compiler.runtime_type settings for MSVC
if(CMAKE_MSVC_RUNTIME_LIBRARY)
set(_msvc_runtime_library ${CMAKE_MSVC_RUNTIME_LIBRARY})
else()
set(_msvc_runtime_library MultiThreaded$<$<CONFIG:Debug>:Debug>DLL) # default value documented by CMake
endif()
set(_KNOWN_MSVC_RUNTIME_VALUES "")
list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreaded MultiThreadedDLL)
list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreadedDebug MultiThreadedDebugDLL)
list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreaded$<$<CONFIG:Debug>:Debug> MultiThreaded$<$<CONFIG:Debug>:Debug>DLL)
# only accept the 6 possible values, otherwise we don't don't know to map this
if(NOT _msvc_runtime_library IN_LIST _KNOWN_MSVC_RUNTIME_VALUES)
message(FATAL_ERROR "CMake-Conan: unable to map MSVC runtime: ${_msvc_runtime_library} to Conan settings")
endif()
# Runtime is "dynamic" in all cases if it ends in DLL
if(_msvc_runtime_library MATCHES ".*DLL$")
set(_compiler_runtime "dynamic")
else()
set(_compiler_runtime "static")
endif()
message(STATUS "CMake-Conan: CMake compiler.runtime=${_compiler_runtime}")
# Only define compiler.runtime_type when explicitly requested
# If a generator expression is used, let Conan handle it conditional on build_type
if(NOT _msvc_runtime_library MATCHES "<CONFIG:Debug>:Debug>")
if(_msvc_runtime_library MATCHES "Debug")
set(_compiler_runtime_type "Debug")
else()
set(_compiler_runtime_type "Release")
endif()
message(STATUS "CMake-Conan: CMake compiler.runtime_type=${_compiler_runtime_type}")
endif()
unset(_KNOWN_MSVC_RUNTIME_VALUES)
elseif(_compiler MATCHES AppleClang)
set(_compiler "apple-clang")
string(REPLACE "." ";" VERSION_LIST ${_compiler_version})
list(GET VERSION_LIST 0 _compiler_version)
elseif(_compiler MATCHES Clang)
set(_compiler "clang")
string(REPLACE "." ";" VERSION_LIST ${_compiler_version})
list(GET VERSION_LIST 0 _compiler_version)
elseif(_compiler MATCHES GNU)
set(_compiler "gcc")
string(REPLACE "." ";" VERSION_LIST ${_compiler_version})
list(GET VERSION_LIST 0 _compiler_version)
endif()
message(STATUS "CMake-Conan: [settings] compiler=${_compiler}")
message(STATUS "CMake-Conan: [settings] compiler.version=${_compiler_version}")
if (_compiler_runtime)
message(STATUS "CMake-Conan: [settings] compiler.runtime=${_compiler_runtime}")
endif()
if (_compiler_runtime_type)
message(STATUS "CMake-Conan: [settings] compiler.runtime_type=${_compiler_runtime_type}")
endif()
set(${compiler} ${_compiler} PARENT_SCOPE)
set(${compiler_version} ${_compiler_version} PARENT_SCOPE)
set(${compiler_runtime} ${_compiler_runtime} PARENT_SCOPE)
set(${compiler_runtime_type} ${_compiler_runtime_type} PARENT_SCOPE)
endfunction()
function(detect_build_type build_type)
get_property(multiconfig_generator GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(NOT multiconfig_generator)
# Only set when we know we are in a single-configuration generator
# Note: we may want to fail early if `CMAKE_BUILD_TYPE` is not defined
set(${build_type} ${CMAKE_BUILD_TYPE} PARENT_SCOPE)
endif()
endfunction()
macro(set_conan_compiler_if_appleclang lang command output_variable)
if(CMAKE_${lang}_COMPILER_ID STREQUAL "AppleClang")
execute_process(COMMAND xcrun --find ${command}
OUTPUT_VARIABLE _xcrun_out OUTPUT_STRIP_TRAILING_WHITESPACE)
cmake_path(GET _xcrun_out PARENT_PATH _xcrun_toolchain_path)
cmake_path(GET CMAKE_${lang}_COMPILER PARENT_PATH _compiler_parent_path)
if ("${_xcrun_toolchain_path}" STREQUAL "${_compiler_parent_path}")
set(${output_variable} "")
endif()
unset(_xcrun_out)
unset(_xcrun_toolchain_path)
unset(_compiler_parent_path)
endif()
endmacro()
macro(append_compiler_executables_configuration)
set(_conan_c_compiler "")
set(_conan_cpp_compiler "")
set(_conan_rc_compiler "")
set(_conan_compilers_list "")
if(CMAKE_C_COMPILER)
set(_conan_c_compiler "\"c\":\"${CMAKE_C_COMPILER}\"")
set_conan_compiler_if_appleclang(C cc _conan_c_compiler)
list(APPEND _conan_compilers_list ${_conan_c_compiler})
else()
message(WARNING "CMake-Conan: The C compiler is not defined. "
"Please define CMAKE_C_COMPILER or enable the C language.")
endif()
if(CMAKE_CXX_COMPILER)
set(_conan_cpp_compiler "\"cpp\":\"${CMAKE_CXX_COMPILER}\"")
set_conan_compiler_if_appleclang(CXX c++ _conan_cpp_compiler)
list(APPEND _conan_compilers_list ${_conan_cpp_compiler})
else()
message(WARNING "CMake-Conan: The C++ compiler is not defined. "
"Please define CMAKE_CXX_COMPILER or enable the C++ language.")
endif()
if(CMAKE_RC_COMPILER)
set(_conan_rc_compiler "\"rc\":\"${CMAKE_RC_COMPILER}\"")
list(APPEND _conan_compilers_list ${_conan_rc_compiler})
# Not necessary to warn if RC not defined
endif()
if(NOT "x${_conan_compilers_list}" STREQUAL "x")
string(REPLACE ";" "," _conan_compilers_list "${_conan_compilers_list}")
string(APPEND profile "tools.build:compiler_executables={${_conan_compilers_list}}\n")
endif()
unset(_conan_c_compiler)
unset(_conan_cpp_compiler)
unset(_conan_rc_compiler)
unset(_conan_compilers_list)
endmacro()
function(detect_host_profile output_file)
detect_os(os os_api_level os_sdk os_subsystem os_version)
detect_arch(arch)
detect_compiler(compiler compiler_version compiler_runtime compiler_runtime_type)
detect_cxx_standard(compiler_cppstd)
detect_lib_cxx(compiler_libcxx)
detect_build_type(build_type)
set(profile "")
string(APPEND profile "[settings]\n")
if(arch)
string(APPEND profile arch=${arch} "\n")
endif()
if(os)
string(APPEND profile os=${os} "\n")
endif()
if(os_api_level)
string(APPEND profile os.api_level=${os_api_level} "\n")
endif()
if(os_version)
string(APPEND profile os.version=${os_version} "\n")
endif()
if(os_sdk)
string(APPEND profile os.sdk=${os_sdk} "\n")
endif()
if(os_subsystem)
string(APPEND profile os.subsystem=${os_subsystem} "\n")
endif()
if(compiler)
string(APPEND profile compiler=${compiler} "\n")
endif()
if(compiler_version)
string(APPEND profile compiler.version=${compiler_version} "\n")
endif()
if(compiler_runtime)
string(APPEND profile compiler.runtime=${compiler_runtime} "\n")
endif()
if(compiler_runtime_type)
string(APPEND profile compiler.runtime_type=${compiler_runtime_type} "\n")
endif()
if(compiler_cppstd)
string(APPEND profile compiler.cppstd=${compiler_cppstd} "\n")
endif()
if(compiler_libcxx)
string(APPEND profile compiler.libcxx=${compiler_libcxx} "\n")
endif()
if(build_type)
string(APPEND profile "build_type=${build_type}\n")
endif()
if(NOT DEFINED output_file)
set(file_name "${CMAKE_BINARY_DIR}/profile")
else()
set(file_name ${output_file})
endif()
string(APPEND profile "[conf]\n")
string(APPEND profile "tools.cmake.cmaketoolchain:generator=${CMAKE_GENERATOR}\n")
# propagate compilers via profile
append_compiler_executables_configuration()
if(os STREQUAL "Android")
string(APPEND profile "tools.android:ndk_path=${CMAKE_ANDROID_NDK}\n")
endif()
message(STATUS "CMake-Conan: Creating profile ${file_name}")
file(WRITE ${file_name} ${profile})
message(STATUS "CMake-Conan: Profile: \n${profile}")
endfunction()
function(conan_profile_detect_default)
message(STATUS "CMake-Conan: Checking if a default profile exists")
execute_process(COMMAND ${CONAN_COMMAND} profile path default
RESULT_VARIABLE return_code
OUTPUT_VARIABLE conan_stdout
ERROR_VARIABLE conan_stderr
ECHO_ERROR_VARIABLE # show the text output regardless
ECHO_OUTPUT_VARIABLE
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
if(NOT ${return_code} EQUAL "0")
message(STATUS "CMake-Conan: The default profile doesn't exist, detecting it.")
execute_process(COMMAND ${CONAN_COMMAND} profile detect
RESULT_VARIABLE return_code
OUTPUT_VARIABLE conan_stdout
ERROR_VARIABLE conan_stderr
ECHO_ERROR_VARIABLE # show the text output regardless
ECHO_OUTPUT_VARIABLE
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
endif()
endfunction()
function(conan_install)
set(conan_output_folder ${CMAKE_BINARY_DIR}/conan)
# Invoke "conan install" with the provided arguments
set(conan_args ${conan_args} -of=${conan_output_folder})
message(STATUS "CMake-Conan: conan install ${CMAKE_SOURCE_DIR} ${conan_args} ${ARGN}")
# In case there was not a valid cmake executable in the PATH, we inject the
# same we used to invoke the provider to the PATH
if(DEFINED PATH_TO_CMAKE_BIN)
set(old_path $ENV{PATH})
set(ENV{PATH} "$ENV{PATH}:${PATH_TO_CMAKE_BIN}")
endif()
execute_process(COMMAND ${CONAN_COMMAND} install ${CMAKE_SOURCE_DIR} ${conan_args} ${ARGN} --format=json
RESULT_VARIABLE return_code
OUTPUT_VARIABLE conan_stdout
ERROR_VARIABLE conan_stderr
ECHO_ERROR_VARIABLE # show the text output regardless
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
if(DEFINED PATH_TO_CMAKE_BIN)
set(ENV{PATH} "${old_path}")
endif()
if(NOT "${return_code}" STREQUAL "0")
message(FATAL_ERROR "Conan install failed='${return_code}'")
endif()
# the files are generated in a folder that depends on the layout used, if
# one is specified, but we don't know a priori where this is.
# TODO: this can be made more robust if Conan can provide this in the json output
string(JSON conan_generators_folder GET "${conan_stdout}" graph nodes 0 generators_folder)
cmake_path(CONVERT ${conan_generators_folder} TO_CMAKE_PATH_LIST conan_generators_folder)
message(STATUS "CMake-Conan: CONAN_GENERATORS_FOLDER=${conan_generators_folder}")
set_property(GLOBAL PROPERTY CONAN_GENERATORS_FOLDER "${conan_generators_folder}")
# reconfigure on conanfile changes
string(JSON conanfile GET "${conan_stdout}" graph nodes 0 label)
message(STATUS "CMake-Conan: CONANFILE=${CMAKE_SOURCE_DIR}/${conanfile}")
set_property(DIRECTORY ${CMAKE_SOURCE_DIR} APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/${conanfile}")
# success
set_property(GLOBAL PROPERTY CONAN_INSTALL_SUCCESS TRUE)
endfunction()
function(conan_get_version conan_command conan_current_version)
execute_process(
COMMAND ${conan_command} --version
OUTPUT_VARIABLE conan_output
RESULT_VARIABLE conan_result
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(conan_result)
message(FATAL_ERROR "CMake-Conan: Error when trying to run Conan")
endif()
string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" conan_version ${conan_output})
set(${conan_current_version} ${conan_version} PARENT_SCOPE)
endfunction()
function(conan_version_check)
set(options )
set(one_value_args MINIMUM CURRENT)
set(multi_value_args )
cmake_parse_arguments(conan_version_check
"${options}" "${one_value_args}" "${multi_value_args}" ${ARGN})
if(NOT conan_version_check_MINIMUM)
message(FATAL_ERROR "CMake-Conan: Required parameter MINIMUM not set!")
endif()
if(NOT conan_version_check_CURRENT)
message(FATAL_ERROR "CMake-Conan: Required parameter CURRENT not set!")
endif()
if(conan_version_check_CURRENT VERSION_LESS conan_version_check_MINIMUM)
message(FATAL_ERROR "CMake-Conan: Conan version must be ${conan_version_check_MINIMUM} or later")
endif()
endfunction()
macro(construct_profile_argument argument_variable profile_list)
set(${argument_variable} "")
if("${profile_list}" STREQUAL "CONAN_HOST_PROFILE")
set(_arg_flag "--profile:host=")
elseif("${profile_list}" STREQUAL "CONAN_BUILD_PROFILE")
set(_arg_flag "--profile:build=")
endif()
set(_profile_list "${${profile_list}}")
list(TRANSFORM _profile_list REPLACE "auto-cmake" "${CMAKE_BINARY_DIR}/conan_host_profile")
list(TRANSFORM _profile_list PREPEND ${_arg_flag})
set(${argument_variable} ${_profile_list})
unset(_arg_flag)
unset(_profile_list)
endmacro()
macro(conan_provide_dependency method package_name)
set_property(GLOBAL PROPERTY CONAN_PROVIDE_DEPENDENCY_INVOKED TRUE)
get_property(_conan_install_success GLOBAL PROPERTY CONAN_INSTALL_SUCCESS)
if(NOT _conan_install_success)
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
set(CONAN_COMMAND "${CMAKE_SOURCE_DIR}/build/bin/conan.exe")
else ()
set(CONAN_COMMAND "${CMAKE_SOURCE_DIR}/build/bin/conan")
endif ()
if(NOT EXISTS ${CONAN_COMMAND})
message(STATUS "CMake-Conan: Local conan not found, attempting to download it.")
execute_process(COMMAND "${CMAKE_COMMAND}" -P "${CMAKE_SOURCE_DIR}/cmake/ConanGet.cmake"
RESULT_VARIABLE result
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}")
if(NOT result EQUAL 0)
message(FATAL_ERROR "Failed to download conan.")
endif()
endif()
if(NOT EXISTS ${CONAN_COMMAND})
message(FATAL_ERROR "Conan executable not found at ${CONAN_COMMAND} after trying to download it. Also, make sure it has execution permissions.")
endif()
conan_get_version(${CONAN_COMMAND} CONAN_CURRENT_VERSION)
conan_version_check(MINIMUM ${CONAN_MINIMUM_VERSION} CURRENT ${CONAN_CURRENT_VERSION})
message(STATUS "CMake-Conan: first find_package() found. Installing dependencies with Conan")
if("default" IN_LIST CONAN_HOST_PROFILE OR "default" IN_LIST CONAN_BUILD_PROFILE)
conan_profile_detect_default()
endif()
if("auto-cmake" IN_LIST CONAN_HOST_PROFILE)
detect_host_profile(${CMAKE_BINARY_DIR}/conan_host_profile)
endif()
construct_profile_argument(_host_profile_flags CONAN_HOST_PROFILE)
construct_profile_argument(_build_profile_flags CONAN_BUILD_PROFILE)
if(EXISTS "${CMAKE_SOURCE_DIR}/conanfile.py")
file(READ "${CMAKE_SOURCE_DIR}/conanfile.py" outfile)
if(NOT "${outfile}" MATCHES ".*CMakeDeps.*")
message(WARNING "Cmake-conan: CMakeDeps generator was not defined in the conanfile")
endif()
set(generator "")
elseif (EXISTS "${CMAKE_SOURCE_DIR}/conanfile.txt")
file(READ "${CMAKE_SOURCE_DIR}/conanfile.txt" outfile)
if(NOT "${outfile}" MATCHES ".*CMakeDeps.*")
message(WARNING "Cmake-conan: CMakeDeps generator was not defined in the conanfile. "
"Please define the generator as it will be mandatory in the future")
endif()
set(generator "-g;CMakeDeps")
endif()
get_property(_multiconfig_generator GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(NOT _multiconfig_generator)
message(STATUS "CMake-Conan: Installing single configuration ${CMAKE_BUILD_TYPE}")
conan_install(${_host_profile_flags} ${_build_profile_flags} ${CONAN_INSTALL_ARGS} ${generator})
else()
message(STATUS "CMake-Conan: Installing both Debug and Release")
conan_install(${_host_profile_flags} ${_build_profile_flags} -s build_type=Release ${CONAN_INSTALL_ARGS} ${generator})
conan_install(${_host_profile_flags} ${_build_profile_flags} -s build_type=Debug ${CONAN_INSTALL_ARGS} ${generator})
endif()
unset(_host_profile_flags)
unset(_build_profile_flags)
unset(_multiconfig_generator)
unset(_conan_install_success)
else()
message(STATUS "CMake-Conan: find_package(${ARGV1}) found, 'conan install' already ran")
unset(_conan_install_success)
endif()
get_property(_conan_generators_folder GLOBAL PROPERTY CONAN_GENERATORS_FOLDER)
# Ensure that we consider Conan-provided packages ahead of any other,
# irrespective of other settings that modify the search order or search paths
# This follows the guidelines from the find_package documentation
# (https://cmake.org/cmake/help/latest/command/find_package.html):
# find_package (<PackageName> PATHS paths... NO_DEFAULT_PATH)
# find_package (<PackageName>)
# Filter out `REQUIRED` from the argument list, as the first call may fail
set(_find_args_${package_name} "${ARGN}")
list(REMOVE_ITEM _find_args_${package_name} "REQUIRED")
if(NOT "MODULE" IN_LIST _find_args_${package_name})
find_package(${package_name} ${_find_args_${package_name}} BYPASS_PROVIDER PATHS "${_conan_generators_folder}" NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
unset(_find_args_${package_name})
endif()
# Invoke find_package a second time - if the first call succeeded,
# this will simply reuse the result. If not, fall back to CMake default search
# behaviour, also allowing modules to be searched.
if(NOT ${package_name}_FOUND)
list(FIND CMAKE_MODULE_PATH "${_conan_generators_folder}" _index)
if(_index EQUAL -1)
list(PREPEND CMAKE_MODULE_PATH "${_conan_generators_folder}")
endif()
unset(_index)
find_package(${package_name} ${ARGN} BYPASS_PROVIDER)
list(REMOVE_ITEM CMAKE_MODULE_PATH "${_conan_generators_folder}")
endif()
endmacro()
cmake_language(
SET_DEPENDENCY_PROVIDER conan_provide_dependency
SUPPORTED_METHODS FIND_PACKAGE
)
macro(conan_provide_dependency_check)
set(_conan_provide_dependency_invoked FALSE)
get_property(_conan_provide_dependency_invoked GLOBAL PROPERTY CONAN_PROVIDE_DEPENDENCY_INVOKED)
if(NOT _conan_provide_dependency_invoked)
message(WARNING "Conan is correctly configured as dependency provider, "
"but Conan has not been invoked. Please add at least one "
"call to `find_package()`.")
if(DEFINED CONAN_COMMAND)
# supress warning in case `CONAN_COMMAND` was specified but unused.
set(_conan_command ${CONAN_COMMAND})
unset(_conan_command)
endif()
endif()
unset(_conan_provide_dependency_invoked)
endmacro()
# Add a deferred call at the end of processing the top-level directory
# to check if the dependency provider was invoked at all.
cmake_language(DEFER DIRECTORY "${CMAKE_SOURCE_DIR}" CALL conan_provide_dependency_check)
# Configurable variables for Conan profiles
set(CONAN_HOST_PROFILE "default;auto-cmake" CACHE STRING "Conan host profile")
set(CONAN_BUILD_PROFILE "default" CACHE STRING "Conan build profile")
set(CONAN_INSTALL_ARGS "--build=missing" CACHE STRING "Command line arguments for conan install")
find_program(_cmake_program NAMES cmake NO_PACKAGE_ROOT_PATH NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH NO_CMAKE_FIND_ROOT_PATH)
if(NOT _cmake_program)
get_filename_component(PATH_TO_CMAKE_BIN "${CMAKE_COMMAND}" DIRECTORY)
set(PATH_TO_CMAKE_BIN "${PATH_TO_CMAKE_BIN}" CACHE INTERNAL "Path where the CMake executable is")
endif()
cmake_policy(POP)

45
cmake/DocBuilder.cmake Normal file
View file

@ -0,0 +1,45 @@
set(MKDOCS_SRC "${CMAKE_SOURCE_DIR}/docs")
set(MKDOCS_OUT "${CMAKE_BINARY_DIR}/../docs")
message("MKDocs src: ${MKDOCS_SRC} > ${MKDOCS_OUT}")
file(MAKE_DIRECTORY "${MKDOCS_OUT}")
add_custom_target(docs
COMMAND ${CMAKE_COMMAND} -E env PYTHONUNBUFFERED=1
mkdocs build
--clean
--site-dir "${MKDOCS_OUT}"
--config-file "${MKDOCS_SRC}/mkdocs.yml"
WORKING_DIRECTORY "${MKDOCS_SRC}"
COMMENT "Generating documentation with MkDocs"
VERBATIM
)
# Optional install step
install(DIRECTORY "${MKDOCS_OUT}/"
DESTINATION "share/doc/${PROJECT_NAME}")
add_custom_target(install-docs
DEPENDS docs
COMMAND "${CMAKE_COMMAND}" --install . --component docs
COMMENT "Installing documentation")
# Name of the target that launches the dev server
add_custom_target(
serve_docs # invoke with `make serve_docs`
COMMAND ${CMAKE_COMMAND} -E env PYTHONUNBUFFERED=1
# On Windows we need to run the command through the shell
# so that the `&&` operator works correctly.
${CMAKE_COMMAND} -E env
mkdocs serve
--dev-addr "127.0.0.1:8000" # optional explicit bind address
--watch "${MKDOCS_SRC}" # watch source files for changes
--config-file "${MKDOCS_SRC}/mkdocs.yml"
WORKING_DIRECTORY "${MKDOCS_SRC}"
USES_TERMINAL # tells CMake to attach the child process to the console
COMMENT "Starting MkDocs livepreview server (CtrlC to stop)"
VERBATIM
)
add_dependencies(serve_docs docs) # ensures the static site is uptodate before serving

8
cmake/FindCcache.cmake Normal file
View file

@ -0,0 +1,8 @@
find_program(CCACHE_FOUND ccache)
if (CCACHE_FOUND)
message(STATUS "Found usable ccache: ${CCACHE_FOUND}")
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_FOUND} cache_dir=${CMAKE_SOURCE_DIR}/build/.ccache")
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK "${CCACHE_FOUND} cache_dir=${CMAKE_SOURCE_DIR}/build/.ccache")
else()
message(STATUS "ccache NOT found! Please install it for faster rebuilds.")
endif()

View file

@ -0,0 +1,9 @@
[settings]
os=Macos
arch=armv8
compiler=apple-clang
compiler.version=13
compiler.libcxx=libc++
[conf]

View file

@ -0,0 +1,8 @@
[settings]
os=Macos
arch=x86_64
compiler=apple-clang
compiler.version=13
compiler.libcxx=libc++
[conf]

View file

@ -0,0 +1,9 @@
[settings]
os=Linux
arch=armv8
compiler=gcc
compiler.version=11
compiler.libcxx=libstdc++11
[conf]
tools.cmake.cmaketoolchain:user_presets=False

View file

@ -0,0 +1,9 @@
[settings]
os=Linux
arch=x86_64
compiler=gcc
compiler.version=11
compiler.libcxx=libstdc++11
[conf]
tools.cmake.cmaketoolchain:user_presets=False

View file

@ -0,0 +1,10 @@
[settings]
arch=x86_64
compiler=msvc
compiler.cppstd=17
compiler.runtime=static
compiler.version=193
os=Windows
[conf]
tools.cmake.cmaketoolchain:user_presets=False

View file

@ -0,0 +1,8 @@
[settings]
arch=x86_64
compiler=msvc
compiler.cppstd=17
compiler.runtime=static
compiler.version=194
os=Windows
build_type=Release

View file

@ -3,4 +3,4 @@
static_assert(1, "FAIL");
int main(int argc, char *argv[]) {
return 0;
}
}

View file

@ -1,7 +1,6 @@
add_subdirectory(db)
add_subdirectory(ethereum)
add_subdirectory(randomx)
if(USE_BITCOIN_SECP256K1_FOR_ECDSA)
option(SECP256K1_BUILD_BENCHMARK "Build benchmarks." OFF)

@ -1 +0,0 @@
Subproject commit cf15f4023ec8ddaa842f49111ba80ead1b5937f1

View file

@ -1,30 +0,0 @@
{
"payments": [
{
"address_this": "iTHNdRWX6pKGXF1HqHgZyXie8EdaCwwdWUmsEnQhNojSUrkrR2eTemhFYkjWXbhdbyGcRBLgV2RYp3HhNAFCQ67w4bTHErZL1J",
"amount_this": 10000000.0,
"this_usd_price": "1.0",
"paid_prm": "",
"prm_usd_price": "",
"paid_xmr": "",
"xmr_usd_price": "",
"paid_qtum": "",
"qtum_usd_price": "",
"paid_bch": "",
"bch_usd_price": "",
"paid_rep": "",
"rep_usd_price": "",
"paid_dash": "",
"dash_usd_price": "",
"paid_ltc": "",
"ltc_usd_price": "",
"paid_eos": "",
"eos_usd_price": "",
"paid_eth": "",
"eth_usd_price": "",
"paid_btc": "",
"btc_usd_price": ""
}
],
"proof_string": "Lethean genesis — the advantage of the nature of information being easy to spread but hard to stifle. - Satoshi Nakamoto"
}

View file

@ -1,7 +0,0 @@
-------------genesis_acc.cpp-------------
const std::string ggenesis_tx_pub_key_str = "503ec7c167e3f2ead7d801bcbcebb3c58a84a2ba26a21ecb1f5c105fa159932b";
const crypto::public_key ggenesis_tx_pub_key = epee::string_tools::parse_tpod_from_hex_string<crypto::public_key>(ggenesis_tx_pub_key_str);
extern const genesis_tx_dictionary_entry ggenesis_dict[1];
const genesis_tx_dictionary_entry ggenesis_dict[1] = {
{12778448838847345770ULL,0}
};

View file

@ -1 +0,0 @@
01010000018080a0cfc8e0c8e38a0103bd6b4dda729d39dc85cb22a0b3db9b4b04d6464be9f3c84640bdca8bc0afb148000516503ec7c167e3f2ead7d801bcbcebb3c58a84a2ba26a21ecb1f5c105fa159932b137a4c65746865616e2067656e6573697320e280942074686520616476616e74616765206f6620746865206e6174757265206f6620696e666f726d6174696f6e206265696e67206561737920746f2073707265616420627574206861726420746f20737469666c652e202d205361746f736869204e616b616d6f746f15000b029e4e0e0a0000

View file

@ -1,14 +0,0 @@
--------- genesis.h---------
#pragma pack(push, 1)
struct genesis_tx_raw_data
{
uint64_t const v[27];
uint8_t const r[1];
};
#pragma pack(pop)
extern const genesis_tx_raw_data ggenesis_tx_raw;
--------- genesis.cpp---------
const genesis_tx_raw_data ggenesis_tx_raw = {{
0xa080800100000101,0x03018ae3c8e0c8cf,0xdc399d72da4d6bbd,0x4b9bdbb3a022cb85,0x46c8f3e94b46d604,0x48b1afc08bcabd40,0x67c1c73e50160500,0xbcbc01d8d7eaf2e3,0x26baa2848ac5b3eb,0xa15f105c1fcb1ea2,0x74654c7a132b9359,0x6e6567206e616568,0x9480e22073697365,0x7664612065687420,0x6f20656761746e61,0x616e206568742066,0x20666f2065727574,0x74616d726f666e69,0x6e696562206e6f69,0x7420797361652067,0x646165727073206f,0x7261682074756220,0x697473206f742064,0x53202d202e656c66,0x4e206968736f7461,0x156f746f6d616b61,0x000a0e4e9e020b00},
{0x00}};

View file

@ -1,14 +0,0 @@
NAME AMOUNT AMOUNT THIS USD EQ
bch 0.0000000000 0.000000000000 0.0000000000
btc 0.0000000000 0.000000000000 0.0000000000
dash 0.0000000000 0.000000000000 0.0000000000
eos 0.0000000000 0.000000000000 0.0000000000
eth 0.0000000000 0.000000000000 0.0000000000
ltc 0.0000000000 0.000000000000 0.0000000000
prm 0.0000000000 0.000000000000 0.0000000000
qtum 0.0000000000 0.000000000000 0.0000000000
rep 0.0000000000 0.000000000000 0.0000000000
TOTAL 0.000000000000 0.0000000000
PREMINE_AMOUNT 0 (0.000000000000THIS)

Binary file not shown.

View file

@ -1 +0,0 @@
iTHNdRWX6pKGXF1HqHgZyXie8EdaCwwdWUmsEnQhNojSUrkrR2eTemhFYkjWXbhdbyGcRBLgV2RYp3HhNAFCQ67w4bTHErZL1J

View file

@ -119,7 +119,6 @@ endif()
add_library(currency_core ${CURRENCY_CORE})
add_dependencies(currency_core version config ${PCH_LIB_NAME})
target_link_libraries(currency_core config)
target_include_directories(currency_core PRIVATE ${RANDOMX_INCLUDE})
ENABLE_SHARED_PCH(currency_core CURRENCY_CORE)
add_library(wallet ${WALLET})
@ -165,19 +164,19 @@ target_link_libraries(currency_core config lmdb mdbx)
add_executable(daemon ${DAEMON} ${P2P} ${CURRENCY_PROTOCOL})
add_dependencies(daemon version)
target_link_libraries(daemon rpc stratum currency_core crypto common miniupnpc::miniupnpc ZLIB::ZLIB ethash randomx api::server ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto)
target_link_libraries(daemon rpc stratum currency_core crypto common miniupnpc::miniupnpc ZLIB::ZLIB ethash api::server ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto)
ENABLE_SHARED_PCH(daemon DAEMON)
ENABLE_SHARED_PCH_EXECUTABLE(daemon)
add_executable(connectivity_tool ${CONN_TOOL})
add_dependencies(connectivity_tool version)
target_link_libraries(connectivity_tool currency_core crypto common ZLIB::ZLIB ethash randomx ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto)
target_link_libraries(connectivity_tool currency_core crypto common ZLIB::ZLIB ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto)
ENABLE_SHARED_PCH(connectivity_tool CONN_TOOL)
ENABLE_SHARED_PCH_EXECUTABLE(connectivity_tool)
add_executable(simplewallet ${SIMPLEWALLET})
add_dependencies(simplewallet version)
target_link_libraries(simplewallet wallet rpc currency_core crypto common ZLIB::ZLIB ethash randomx ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto)
target_link_libraries(simplewallet wallet rpc currency_core crypto common ZLIB::ZLIB ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto)
ENABLE_SHARED_PCH(simplewallet SIMPLEWALLET)
ENABLE_SHARED_PCH_EXECUTABLE(simplewallet)

View file

@ -59,7 +59,6 @@ target_link_libraries(api_server
crypto
common
ethash
randomx
${Boost_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
OpenSSL::SSL

View file

@ -21,7 +21,7 @@ set(base_reward_dust_threshold 1000000 CACHE STRING "BASE_REWARD_DUST_THRESHOLD"
set(default_dust_threshold 0 CACHE STRING "DEFAULT_DUST_THRESHOLD" )
set(difficulty_pow_starter 1 CACHE STRING "DIFFICULTY_POW_STARTER" )
set(difficulty_pos_target 120 CACHE STRING "DIFFICULTY_POS_TARGET" )
set(difficulty_pow_target 10 CACHE STRING "DIFFICULTY_POW_TARGET" )
set(difficulty_pow_target 120 CACHE STRING "DIFFICULTY_POW_TARGET" )
set(difficulty_window 720 CACHE STRING "DIFFICULTY_WINDOW" )
set(difficulty_lag 15 CACHE STRING "DIFFICULTY_LAG" )
set(difficulty_cut 60 CACHE STRING "DIFFICULTY_CUT" )

View file

@ -27,102 +27,39 @@ using namespace epee;
#include "crypto/crypto.h"
#include "crypto/hash.h"
#include "common/int-util.h"
// RandomX PoW
#include "randomx.h"
// Keep ethash headers for stratum/RPC compatibility (epoch seed helpers)
#include "ethereum/libethash/ethash/ethash.hpp"
#include <mutex>
#include <thread>
#include <vector>
#include <algorithm>
#include <cstring>
#include "ethereum/libethash/ethash/progpow.hpp"
namespace currency
{
//--------------------------------------------------------------
// RandomX global state — full dataset mode for fast hashing
//--------------------------------------------------------------
static randomx_cache* rx_cache = nullptr;
static randomx_dataset* rx_dataset = nullptr;
static randomx_flags rx_flags = RANDOMX_FLAG_DEFAULT;
static std::once_flag rx_init_flag;
static void init_randomx()
//--------------------------------------------------------------
int ethash_custom_log_get_level()
{
rx_flags = randomx_get_flags() | RANDOMX_FLAG_FULL_MEM;
LOG_PRINT_L0("[RandomX] Initializing with flags: " << static_cast<int>(rx_flags));
return epee::log_space::get_set_log_detalisation_level();
}
//--------------------------------------------------------------
void ethash_custom_log(const std::string& m, bool add_callstack)
{
std::string msg = epee::log_space::log_singletone::get_prefix_entry() + "[ETHASH]" + m;
if (add_callstack)
msg = msg + "callstask: " + epee::misc_utils::get_callstack();
rx_cache = randomx_alloc_cache(rx_flags);
if (!rx_cache)
{
LOG_ERROR("[RandomX] Failed to allocate cache");
throw std::bad_alloc();
}
static const char rx_key[] = "LetheanRandomXv1";
randomx_init_cache(rx_cache, rx_key, sizeof(rx_key) - 1);
LOG_PRINT_L0("[RandomX] Cache initialized with key \"LetheanRandomXv1\"");
rx_dataset = randomx_alloc_dataset(rx_flags);
if (!rx_dataset)
{
LOG_ERROR("[RandomX] Failed to allocate dataset, falling back to light mode");
rx_flags = rx_flags & ~RANDOMX_FLAG_FULL_MEM;
epee::log_space::log_singletone::do_log_message(msg, LOG_LEVEL_0, epee::log_space::console_color_default, true, LOG_DEFAULT_TARGET);
}
//--------------------------------------------------------------
void init_ethash_log_if_necessary()
{
static bool inited = false;
if (inited)
return;
}
// Multi-threaded dataset init
unsigned long item_count = randomx_dataset_item_count();
unsigned int num_threads = std::thread::hardware_concurrency();
if (num_threads == 0) num_threads = 4;
if (num_threads > 16) num_threads = 16;
ethash::access_custom_log_level_function() = &ethash_custom_log_get_level;
ethash::access_custom_log_function() = &ethash_custom_log;
LOG_PRINT_L0("[RandomX] Initializing dataset (" << item_count << " items, " << num_threads << " threads)...");
std::vector<std::thread> threads;
unsigned long per_thread = item_count / num_threads;
unsigned long remainder = item_count % num_threads;
for (unsigned int i = 0; i < num_threads; ++i)
{
unsigned long start = i * per_thread + std::min((unsigned long)i, remainder);
unsigned long count = per_thread + (i < remainder ? 1 : 0);
threads.emplace_back([start, count]() {
randomx_init_dataset(rx_dataset, rx_cache, start, count);
});
}
for (auto& t : threads) t.join();
LOG_PRINT_L0("[RandomX] Dataset initialized OK");
inited = true;
}
static randomx_vm* get_thread_vm()
{
std::call_once(rx_init_flag, init_randomx);
static thread_local randomx_vm* vm = nullptr;
if (!vm)
{
if (rx_dataset)
vm = randomx_create_vm(rx_flags, nullptr, rx_dataset);
else
vm = randomx_create_vm(rx_flags & ~RANDOMX_FLAG_FULL_MEM, rx_cache, nullptr);
if (!vm)
{
LOG_ERROR("[RandomX] Failed to create VM");
throw std::bad_alloc();
}
}
return vm;
}
//--------------------------------------------------------------
// Ethash helpers kept for stratum/RPC backward compat
//--------------------------------------------------------------
//------------------------------------------------------------------
int ethash_height_to_epoch(uint64_t height)
{
return static_cast<int>(height / ETHASH_EPOCH_LENGTH);
@ -138,20 +75,17 @@ namespace currency
//--------------------------------------------------------------
crypto::hash get_block_longhash(uint64_t height, const crypto::hash& block_header_hash, uint64_t nonce)
{
// Combine header hash + nonce into a single input buffer
struct {
crypto::hash header;
uint64_t nonce;
} input;
input.header = block_header_hash;
input.nonce = nonce;
char hash_out[RANDOMX_HASH_SIZE];
randomx_vm* vm = get_thread_vm();
randomx_calculate_hash(vm, &input, sizeof(input), hash_out);
init_ethash_log_if_necessary();
int epoch = ethash_height_to_epoch(height);
std::shared_ptr<ethash::epoch_context_full> p_context = progpow::get_global_epoch_context_full(static_cast<int>(epoch));
if (!p_context)
{
LOG_ERROR("fatal error: get_global_epoch_context_full failed, throwing bad_alloc...");
throw std::bad_alloc();
}
auto res_eth = progpow::hash(*p_context, static_cast<int>(height), *(ethash::hash256*)&block_header_hash, nonce);
crypto::hash result = currency::null_hash;
std::memcpy(&result.data, hash_out, sizeof(result.data));
memcpy(&result.data, &res_eth.final_hash, sizeof(res_eth.final_hash));
return result;
}
//---------------------------------------------------------------

View file

@ -1428,7 +1428,14 @@ wide_difficulty_type blockchain_storage::calc_diff_at_h_from_timestamps(std::vec
{
wide_difficulty_type dif;
TIME_MEASURE_START_PD(target_calculating_calc);
dif = next_difficulty_lwma(timestamps, commulative_difficulties, pos ? global_difficulty_pos_target : global_difficulty_pow_target, pos ? global_difficulty_pos_starter : global_difficulty_pow_starter);
if (m_core_runtime_config.is_hardfork_active_for_height(1, h))
{
dif = next_difficulty_2(timestamps, commulative_difficulties, pos ? global_difficulty_pos_target : global_difficulty_pow_target, pos ? global_difficulty_pos_starter : global_difficulty_pow_starter);
}
else
{
dif = next_difficulty_1(timestamps, commulative_difficulties, pos ? global_difficulty_pos_target : global_difficulty_pow_target, pos ? global_difficulty_pos_starter : global_difficulty_pow_starter);
}
TIME_MEASURE_FINISH_PD(target_calculating_calc);
return dif;
}

View file

@ -267,75 +267,4 @@ namespace currency {
}
return summ / devider;
}
//--------------------------------------------------------------
// LWMA-1 difficulty algorithm (zawy12)
// Linear Weighted Moving Average — adjusts every block with a
// ~60-block window. Battle-tested in Monero against ASICs and
// botnets. Much faster convergence than the 720-block Zano algo.
//--------------------------------------------------------------
wide_difficulty_type next_difficulty_lwma(vector<uint64_t>& timestamps, vector<wide_difficulty_type>& cumulative_difficulties, size_t target_seconds, const wide_difficulty_type& difficulty_starter)
{
const int64_t T = static_cast<int64_t>(target_seconds);
const size_t N = 60; // LWMA window size (solve times)
size_t length = timestamps.size();
CHECK_AND_ASSERT_MES(length == cumulative_difficulties.size(), difficulty_starter,
"LWMA: timestamps/difficulties size mismatch");
if (length <= 1)
return difficulty_starter;
// We need at most N+1 entries (giving N solve times)
if (length > N + 1)
{
timestamps.resize(N + 1);
cumulative_difficulties.resize(N + 1);
length = N + 1;
}
// Input arrives newest-first; LWMA needs oldest-first
std::reverse(timestamps.begin(), timestamps.end());
std::reverse(cumulative_difficulties.begin(), cumulative_difficulties.end());
// Now: [0]=oldest … [length-1]=newest
size_t n = length - 1; // number of solve-time intervals
int64_t weighted_solvetimes = 0;
for (size_t i = 1; i <= n; i++)
{
int64_t st = static_cast<int64_t>(timestamps[i])
- static_cast<int64_t>(timestamps[i - 1]);
// Clamp to [-6T, 6T] to limit timestamp-manipulation impact
if (st < -(6 * T)) st = -(6 * T);
if (st > (6 * T)) st = (6 * T);
weighted_solvetimes += st * static_cast<int64_t>(i);
}
// Guard against zero / negative (would be pathological timestamps)
if (weighted_solvetimes <= 0)
weighted_solvetimes = 1;
wide_difficulty_type total_work = cumulative_difficulties[n] - cumulative_difficulties[0];
// LWMA-1 formula:
// next_D = total_work * T * (n+1) / (2 * weighted_solvetimes * n)
//
// The divisor (n+1)/(2*n) normalises the linear weights 1..n
// whose sum is n*(n+1)/2.
boost::multiprecision::uint256_t next_d =
(boost::multiprecision::uint256_t(total_work) * T * (n + 1))
/ (boost::multiprecision::uint256_t(2) * weighted_solvetimes * n);
if (next_d < 1)
next_d = 1;
if (next_d > max128bit)
return difficulty_starter;
return next_d.convert_to<wide_difficulty_type>();
}
}

View file

@ -32,7 +32,6 @@ namespace currency
bool check_hash(const crypto::hash &hash, wide_difficulty_type difficulty);
wide_difficulty_type next_difficulty_1(std::vector<std::uint64_t>& timestamps, std::vector<wide_difficulty_type>& cumulative_difficulties, size_t target_seconds, const wide_difficulty_type& difficulty_starter);
wide_difficulty_type next_difficulty_2(std::vector<std::uint64_t>& timestamps, std::vector<wide_difficulty_type>& cumulative_difficulties, size_t target_seconds, const wide_difficulty_type& difficulty_starter);
wide_difficulty_type next_difficulty_lwma(std::vector<std::uint64_t>& timestamps, std::vector<wide_difficulty_type>& cumulative_difficulties, size_t target_seconds, const wide_difficulty_type& difficulty_starter);
uint64_t difficulty_to_boundary(wide_difficulty_type difficulty);
void difficulty_to_boundary_long(wide_difficulty_type difficulty, crypto::hash& result);
}

View file

@ -1,3 +1,3 @@
const genesis_tx_raw_data ggenesis_tx_raw = {{
0xa080800100000101,0x03018ae3c8e0c8cf,0xdc399d72da4d6bbd,0x4b9bdbb3a022cb85,0x46c8f3e94b46d604,0x48b1afc08bcabd40,0x67c1c73e50160500,0xbcbc01d8d7eaf2e3,0x26baa2848ac5b3eb,0xa15f105c1fcb1ea2,0x74654c7a132b9359,0x6e6567206e616568,0x9480e22073697365,0x7664612065687420,0x6f20656761746e61,0x616e206568742066,0x20666f2065727574,0x74616d726f666e69,0x6e696562206e6f69,0x7420797361652067,0x646165727073206f,0x7261682074756220,0x697473206f742064,0x53202d202e656c66,0x4e206968736f7461,0x156f746f6d616b61,0x000a0e4e9e020b00},
{0x00}};
0xe980800100000101,0xfbfa3a0316deb183,0x0e4d0bf7103b2df2,0x682df55627fc33ed,0xcd945b3d70689611,0x16050066b218269a,0x34af8b24a9c955d2,0x3f514b3a2be34ee9,0xb6525b442410e776,0x256d4d83666fb42a,0x6b61742074496b13,0x6e61766461207365,0x20666f2065676174,0x7574616e20656874,0x6e6920666f206572,0x6f6974616d726f66,0x20676e696562206e,0x206f742079736165,0x6220646165727073,0x2064726168207475,0x6c66697473206f74,0x746153202d202e65,0x6b614e206968736f,0x0b00156f746f6d61},
{0x02,0x8a,0x56,0x0e,0x0a,0x00,0x00}};

View file

@ -1,5 +1,5 @@
struct genesis_tx_raw_data
{
uint64_t const v[27];
uint8_t const r[1];
uint64_t const v[42];
uint8_t const r[42];
};

View file

@ -1,6 +1,6 @@
const std::string ggenesis_tx_pub_key_str = "503ec7c167e3f2ead7d801bcbcebb3c58a84a2ba26a21ecb1f5c105fa159932b";
const std::string ggenesis_tx_pub_key_str = "d255c9a9248baf34e94ee32b3a4b513f76e71024445b52b62ab46f66834d6d25";
const crypto::public_key ggenesis_tx_pub_key = epee::string_tools::parse_tpod_from_hex_string<crypto::public_key>(ggenesis_tx_pub_key_str);
extern const genesis_tx_dictionary_entry ggenesis_dict[1];
const genesis_tx_dictionary_entry ggenesis_dict[1] = {
{12778448838847345770ULL,0}
{1056117391700764468ULL,0}
};

View file

@ -808,7 +808,6 @@ namespace
, m_context(context)
, m_connection_initialized(false)
, m_last_reported_hashrate(0)
, m_use_standard_stratum(false)
{
LOG_PRINT_CC(m_context, "stratum_protocol_handler::ctor()", LOG_LEVEL_4);
}
@ -916,11 +915,6 @@ namespace
m_methods_handlers.insert(std::make_pair("eth_getWork", &this_t::handle_method_eth_getWork));
m_methods_handlers.insert(std::make_pair("eth_submitHashrate", &this_t::handle_method_eth_submitHashrate));
m_methods_handlers.insert(std::make_pair("eth_submitWork", &this_t::handle_method_eth_submitWork));
// Standard ETH stratum (mining.*) — used by XMRig-based miners
m_methods_handlers.insert(std::make_pair("mining.subscribe", &this_t::handle_method_mining_subscribe));
m_methods_handlers.insert(std::make_pair("mining.authorize", &this_t::handle_method_mining_authorize));
m_methods_handlers.insert(std::make_pair("mining.submit", &this_t::handle_method_mining_submit));
m_methods_handlers.insert(std::make_pair("mining.extranonce.subscribe", &this_t::handle_method_mining_extranonce_subscribe));
}
}
@ -1000,58 +994,6 @@ namespace
return m_config.handle_work(this, id, worker, nonce, header_hash);
}
// --- Standard ETH stratum (mining.*) handlers ---
bool handle_method_mining_subscribe(const jsonrpc_id_t& id, epee::serialization::portable_storage& ps, epee::serialization::portable_storage::hsection params_section)
{
m_use_standard_stratum = true;
// Respond with: [[["mining.notify", "subscription_id"]], "extranonce"]
// Use "0000" as a default 2-byte extra nonce
send_response(id, R"("result":[["mining.notify","1"],"0000"])");
return true;
}
bool handle_method_mining_authorize(const jsonrpc_id_t& id, epee::serialization::portable_storage& ps, epee::serialization::portable_storage::hsection params_section)
{
// params: [user, pass] — same format as eth_submitLogin
std::string user_str, pass_str;
epee::serialization::harray params_array = ps.get_first_value("params", user_str, nullptr);
if (params_array != nullptr)
ps.get_next_value(params_array, pass_str);
std::string worker_str = std::to_string(m_config.get_number_id_for_nameless_worker());
LOG_PRINT_CC(m_context, "Stratum [mining.authorize] USER: " << user_str << ", pass: " << pass_str << ", worker: " << worker_str, LOG_LEVEL_3);
return m_config.handle_login(this, id, user_str, pass_str, worker_str, 0);
}
bool handle_method_mining_submit(const jsonrpc_id_t& id, epee::serialization::portable_storage& ps, epee::serialization::portable_storage::hsection params_section)
{
// params: [worker, job_id, nonce, header_hash, mix_hash]
std::string worker_str, job_id_str, nonce_str, header_str, mixhash_str;
epee::serialization::harray params_array = ps.get_first_value("params", worker_str, nullptr);
bool r = params_array != nullptr && ps.get_next_value(params_array, job_id_str);
r = r && ps.get_next_value(params_array, nonce_str);
r = r && ps.get_next_value(params_array, header_str);
r = r && ps.get_next_value(params_array, mixhash_str);
CHECK_AND_ASSERT_MES(r, false, "Incorrect parameters for mining.submit");
uint64_t nonce = 0;
CHECK_AND_ASSERT_MES(pod_from_net_format_reverse(nonce_str, nonce, true), false, "Can't parse nonce from " << nonce_str);
crypto::hash header_hash = null_hash;
CHECK_AND_ASSERT_MES(pod_from_net_format(header_str, header_hash), false, "Can't parse header hash from " << header_str);
return m_config.handle_work(this, id, worker_str, nonce, header_hash);
}
bool handle_method_mining_extranonce_subscribe(const jsonrpc_id_t& id, epee::serialization::portable_storage& ps, epee::serialization::portable_storage::hsection params_section)
{
send_response(id, R"("result":true)");
return true;
}
// ---
void send(const std::string& data)
{
static_cast<epee::net_utils::i_service_endpoint*>(m_p_connection)->do_send(data.c_str(), data.size());
@ -1060,40 +1002,6 @@ namespace
void send_notification(const std::string& json)
{
if (m_use_standard_stratum)
{
// Convert EthProxy "result":["header","seed","target","height"] to
// standard stratum mining.notify format: "method":"mining.notify","params":["job_id","header","seed","target",true,"height"]
// json looks like: "result":["0xHEADER","0xSEED","0xTARGET","0xHEIGHT"]
// We need: "method":"mining.notify","params":["job_id","0xHEADER","0xSEED","0xTARGET",true,"0xHEIGHT"]
std::string notify_json = json;
size_t pos = notify_json.find(R"("result":)");
if (pos != std::string::npos)
{
// Extract the array content from "result":[...]
size_t arr_start = notify_json.find('[', pos);
size_t arr_end = notify_json.rfind(']');
if (arr_start != std::string::npos && arr_end != std::string::npos)
{
std::string arr_content = notify_json.substr(arr_start + 1, arr_end - arr_start - 1);
// Insert job ID at beginning and clean_jobs=true before height
// arr_content is: "0xHEADER","0xSEED","0xTARGET","0xHEIGHT"
// We need: "job_id","0xHEADER","0xSEED","0xTARGET",true,"0xHEIGHT"
static uint64_t s_job_counter = 0;
std::string job_id = "\"" + std::to_string(++s_job_counter) + "\"";
// Find the last comma to insert clean_jobs before height
size_t last_comma = arr_content.rfind(',');
if (last_comma != std::string::npos)
{
std::string params = job_id + "," + arr_content.substr(0, last_comma) + ",true" + arr_content.substr(last_comma);
send(R"({"jsonrpc":"2.0","method":"mining.notify","params":[)" + params + "]}\n");
return;
}
}
}
}
// EthProxy mode (default): send as-is
// JSON-RPC 2.0 spec: "A Notification is a Request object without an "id" member."
send(R"({"jsonrpc":"2.0",)" + json + "}" "\n"); // LF character is not specified by JSON-RPC standard, but it is REQUIRED by ethminer 0.12 to work
}
@ -1175,11 +1083,10 @@ namespace
epee::critical_section m_work_change_lock;
uint64_t m_last_reported_hashrate;
bool m_use_standard_stratum; // true = mining.* protocol, false = eth_* EthProxy protocol
typedef bool (this_t::*method_handler_func_t)(const jsonrpc_id_t& id, epee::serialization::portable_storage& ps, epee::serialization::portable_storage::hsection params_section);
static std::unordered_map<std::string, method_handler_func_t> m_methods_handlers;
std::atomic<bool> m_connection_initialized;
}; // class stratum_protocol_handler
//==============================================================================================================================

View file

@ -28,14 +28,14 @@ add_executable(net_load_tests_srv net_load_tests/srv.cpp)
add_dependencies(coretests version)
target_link_libraries(coretests rpc wallet currency_core common crypto ZLIB::ZLIB ethash randomx ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto)
target_link_libraries(functional_tests rpc wallet currency_core crypto common ZLIB::ZLIB ethash randomx miniupnpc::miniupnpc ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto)
target_link_libraries(coretests rpc wallet currency_core common crypto ZLIB::ZLIB ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto)
target_link_libraries(functional_tests rpc wallet currency_core crypto common ZLIB::ZLIB ethash miniupnpc::miniupnpc ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto)
target_link_libraries(hash-tests crypto ethash)
target_link_libraries(hash-target-tests crypto currency_core ethash randomx ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
target_link_libraries(performance_tests wallet rpc currency_core common crypto ZLIB::ZLIB ethash randomx ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto)
target_link_libraries(unit_tests wallet currency_core common crypto gtest_main ZLIB::ZLIB ethash randomx ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto)
target_link_libraries(net_load_tests_clt currency_core common crypto gtest_main randomx ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
target_link_libraries(net_load_tests_srv currency_core common crypto gtest_main randomx ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
target_link_libraries(hash-target-tests crypto currency_core ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
target_link_libraries(performance_tests wallet rpc currency_core common crypto ZLIB::ZLIB ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto)
target_link_libraries(unit_tests wallet currency_core common crypto gtest_main ZLIB::ZLIB ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} OpenSSL::SSL OpenSSL::Crypto)
target_link_libraries(net_load_tests_clt currency_core common crypto gtest_main ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
target_link_libraries(net_load_tests_srv currency_core common crypto gtest_main ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
if(NOT MSVC)
set_property(TARGET gtest gtest_main unit_tests net_load_tests_clt net_load_tests_srv APPEND_STRING PROPERTY COMPILE_FLAGS " -Wno-undef -Wno-sign-compare")

View file

@ -1046,20 +1046,17 @@ bool gen_alias_too_small_reward::init_runtime_config(currency::core& c, size_t e
bool gen_alias_too_small_reward::generate(std::vector<test_event_entry>& events) const
{
// pay for alias too small and see, if it's ok
// Generate distinct addresses from fresh accounts
account_base alias_accs[10];
for (auto& a : alias_accs) a.generate();
const alias_entry aliases[] = {
{"a", alias_accs[0].get_keys().account_address},
{"bb", alias_accs[1].get_keys().account_address},
{"ccc", alias_accs[2].get_keys().account_address},
{"dddd", alias_accs[3].get_keys().account_address},
{"eeeee", alias_accs[4].get_keys().account_address},
{"ffffff", alias_accs[5].get_keys().account_address},
{"ggggggg", alias_accs[6].get_keys().account_address},
{"hhhhhhhh", alias_accs[7].get_keys().account_address},
{"iiiiiiiii", alias_accs[8].get_keys().account_address},
{"jjjjjjjjjj", alias_accs[9].get_keys().account_address}
{"a", pub_addr_from_string("ZxD95C97dFqVBsuTMA1VKjFxx8Cc7by2YTA9kLhFc8JB3zJ3qKKXRm9Lu2YQsjPP5UKhCSfLLEqJr5ovyQNYYQWV1Pv98fRzt")},
{"bb", pub_addr_from_string("ZxDL9euTT4C9FUj28QY1RdWnreMHJiWfrPs39rXhrgai8H4pmaFzJ4vUUYRmHhNxToN64H1U5sMnaHuD3S4kVbyY1mKHnERVZ")},
{"ccc", pub_addr_from_string("ZxBrpHp3xrjLrMMSyJUg44YmyJVZjetouVFdtqLfxpHUMSxiEyyQ7iKSj4sr6gn7qwXrj6YSw7UjJZLyc1H37QtF2p96c2gAD")},
{"dddd", pub_addr_from_string("ZxDtT1pTwt6R2t3eGw9VD6N1heHCKNLKuCFUvqgHpXkAVnPkfai4KDYEjRSV8E42XKN3MJeaHJMaxa9hUmaXLyHm2nQ12aX93")},
{"eeeee", pub_addr_from_string("ZxCABdwUJpqHstWJUHQ21piADBwaSsXcAh5EPtpSr8xXderWqvDef566ReFGrRqBUrE2tCgZ3HE5XRuxoq8mNTrP2X4J35yQq")},
{"ffffff", pub_addr_from_string("ZxC34uAJJ2iW15GkvcqaQd4RKZdu16tpmf4ubmsirw7eFtKoLi2xswhNqy3Q4VacCq5mM7zuYyoWEW8AS5HGtoXr1m9RuTUuu")},
{"ggggggg", pub_addr_from_string("ZxDHxZizSe5MNQoRkC1unqTrhYUkh1ZG7iEXMzLatyZ5EHRPat4Ls4ZRnN4CYLvJLq5F5gxdDtu17Zrvur7dcqU52sv2pryn7")},
{"hhhhhhhh", pub_addr_from_string("ZxDXME4qrbh7mAbrqDmCbzGj14VQP1n9KLLi7fXBMNvDd5UUpcevCSXQ9zSkZcJtbzBS7u16NiykAiv3q9VkZySL2ySB6hTfL")},
{"iiiiiiiii", pub_addr_from_string("ZxDtpxbC2bN8yu3J49tsUYUSoPYTnAgjmBogzFviUg3t2fGfWzmZ2gbKNC1XKVdMEE2hoW5sULs2hAF5T3igoAVW2MsHUmaj4")},
{"jjjjjjjjjj", pub_addr_from_string("ZxCBLxnctYwB37YZi7MsJqBCujXzkBeJEh7wPbYrFUvMiqXiPLkyBRAh6ahQ6wre2tGR8FHesZwKn2zYPkTuibyu2648g2CGV")}
};
const size_t aliases_count = sizeof aliases / sizeof aliases[0];

View file

@ -708,7 +708,7 @@ bool gen_no_attchments_in_coinbase::init_config_set_cp(currency::core& c, size_t
// different checkpoints due to different block versions for different hardforks -> different hashes
if (crc.is_hardfork_active_for_height(ZANO_HARDFORK_03, 11) && !crc.is_hardfork_active_for_height(ZANO_HARDFORK_04_ZARCANUM, 11))
{
m_checkpoints.add_checkpoint(12, "0300604e3c4018c79f4d81fbc0d15b3206956a95efc237f70c963db926773728");
m_checkpoints.add_checkpoint(12, "70fbbd33d88ccaa26f9fe64d102bcff2572494009339de9fab7158a40633fbb5");
}
else
{

View file

@ -1638,7 +1638,7 @@ multisig_and_checkpoints::multisig_and_checkpoints()
bool multisig_and_checkpoints::set_cp(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
{
currency::checkpoints checkpoints;
checkpoints.add_checkpoint(15, "bd41e498afb84ca8bdcf9c1890ab48902dc1f202ce7c2a84cb9fa16c4a526d62");
checkpoints.add_checkpoint(15, "a78fa870608991aa773d5d5aaf684ac77fea30c3e103b00d3c05c15912215c31");
c.set_checkpoints(std::move(checkpoints));
return true;

View file

@ -133,13 +133,13 @@ bool test_block_creation()
{
uint64_t vszs[] = {80,476,476,475,475,474,475,474,474,475,472,476,476,475,475,474,475,474,474,475,472,476,476,475,475,474,475,474,474,475,9391,476,476,475,475,474,475,8819,8301,475,472,4302,5316,14347,16620,19583,19403,19728,19442,19852,19015,19000,19016,19795,19749,18087,19787,19704,19750,19267,19006,19050,19445,19407,19522,19546,19788,19369,19486,19329,19370,18853,19600,19110,19320,19746,19474,19474,19743,19494,19755,19715,19769,19620,19368,19839,19532,23424,28287,30707};
std::vector<uint64_t> szs(&vszs[0], &vszs[90]);
account_base acc;
acc.generate();
account_public_address adr = acc.get_keys().account_address;
account_public_address adr;
bool r = get_account_address_from_str(adr, "ZxDLGBGXbjo5w51tJkvxEPHFRr7Xft4hf33N8EkJPndoGCqocQF1mzpZqYwXByx5gMbfQuPAAB9vj79EFR6Jwkgu1o3aMQPwJ");
CHECK_AND_ASSERT_MES(r, false, "failed to import");
uint64_t block_reward_without_fee = 0;
uint64_t block_reward = 0;
block b;
bool r = construct_miner_tx(90, epee::misc_utils::median(szs), 3553616528562147, 33094, 10000000, adr, adr, b.miner_tx, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, 0);
r = construct_miner_tx(90, epee::misc_utils::median(szs), 3553616528562147, 33094, 10000000, adr, adr, b.miner_tx, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, 0);
return r;
}

View file

@ -30,40 +30,28 @@ bool operator !=(const ec_scalar &a, const ec_scalar &b) {
bool operator !=(const ec_point &a, const ec_point &b) {
return 0 != memcmp(&a, &b, sizeof(ec_point));
}
static string tohex(const void *data, size_t len) {
string res;
res.reserve(len * 2);
const unsigned char *p = reinterpret_cast<const unsigned char *>(data);
for (size_t i = 0; i < len; i++) {
char buf[3];
snprintf(buf, sizeof(buf), "%02x", p[i]);
res += buf;
}
return res;
/*
bool operator !=(const secret_key &a, const secret_key &b) {
return 0 != memcmp(&a, &b, sizeof(secret_key));
}
template<typename T>
static string tohex(const T &v) { return tohex(&v, sizeof(T)); }
bool operator !=(const key_derivation &a, const key_derivation &b) {
return 0 != memcmp(&a, &b, sizeof(key_derivation));
}*/
int main(int argc, char *argv[]) {
fstream input;
string cmd;
size_t test = 0;
bool error = false;
bool generate = false;
setup_random();
if (argc == 3 && string(argv[1]) == "--generate") {
generate = true;
input.open(argv[2], ios_base::in);
} else if (argc == 2) {
input.open(argv[1], ios_base::in);
} else {
cerr << "usage: crypto-tests [--generate] <tests.txt>" << endl;
if (argc != 2) {
cerr << "invalid arguments" << endl;
return 1;
}
input.open(argv[1], ios_base::in);
for (;;) {
++test;
input.exceptions(ios_base::badbit);
@ -76,18 +64,14 @@ int main(int argc, char *argv[]) {
bool expected = false, actual = false;
get(input, scalar, expected);
actual = check_scalar(scalar);
if (generate) {
cout << "check_scalar " << tohex(scalar) << " " << (actual ? "true" : "false") << endl;
} else if (expected != actual) {
if (expected != actual) {
goto error;
}
} else if (cmd == "random_scalar") {
ec_scalar expected, actual;
get(input, expected);
random_scalar(actual);
if (generate) {
cout << "random_scalar " << tohex(actual) << endl;
} else if (expected != actual) {
if (expected != actual) {
goto error;
}
} else if (cmd == "hash_to_scalar") {
@ -95,9 +79,7 @@ int main(int argc, char *argv[]) {
ec_scalar expected, actual;
get(input, data, expected);
hash_to_scalar(data.data(), data.size(), actual);
if (generate) {
cout << "hash_to_scalar " << (data.empty() ? "x" : tohex(data.data(), data.size())) << " " << tohex(actual) << endl;
} else if (expected != actual) {
if (expected != actual) {
goto error;
}
} else if (cmd == "generate_keys") {
@ -105,9 +87,7 @@ int main(int argc, char *argv[]) {
secret_key expected2, actual2;
get(input, expected1, expected2);
generate_keys(actual1, actual2);
if (generate) {
cout << "generate_keys " << tohex(actual1) << " " << tohex(actual2) << endl;
} else if (expected1 != actual1 || expected2 != actual2) {
if (expected1 != actual1 || expected2 != actual2) {
goto error;
}
} else if (cmd == "check_key") {
@ -115,9 +95,7 @@ int main(int argc, char *argv[]) {
bool expected, actual;
get(input, key, expected);
actual = check_key(key);
if (generate) {
cout << "check_key " << tohex(key) << " " << (actual ? "true" : "false") << endl;
} else if (expected != actual) {
if (expected != actual) {
goto error;
}
} else if (cmd == "secret_key_to_public_key") {
@ -129,11 +107,7 @@ int main(int argc, char *argv[]) {
get(input, expected2);
}
actual1 = secret_key_to_public_key(sec, actual2);
if (generate) {
cout << "secret_key_to_public_key " << tohex(sec) << " " << (actual1 ? "true" : "false");
if (actual1) cout << " " << tohex(actual2);
cout << endl;
} else if (expected1 != actual1 || (expected1 && expected2 != actual2)) {
if (expected1 != actual1 || (expected1 && expected2 != actual2)) {
goto error;
}
} else if (cmd == "generate_key_derivation") {
@ -146,11 +120,7 @@ int main(int argc, char *argv[]) {
get(input, expected2);
}
actual1 = generate_key_derivation(key1, key2, actual2);
if (generate) {
cout << "generate_key_derivation " << tohex(key1) << " " << tohex(key2) << " " << (actual1 ? "true" : "false");
if (actual1) cout << " " << tohex(actual2);
cout << endl;
} else if (expected1 != actual1 || (expected1 && expected2 != actual2)) {
if (expected1 != actual1 || (expected1 && expected2 != actual2)) {
goto error;
}
} else if (cmd == "derive_public_key") {
@ -164,11 +134,7 @@ int main(int argc, char *argv[]) {
get(input, expected2);
}
actual1 = derive_public_key(derivation, output_index, base, actual2);
if (generate) {
cout << "derive_public_key " << tohex(derivation) << " " << output_index << " " << tohex(base) << " " << (actual1 ? "true" : "false");
if (actual1) cout << " " << tohex(actual2);
cout << endl;
} else if (expected1 != actual1 || (expected1 && expected2 != actual2)) {
if (expected1 != actual1 || (expected1 && expected2 != actual2)) {
goto error;
}
} else if (cmd == "derive_secret_key") {
@ -178,9 +144,7 @@ int main(int argc, char *argv[]) {
secret_key expected, actual;
get(input, derivation, output_index, base, expected);
derive_secret_key(derivation, output_index, base, actual);
if (generate) {
cout << "derive_secret_key " << tohex(derivation) << " " << output_index << " " << tohex(base) << " " << tohex(actual) << endl;
} else if (expected != actual) {
if (expected != actual) {
goto error;
}
} else if (cmd == "generate_signature") {
@ -190,9 +154,7 @@ int main(int argc, char *argv[]) {
signature expected, actual;
get(input, prefix_hash, pub, sec, expected);
generate_signature(prefix_hash, pub, sec, actual);
if (generate) {
cout << "generate_signature " << tohex(prefix_hash) << " " << tohex(pub) << " " << tohex(sec) << " " << tohex(actual) << endl;
} else if (expected != actual) {
if (expected != actual) {
goto error;
}
} else if (cmd == "check_signature") {
@ -202,9 +164,7 @@ int main(int argc, char *argv[]) {
bool expected = false, actual = false;
get(input, prefix_hash, pub, sig, expected);
actual = check_signature(prefix_hash, pub, sig);
if (generate) {
cout << "check_signature " << tohex(prefix_hash) << " " << tohex(pub) << " " << tohex(sig) << " " << (actual ? "true" : "false") << endl;
} else if (expected != actual) {
if (expected != actual) {
goto error;
}
} else if (cmd == "hash_to_point") {
@ -212,9 +172,7 @@ int main(int argc, char *argv[]) {
ec_point expected, actual;
get(input, h, expected);
hash_to_point(h, actual);
if (generate) {
cout << "hash_to_point " << tohex(h) << " " << tohex(actual) << endl;
} else if (expected != actual) {
if (expected != actual) {
goto error;
}
} else if (cmd == "hash_to_ec") {
@ -222,9 +180,7 @@ int main(int argc, char *argv[]) {
ec_point expected, actual;
get(input, key, expected);
hash_to_ec(key, actual);
if (generate) {
cout << "hash_to_ec " << tohex(key) << " " << tohex(actual) << endl;
} else if (expected != actual) {
if (expected != actual) {
goto error;
}
} else if (cmd == "generate_key_image") {
@ -233,9 +189,7 @@ int main(int argc, char *argv[]) {
key_image expected, actual;
get(input, pub, sec, expected);
generate_key_image(pub, sec, actual);
if (generate) {
cout << "generate_key_image " << tohex(pub) << " " << tohex(sec) << " " << tohex(actual) << endl;
} else if (expected != actual) {
if (expected != actual) {
goto error;
}
} else if (cmd == "generate_ring_signature") {
@ -260,11 +214,7 @@ int main(int argc, char *argv[]) {
getvar(input, pubs_count * sizeof(signature), expected.data());
actual.resize(pubs_count);
generate_ring_signature(prefix_hash, image, pubs.data(), pubs_count, sec, sec_index, actual.data());
if (generate) {
cout << "generate_ring_signature " << tohex(prefix_hash) << " " << tohex(image) << " " << pubs_count;
for (i = 0; i < pubs_count; i++) cout << " " << tohex(vpubs[i]);
cout << " " << tohex(sec) << " " << sec_index << " " << tohex(actual.data(), pubs_count * sizeof(signature)) << endl;
} else if (expected != actual) {
if (expected != actual) {
goto error;
}
} else if (cmd == "check_ring_signature") {
@ -287,11 +237,7 @@ int main(int argc, char *argv[]) {
getvar(input, pubs_count * sizeof(signature), sigs.data());
get(input, expected);
actual = check_ring_signature(prefix_hash, image, pubs.data(), pubs_count, sigs.data());
if (generate) {
cout << "check_ring_signature " << tohex(prefix_hash) << " " << tohex(image) << " " << pubs_count;
for (i = 0; i < pubs_count; i++) cout << " " << tohex(vpubs[i]);
cout << " " << tohex(sigs.data(), pubs_count * sizeof(signature)) << " " << (actual ? "true" : "false") << endl;
} else if (expected != actual) {
if (expected != actual) {
goto error;
}
} else {

View file

@ -7,6 +7,5 @@
#include "crypto-tests.h"
void setup_random(void) {
grant_random_initialize_no_lock();
memset(&state, 42, sizeof(union hash_state));
}

View file

@ -33,11 +33,11 @@ void run_plain_wallet_api_test()
LOG_PRINT_L0("Creating instance...");
//plain_wallet::set_bundle_working_dir("E:\\tmp\\check_export");
std::string s = plain_wallet::init("127.0.0.1", "36941", boost::dll::program_location().parent_path().string(), 1);
std::string s = plain_wallet::init("195.201.107.230", "33333", boost::dll::program_location().parent_path().string(), 1);
//s = plain_wallet::get_export_private_info("E:\\tmp\\check_export");
std::string res = plain_wallet::sync_call("get_seed_phrase_info", 0, "{\"seed_phrase\":\"iTHNHvUTA2gR7gSb854s58SpAyqtR5aCNcfzBzVHjhvPcw2gQ2PHDiwT48U4ZyLVjtLxev8fAQ7NaGLZe6ihTSgp7gL45MJTCK:1780c4d5dd7e97cc4a75ea8baa7977d12ef948b9a6dddc2a9a37e5e22ac7180e:1599495055\"}");
std::string res = plain_wallet::sync_call("get_seed_phrase_info", 0, "{\"seed_phrase\":\"aZxat4HAWriVQ3enkGcVsrZRdMseAJswG3CSEwTqZS246VsFQ53w26eZstYsu1jWE74Atz9ajLxFnBsVTafncWNH5SMv4zHFaTS:1780c4d5dd7e97cc4a75ea8baa7977d12ef948b9a6dddc2a9a37e5e22ac7180e:1599495055\"}");
// res = plain_wallet::restore("footstep knowledge fur capture honey minute carefully peaceful lovely crawl lunch government nightmare friendship myself sign possibly plan flower depression bread rainbow wrong hardly dark chest",
@ -50,7 +50,7 @@ void run_plain_wallet_api_test()
res = plain_wallet::close_wallet(0);
res = plain_wallet::invoke(0, "{\"method\":\"transfer\",\"params\":{\"destinations\":[{\"amount\":10000000000,\"address\":\"iTHNHvUTA2gR7gSb854s58SpAyqtR5aCNcfzBzVHjhvPcw2gQ2PHDiwT48U4ZyLVjtLxev8fAQ7NaGLZe6ihTSgp7gL45MJTCK\"}],\"fee\":10000000000,\"mixin\":1011111,\"payment_id\":\"\",\"push_payer\":true,\"hide_receiver\":false}}");
res = plain_wallet::invoke(0, "{\"method\":\"transfer\",\"params\":{\"destinations\":[{\"amount\":10000000000,\"address\":\"aZxat4HAWriVQ3enkGcVsrZRdMseAJswG3CSEwTqZS246VsFQ53w26eZstYsu1jWE74Atz9ajLxFnBsVTafncWNH5SMv4zHFaTS\"}],\"fee\":10000000000,\"mixin\":1011111,\"payment_id\":\"\",\"push_payer\":true,\"hide_receiver\":false}}");
//epee::misc_utils::sleep_no_w(10000000);

View file

@ -74,7 +74,7 @@ void test_plain_wallet()
{
//std::string res = plain_wallet::init("195.201.107.230", "33340", "C:\\Users\\roky\\home\\", 0);
//std::string res = plain_wallet::init("", "", "C:\\Users\\roky\\home\\", 0);
std::string res = plain_wallet::init("127.0.0.1", "36941", "C:\\Users\\roky\\home\\", LOG_LEVEL_2);
std::string res = plain_wallet::init("https://node.zano.org", "443", "C:\\Users\\roky\\home\\", LOG_LEVEL_2);
//std::string res = plain_wallet::init("127.0.0.1", "12111", "C:\\Users\\roky\\home22\\", 0);
plain_wallet::configure_object conf = AUTO_VAL_INIT(conf);
@ -112,9 +112,9 @@ void test_plain_wallet()
epee::misc_utils::sleep_no_w(2000);
//res = plain_wallet::sync_call("reset_connection_url", 0, "195.201.107.230:33336");
//res = plain_wallet::sync_call("reset_connection_url", 0, "127.0.0.1:36941");
//res = plain_wallet::sync_call("reset_connection_url", 0, "127.0.0.1:36941");
//res = plain_wallet::sync_call("reset_connection_url", 0, "127.0.0.1:36941");
//res = plain_wallet::sync_call("reset_connection_url", 0, "https://node.zano.org:443");
//res = plain_wallet::sync_call("reset_connection_url", 0, "https://zano.cakewallet.com");
//res = plain_wallet::sync_call("reset_connection_url", 0, "https://zano.api.wombat.systems:443");
//res = plain_wallet::sync_call("reset_connection_url", 0, "http://127.0.0.1:11211");
@ -178,7 +178,7 @@ void test_plain_wallet()
std::string res3 = plain_wallet::sync_call("invoke", instance_id, invoke_body);
//invoke_body = "{\r\n \"method\": \"transfer\",\r\n \"params\": {\r\n \"destinations\": [\r\n {\r\n \"amount\": \"1000000000000\",\r\n \"address\": \"iTHNHvUTA2gR7gSb854s58SpAyqtR5aCNcfzBzVHjhvPcw2gQ2PHDiwT48U4ZyLVjtLxev8fAQ7NaGLZe6ihTSgp7gL45MJTCK\",\r\n \"asset_id\": \"cc4e69455e63f4a581257382191de6856c2156630b3fba0db4bdd73ffcfb36b6\"\r\n }\r\n ],\r\n \"fee\": 10000000000,\r\n \"mixin\": 10,\r\n \"payment_id\": \"\",\r\n \"comment\": \"\",\r\n \"push_payer\": false,\r\n \"hide_receiver\": true\r\n }\r\n}";
//invoke_body = "{\r\n \"method\": \"transfer\",\r\n \"params\": {\r\n \"destinations\": [\r\n {\r\n \"amount\": \"1000000000000\",\r\n \"address\": \"ZxD9oVwGwW6ULix9Pqttnr7JDpaoLvDVA1KJ9eA9KRxPMRZT5X7WwtU94XH1Z6q6XTMxNbHmbV2xfZ429XxV6fST2DxEg4BQV\",\r\n \"asset_id\": \"cc4e69455e63f4a581257382191de6856c2156630b3fba0db4bdd73ffcfb36b6\"\r\n }\r\n ],\r\n \"fee\": 10000000000,\r\n \"mixin\": 10,\r\n \"payment_id\": \"\",\r\n \"comment\": \"\",\r\n \"push_payer\": false,\r\n \"hide_receiver\": true\r\n }\r\n}";
//std::string res4 = plain_wallet::sync_call("invoke", instance_id, invoke_body);
//LOG_PRINT_L0(res);

View file

@ -441,6 +441,7 @@ namespace
"\x22\x09\x39\x68\x9e\xdf\x1a\xbd\x5b\xc1\xd0\x31\xf7\x3e\xcd\x6c"
"\x99\x3a\xdd\x66\xd6\x80\x88\x70\x45\x6a\xfe\xb8\xe7\xee\xb6\x8d"
"\x00");
std::string test_keys_addr_str = "ZxDqHy6WnyYY5yQcdApjMb8tVPik5BC3LFdaevfbGq7X1KY5vdsWmUi5UQgse2GBZFbMsb47TFqBmPpdFHDDwDxR2ZuZ6zX4W"; // correct str address depends on CURRENCY_PUBLIC_ADDRESS_BASE58_PREFIX value
}
TEST(get_account_address_as_str, works_correctly)
@ -448,23 +449,13 @@ TEST(get_account_address_as_str, works_correctly)
currency::account_public_address addr;
ASSERT_TRUE(serialization::parse_binary(test_serialized_keys, addr));
std::string addr_str = currency::get_account_address_as_str(addr);
// Verify round-trip: parse the generated address back and check keys match
currency::account_public_address addr2;
ASSERT_TRUE(currency::get_account_address_from_str(addr2, addr_str));
std::string blob;
ASSERT_TRUE(serialization::dump_binary(addr2, blob));
ASSERT_EQ(blob, test_serialized_keys);
ASSERT_EQ(addr_str, test_keys_addr_str);
}
TEST(get_account_address_from_str, handles_valid_address)
{
// Generate a valid address from the test keys
currency::account_public_address addr_orig;
ASSERT_TRUE(serialization::parse_binary(test_serialized_keys, addr_orig));
std::string valid_addr_str = currency::get_account_address_as_str(addr_orig);
currency::account_public_address addr;
ASSERT_TRUE(currency::get_account_address_from_str(addr, valid_addr_str));
ASSERT_TRUE(currency::get_account_address_from_str(addr, test_keys_addr_str));
std::string blob;
ASSERT_TRUE(serialization::dump_binary(addr, blob));
@ -473,12 +464,10 @@ TEST(get_account_address_from_str, handles_valid_address)
TEST(get_account_address_from_str, fails_on_invalid_address_format)
{
currency::account_public_address addr_orig;
ASSERT_TRUE(serialization::parse_binary(test_serialized_keys, addr_orig));
std::string addr_str = currency::get_account_address_as_str(addr_orig);
currency::account_public_address addr;
std::string addr_str = test_keys_addr_str;
addr_str[0] = '0';
currency::account_public_address addr;
ASSERT_FALSE(currency::get_account_address_from_str(addr, addr_str));
}
@ -571,11 +560,11 @@ struct addr_entry_t
uint8_t flags;
};
addr_entry_t addr_entries[] =
addr_entry_t addr_entries[] =
{
{
// classic normal address — generated at runtime from keys
"", // address (empty = auto-generate from keys + prefix)
// classic normal address
"ZxD5aoLDPTdcaRx4uCpyW4XiLfEXejepAVz8cSY2fwHNEiJNu6NmpBBDLGTJzCsUvn3acCVDVDPMV8yQXdPooAp338Se7AxeH", // address
"a3f208c8f9ba49bab28eed62b35b0f6be0a297bcd85c2faa1eb1820527bcf7e3", // view_pub_key
"9f5e1fa93630d4b281b18bb67a3db79e9622fc703cc3ad4a453a82e0a36d51fa", // spend_pub_key
"", // payment_id_hex
@ -583,15 +572,31 @@ addr_entry_t addr_entries[] =
},
{
// classic integrated address
"",
"iZ2Zi6RmTWwcaRx4uCpyW4XiLfEXejepAVz8cSY2fwHNEiJNu6NmpBBDLGTJzCsUvn3acCVDVDPMV8yQXdPooAp3iTqEsjvJoco1aLSZXS6T", // address
"a3f208c8f9ba49bab28eed62b35b0f6be0a297bcd85c2faa1eb1820527bcf7e3", // view_pub_key
"9f5e1fa93630d4b281b18bb67a3db79e9622fc703cc3ad4a453a82e0a36d51fa", // spend_pub_key
"87440d0b9acc42f1", // payment_id_hex
0 // flags
},
{
// new format normal address with custom flags
"ZxD5aoLDPTdcaRx4uCpyW4XiLfEXejepAVz8cSY2fwHNEiJNu6NmpBBDLGTJzCsUvn3acCVDVDPMV8yQXdPooAp3APrDvRoL5C", // address
"a3f208c8f9ba49bab28eed62b35b0f6be0a297bcd85c2faa1eb1820527bcf7e3", // view_pub_key
"9f5e1fa93630d4b281b18bb67a3db79e9622fc703cc3ad4a453a82e0a36d51fa", // spend_pub_key
"", // payment_id_hex
0xfe // flags
},
{
// new format integrated address with custom flags
"iZ4mBxubNfqcaRx4uCpyW4XiLfEXejepAVz8cSY2fwHNEiJNu6NmpBBDLGTJzCsUvn3acCVDVDPMV8yQXdPooAp3iTrG7nU5rRCWmcozLaMoY95sAbo6", // address
"a3f208c8f9ba49bab28eed62b35b0f6be0a297bcd85c2faa1eb1820527bcf7e3", // view_pub_key
"9f5e1fa93630d4b281b18bb67a3db79e9622fc703cc3ad4a453a82e0a36d51fa", // spend_pub_key
"3ba0527bcfb1fa93630d28eed6", // payment_id
0xfe // flags
},
{
// normal auditable address
"",
"aZxb9Et6FhP9AinRwcPqSqBKjckre7PgoZjK3q5YG2fUKHYWFZMWjB6YAEAdw4yDDUGEQ7CGEgbqhGRKeadGV1jLYcEJMEmqQFn", // address
"a3f208c8f9ba49bab28eed62b35b0f6be0a297bcd85c2faa1eb1820527bcf7e3", // view_pub_key
"9f5e1fa93630d4b281b18bb67a3db79e9622fc703cc3ad4a453a82e0a36d51fa", // spend_pub_key
"", // payment_id
@ -599,7 +604,7 @@ addr_entry_t addr_entries[] =
},
{
// auditable integrated address
"",
"aiZXDondHWu9AinRwcPqSqBKjckre7PgoZjK3q5YG2fUKHYWFZMWjB6YAEAdw4yDDUGEQ7CGEgbqhGRKeadGV1jLYcEJM9xJH8EbjuRiMJgFmPRATsEV9", // address
"a3f208c8f9ba49bab28eed62b35b0f6be0a297bcd85c2faa1eb1820527bcf7e3", // view_pub_key
"9f5e1fa93630d4b281b18bb67a3db79e9622fc703cc3ad4a453a82e0a36d51fa", // spend_pub_key
"3ba0527bcfb1fa93630d28eed6", // payment_id
@ -609,34 +614,16 @@ addr_entry_t addr_entries[] =
void check_add_entry(const addr_entry_t& ae)
{
// Build address struct from hex keys
currency::account_public_address addr_built = AUTO_VAL_INIT(addr_built);
ASSERT_TRUE(epee::string_tools::parse_tpod_from_hex_string(ae.view_pub_key, addr_built.view_public_key));
ASSERT_TRUE(epee::string_tools::parse_tpod_from_hex_string(ae.spend_pub_key, addr_built.spend_public_key));
addr_built.flags = ae.flags;
std::string payment_id, payment_id_hex;
currency::account_public_address addr = AUTO_VAL_INIT(addr);
// Encode to string (with or without payment id)
std::string payment_id_bin;
if (!ae.payment_id_hex.empty())
epee::string_tools::parse_hexstr_to_binbuff(ae.payment_id_hex, payment_id_bin);
ASSERT_TRUE(currency::get_account_address_and_payment_id_from_str(addr, payment_id, ae.address));
payment_id_hex = epee::string_tools::buff_to_hex_nodelimer(payment_id);
std::string addr_str = payment_id_bin.empty()
? currency::get_account_address_as_str(addr_built)
: currency::get_account_address_and_payment_id_as_str(addr_built, payment_id_bin);
ASSERT_FALSE(addr_str.empty());
// Round-trip: parse the generated address back
currency::account_public_address addr_parsed = AUTO_VAL_INIT(addr_parsed);
std::string payment_id_parsed;
ASSERT_TRUE(currency::get_account_address_and_payment_id_from_str(addr_parsed, payment_id_parsed, addr_str));
std::string payment_id_parsed_hex = epee::string_tools::buff_to_hex_nodelimer(payment_id_parsed);
ASSERT_EQ(ae.flags, addr_parsed.flags);
ASSERT_EQ(ae.payment_id_hex, payment_id_parsed_hex);
ASSERT_EQ(ae.view_pub_key, epee::string_tools::pod_to_hex(addr_parsed.view_public_key));
ASSERT_EQ(ae.spend_pub_key, epee::string_tools::pod_to_hex(addr_parsed.spend_public_key));
ASSERT_EQ(ae.flags, addr.flags);
ASSERT_EQ(ae.payment_id_hex, payment_id_hex);
ASSERT_EQ(ae.view_pub_key, epee::string_tools::pod_to_hex(addr.view_public_key));
ASSERT_EQ(ae.spend_pub_key, epee::string_tools::pod_to_hex(addr.spend_public_key));
}
TEST(auditable_addresses, basic)

View file

@ -10,7 +10,6 @@
#include <boost/foreach.hpp>
#include "currency_core/currency_basic.h"
#include "currency_core/currency_format_utils.h"
#include "currency_core/account.h"
#include "serialization/serialization.h"
#include "serialization/binary_archive.h"
#include "serialization/json_archive.h"
@ -728,7 +727,7 @@ TEST(Serialization, serializes_transacion_versions)
c.comment = "sdcwdcwcewdcecevthbtg";
tx.extra.push_back(c);
extra_alias_entry eae = AUTO_VAL_INIT(eae);
{ currency::account_base tmp_acc; tmp_acc.generate(); eae.m_address = tmp_acc.get_keys().account_address; }
currency::get_account_address_from_str(eae.m_address, "ZxDcDWmA7Yj32srfjMHAY6WPzBB8uqpvzKxEsAjDZU6NRg1yZsRfmr87mLXCvMRHXd5n2kdRWhbqA3WWTbEW4jLd1XxL46tnv");
eae.m_alias = "eokcmeockme";
eae.m_text_comment = "sdssccsc";
tx.extra.push_back(eae);