diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..5ed4cdc --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,236 @@ +name: Release + +on: + workflow_dispatch: + inputs: + version: + description: 'v4.12' + required: true + type: string + +jobs: + build-linux-x64: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Build static binary + run: | + sudo apt update + sudo apt install -y build-essential cmake + cd external/src/curl + cmake . -DCMAKE_BUILD_TYPE=Release -DBUILD_CURL_EXE=OFF -DBUILD_SHARED_LIBS=OFF -DCURL_DISABLE_INSTALL=ON -DHTTP_ONLY=ON -DCURL_ENABLE_SSL=OFF + make -j$(nproc) + cd ../../.. + mkdir build && cd build + cmake .. -DCMAKE_BUILD_TYPE=Release -DSTATIC_BINARY=ON -DWITH_LTO=OFF + make -j$(nproc) + strip p2pool-salvium + + - name: Package + run: | + cd build + tar -czf p2pool-salvium-v${{ inputs.version }}-linux-x64.tar.gz p2pool-salvium + + - uses: actions/upload-artifact@v4 + with: + name: linux-x64 + path: build/p2pool-salvium-v${{ inputs.version }}-linux-x64.tar.gz + + build-linux-aarch64: + runs-on: ubuntu-22.04 + steps: + - uses: jirutka/setup-alpine@v1 + with: + arch: aarch64 + branch: latest-stable + + - name: Install dependencies and build + shell: alpine.sh {0} + run: | + apk add git cmake gcc g++ make linux-headers xz + + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Build + shell: alpine.sh {0} + run: | + cd external/src/curl + cmake . -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS="-Os -flto=auto" -DBUILD_CURL_EXE=OFF -DBUILD_SHARED_LIBS=OFF -DCURL_DISABLE_INSTALL=ON -DHTTP_ONLY=ON -DCURL_ENABLE_SSL=OFF + make -j$(nproc) + cd ../../.. + mkdir build && cd build + cmake .. -DCMAKE_BUILD_TYPE=Release -DSTATIC_BINARY=ON -DWITH_LTO=OFF + make -j$(nproc) + strip p2pool-salvium + tar -czf p2pool-salvium-v${{ inputs.version }}-linux-aarch64.tar.gz p2pool-salvium + + - uses: actions/upload-artifact@v4 + with: + name: linux-aarch64 + path: build/p2pool-salvium-v${{ inputs.version }}-linux-aarch64.tar.gz + + build-linux-riscv64: + runs-on: ubuntu-22.04 + steps: + - uses: jirutka/setup-alpine@v1 + with: + arch: riscv64 + branch: latest-stable + + - name: Install dependencies + shell: alpine.sh --root {0} + run: apk add git cmake gcc g++ make linux-headers xz + + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Build + shell: alpine.sh {0} + run: | + cd external/src/curl + cmake . -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS="-Os" -DBUILD_CURL_EXE=OFF -DBUILD_SHARED_LIBS=OFF -DCURL_DISABLE_INSTALL=ON -DHTTP_ONLY=ON -DCURL_ENABLE_SSL=OFF + make -j$(nproc) + cd ../../.. + mkdir build && cd build + cmake .. -DCMAKE_BUILD_TYPE=Release -DSTATIC_BINARY=ON -DWITH_LTO=OFF + make -j$(nproc) + strip p2pool-salvium + tar -czf p2pool-salvium-v${{ inputs.version }}-linux-riscv64.tar.gz p2pool-salvium + + - uses: actions/upload-artifact@v4 + with: + name: linux-riscv64 + path: build/p2pool-salvium-v${{ inputs.version }}-linux-riscv64.tar.gz + + build-macos-x64: + runs-on: macos-13 + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Build + run: | + brew install cmake + cd external/src/curl + cmake . -DCMAKE_BUILD_TYPE=Release -DBUILD_CURL_EXE=OFF -DBUILD_SHARED_LIBS=OFF -DCURL_DISABLE_INSTALL=ON -DHTTP_ONLY=ON -DCURL_ENABLE_SSL=OFF + make -j$(sysctl -n hw.ncpu) + cd ../../.. + mkdir build && cd build + cmake .. -DCMAKE_BUILD_TYPE=Release + make -j$(sysctl -n hw.ncpu) + strip p2pool-salvium + tar -czf p2pool-salvium-v${{ inputs.version }}-macos-x64.tar.gz p2pool-salvium + + - uses: actions/upload-artifact@v4 + with: + name: macos-x64 + path: build/p2pool-salvium-v${{ inputs.version }}-macos-x64.tar.gz + + build-macos-aarch64: + runs-on: macos-14 + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Build + run: | + brew install cmake + cd external/src/curl + cmake . -DCMAKE_BUILD_TYPE=Release -DBUILD_CURL_EXE=OFF -DBUILD_SHARED_LIBS=OFF -DCURL_DISABLE_INSTALL=ON -DHTTP_ONLY=ON -DCURL_ENABLE_SSL=OFF + make -j$(sysctl -n hw.ncpu) + cd ../../.. + mkdir build && cd build + cmake .. -DCMAKE_BUILD_TYPE=Release + make -j$(sysctl -n hw.ncpu) + strip p2pool-salvium + tar -czf p2pool-salvium-v${{ inputs.version }}-macos-aarch64.tar.gz p2pool-salvium + + - uses: actions/upload-artifact@v4 + with: + name: macos-aarch64 + path: build/p2pool-salvium-v${{ inputs.version }}-macos-aarch64.tar.gz + + build-windows-x64: + runs-on: windows-latest + defaults: + run: + shell: msys2 {0} + steps: + - uses: msys2/setup-msys2@v2 + with: + msystem: MINGW64 + update: true + install: git make mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake + + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Build + run: | + cd external/src/curl + cmake . -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DBUILD_CURL_EXE=OFF -DBUILD_SHARED_LIBS=OFF -DCURL_DISABLE_INSTALL=ON -DHTTP_ONLY=ON -DCURL_ENABLE_SSL=OFF + make -j$(nproc) + cd ../../.. + mkdir build && cd build + cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release + make -j$(nproc) + strip p2pool-salvium.exe + zip p2pool-salvium-v${{ inputs.version }}-windows-x64.zip p2pool-salvium.exe + + - uses: actions/upload-artifact@v4 + with: + name: windows-x64 + path: build/p2pool-salvium-v${{ inputs.version }}-windows-x64.zip + + create-checksums: + needs: [build-linux-x64, build-linux-aarch64, build-linux-riscv64, build-macos-x64, build-macos-aarch64, build-windows-x64] + runs-on: ubuntu-latest + steps: + - uses: actions/download-artifact@v4 + with: + path: artifacts + + - name: Create source archive + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Package source + run: | + cd .. + tar --exclude='.git' -cJf p2pool-salvium_source-v${{ inputs.version }}.tar.xz p2pool-salvium + mv p2pool-salvium_source-v${{ inputs.version }}.tar.xz p2pool-salvium/ + + - name: Generate checksums + run: | + cd artifacts + find . -name "*.tar.gz" -o -name "*.zip" | while read file; do + sha256sum "$file" >> ../sha256sums.txt + done + cd .. + sha256sum p2pool-salvium_source-v${{ inputs.version }}.tar.xz >> sha256sums.txt + # Clean up paths in checksum file + sed -i 's|\.\/[^/]*\/||g' sha256sums.txt + + - name: Move all files to release directory + run: | + mkdir release + find artifacts -name "*.tar.gz" -exec mv {} release/ \; + find artifacts -name "*.zip" -exec mv {} release/ \; + mv p2pool-salvium_source-v${{ inputs.version }}.tar.xz release/ + mv sha256sums.txt release/ + + - uses: actions/upload-artifact@v4 + with: + name: release-files + path: release/ + diff --git a/.gitignore b/.gitignore index 110c231..a91886b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ .vscode build logs +tests/extract_cache +tests/extract_chain +tests/inspect_dump + diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 78a140d..f685c07 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -189,5 +189,6 @@ target_link_libraries(${CMAKE_PROJECT_NAME} debug ${ZMQ_LIBRARY_DEBUG} debug ${U add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/src/crypto_tests.txt" $) add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/src/block.dat" $) add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/src/sidechain_dump.dat.xz" $) -add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/src/sidechain_dump_mini.dat.xz" $) -add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/src/sidechain_dump_nano.dat.xz" $) +#add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/src/sidechain_dump_mini.dat.xz" $) +#add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/src/sidechain_dump_nano.dat.xz" $) + diff --git a/tests/extract_cache.cpp b/tests/extract_cache.cpp new file mode 100644 index 0000000..0eb072b --- /dev/null +++ b/tests/extract_cache.cpp @@ -0,0 +1,40 @@ +#include +#include +#include +#include + +static constexpr uint32_t BLOCK_SIZE = 96 * 1024; + +int main(int argc, char* argv[]) { + if (argc != 4) { + std::cerr << "Usage: " << argv[0] << " \n"; + return 1; + } + + std::ifstream in(argv[1], std::ios::binary); + std::ofstream out(argv[2], std::ios::binary); + int max_blocks = std::stoi(argv[3]); + + std::vector slot(BLOCK_SIZE); + int blocks_written = 0; + + while (in && blocks_written < max_blocks) { + // Read 96KB slot + in.read(reinterpret_cast(slot.data()), BLOCK_SIZE); + if (!in) break; + + // Read size from first 4 bytes + uint32_t size = *reinterpret_cast(slot.data()); + + // Skip empty slots + if (size == 0 || size > BLOCK_SIZE - 4) continue; + + // Write: size + data + out.write(reinterpret_cast(&size), sizeof(size)); + out.write(reinterpret_cast(slot.data() + 4), size); + blocks_written++; + } + + std::cout << "Extracted " << blocks_written << " blocks\n"; + return 0; +} diff --git a/tests/extract_chain.cpp b/tests/extract_chain.cpp new file mode 100644 index 0000000..68debcc --- /dev/null +++ b/tests/extract_chain.cpp @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +#include + +static constexpr uint32_t BLOCK_SIZE = 96 * 1024; +static constexpr uint32_t NUM_BLOCKS = 4608; + +int main(int argc, char* argv[]) { + if (argc != 4) { + std::cerr << "Usage: " << argv[0] << " \n"; + return 1; + } + + std::ifstream cache(argv[1], std::ios::binary); + std::ofstream out(argv[2], std::ios::binary); + int want_blocks = std::stoi(argv[3]); + + // Read all slots to find the last written block + std::vector>> slots; + std::vector slot(BLOCK_SIZE); + + for (int i = 0; i < NUM_BLOCKS; ++i) { + cache.read(reinterpret_cast(slot.data()), BLOCK_SIZE); + uint32_t size = *reinterpret_cast(slot.data()); + + if (size > 0 && size < BLOCK_SIZE - 4) { + std::vector data(size); + memcpy(data.data(), slot.data() + 4, size); + slots.push_back({i, std::move(data)}); + } + } + + std::cout << "Found " << slots.size() << " valid blocks in cache\n"; + + // Take the last N blocks (most recent) + int start = std::max(0, (int)slots.size() - want_blocks); + int written = 0; + + for (int i = start; i < slots.size(); ++i) { + uint32_t size = slots[i].second.size(); + out.write(reinterpret_cast(&size), 4); + out.write(reinterpret_cast(slots[i].second.data()), size); + written++; + } + + std::cout << "Extracted " << written << " consecutive blocks (slots " << slots[start].first << " to " << slots.back().first << ")\n"; + return 0; +} diff --git a/tests/inspect_dump.cpp b/tests/inspect_dump.cpp new file mode 100644 index 0000000..95e6b15 --- /dev/null +++ b/tests/inspect_dump.cpp @@ -0,0 +1,23 @@ +#include +#include +#include + +int main(int argc, char* argv[]) { + std::ifstream in(argv[1], std::ios::binary); + + uint32_t size; + in.read(reinterpret_cast(&size), 4); + + std::cout << "First block size: " << size << " bytes\n"; + std::cout << "Total blocks in file: "; + + int count = 1; + while (in) { + in.seekg(size, std::ios::cur); + in.read(reinterpret_cast(&size), 4); + if (in) count++; + } + + std::cout << count << "\n"; + return 0; +} diff --git a/tests/src/pool_block_tests.cpp b/tests/src/pool_block_tests.cpp index 6cb7250..da8ae9f 100644 --- a/tests/src/pool_block_tests.cpp +++ b/tests/src/pool_block_tests.cpp @@ -151,21 +151,18 @@ TEST(pool_block, verify) uint32_t m_expectedSharesNextBlock; bool m_shuffle; hash m_templateBlobsHash; - } tests[6] = { - { "default", "sidechain_dump.dat", 3456189, 11704382, 53, false, H("c84a85eebf17ab266e8a81b347dd7490043ede3a055c0dbe85e9cd378905845a") }, - { "default", "sidechain_dump.dat", 3456189, 11704382, 53, true, H("c84a85eebf17ab266e8a81b347dd7490043ede3a055c0dbe85e9cd378905845a") }, - { "mini", "sidechain_dump_mini.dat", 3456189, 11207082, 578, false, H("08debd1378bae899017eb58362f4c638d78e5218558025142dcbc2651c76b27e") }, - { "mini", "sidechain_dump_mini.dat", 3456189, 11207082, 578, true, H("08debd1378bae899017eb58362f4c638d78e5218558025142dcbc2651c76b27e") }, - { "nano", "sidechain_dump_nano.dat", 3456189, 188542, 115, false, H("dd667c41eb15ffb0eb662065545dc0dfbbcac8393348a4fc0a7367040319b0d5") }, - { "nano", "sidechain_dump_nano.dat", 3456189, 188542, 115, true, H("dd667c41eb15ffb0eb662065545dc0dfbbcac8393348a4fc0a7367040319b0d5") }, - }; + } tests[] = { + // Salvium mainnet - full cache (4608 blocks at sidechain height 11536) + { "salvium_main", "sidechain_dump.dat", 357365, 11536, 3, false, H("5634d8403f91c81ff792504419b63c617efb372aff6144ab9e025501df45c821") }, + { "salvium_main", "sidechain_dump.dat", 357365, 11536, 3, true, H("5634d8403f91c81ff792504419b63c617efb372aff6144ab9e025501df45c821") }, + }; for (const STest& t : tests) { SideChain sidechain(nullptr, NetworkType::Mainnet, t.m_poolName); - // Difficulty of block 3454976 - sidechain.m_testMainChainDiff = difficulty_type(625461936742ULL, 0ULL); + // Difficulty at Salvium height ~357000 + sidechain.m_testMainChainDiff = difficulty_type(12964350330ULL, 0ULL); std::ifstream f(t.m_fileName, std::ios::binary | std::ios::ate); ASSERT_EQ(f.good() && f.is_open(), true); @@ -224,13 +221,14 @@ TEST(pool_block, verify) auto& r = tpl.rng(); r.seed(0); - MinerData data; - data.major_version = 16; - data.height = t.m_txinGenHeight; - data.prev_id = H("f7723462d2f4d9f605601df8de8bd483802d2275f77cbf3a6f61d8f3fc4c47bc"); - data.seed_hash = H("11186f5a8473d8dc7a0d3a0bf25834a07b1dffe8741d53cd543a8708c2e8b2a9"); - data.difficulty = { 656711234691ULL, 0 }; - data.median_weight = 300000; + MinerData data; + data.major_version = 10; // Salvium Carrot v1 + data.height = t.m_txinGenHeight; + data.prev_id = tip->m_sidechainId; // Use actual tip block ID + data.seed_hash = H("65d2f44f763238aa3363add8f638f78dc811e084ce8b244916ab7589650b760b"); // Current Salvium seed + data.difficulty = { 12964350330ULL, 0 }; // Current Salvium difficulty + data.median_weight = 300000; + data.already_generated_coins = std::numeric_limits::max(); data.median_timestamp = (1ULL << 35) - 2; @@ -249,8 +247,8 @@ TEST(pool_block, verify) Params params; - params.m_miningWallet = Wallet("44MnN1f3Eto8DZYUWuE5XZNUtE3vcRzt2j6PzqWpPau34e6Cf4fAxt6X2MBmrm6F9YMEiMNjN6W4Shn4pLcfNAja621jwyg"); - params.m_subaddress = Wallet("86eQxzSW4AZfvsWRSop755WZUsog6L3x32NRZukeeShnS4mBGVpcqQhS6pCNxj44usPKNwesZ45ooHyjDku6nVZdT3Q9qrz"); + params.m_miningWallet = Wallet("SC11n4s2UEj9Rc8XxppPbegwQethVmREpG9JP3aJUBGRCuD3wEvS4qtYtBjhqSx3S1hw3WDCfmbWKHJqa9g5Vqyo3jrsReJ5vp"); + params.m_subaddress = Wallet("SC1siDDg9o3hBrSHJPBaGPXmJvPcUku8nD84cCT2PNUn61PxtdtBynHBiCaUf7BbNJctmU8LKabiHNE8x5ReYg6RYEhSqRFcL2W"); tpl.update(data, mempool, ¶ms); @@ -269,7 +267,7 @@ TEST(pool_block, verify) } PoolBlock block; - ASSERT_TRUE(block.m_minerWallet.decode("44MnN1f3Eto8DZYUWuE5XZNUtE3vcRzt2j6PzqWpPau34e6Cf4fAxt6X2MBmrm6F9YMEiMNjN6W4Shn4pLcfNAja621jwyg")); + ASSERT_TRUE(block.m_minerWallet.decode("SC11n4s2UEj9Rc8XxppPbegwQethVmREpG9JP3aJUBGRCuD3wEvS4qtYtBjhqSx3S1hw3WDCfmbWKHJqa9g5Vqyo3jrsReJ5vp")); std::vector shares; diff --git a/tests/src/sidechain_dump.dat.xz b/tests/src/sidechain_dump.dat.xz index 10a3f43..92164c0 100644 Binary files a/tests/src/sidechain_dump.dat.xz and b/tests/src/sidechain_dump.dat.xz differ