diff --git a/.github/workflows/c_hooks_test.yml b/.github/workflows/c_hooks_test.yml new file mode 100644 index 0000000000..704a2ab7f5 --- /dev/null +++ b/.github/workflows/c_hooks_test.yml @@ -0,0 +1,87 @@ +name: CHooks Test sources + +on: + push: + branches: ["dev", "candidate", "release"] + pull_request: + branches: ["dev", "candidate", "release"] + +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: false + +jobs: + chooks-test-sources: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y build-essential clang-format wabt xxd bc + + - name: Export PATH + run: | + echo "$HOME/.local/bin" >> $GITHUB_PATH + + - name: Install wasmcc + run: | + curl https://raw.githubusercontent.com/wasienv/wasienv/master/install.sh | sh || true + wasienv install-sdk unstable + wasmcc --version + + - name: Install hook-cleaner + run: | + # Clone only the latest commit with minimal data transfer + git clone --depth 1 https://github.com/RichardAH/hook-cleaner-c.git + cd hook-cleaner-c + make && sudo make install + cd .. + + - name: Backup original SetHook_wasm.h + run: | + # Creating backup of the existing file + cp src/test/app/SetHook_wasm.h src/test/app/SetHook_wasm.h.original + echo "Original file backed up" + + - name: Setup build environment + run: | + # Make scripts executable + chmod +x src/test/app/build_test_hooks.sh + + # Check if necessary test files exist + if [ ! -f src/test/app/SetHook_test.cpp ]; then + echo "Error: SetHook_test.cpp not found" + ls -la src/test/app/ + exit 1 + fi + + - name: Run build_test_hooks.sh + run: | + rm -f src/test/app/SetHook_wasm.h + src/test/app/build_test_hooks.sh + # Check if output file was created + if [ ! -f src/test/app/SetHook_wasm.h ]; then + echo "Error: SetHook_wasm.h was not created" + exit 1 + fi + + - name: Check for differences + run: | + # Format original file for fair comparison + cp src/test/app/SetHook_wasm.h.original src/test/app/SetHook_wasm.h.original.formatted + clang-format -i src/test/app/SetHook_wasm.h.original.formatted + + # Compare formatted files + if diff -u -s src/test/app/SetHook_wasm.h.original.formatted src/test/app/SetHook_wasm.h; then + echo "✅ SetHook_wasm.h is generated consistently with the original file!" + else + echo "❌ SetHook_wasm.h has differences compared to the original file!" + echo "Differences:" + diff -u src/test/app/SetHook_wasm.h.original.formatted src/test/app/SetHook_wasm.h + echo "Run 'src/test/app/build_test_hooks.sh' to generate the SetHook_wasm.h file." + exit 1 + fi diff --git a/.gitignore b/.gitignore index c7e12ec1b7..e372019ed2 100644 --- a/.gitignore +++ b/.gitignore @@ -114,3 +114,5 @@ pkg_out pkg CMakeUserPresets.json bld.rippled/ + +generated diff --git a/src/test/app/build_test_hooks.sh b/src/test/app/build_test_hooks.sh index 4135265477..f8a6427d4a 100755 --- a/src/test/app/build_test_hooks.sh +++ b/src/test/app/build_test_hooks.sh @@ -1,4 +1,35 @@ -#!/bin/bash +#!/bin/bash -u + +# Generate the SetHook_wasm.h file from the SetHook_test.cpp file. +# +# Prerequisites: +# - wasmcc: +# https://github.com/wasienv/wasienv +# +# - hook-cleaner: +# https://github.com/RichardAH/hook-cleaner-c +# +# - wat2wasm +# https://github.com/WebAssembly/wabt +# +# - clang-format: +# Ubuntu: $sudo apt-get install clang-format +# macOS: $brew install clang-format +# +# - (macOS Only) GNU sed, grep: +# $brew install gnu-sed grep +# add path: PATH="/opt/homebrew/opt/gnu-sed/libexec/gnubin:$PATH" + +set -e +# Get the script directory (retrieving the correct path regardless of where it's executed from) +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "${SCRIPT_DIR}" +# Set the project root directory +WASM_DIR="generated/hook/c" +INPUT_FILE="SetHook_test.cpp" +OUTPUT_FILE="SetHook_wasm.h" + +mkdir -p $WASM_DIR echo ' //This file is generated by build_test_hooks.h #ifndef SETHOOK_WASM_INCLUDED @@ -9,54 +40,55 @@ echo ' #include namespace ripple { namespace test { -std::map> wasm = {' > SetHook_wasm.h +std::map> wasm = {' > $OUTPUT_FILE COUNTER="0" -cat SetHook_test.cpp | tr '\n' '\f' | +cat $INPUT_FILE | tr '\n' '\f' | grep -Po 'R"\[test\.hook\](.*?)\[test\.hook\]"' | sed -E 's/R"\[test\.hook\]\(//g' | sed -E 's/\)\[test\.hook\]"[\f \t]*/\/*end*\//g' | while read -r line do - echo "/* ==== WASM: $COUNTER ==== */" >> SetHook_wasm.h - echo -n '{ R"[test.hook](' >> SetHook_wasm.h - cat <<< $line | sed -E 's/.{7}$//g' | tr -d '\n' | tr '\f' '\n' >> SetHook_wasm.h + echo "/* ==== WASM: $COUNTER ==== */" >> $OUTPUT_FILE + echo -n '{ R"[test.hook](' >> $OUTPUT_FILE + cat <<< "$line" | sed -E 's/.{7}$//g' | tr -d '\n' | tr '\f' '\n' >> $OUTPUT_FILE echo ')[test.hook]",' >> SetHook_wasm.h echo "{" >> SetHook_wasm.h WAT=`grep -Eo '\(module' <<< $line | wc -l` if [ "$WAT" -eq "0" ] then - echo '#include "api.h"' > /root/xrpld-hooks/hook/tests/hookapi/wasm/test-$COUNTER-gen.c - tr '\f' '\n' <<< $line >> /root/xrpld-hooks/hook/tests/hookapi/wasm/test-$COUNTER-gen.c + echo '#include "api.h"' > "$WASM_DIR/test-$COUNTER-gen.c" + tr '\f' '\n' <<< $line >> "$WASM_DIR/test-$COUNTER-gen.c" DECLARED="`tr '\f' '\n' <<< $line | grep -E '(extern|define) ' | grep -Eo '[a-z\-\_]+ *\(' | grep -v 'sizeof' | sed -E 's/[^a-z\-\_]//g' | sort | uniq`" USED="`tr '\f' '\n' <<< $line | grep -vE '(extern|define) ' | grep -Eo '[a-z\-\_]+\(' | grep -v 'sizeof' | sed -E 's/[^a-z\-\_]//g' | grep -vE '^(hook|cbak)' | sort | uniq`" ONCE="`echo $DECLARED $USED | tr ' ' '\n' | sort | uniq -c | grep '1 ' | sed -E 's/^ *1 //g'`" - FILTER="`echo $DECLARED | tr ' ' '|' | sed -E 's/|$//g'`" - UNDECL=`echo "$ONCE" | grep -v -E "$FILTER"` + FILTER="`echo $DECLARED | tr ' ' '|' | sed -E 's/\|$//g'`" + UNDECL="`echo $ONCE | grep -v -E $FILTER 2>/dev/null || echo ''`" if [ ! -z "$UNDECL" ] then echo "Undeclared in $COUNTER: $UNDECL" echo "$line" exit 1 fi - wasmcc -x c /dev/stdin -o /dev/stdout -O2 -Wl,--allow-undefined <<< `tr '\f' '\n' <<< $line` | + wasmcc -x c /dev/stdin -o /dev/stdout -O2 -Wl,--allow-undefined <<< "`tr '\f' '\n' <<< $line`" | hook-cleaner - - 2>/dev/null | - xxd -p -u -c 19 | - sed -E 's/../0x\0U,/g' | sed -E 's/^/ /g' >> SetHook_wasm.h + xxd -p -u -c 10 | + sed -E 's/../0x&U,/g' | sed -E 's/^/ /g' >> $OUTPUT_FILE else - wat2wasm - -o /dev/stdout <<< `tr '\f' '\n' <<< $(sed -E 's/.{7}$//g' <<< $line)` | - xxd -p -u -c 19 | - sed -E 's/../0x\0U,/g' | sed -E 's/^/ /g' >> SetHook_wasm.h + wat2wasm - -o /dev/stdout <<< "`tr '\f' '\n' <<< $(sed -E 's/.{7}$//g' <<< $line)`" | + xxd -p -u -c 10 | + sed -E 's/../0x&U,/g' | sed -E 's/^/ /g' >> $OUTPUT_FILE fi if [ "$?" -gt "0" ] then echo "Compilation error ^" exit 1 fi - echo '}},' >> SetHook_wasm.h - echo >> SetHook_wasm.h + echo '}},' >> $OUTPUT_FILE + echo >> $OUTPUT_FILE COUNTER=`echo $COUNTER + 1 | bc` done echo '}; } } -#endif' >> SetHook_wasm.h +#endif' >> $OUTPUT_FILE +clang-format -i $OUTPUT_FILE