diff --git a/.github/actions/xahau-configure-ccache/action.yml b/.github/actions/xahau-configure-ccache/action.yml deleted file mode 100644 index 44414b98a..000000000 --- a/.github/actions/xahau-configure-ccache/action.yml +++ /dev/null @@ -1,63 +0,0 @@ -name: 'Configure ccache' -description: 'Sets up ccache with consistent configuration' - -inputs: - max_size: - description: 'Maximum cache size' - required: false - default: '2G' - hash_dir: - description: 'Whether to include directory paths in hash' - required: false - default: 'true' - compiler_check: - description: 'How to check compiler for changes' - required: false - default: 'content' - is_main_branch: - description: 'Whether the current branch is the main branch' - required: false - default: 'false' - main_cache_dir: - description: 'Path to the main branch cache directory' - required: false - default: '~/.ccache-main' - current_cache_dir: - description: 'Path to the current branch cache directory' - required: false - default: '~/.ccache-current' - -runs: - using: 'composite' - steps: - - name: Configure ccache - shell: bash - run: | - # Create cache directories - mkdir -p ${{ inputs.main_cache_dir }} ${{ inputs.current_cache_dir }} - - # Set compiler check globally - ccache -o compiler_check=${{ inputs.compiler_check }} - - # Use a single config file location - mkdir -p ~/.ccache - export CONF_PATH="$HOME/.ccache/ccache.conf" - - # Apply common settings - echo "max_size = ${{ inputs.max_size }}" > "$CONF_PATH" - echo "hash_dir = ${{ inputs.hash_dir }}" >> "$CONF_PATH" - echo "compiler_check = ${{ inputs.compiler_check }}" >> "$CONF_PATH" - - if [ "${{ inputs.is_main_branch }}" == "true" ]; then - # Main branch: use main branch cache - ccache --set-config=cache_dir="${{ inputs.main_cache_dir }}" - echo "CCACHE_DIR=${{ inputs.main_cache_dir }}" >> $GITHUB_ENV - else - # Feature branch: use current branch cache with main as secondary - ccache --set-config=cache_dir="${{ inputs.current_cache_dir }}" - ccache --set-config=secondary_storage="file:${{ inputs.main_cache_dir }}" - echo "CCACHE_DIR=${{ inputs.current_cache_dir }}" >> $GITHUB_ENV - fi - - ccache -p # Print config for verification - ccache -z # Zero statistics before the build \ No newline at end of file diff --git a/.github/actions/xahau-ga-build/action.yml b/.github/actions/xahau-ga-build/action.yml index 71f0edb2b..71beb7443 100644 --- a/.github/actions/xahau-ga-build/action.yml +++ b/.github/actions/xahau-ga-build/action.yml @@ -47,6 +47,18 @@ inputs: description: 'GCC version to use for Clang toolchain (e.g. 11, 13)' required: false default: '' + ccache_max_size: + description: 'Maximum ccache size' + required: false + default: '2G' + ccache_hash_dir: + description: 'Whether to include directory paths in hash' + required: false + default: 'true' + ccache_compiler_check: + description: 'How to check compiler for changes' + required: false + default: 'content' runs: using: 'composite' @@ -59,21 +71,22 @@ runs: SAFE_BRANCH=$(echo "${{ github.ref_name }}" | tr -c 'a-zA-Z0-9_.-' '-') echo "name=${SAFE_BRANCH}" >> $GITHUB_OUTPUT - - name: Restore ccache directory for default branch + - name: Restore ccache directory for main branch if: inputs.ccache_enabled == 'true' id: ccache-restore - uses: actions/cache/restore@v4 + uses: ./.github/actions/xahau-ga-cache-restore with: path: ~/.ccache-main key: ${{ runner.os }}-ccache-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}-${{ inputs.configuration }}-${{ inputs.main_branch }} restore-keys: | ${{ runner.os }}-ccache-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}-${{ inputs.configuration }}- ${{ runner.os }}-ccache-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}- + cache-type: ccache-main - name: Restore ccache directory for current branch if: inputs.ccache_enabled == 'true' && steps.safe-branch.outputs.name != inputs.main_branch id: ccache-restore-current-branch - uses: actions/cache/restore@v4 + uses: ./.github/actions/xahau-ga-cache-restore with: path: ~/.ccache-current key: ${{ runner.os }}-ccache-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}-${{ inputs.configuration }}-${{ steps.safe-branch.outputs.name }} @@ -81,6 +94,40 @@ runs: ${{ runner.os }}-ccache-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}-${{ inputs.configuration }}-${{ inputs.main_branch }} ${{ runner.os }}-ccache-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}-${{ inputs.configuration }}- ${{ runner.os }}-ccache-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}- + cache-type: ccache-current + + - name: Configure ccache + if: inputs.ccache_enabled == 'true' + shell: bash + run: | + # Create cache directories + mkdir -p ~/.ccache-main ~/.ccache-current + + # Configure ccache settings AFTER cache restore (prevents stale cached config) + ccache --set-config=max_size=${{ inputs.ccache_max_size }} + ccache --set-config=hash_dir=${{ inputs.ccache_hash_dir }} + ccache --set-config=compiler_check=${{ inputs.ccache_compiler_check }} + + # Determine if we're on the main branch + if [ "${{ steps.safe-branch.outputs.name }}" = "${{ inputs.main_branch }}" ]; then + # Main branch: use main branch cache only + ccache --set-config=cache_dir="$HOME/.ccache-main" + echo "CCACHE_DIR=$HOME/.ccache-main" >> $GITHUB_ENV + echo "đŸ“Ļ Main branch: using ~/.ccache-main" + else + # Feature branch: use current branch cache with main as secondary (read-only fallback) + ccache --set-config=cache_dir="$HOME/.ccache-current" + ccache --set-config=secondary_storage="file:$HOME/.ccache-main" + echo "CCACHE_DIR=$HOME/.ccache-current" >> $GITHUB_ENV + echo "đŸ“Ļ Feature branch: using ~/.ccache-current with ~/.ccache-main as secondary" + fi + + # Print config for verification + echo "=== ccache configuration ===" + ccache -p + + # Zero statistics before the build + ccache -z - name: Configure project shell: bash @@ -96,14 +143,27 @@ runs: if [ -n "${{ inputs.cxx }}" ]; then export CXX="${{ inputs.cxx }}" fi - - - # Configure ccache launcher args - CCACHE_ARGS="" + + # Create wrapper toolchain that overlays ccache on top of Conan's toolchain + # This enables ccache for the main app build without affecting Conan dependency builds if [ "${{ inputs.ccache_enabled }}" = "true" ]; then - CCACHE_ARGS="-DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache" + cat > wrapper_toolchain.cmake <<'EOF' + # Include Conan's generated toolchain first (sets compiler, flags, etc.) + # Note: CMAKE_CURRENT_LIST_DIR is the directory containing this wrapper (.build/) + include(${CMAKE_CURRENT_LIST_DIR}/build/generators/conan_toolchain.cmake) + + # Overlay ccache configuration for main application build + # This does NOT affect Conan dependency builds (already completed) + set(CMAKE_C_COMPILER_LAUNCHER ccache CACHE STRING "C compiler launcher" FORCE) + set(CMAKE_CXX_COMPILER_LAUNCHER ccache CACHE STRING "C++ compiler launcher" FORCE) + EOF + TOOLCHAIN_FILE="wrapper_toolchain.cmake" + echo "✅ Created wrapper toolchain with ccache enabled" + else + TOOLCHAIN_FILE="build/generators/conan_toolchain.cmake" + echo "â„šī¸ Using Conan toolchain directly (ccache disabled)" fi - + # Configure C++ standard library if specified # libstdcxx used for clang-14/16 to work around missing lexicographical_compare_three_way in libc++ # libcxx can be used with clang-17+ which has full C++20 support @@ -143,33 +203,50 @@ runs: # So we get: .build/build/generators/ with our non-standard folder name cmake .. \ -G "${{ inputs.generator }}" \ - $CCACHE_ARGS \ ${CMAKE_CXX_FLAGS:+-DCMAKE_CXX_FLAGS="$CMAKE_CXX_FLAGS"} \ - -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \ + -DCMAKE_TOOLCHAIN_FILE:FILEPATH=${TOOLCHAIN_FILE} \ -DCMAKE_BUILD_TYPE=${{ inputs.configuration }} \ -Dtests=TRUE \ -Dxrpld=TRUE + - name: Show ccache config before build + if: inputs.ccache_enabled == 'true' + shell: bash + run: | + echo "==========================================" + echo "ccache configuration before build" + echo "==========================================" + ccache -p + echo "" + - name: Build project shell: bash run: | cd ${{ inputs.build_dir }} - cmake --build . --config ${{ inputs.configuration }} --parallel $(nproc) + + # Check for verbose build flag in commit message + VERBOSE_FLAG="" + if echo "${XAHAU_GA_COMMIT_MSG}" | grep -q '\[ci-ga-cmake-verbose\]'; then + echo "🔊 [ci-ga-cmake-verbose] detected - enabling verbose output" + VERBOSE_FLAG="-- -v" + fi + + cmake --build . --config ${{ inputs.configuration }} --parallel $(nproc) ${VERBOSE_FLAG} - name: Show ccache statistics if: inputs.ccache_enabled == 'true' shell: bash run: ccache -s - - name: Save ccache directory for default branch - if: always() && inputs.ccache_enabled == 'true' && steps.safe-branch.outputs.name == inputs.main_branch + - name: Save ccache directory for main branch + if: success() && inputs.ccache_enabled == 'true' && steps.safe-branch.outputs.name == inputs.main_branch uses: actions/cache/save@v4 with: path: ~/.ccache-main key: ${{ steps.ccache-restore.outputs.cache-primary-key }} - name: Save ccache directory for current branch - if: always() && inputs.ccache_enabled == 'true' && steps.safe-branch.outputs.name != inputs.main_branch + if: success() && inputs.ccache_enabled == 'true' && steps.safe-branch.outputs.name != inputs.main_branch uses: actions/cache/save@v4 with: path: ~/.ccache-current diff --git a/.github/actions/xahau-ga-cache-restore/action.yml b/.github/actions/xahau-ga-cache-restore/action.yml new file mode 100644 index 000000000..de7b8c2fa --- /dev/null +++ b/.github/actions/xahau-ga-cache-restore/action.yml @@ -0,0 +1,146 @@ +name: 'Cache Restore' +description: 'Restores cache with optional clearing based on commit message tags' + +inputs: + path: + description: 'A list of files, directories, and wildcard patterns to cache' + required: true + key: + description: 'An explicit key for restoring the cache' + required: true + restore-keys: + description: 'An ordered list of prefix-matched keys to use for restoring stale cache if no cache hit occurred for key' + required: false + default: '' + cache-type: + description: 'Type of cache (for logging purposes, e.g., "ccache-main", "Conan")' + required: false + default: 'cache' + fail-on-cache-miss: + description: 'Fail the workflow if cache entry is not found' + required: false + default: 'false' + lookup-only: + description: 'Check if a cache entry exists for the given input(s) without downloading it' + required: false + default: 'false' + additional-clear-keys: + description: 'Additional cache keys to clear (newline separated)' + required: false + default: '' + +outputs: + cache-hit: + description: 'A boolean value to indicate an exact match was found for the primary key' + value: ${{ steps.restore-cache.outputs.cache-hit }} + cache-primary-key: + description: 'The key that was used to restore the cache' + value: ${{ steps.restore-cache.outputs.cache-primary-key }} + cache-matched-key: + description: 'The key that was used to restore the cache (exact or prefix match)' + value: ${{ steps.restore-cache.outputs.cache-matched-key }} + +runs: + using: 'composite' + steps: + - name: Clear cache if requested via commit message + shell: bash + env: + GH_TOKEN: ${{ github.token }} + run: | + echo "==========================================" + echo "${{ inputs.cache-type }} cache clear tag detection" + echo "==========================================" + echo "Searching for: [ci-ga-clear-cache] or [ci-ga-clear-cache:*]" + echo "" + + CACHE_KEY="${{ inputs.key }}" + + # Extract search terms if present (e.g., "ccache" from "[ci-ga-clear-cache:ccache]") + SEARCH_TERMS=$(echo "${XAHAU_GA_COMMIT_MSG}" | grep -o '\[ci-ga-clear-cache:[^]]*\]' | sed 's/\[ci-ga-clear-cache://;s/\]//' || echo "") + + SHOULD_CLEAR=false + + if [ -n "${SEARCH_TERMS}" ]; then + # Search terms provided - check if THIS cache key matches ALL terms (AND logic) + echo "🔍 [ci-ga-clear-cache:${SEARCH_TERMS}] detected" + echo "Checking if cache key matches search terms..." + echo " Cache key: ${CACHE_KEY}" + echo " Search terms: ${SEARCH_TERMS}" + echo "" + + MATCHES=true + for term in ${SEARCH_TERMS}; do + if ! echo "${CACHE_KEY}" | grep -q "${term}"; then + MATCHES=false + echo " ✗ Key does not contain '${term}'" + break + else + echo " ✓ Key contains '${term}'" + fi + done + + if [ "${MATCHES}" = "true" ]; then + echo "" + echo "✅ Cache key matches all search terms - will clear cache" + SHOULD_CLEAR=true + else + echo "" + echo "â­ī¸ Cache key doesn't match search terms - skipping cache clear" + fi + elif echo "${XAHAU_GA_COMMIT_MSG}" | grep -q '\[ci-ga-clear-cache\]'; then + # No search terms - always clear this job's cache + echo "đŸ—‘ī¸ [ci-ga-clear-cache] detected in commit message" + echo "Clearing ${{ inputs.cache-type }} cache for key: ${CACHE_KEY}" + SHOULD_CLEAR=true + fi + + if [ "${SHOULD_CLEAR}" = "true" ]; then + echo "" + echo "Deleting ${{ inputs.cache-type }} caches via GitHub API..." + + # Delete primary cache key + echo "Checking for cache: ${CACHE_KEY}" + if gh cache list --key "${CACHE_KEY}" --json key --jq '.[].key' | grep -q "${CACHE_KEY}"; then + echo " Deleting: ${CACHE_KEY}" + gh cache delete "${CACHE_KEY}" || true + echo " ✓ Deleted" + else + echo " â„šī¸ Not found" + fi + + # Delete additional keys if provided + if [ -n "${{ inputs.additional-clear-keys }}" ]; then + echo "" + echo "Checking additional keys..." + while IFS= read -r key; do + [ -z "${key}" ] && continue + echo "Checking for cache: ${key}" + if gh cache list --key "${key}" --json key --jq '.[].key' | grep -q "${key}"; then + echo " Deleting: ${key}" + gh cache delete "${key}" || true + echo " ✓ Deleted" + else + echo " â„šī¸ Not found" + fi + done <<< "${{ inputs.additional-clear-keys }}" + fi + + echo "" + echo "✅ ${{ inputs.cache-type }} cache cleared successfully" + echo "Build will proceed from scratch" + else + echo "" + echo "â„šī¸ No ${{ inputs.cache-type }} cache clear requested" + fi + echo "==========================================" + + - name: Restore cache + id: restore-cache + uses: actions/cache/restore@v4 + with: + path: ${{ inputs.path }} + key: ${{ inputs.key }} + restore-keys: ${{ inputs.restore-keys }} + fail-on-cache-miss: ${{ inputs.fail-on-cache-miss }} + lookup-only: ${{ inputs.lookup-only }} diff --git a/.github/actions/xahau-ga-dependencies/action.yml b/.github/actions/xahau-ga-dependencies/action.yml index 38307c4be..1e0c49945 100644 --- a/.github/actions/xahau-ga-dependencies/action.yml +++ b/.github/actions/xahau-ga-dependencies/action.yml @@ -25,6 +25,28 @@ inputs: description: 'Main branch name for restore keys' required: false default: 'dev' + os: + description: 'Operating system (Linux, Macos)' + required: false + default: 'Linux' + arch: + description: 'Architecture (x86_64, armv8)' + required: false + default: 'x86_64' + compiler: + description: 'Compiler type (gcc, clang, apple-clang)' + required: true + compiler_version: + description: 'Compiler version (11, 13, 14, etc.)' + required: true + cc: + description: 'C compiler executable (gcc-13, clang-14, etc.), empty for macOS' + required: false + default: '' + cxx: + description: 'C++ compiler executable (g++-14, clang++-14, etc.), empty for macOS' + required: false + default: '' stdlib: description: 'C++ standard library for Conan configuration (note: also in compiler-id)' required: true @@ -41,47 +63,70 @@ outputs: runs: using: 'composite' steps: - - name: Generate safe branch name - if: inputs.cache_enabled == 'true' - id: safe-branch - shell: bash - run: | - SAFE_BRANCH=$(echo "${{ github.ref_name }}" | tr -c 'a-zA-Z0-9_.-' '-') - echo "name=${SAFE_BRANCH}" >> $GITHUB_OUTPUT - - - name: Check conanfile changes - if: inputs.cache_enabled == 'true' - id: check-conanfile-changes - shell: bash - run: | - # Check if we're on the main branch - if [ "${{ github.ref_name }}" == "${{ inputs.main_branch }}" ]; then - echo "should-save-conan-cache=true" >> $GITHUB_OUTPUT - else - # Fetch main branch for comparison - git fetch origin ${{ inputs.main_branch }} - - # Check if conanfile.txt or conanfile.py has changed compared to main branch - if git diff --quiet origin/${{ inputs.main_branch }}..HEAD -- '**/conanfile.txt' '**/conanfile.py'; then - echo "should-save-conan-cache=false" >> $GITHUB_OUTPUT - else - echo "should-save-conan-cache=true" >> $GITHUB_OUTPUT - fi - fi - - name: Restore Conan cache if: inputs.cache_enabled == 'true' id: cache-restore-conan - uses: actions/cache/restore@v4 + uses: ./.github/actions/xahau-ga-cache-restore with: - path: | - ~/.conan - ~/.conan2 + path: ~/.conan2 # Note: compiler-id format is compiler-version-stdlib[-gccversion] - key: ${{ runner.os }}-conan-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}-${{ hashFiles('**/conanfile.txt', '**/conanfile.py') }}-${{ inputs.configuration }} + key: ${{ runner.os }}-conan-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}-${{ hashFiles('**/conanfile.py') }}-${{ inputs.configuration }} restore-keys: | - ${{ runner.os }}-conan-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}-${{ hashFiles('**/conanfile.txt', '**/conanfile.py') }}- + ${{ runner.os }}-conan-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}-${{ hashFiles('**/conanfile.py') }}- ${{ runner.os }}-conan-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}- + cache-type: Conan + + - name: Configure Conan + shell: bash + run: | + # Create the default profile directory if it doesn't exist + mkdir -p ~/.conan2/profiles + + # Determine the correct libcxx based on stdlib parameter + if [ "${{ inputs.stdlib }}" = "libcxx" ]; then + LIBCXX="libc++" + else + LIBCXX="libstdc++11" + fi + + # Create profile with our specific settings + # This overwrites any cached profile to ensure fresh configuration + cat > ~/.conan2/profiles/default <> ~/.conan2/profiles/default <> ~/.conan2/profiles/default < ~/.conan2/profiles/default <> $GITHUB_OUTPUT + echo "Detected Apple Clang version: ${COMPILER_VERSION}" - name: Install dependencies uses: ./.github/actions/xahau-ga-dependencies @@ -133,6 +113,11 @@ jobs: compiler-id: clang cache_version: ${{ env.CACHE_VERSION }} main_branch: ${{ env.MAIN_BRANCH_NAME }} + os: Macos + arch: armv8 + compiler: apple-clang + compiler_version: ${{ steps.detect-compiler.outputs.compiler_version }} + stdlib: libcxx - name: Build uses: ./.github/actions/xahau-ga-build @@ -143,6 +128,7 @@ jobs: compiler-id: clang cache_version: ${{ env.CACHE_VERSION }} main_branch: ${{ env.MAIN_BRANCH_NAME }} + stdlib: libcxx - name: Test run: | diff --git a/.github/workflows/xahau-ga-nix.yml b/.github/workflows/xahau-ga-nix.yml index 8e5c4c4c6..55c1d69f9 100644 --- a/.github/workflows/xahau-ga-nix.yml +++ b/.github/workflows/xahau-ga-nix.yml @@ -19,13 +19,24 @@ jobs: outputs: matrix: ${{ steps.set-matrix.outputs.matrix }} steps: + - name: escape double quotes + id: escape + shell: bash + env: + PR_TITLE: ${{ github.event.pull_request.title }} + run: | + ESCAPED_PR_TITLE="${PR_TITLE//\"/\\\"}" + echo "title=${ESCAPED_PR_TITLE}" >> "$GITHUB_OUTPUT" - name: Generate build matrix id: set-matrix shell: python + env: + GH_TOKEN: ${{ github.token }} run: | import json import os - + import urllib.request + # Full matrix with all 6 compiler configurations # Each configuration includes all parameters needed by the build job full_matrix = [ @@ -99,13 +110,31 @@ jobs: ref = "${{ github.ref }}" base_ref = "${{ github.base_ref }}" # For PRs, this is the target branch event_name = "${{ github.event_name }}" - commit_message = """${{ github.event.head_commit.message }}""" - pr_title = """${{ github.event.pull_request.title }}""" - + pr_title = """${{ steps.escape.outputs.title }}""" + pr_head_sha = "${{ github.event.pull_request.head.sha }}" + + # Get commit message - for PRs, fetch via API since head_commit.message is empty + if event_name == "pull_request" and pr_head_sha: + try: + url = f"https://api.github.com/repos/${{ github.repository }}/commits/{pr_head_sha}" + req = urllib.request.Request(url, headers={ + "Accept": "application/vnd.github.v3+json", + "Authorization": f"Bearer {os.environ.get('GH_TOKEN', '')}" + }) + with urllib.request.urlopen(req) as response: + data = json.load(response) + commit_message = data["commit"]["message"] + except Exception as e: + print(f"Failed to fetch commit message: {e}") + commit_message = "" + else: + commit_message = """${{ github.event.head_commit.message }}""" + # Debug logging print(f"Event: {event_name}") print(f"Ref: {ref}") print(f"Base ref: {base_ref}") + print(f"PR head SHA: {pr_head_sha}") print(f"PR title: {pr_title}") print(f"Commit message: {commit_message}") @@ -156,12 +185,20 @@ jobs: env: build_dir: .build # Bump this number to invalidate all caches globally. - CACHE_VERSION: 2 + CACHE_VERSION: 3 MAIN_BRANCH_NAME: dev steps: - name: Checkout uses: actions/checkout@v4 + - name: Get commit message + id: get-commit-message + uses: ./.github/actions/xahau-ga-get-commit-message + with: + event-name: ${{ github.event_name }} + head-commit-message: ${{ github.event.head_commit.message }} + pr-head-sha: ${{ github.event.pull_request.head.sha }} + - name: Install build dependencies run: | sudo apt-get update @@ -231,48 +268,6 @@ jobs: # Install Conan 2 pip install --upgrade "conan>=2.0,<3" - - name: Configure ccache - uses: ./.github/actions/xahau-configure-ccache - with: - max_size: 2G - hash_dir: true - compiler_check: content - is_main_branch: ${{ github.ref_name == env.MAIN_BRANCH_NAME }} - - - name: Configure Conan - run: | - # Create the default profile directory if it doesn't exist - mkdir -p ~/.conan2/profiles - - # Determine the correct libcxx based on stdlib parameter - if [ "${{ matrix.stdlib }}" = "libcxx" ]; then - LIBCXX="libc++" - else - LIBCXX="libstdc++11" - fi - - # Create profile with our specific settings - cat > ~/.conan2/profiles/default <info().drops; + auto const txnFee = + env.current()->rules().enabled(fixEtxnFeeBase) ? 0 : 10; BEAST_EXPECT( initCoins - 1'000'000 /* txn fee */ - - 10 /* emitted txn fee */ + - txnFee /* emitted txn fee */ + 123'000'000 /* minted */ == postCoins); } @@ -622,8 +629,11 @@ struct GenesisMint_test : public beast::unit_test::suite le->getFieldAmount(sfBalance).xrp().drops() == amtResult); auto const postCoins = env.current()->info().drops; + auto const txnFee = + env.current()->rules().enabled(fixEtxnFeeBase) ? 0 : 10; BEAST_EXPECT( - initCoins - 1'000'000 /* txn fee */ - 10 /* emitted txn fee */ + initCoins - 1'000'000 /* txn fee */ - + txnFee /* emitted txn fee */ == postCoins); } } @@ -689,10 +699,11 @@ public: auto const sa = supported_amendments(); testWithFeats(sa); testWithFeats(sa - fixXahauV1); + testWithFeats(sa - fixEtxnFeeBase); } }; BEAST_DEFINE_TESTSUITE(GenesisMint, app, ripple); } // namespace test -} // namespace ripple \ No newline at end of file +} // namespace ripple diff --git a/src/test/app/SetHook_test.cpp b/src/test/app/SetHook_test.cpp index b1986bb31..54deb5647 100644 --- a/src/test/app/SetHook_test.cpp +++ b/src/test/app/SetHook_test.cpp @@ -3137,12 +3137,8 @@ public: testcase("Test etxn_fee_base"); using namespace jtx; - Env env{*this, features}; - auto const alice = Account{"alice"}; auto const bob = Account{"bob"}; - env.fund(XRP(10000), alice); - env.fund(XRP(10000), bob); TestHook hook = wasm[R"[test.hook]( #include @@ -3159,6 +3155,23 @@ public: #define ASSERT(x)\ if (!(x))\ rollback((uint32_t)#x, sizeof(#x), __LINE__); + + // { + // "TransactionType": "Invoke", + // "Account": "rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn", + // "Blob": "DEADBEEF", + // "Sequence": 0, + // "Fee": "0", + // "SigningPubKey": "" + // } + uint8_t tx[48] = { + 0x12U,0x00U,0x63U,0x24U,0x00U,0x00U,0x00U,0x00U,0x68U,0x40U, + 0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,0x73U,0x00U,0x70U, + 0x1AU,0x04U,0xDEU,0xADU,0xBEU,0xEFU,0x81U,0x14U,0xAEU,0x12U, + 0x3AU,0x85U,0x56U,0xF3U,0xCFU,0x91U,0x15U,0x47U,0x11U,0x37U, + 0x6AU,0xFBU,0x0FU,0x89U,0x4FU,0x83U,0x2BU,0x3DU + }; + int64_t hook(uint32_t reservmaed ) { _g(1,1); @@ -3173,18 +3186,49 @@ public: etxn_reserve(1); ASSERT(etxn_fee_base((uint32_t)det, 116) == INVALID_TXN); - return accept(0,0,0); + int64_t fee = etxn_fee_base((uint32_t)tx, sizeof(tx)); + return accept(0,0,fee); } )[test.hook]"]; - // install the hook on alice - env(ripple::test::jtx::hook(alice, {{hso(hook, overrideFlag)}}, 0), - M("set etxn_fee_base"), - HSFEE); - env.close(); + for (auto hasFix : {true, false}) + { + auto f = features; + if (!hasFix) + f = f - fixEtxnFeeBase; - // invoke the hook - env(pay(bob, alice, XRP(1)), M("test etxn_fee_base"), fee(XRP(1))); + Env env{*this, f}; + + env.fund(XRP(10000), alice); + env.fund(XRP(10000), bob); + // install the hook on alice + auto hsobj = hso(hook, overrideFlag); + hsobj[jss::HookOn] = + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFF" + "FE"; // payment high + env(ripple::test::jtx::hook(alice, {{hsobj}}, 0), + M("set etxn_fee_base"), + HSFEE); + env.close(); + + // invoke the hook + env(pay(bob, alice, XRP(1)), M("test etxn_fee_base"), fee(XRP(1))); + env.close(); + + BEAST_EXPECT(env.meta()); + auto const meta = env.meta(); + // sfHookExecution + BEAST_REQUIRE(meta->isFieldPresent(sfHookExecutions)); + auto const hookExecutions = meta->getFieldArray(sfHookExecutions); + BEAST_REQUIRE(hookExecutions.size() == 1); + auto const hookExecution = hookExecutions[0]; + BEAST_REQUIRE(hookExecution.isFieldPresent(sfHookReturnCode)); + auto const returnCode = hookExecution.getFieldU64(sfHookReturnCode); + if (hasFix) + BEAST_EXPECT(returnCode == 14); + else + BEAST_EXPECT(returnCode == 10); + } } void @@ -10119,15 +10163,16 @@ public: { testcase("Test sto_emplace"); using namespace jtx; - - Env env{*this, features}; - auto const bob = Account{"bob"}; auto const alice = Account{"alice"}; - env.fund(XRP(10000), alice); - env.fund(XRP(10000), bob); - TestHook hook = wasm[R"[test.hook]( + { + Env env{*this, features}; + + env.fund(XRP(10000), alice); + env.fund(XRP(10000), bob); + + TestHook hook = wasm[R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); #define GUARD(maxiter) _g((1ULL << 31U) + __LINE__, (maxiter)+1) @@ -10298,14 +10343,92 @@ public: } )[test.hook]"]; - // install the hook on alice - env(ripple::test::jtx::hook(alice, {{hso(hook, overrideFlag)}}, 0), - M("set sto_emplace"), - HSFEE); - env.close(); + // install the hook on alice + env(ripple::test::jtx::hook(alice, {{hso(hook, overrideFlag)}}, 0), + M("set sto_emplace"), + HSFEE); + env.close(); - // invoke the hook - env(pay(bob, alice, XRP(1)), M("test sto_emplace"), fee(XRP(1))); + // invoke the hook + env(pay(bob, alice, XRP(1)), M("test sto_emplace"), fee(XRP(1))); + } + + { + TestHook hook = wasm[R"[test.hook]( + #include + extern int32_t _g (uint32_t id, uint32_t maxiter); + #define GUARD(maxiter) _g((1ULL << 31U) + __LINE__, (maxiter)+1) + extern int64_t accept (uint32_t read_ptr, uint32_t read_len, int64_t error_code); + extern int64_t rollback (uint32_t read_ptr, uint32_t read_len, int64_t error_code); + extern int64_t sto_emplace ( + uint32_t write_ptr, uint32_t write_len, + uint32_t sread_ptr, uint32_t sread_len, + uint32_t fread_ptr, uint32_t fread_len, uint32_t field_id ); + #define PARSE_ERROR -18 + #define ASSERT(x)\ + if (!(x))\ + rollback((uint32_t)#x, sizeof(#x), __LINE__); + #define sfSequence ((2U << 16U) + 4U) + #define sfAmount ((6U << 16U) + 1U) + + // {"Account": } + uint8_t sto[] = {0x81U, 0x14U, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + // {"Sequence": 1} + uint8_t ins[] = {0x24U, 0x00U, 0x00U, 0x00U, 0x01U}; + + uint8_t buf[1024]; + + int64_t hook(uint32_t reserved ) + { + _g(1,1); + + // check inject field should be valid sto object and it's field id should + // match the field_id + ASSERT(sto_emplace(buf, sizeof(buf), sto, sizeof(sto), ins, sizeof(ins), sfSequence) > 0); + int64_t result = sto_emplace(buf, sizeof(buf), sto, sizeof(sto), ins, sizeof(ins), sfAmount); + + accept(0,0,result); + } + )[test.hook]"]; + + for (auto f : {features, features - fixStoEmplaceFieldIdCheck}) + { + Env env{*this, f}; + bool const hasFix = + env.current()->rules().enabled(fixStoEmplaceFieldIdCheck); + + env.fund(XRP(10000), alice); + env.fund(XRP(10000), bob); + + // install the hook on alice + env(ripple::test::jtx::hook( + alice, {{hso(hook, overrideFlag)}}, 0), + M("set sto_emplace"), + HSFEE); + env.close(); + + // invoke the hook + env(pay(bob, alice, XRP(1)), + M("test sto_emplace"), + fee(XRP(1))); + env.close(); + auto meta = env.meta(); + BEAST_REQUIRE(meta); + BEAST_REQUIRE(meta->isFieldPresent(sfHookExecutions)); + auto const hookExecutions = + meta->getFieldArray(sfHookExecutions); + BEAST_REQUIRE(hookExecutions.size() == 1); + + if (hasFix) + BEAST_EXPECT( + hookExecutions[0].getFieldU64(sfHookReturnCode) == + 0x8000000000000000ULL + 18); + else + BEAST_EXPECT( + hookExecutions[0].getFieldU64(sfHookReturnCode) > 0); + } + } } void diff --git a/src/test/app/SetHook_wasm.h b/src/test/app/SetHook_wasm.h index ee0e80dcb..c21f407fb 100644 --- a/src/test/app/SetHook_wasm.h +++ b/src/test/app/SetHook_wasm.h @@ -1280,6 +1280,23 @@ std::map> wasm = { #define ASSERT(x)\ if (!(x))\ rollback((uint32_t)#x, sizeof(#x), __LINE__); + + // { + // "TransactionType": "Invoke", + // "Account": "rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn", + // "Blob": "DEADBEEF", + // "Sequence": 0, + // "Fee": "0", + // "SigningPubKey": "" + // } + uint8_t tx[48] = { + 0x12U,0x00U,0x63U,0x24U,0x00U,0x00U,0x00U,0x00U,0x68U,0x40U, + 0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,0x73U,0x00U,0x70U, + 0x1AU,0x04U,0xDEU,0xADU,0xBEU,0xEFU,0x81U,0x14U,0xAEU,0x12U, + 0x3AU,0x85U,0x56U,0xF3U,0xCFU,0x91U,0x15U,0x47U,0x11U,0x37U, + 0x6AU,0xFBU,0x0FU,0x89U,0x4FU,0x83U,0x2BU,0x3DU + }; + int64_t hook(uint32_t reservmaed ) { _g(1,1); @@ -1294,7 +1311,8 @@ std::map> wasm = { etxn_reserve(1); ASSERT(etxn_fee_base((uint32_t)det, 116) == INVALID_TXN); - return accept(0,0,0); + int64_t fee = etxn_fee_base((uint32_t)tx, sizeof(tx)); + return accept(0,0,fee); } )[test.hook]", { @@ -1310,55 +1328,62 @@ std::map> wasm = { 0x6EU, 0x5FU, 0x72U, 0x65U, 0x73U, 0x65U, 0x72U, 0x76U, 0x65U, 0x00U, 0x03U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x06U, 0x61U, 0x63U, 0x63U, 0x65U, 0x70U, 0x74U, 0x00U, 0x02U, 0x03U, 0x02U, 0x01U, 0x03U, 0x05U, 0x03U, - 0x01U, 0x00U, 0x02U, 0x06U, 0x21U, 0x05U, 0x7FU, 0x01U, 0x41U, 0xD0U, - 0x89U, 0x04U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0xC3U, 0x09U, 0x0BU, 0x7FU, - 0x00U, 0x41U, 0x80U, 0x08U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0xD0U, 0x89U, - 0x04U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0x80U, 0x08U, 0x0BU, 0x07U, 0x08U, - 0x01U, 0x04U, 0x68U, 0x6FU, 0x6FU, 0x6BU, 0x00U, 0x05U, 0x0AU, 0xDFU, - 0x81U, 0x00U, 0x01U, 0xDBU, 0x81U, 0x00U, 0x02U, 0x01U, 0x7FU, 0x01U, - 0x7EU, 0x23U, 0x80U, 0x80U, 0x80U, 0x80U, 0x00U, 0x41U, 0x80U, 0x01U, - 0x6BU, 0x22U, 0x01U, 0x24U, 0x80U, 0x80U, 0x80U, 0x80U, 0x00U, 0x41U, - 0x01U, 0x41U, 0x01U, 0x10U, 0x80U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, - 0x02U, 0x40U, 0x41U, 0xC0U, 0x84U, 0x3DU, 0x41U, 0xF4U, 0x00U, 0x10U, - 0x81U, 0x80U, 0x80U, 0x80U, 0x00U, 0x42U, 0x7FU, 0x51U, 0x0DU, 0x00U, - 0x41U, 0x80U, 0x88U, 0x80U, 0x80U, 0x00U, 0x41U, 0x2DU, 0x42U, 0x16U, - 0x10U, 0x82U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, 0x02U, 0x40U, - 0x41U, 0x00U, 0x41U, 0xC0U, 0x84U, 0x3DU, 0x10U, 0x81U, 0x80U, 0x80U, - 0x80U, 0x00U, 0x42U, 0x7FU, 0x51U, 0x0DU, 0x00U, 0x41U, 0xADU, 0x88U, - 0x80U, 0x80U, 0x00U, 0x41U, 0x2BU, 0x42U, 0x17U, 0x10U, 0x82U, 0x80U, - 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, 0x02U, 0x40U, 0x20U, 0x01U, 0x41U, - 0xF4U, 0x00U, 0x10U, 0x81U, 0x80U, 0x80U, 0x80U, 0x00U, 0x42U, 0x77U, - 0x51U, 0x0DU, 0x00U, 0x41U, 0xD8U, 0x88U, 0x80U, 0x80U, 0x00U, 0x41U, - 0x3AU, 0x42U, 0x19U, 0x10U, 0x82U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, - 0x0BU, 0x41U, 0x01U, 0x10U, 0x83U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, - 0x02U, 0x40U, 0x20U, 0x01U, 0x41U, 0xF4U, 0x00U, 0x10U, 0x81U, 0x80U, - 0x80U, 0x80U, 0x00U, 0x42U, 0x5BU, 0x51U, 0x0DU, 0x00U, 0x41U, 0x92U, - 0x89U, 0x80U, 0x80U, 0x00U, 0x41U, 0x31U, 0x42U, 0x1CU, 0x10U, 0x82U, - 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, 0x41U, 0x00U, 0x41U, 0x00U, - 0x42U, 0x00U, 0x10U, 0x84U, 0x80U, 0x80U, 0x80U, 0x00U, 0x21U, 0x02U, - 0x20U, 0x01U, 0x41U, 0x80U, 0x01U, 0x6AU, 0x24U, 0x80U, 0x80U, 0x80U, - 0x80U, 0x00U, 0x20U, 0x02U, 0x0BU, 0x0BU, 0xCBU, 0x01U, 0x01U, 0x00U, - 0x41U, 0x80U, 0x08U, 0x0BU, 0xC3U, 0x01U, 0x65U, 0x74U, 0x78U, 0x6EU, + 0x01U, 0x00U, 0x02U, 0x06U, 0x27U, 0x06U, 0x7FU, 0x01U, 0x41U, 0x80U, + 0x8AU, 0x04U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0xF3U, 0x09U, 0x0BU, 0x7FU, + 0x00U, 0x41U, 0x80U, 0x08U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0x80U, 0x8AU, + 0x04U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0x80U, 0x08U, 0x0BU, 0x7FU, 0x00U, + 0x41U, 0x80U, 0x08U, 0x0BU, 0x07U, 0x08U, 0x01U, 0x04U, 0x68U, 0x6FU, + 0x6FU, 0x6BU, 0x00U, 0x05U, 0x0AU, 0xEBU, 0x81U, 0x00U, 0x01U, 0xE7U, + 0x81U, 0x00U, 0x02U, 0x01U, 0x7FU, 0x01U, 0x7EU, 0x23U, 0x80U, 0x80U, + 0x80U, 0x80U, 0x00U, 0x41U, 0x80U, 0x01U, 0x6BU, 0x22U, 0x01U, 0x24U, + 0x80U, 0x80U, 0x80U, 0x80U, 0x00U, 0x41U, 0x01U, 0x41U, 0x01U, 0x10U, + 0x80U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x02U, 0x40U, 0x41U, 0xC0U, + 0x84U, 0x3DU, 0x41U, 0xF4U, 0x00U, 0x10U, 0x81U, 0x80U, 0x80U, 0x80U, + 0x00U, 0x42U, 0x7FU, 0x51U, 0x0DU, 0x00U, 0x41U, 0xB0U, 0x88U, 0x80U, + 0x80U, 0x00U, 0x41U, 0x2DU, 0x42U, 0x27U, 0x10U, 0x82U, 0x80U, 0x80U, + 0x80U, 0x00U, 0x1AU, 0x0BU, 0x02U, 0x40U, 0x41U, 0x00U, 0x41U, 0xC0U, + 0x84U, 0x3DU, 0x10U, 0x81U, 0x80U, 0x80U, 0x80U, 0x00U, 0x42U, 0x7FU, + 0x51U, 0x0DU, 0x00U, 0x41U, 0xDDU, 0x88U, 0x80U, 0x80U, 0x00U, 0x41U, + 0x2BU, 0x42U, 0x28U, 0x10U, 0x82U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, + 0x0BU, 0x02U, 0x40U, 0x20U, 0x01U, 0x41U, 0xF4U, 0x00U, 0x10U, 0x81U, + 0x80U, 0x80U, 0x80U, 0x00U, 0x42U, 0x77U, 0x51U, 0x0DU, 0x00U, 0x41U, + 0x88U, 0x89U, 0x80U, 0x80U, 0x00U, 0x41U, 0x3AU, 0x42U, 0x2AU, 0x10U, + 0x82U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x0BU, 0x41U, 0x01U, 0x10U, + 0x83U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x02U, 0x40U, 0x20U, 0x01U, + 0x41U, 0xF4U, 0x00U, 0x10U, 0x81U, 0x80U, 0x80U, 0x80U, 0x00U, 0x42U, + 0x5BU, 0x51U, 0x0DU, 0x00U, 0x41U, 0xC2U, 0x89U, 0x80U, 0x80U, 0x00U, + 0x41U, 0x31U, 0x42U, 0x2DU, 0x10U, 0x82U, 0x80U, 0x80U, 0x80U, 0x00U, + 0x1AU, 0x0BU, 0x41U, 0x00U, 0x41U, 0x00U, 0x41U, 0x80U, 0x88U, 0x80U, + 0x80U, 0x00U, 0x41U, 0x30U, 0x10U, 0x81U, 0x80U, 0x80U, 0x80U, 0x00U, + 0x10U, 0x84U, 0x80U, 0x80U, 0x80U, 0x00U, 0x21U, 0x02U, 0x20U, 0x01U, + 0x41U, 0x80U, 0x01U, 0x6AU, 0x24U, 0x80U, 0x80U, 0x80U, 0x80U, 0x00U, + 0x20U, 0x02U, 0x0BU, 0x0BU, 0x81U, 0x02U, 0x02U, 0x00U, 0x41U, 0x80U, + 0x08U, 0x0BU, 0x30U, 0x12U, 0x00U, 0x63U, 0x24U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x68U, 0x40U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x73U, 0x00U, 0x70U, 0x1AU, 0x04U, 0xDEU, 0xADU, 0xBEU, 0xEFU, 0x81U, + 0x14U, 0xAEU, 0x12U, 0x3AU, 0x85U, 0x56U, 0xF3U, 0xCFU, 0x91U, 0x15U, + 0x47U, 0x11U, 0x37U, 0x6AU, 0xFBU, 0x0FU, 0x89U, 0x4FU, 0x83U, 0x2BU, + 0x3DU, 0x00U, 0x41U, 0xB0U, 0x08U, 0x0BU, 0xC3U, 0x01U, 0x65U, 0x74U, + 0x78U, 0x6EU, 0x5FU, 0x66U, 0x65U, 0x65U, 0x5FU, 0x62U, 0x61U, 0x73U, + 0x65U, 0x28U, 0x31U, 0x30U, 0x30U, 0x30U, 0x30U, 0x30U, 0x30U, 0x2CU, + 0x20U, 0x31U, 0x31U, 0x36U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x4FU, + 0x55U, 0x54U, 0x5FU, 0x4FU, 0x46U, 0x5FU, 0x42U, 0x4FU, 0x55U, 0x4EU, + 0x44U, 0x53U, 0x00U, 0x65U, 0x74U, 0x78U, 0x6EU, 0x5FU, 0x66U, 0x65U, + 0x65U, 0x5FU, 0x62U, 0x61U, 0x73U, 0x65U, 0x28U, 0x30U, 0x2CU, 0x20U, + 0x31U, 0x30U, 0x30U, 0x30U, 0x30U, 0x30U, 0x30U, 0x29U, 0x20U, 0x3DU, + 0x3DU, 0x20U, 0x4FU, 0x55U, 0x54U, 0x5FU, 0x4FU, 0x46U, 0x5FU, 0x42U, + 0x4FU, 0x55U, 0x4EU, 0x44U, 0x53U, 0x00U, 0x65U, 0x74U, 0x78U, 0x6EU, 0x5FU, 0x66U, 0x65U, 0x65U, 0x5FU, 0x62U, 0x61U, 0x73U, 0x65U, 0x28U, - 0x31U, 0x30U, 0x30U, 0x30U, 0x30U, 0x30U, 0x30U, 0x2CU, 0x20U, 0x31U, - 0x31U, 0x36U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x4FU, 0x55U, 0x54U, - 0x5FU, 0x4FU, 0x46U, 0x5FU, 0x42U, 0x4FU, 0x55U, 0x4EU, 0x44U, 0x53U, - 0x00U, 0x65U, 0x74U, 0x78U, 0x6EU, 0x5FU, 0x66U, 0x65U, 0x65U, 0x5FU, - 0x62U, 0x61U, 0x73U, 0x65U, 0x28U, 0x30U, 0x2CU, 0x20U, 0x31U, 0x30U, - 0x30U, 0x30U, 0x30U, 0x30U, 0x30U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, - 0x4FU, 0x55U, 0x54U, 0x5FU, 0x4FU, 0x46U, 0x5FU, 0x42U, 0x4FU, 0x55U, - 0x4EU, 0x44U, 0x53U, 0x00U, 0x65U, 0x74U, 0x78U, 0x6EU, 0x5FU, 0x66U, + 0x28U, 0x75U, 0x69U, 0x6EU, 0x74U, 0x33U, 0x32U, 0x5FU, 0x74U, 0x29U, + 0x64U, 0x65U, 0x74U, 0x2CU, 0x20U, 0x31U, 0x31U, 0x36U, 0x29U, 0x20U, + 0x3DU, 0x3DU, 0x20U, 0x50U, 0x52U, 0x45U, 0x52U, 0x45U, 0x51U, 0x55U, + 0x49U, 0x53U, 0x49U, 0x54U, 0x45U, 0x5FU, 0x4EU, 0x4FU, 0x54U, 0x5FU, + 0x4DU, 0x45U, 0x54U, 0x00U, 0x65U, 0x74U, 0x78U, 0x6EU, 0x5FU, 0x66U, 0x65U, 0x65U, 0x5FU, 0x62U, 0x61U, 0x73U, 0x65U, 0x28U, 0x28U, 0x75U, 0x69U, 0x6EU, 0x74U, 0x33U, 0x32U, 0x5FU, 0x74U, 0x29U, 0x64U, 0x65U, 0x74U, 0x2CU, 0x20U, 0x31U, 0x31U, 0x36U, 0x29U, 0x20U, 0x3DU, 0x3DU, - 0x20U, 0x50U, 0x52U, 0x45U, 0x52U, 0x45U, 0x51U, 0x55U, 0x49U, 0x53U, - 0x49U, 0x54U, 0x45U, 0x5FU, 0x4EU, 0x4FU, 0x54U, 0x5FU, 0x4DU, 0x45U, - 0x54U, 0x00U, 0x65U, 0x74U, 0x78U, 0x6EU, 0x5FU, 0x66U, 0x65U, 0x65U, - 0x5FU, 0x62U, 0x61U, 0x73U, 0x65U, 0x28U, 0x28U, 0x75U, 0x69U, 0x6EU, - 0x74U, 0x33U, 0x32U, 0x5FU, 0x74U, 0x29U, 0x64U, 0x65U, 0x74U, 0x2CU, - 0x20U, 0x31U, 0x31U, 0x36U, 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x49U, - 0x4EU, 0x56U, 0x41U, 0x4CU, 0x49U, 0x44U, 0x5FU, 0x54U, 0x58U, 0x4EU, - 0x00U, + 0x20U, 0x49U, 0x4EU, 0x56U, 0x41U, 0x4CU, 0x49U, 0x44U, 0x5FU, 0x54U, + 0x58U, 0x4EU, 0x00U, }}, /* ==== WASM: 9 ==== */ @@ -16049,6 +16074,193 @@ std::map> wasm = { }}, /* ==== WASM: 76 ==== */ + {R"[test.hook]( + #include + extern int32_t _g (uint32_t id, uint32_t maxiter); + #define GUARD(maxiter) _g((1ULL << 31U) + __LINE__, (maxiter)+1) + extern int64_t accept (uint32_t read_ptr, uint32_t read_len, int64_t error_code); + extern int64_t rollback (uint32_t read_ptr, uint32_t read_len, int64_t error_code); + extern int64_t sto_emplace ( + uint32_t write_ptr, uint32_t write_len, + uint32_t sread_ptr, uint32_t sread_len, + uint32_t fread_ptr, uint32_t fread_len, uint32_t field_id ); + #define PARSE_ERROR -18 + #define ASSERT(x)\ + if (!(x))\ + rollback((uint32_t)#x, sizeof(#x), __LINE__); + #define sfSequence ((2U << 16U) + 4U) + #define sfAmount ((6U << 16U) + 1U) + + // {"Account": } + uint8_t sto[] = {0x81U, 0x14U, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + // {"Sequence": 1} + uint8_t ins[] = {0x24U, 0x00U, 0x00U, 0x00U, 0x01U}; + + uint8_t buf[1024]; + + int64_t hook(uint32_t reserved ) + { + _g(1,1); + + // check inject field should be valid sto object and it's field id should + // match the field_id + ASSERT(sto_emplace(buf, sizeof(buf), sto, sizeof(sto), ins, sizeof(ins), sfSequence) > 0); + int64_t result = sto_emplace(buf, sizeof(buf), sto, sizeof(sto), ins, sizeof(ins), sfAmount); + + accept(0,0,result); + } + )[test.hook]", + { + 0x00U, 0x61U, 0x73U, 0x6DU, 0x01U, 0x00U, 0x00U, 0x00U, 0x01U, 0x1EU, + 0x04U, 0x60U, 0x02U, 0x7FU, 0x7FU, 0x01U, 0x7FU, 0x60U, 0x07U, 0x7FU, + 0x7FU, 0x7FU, 0x7FU, 0x7FU, 0x7FU, 0x7FU, 0x01U, 0x7EU, 0x60U, 0x03U, + 0x7FU, 0x7FU, 0x7EU, 0x01U, 0x7EU, 0x60U, 0x01U, 0x7FU, 0x01U, 0x7EU, + 0x02U, 0x38U, 0x04U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x02U, 0x5FU, 0x67U, + 0x00U, 0x00U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x0BU, 0x73U, 0x74U, 0x6FU, + 0x5FU, 0x65U, 0x6DU, 0x70U, 0x6CU, 0x61U, 0x63U, 0x65U, 0x00U, 0x01U, + 0x03U, 0x65U, 0x6EU, 0x76U, 0x08U, 0x72U, 0x6FU, 0x6CU, 0x6CU, 0x62U, + 0x61U, 0x63U, 0x6BU, 0x00U, 0x02U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x06U, + 0x61U, 0x63U, 0x63U, 0x65U, 0x70U, 0x74U, 0x00U, 0x02U, 0x03U, 0x02U, + 0x01U, 0x03U, 0x05U, 0x03U, 0x01U, 0x00U, 0x02U, 0x06U, 0x33U, 0x08U, + 0x7FU, 0x01U, 0x41U, 0x80U, 0x91U, 0x04U, 0x0BU, 0x7FU, 0x00U, 0x41U, + 0xF2U, 0x10U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0x80U, 0x08U, 0x0BU, 0x7FU, + 0x00U, 0x41U, 0x80U, 0x91U, 0x04U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0x80U, + 0x08U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0xA0U, 0x08U, 0x0BU, 0x7FU, 0x00U, + 0x41U, 0x80U, 0x08U, 0x0BU, 0x7FU, 0x00U, 0x41U, 0x96U, 0x08U, 0x0BU, + 0x07U, 0x08U, 0x01U, 0x04U, 0x68U, 0x6FU, 0x6FU, 0x6BU, 0x00U, 0x04U, + 0x0AU, 0x80U, 0x81U, 0x00U, 0x01U, 0xFCU, 0x80U, 0x00U, 0x01U, 0x01U, + 0x7EU, 0x41U, 0x01U, 0x41U, 0x01U, 0x10U, 0x80U, 0x80U, 0x80U, 0x80U, + 0x00U, 0x1AU, 0x02U, 0x40U, 0x41U, 0xA0U, 0x88U, 0x80U, 0x80U, 0x00U, + 0x41U, 0x80U, 0x08U, 0x41U, 0x80U, 0x88U, 0x80U, 0x80U, 0x00U, 0x41U, + 0x16U, 0x41U, 0x96U, 0x88U, 0x80U, 0x80U, 0x00U, 0x41U, 0x05U, 0x41U, + 0x84U, 0x80U, 0x08U, 0x10U, 0x81U, 0x80U, 0x80U, 0x80U, 0x00U, 0x42U, + 0x00U, 0x55U, 0x0DU, 0x00U, 0x41U, 0xA0U, 0x90U, 0x80U, 0x80U, 0x00U, + 0x41U, 0xD2U, 0x00U, 0x42U, 0x20U, 0x10U, 0x82U, 0x80U, 0x80U, 0x80U, + 0x00U, 0x1AU, 0x0BU, 0x41U, 0x00U, 0x41U, 0x00U, 0x41U, 0xA0U, 0x88U, + 0x80U, 0x80U, 0x00U, 0x41U, 0x80U, 0x08U, 0x41U, 0x80U, 0x88U, 0x80U, + 0x80U, 0x00U, 0x41U, 0x16U, 0x41U, 0x96U, 0x88U, 0x80U, 0x80U, 0x00U, + 0x41U, 0x05U, 0x41U, 0x81U, 0x80U, 0x18U, 0x10U, 0x81U, 0x80U, 0x80U, + 0x80U, 0x00U, 0x10U, 0x83U, 0x80U, 0x80U, 0x80U, 0x00U, 0x1AU, 0x20U, + 0x01U, 0x0BU, 0x0BU, 0x81U, 0x09U, 0x03U, 0x00U, 0x41U, 0x80U, 0x08U, + 0x0BU, 0x1BU, 0x81U, 0x14U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x24U, 0x00U, 0x00U, 0x00U, 0x01U, 0x00U, + 0x41U, 0xA0U, 0x08U, 0x0BU, 0x80U, 0x08U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x41U, 0xA0U, 0x10U, 0x0BU, 0x52U, 0x73U, 0x74U, 0x6FU, 0x5FU, + 0x65U, 0x6DU, 0x70U, 0x6CU, 0x61U, 0x63U, 0x65U, 0x28U, 0x62U, 0x75U, + 0x66U, 0x2CU, 0x20U, 0x73U, 0x69U, 0x7AU, 0x65U, 0x6FU, 0x66U, 0x28U, + 0x62U, 0x75U, 0x66U, 0x29U, 0x2CU, 0x20U, 0x73U, 0x74U, 0x6FU, 0x2CU, + 0x20U, 0x73U, 0x69U, 0x7AU, 0x65U, 0x6FU, 0x66U, 0x28U, 0x73U, 0x74U, + 0x6FU, 0x29U, 0x2CU, 0x20U, 0x69U, 0x6EU, 0x73U, 0x2CU, 0x20U, 0x73U, + 0x69U, 0x7AU, 0x65U, 0x6FU, 0x66U, 0x28U, 0x69U, 0x6EU, 0x73U, 0x29U, + 0x2CU, 0x20U, 0x73U, 0x66U, 0x53U, 0x65U, 0x71U, 0x75U, 0x65U, 0x6EU, + 0x63U, 0x65U, 0x29U, 0x20U, 0x3EU, 0x20U, 0x30U, 0x00U, + }}, + + /* ==== WASM: 77 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -16398,7 +16610,7 @@ std::map> wasm = { 0x20U, 0x30U, 0x00U, }}, - /* ==== WASM: 77 ==== */ + /* ==== WASM: 78 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -16534,7 +16746,7 @@ std::map> wasm = { 0x00U, }}, - /* ==== WASM: 78 ==== */ + /* ==== WASM: 79 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -16707,7 +16919,7 @@ std::map> wasm = { 0x54U, 0x5FU, 0x45U, 0x58U, 0x49U, 0x53U, 0x54U, 0x00U, }}, - /* ==== WASM: 79 ==== */ + /* ==== WASM: 80 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -16855,7 +17067,7 @@ std::map> wasm = { 0x30U, 0x00U, 0x22U, 0x00U, 0x00U, 0x00U, 0x00U, }}, - /* ==== WASM: 80 ==== */ + /* ==== WASM: 81 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -16952,7 +17164,7 @@ std::map> wasm = { 0x3DU, 0x20U, 0x30U, 0x00U, }}, - /* ==== WASM: 81 ==== */ + /* ==== WASM: 82 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -17011,7 +17223,7 @@ std::map> wasm = { 0x4FU, 0x46U, 0x5FU, 0x42U, 0x4FU, 0x55U, 0x4EU, 0x44U, 0x53U, 0x00U, }}, - /* ==== WASM: 82 ==== */ + /* ==== WASM: 83 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -17070,7 +17282,7 @@ std::map> wasm = { 0x4EU, 0x44U, 0x53U, 0x00U, }}, - /* ==== WASM: 83 ==== */ + /* ==== WASM: 84 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -18899,7 +19111,7 @@ std::map> wasm = { 0x53U, 0x4DU, 0x41U, 0x4CU, 0x4CU, 0x00U, }}, - /* ==== WASM: 84 ==== */ + /* ==== WASM: 85 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -20241,7 +20453,7 @@ std::map> wasm = { 0x20U, 0x30U, 0x2CU, 0x20U, 0x30U, 0x29U, 0x29U, 0x00U, }}, - /* ==== WASM: 85 ==== */ + /* ==== WASM: 86 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -23174,7 +23386,7 @@ std::map> wasm = { 0x4FU, 0x4FU, 0x5FU, 0x53U, 0x4DU, 0x41U, 0x4CU, 0x4CU, 0x00U, }}, - /* ==== WASM: 86 ==== */ + /* ==== WASM: 87 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -25139,7 +25351,7 @@ std::map> wasm = { 0x54U, 0x4FU, 0x4FU, 0x5FU, 0x53U, 0x4DU, 0x41U, 0x4CU, 0x4CU, 0x00U, }}, - /* ==== WASM: 87 ==== */ + /* ==== WASM: 88 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -25424,7 +25636,7 @@ std::map> wasm = { 0x29U, 0x20U, 0x3DU, 0x3DU, 0x20U, 0x30U, 0x00U, }}, - /* ==== WASM: 88 ==== */ + /* ==== WASM: 89 ==== */ {R"[test.hook]( #include extern int32_t _g(uint32_t, uint32_t); @@ -26011,7 +26223,7 @@ std::map> wasm = { 0x4EU, 0x5FU, 0x46U, 0x41U, 0x49U, 0x4CU, 0x55U, 0x52U, 0x45U, 0x00U, }}, - /* ==== WASM: 89 ==== */ + /* ==== WASM: 90 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -26040,7 +26252,7 @@ std::map> wasm = { 0x0BU, }}, - /* ==== WASM: 90 ==== */ + /* ==== WASM: 91 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -26072,7 +26284,7 @@ std::map> wasm = { 0x20U, 0x52U, 0x65U, 0x6AU, 0x65U, 0x63U, 0x74U, 0x65U, 0x64U, 0x00U, }}, - /* ==== WASM: 91 ==== */ + /* ==== WASM: 92 ==== */ {R"[test.hook]( (module (type (;0;) (func (param i32 i32 i64) (result i64))) @@ -26099,7 +26311,7 @@ std::map> wasm = { 0x41U, 0x00U, 0x41U, 0x00U, 0x42U, 0x00U, 0x10U, 0x00U, 0x0BU, }}, - /* ==== WASM: 92 ==== */ + /* ==== WASM: 93 ==== */ {R"[test.hook]( (module (type (;0;) (func (param i32 i32) (result i32))) @@ -26152,7 +26364,7 @@ std::map> wasm = { 0x00U, 0x1AU, 0x0BU, }}, - /* ==== WASM: 93 ==== */ + /* ==== WASM: 94 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -32795,7 +33007,7 @@ std::map> wasm = { 0x39U, 0x30U, 0x31U, 0x32U, 0x33U, 0x00U, }}, - /* ==== WASM: 94 ==== */ + /* ==== WASM: 95 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); @@ -32841,7 +33053,7 @@ std::map> wasm = { 0x0BU, 0x06U, 0x76U, 0x61U, 0x6CU, 0x75U, 0x65U, 0x00U, }}, - /* ==== WASM: 95 ==== */ + /* ==== WASM: 96 ==== */ {R"[test.hook]( #include extern int32_t _g (uint32_t id, uint32_t maxiter); diff --git a/src/test/app/Touch_test.cpp b/src/test/app/Touch_test.cpp index cbec4d458..ce5a5399b 100644 --- a/src/test/app/Touch_test.cpp +++ b/src/test/app/Touch_test.cpp @@ -1401,8 +1401,9 @@ public: { using namespace test::jtx; auto const sa = supported_amendments(); - testAllTxns(sa - featureTouch); testAllTxns(sa); + testAllTxns(sa - fixEtxnFeeBase); + testAllTxns(sa - featureTouch - fixEtxnFeeBase); } }; diff --git a/src/test/app/TxQ_test.cpp b/src/test/app/TxQ_test.cpp index 17c29ed52..765491004 100644 --- a/src/test/app/TxQ_test.cpp +++ b/src/test/app/TxQ_test.cpp @@ -5060,7 +5060,7 @@ public: testMultiTxnPerAccount(all); // fragile: hardcoded ordering by txID XOR parentHash // parentHash < txTree Hash < txMeta < PreviousTxnID - testTieBreaking(all - fixProvisionalDoubleThreading); + testTieBreaking(all - fixProvisionalDoubleThreading - fixEtxnFeeBase); testAcctTxnID(all); testMaximum(all); testUnexpectedBalanceChange(all); @@ -5080,7 +5080,8 @@ public: testExpirationReplacement(all); // fragile: hardcoded ordering by txID XOR parentHash // parentHash < txTree Hash < txMeta < PreviousTxnID - testFullQueueGapFill(all - fixProvisionalDoubleThreading); + testFullQueueGapFill( + all - fixProvisionalDoubleThreading - fixEtxnFeeBase); testSignAndSubmitSequence(all); testAccountInfo(all); testServerInfo(all); diff --git a/src/test/rpc/LedgerRPC_test.cpp b/src/test/rpc/LedgerRPC_test.cpp index cc66a0d4d..e294f0ff1 100644 --- a/src/test/rpc/LedgerRPC_test.cpp +++ b/src/test/rpc/LedgerRPC_test.cpp @@ -613,7 +613,9 @@ public: { testcase("ledger_entry Request AccountRoot"); using namespace test::jtx; - Env env{*this, supported_amendments() - featureXahauGenesis}; + Env env{ + *this, + supported_amendments() - featureXahauGenesis - fixEtxnFeeBase}; Account const alice{"alice"}; env.fund(XRP(10000), alice); env.close(); @@ -3389,7 +3391,7 @@ public: return cfg; }), supported_amendments() - featureXahauGenesis - - fixProvisionalDoubleThreading}; + fixProvisionalDoubleThreading - fixEtxnFeeBase}; Json::Value jv; jv[jss::ledger_index] = "current"; diff --git a/src/xrpld/app/hook/detail/applyHook.cpp b/src/xrpld/app/hook/detail/applyHook.cpp index 4104c87c9..9f7afd885 100644 --- a/src/xrpld/app/hook/detail/applyHook.cpp +++ b/src/xrpld/app/hook/detail/applyHook.cpp @@ -4547,6 +4547,30 @@ DEFINE_HOOK_FUNCTION( return MEM_OVERLAP; } + if (fread_len > 0 && view.rules().enabled(fixStoEmplaceFieldIdCheck)) + { + // inject field should be valid sto object and it's field id should + // match the field_id + unsigned char* inject_start = (unsigned char*)(memory + fread_ptr); + unsigned char* inject_end = + (unsigned char*)(memory + fread_ptr + fread_len); + int type = -1, field = -1, payload_start = -1, payload_length = -1; + int32_t length = get_stobject_length( + inject_start, + inject_end, + type, + field, + payload_start, + payload_length, + 0); + if (length < 0) + return PARSE_ERROR; + if ((type << 16) + field != field_id) + { + return PARSE_ERROR; + } + } + // we must inject the field at the canonical location.... // so find that location unsigned char* start = (unsigned char*)(memory + sread_ptr); @@ -4787,7 +4811,12 @@ DEFINE_HOOK_FUNCTION( std::unique_ptr stpTrans; stpTrans = std::make_unique(std::ref(sitTrans)); - return Transactor::calculateBaseFee( + if (!view.rules().enabled(fixEtxnFeeBase)) + return Transactor::calculateBaseFee( + *(applyCtx.app.openLedger().current()), *stpTrans) + .drops(); + + return invoke_calculateBaseFee( *(applyCtx.app.openLedger().current()), *stpTrans) .drops(); } diff --git a/src/xrpld/app/tx/detail/Transactor.cpp b/src/xrpld/app/tx/detail/Transactor.cpp index 630845bd6..6091b42f0 100644 --- a/src/xrpld/app/tx/detail/Transactor.cpp +++ b/src/xrpld/app/tx/detail/Transactor.cpp @@ -1617,9 +1617,27 @@ Transactor::doTSH( // add the extra TSH marked out by the specific transactor (if applicable) if (!strong) + { for (auto& weakTsh : additionalWeakTSH_) tsh.emplace_back(weakTsh, false); + if (view.rules().enabled(fixEtxnFeeBase)) + { + // if account_ is not included in tsh , add it only once + bool found = false; + for (auto& tshPair : tsh) + { + if (tshPair.first == account_) + { + found = true; + break; + } + } + if (!found) + tsh.emplace_back(account_, false); + } + } + // we use a vector above for order preservation // but we also don't want to execute any hooks // twice, so keep track as we go with a map @@ -1631,8 +1649,11 @@ Transactor::doTSH( // blindly nominate any TSHes they find but // obviously we will never execute OTXN account // as a TSH because they already had first execution - if (tshAccountID == account_) - continue; + if (!view.rules().enabled(fixEtxnFeeBase)) + { + if (tshAccountID == account_) + continue; + } if (alreadyProcessed.find(tshAccountID) != alreadyProcessed.end()) continue; @@ -1645,6 +1666,14 @@ Transactor::doTSH( touchAccount(view, tshAccountID); + if (view.rules().enabled(fixEtxnFeeBase)) + { + // After fixEtxnFeeBase, the otxn account is prosessed as touched + // account + if (tshAccountID == account_) + continue; + } + auto klTshHook = keylet::hook(tshAccountID); auto tshHook = view.read(klTshHook);