Compare commits

...

7 Commits

Author SHA1 Message Date
Ayaz Salikhov
7e4e12385f ci: Update docker images (#2745) 2025-10-30 17:08:11 +00:00
Ayaz Salikhov
c117f470f2 ci: Install pre-commit in the main CI image as well (#2744) 2025-10-30 14:32:23 +00:00
Ayaz Salikhov
30e88fe72c style: Fix pre-commit style issues (#2743) 2025-10-30 14:04:15 +00:00
Ayaz Salikhov
cecf082952 chore: Update tooling in Docker images (#2737) 2025-10-30 14:04:05 +00:00
Ayaz Salikhov
d5b95c2e61 chore: Use new prepare-runner (#2742) 2025-10-30 14:03:50 +00:00
github-actions[bot]
8375eb1766 style: clang-tidy auto fixes (#2741)
Co-authored-by: godexsoft <385326+godexsoft@users.noreply.github.com>
2025-10-30 11:20:32 +00:00
Ayaz Salikhov
be6aaffa7a ci: Fix nightly commits link (#2738) 2025-10-30 11:19:22 +00:00
24 changed files with 164 additions and 143 deletions

View File

@@ -4,7 +4,7 @@ import json
LINUX_OS = ["heavy", "heavy-arm64"] LINUX_OS = ["heavy", "heavy-arm64"]
LINUX_CONTAINERS = [ LINUX_CONTAINERS = [
'{ "image": "ghcr.io/xrplf/clio-ci:b2be4b51d1d81548ca48e2f2b8f67356b880c96d" }' '{ "image": "ghcr.io/xrplf/clio-ci:c117f470f2ef954520ab5d1c8a5ed2b9e68d6f8a" }'
] ]
LINUX_COMPILERS = ["gcc", "clang"] LINUX_COMPILERS = ["gcc", "clang"]

View File

@@ -45,7 +45,7 @@ jobs:
build_type: [Release, Debug] build_type: [Release, Debug]
container: container:
[ [
'{ "image": "ghcr.io/xrplf/clio-ci:b2be4b51d1d81548ca48e2f2b8f67356b880c96d" }', '{ "image": "ghcr.io/xrplf/clio-ci:c117f470f2ef954520ab5d1c8a5ed2b9e68d6f8a" }',
] ]
static: [true] static: [true]
@@ -75,7 +75,7 @@ jobs:
uses: ./.github/workflows/reusable-build.yml uses: ./.github/workflows/reusable-build.yml
with: with:
runs_on: heavy runs_on: heavy
container: '{ "image": "ghcr.io/xrplf/clio-ci:b2be4b51d1d81548ca48e2f2b8f67356b880c96d" }' container: '{ "image": "ghcr.io/xrplf/clio-ci:c117f470f2ef954520ab5d1c8a5ed2b9e68d6f8a" }'
conan_profile: gcc conan_profile: gcc
build_type: Debug build_type: Debug
download_ccache: true download_ccache: true
@@ -94,7 +94,7 @@ jobs:
uses: ./.github/workflows/reusable-build.yml uses: ./.github/workflows/reusable-build.yml
with: with:
runs_on: heavy runs_on: heavy
container: '{ "image": "ghcr.io/xrplf/clio-ci:b2be4b51d1d81548ca48e2f2b8f67356b880c96d" }' container: '{ "image": "ghcr.io/xrplf/clio-ci:c117f470f2ef954520ab5d1c8a5ed2b9e68d6f8a" }'
conan_profile: gcc conan_profile: gcc
build_type: Release build_type: Release
download_ccache: true download_ccache: true
@@ -111,7 +111,7 @@ jobs:
needs: build-and-test needs: build-and-test
runs-on: heavy runs-on: heavy
container: container:
image: ghcr.io/xrplf/clio-ci:b2be4b51d1d81548ca48e2f2b8f67356b880c96d image: ghcr.io/xrplf/clio-ci:c117f470f2ef954520ab5d1c8a5ed2b9e68d6f8a
steps: steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0

View File

@@ -17,7 +17,7 @@ jobs:
name: Build Clio / `libXRPL ${{ github.event.client_payload.version }}` name: Build Clio / `libXRPL ${{ github.event.client_payload.version }}`
runs-on: heavy runs-on: heavy
container: container:
image: ghcr.io/xrplf/clio-ci:b2be4b51d1d81548ca48e2f2b8f67356b880c96d image: ghcr.io/xrplf/clio-ci:c117f470f2ef954520ab5d1c8a5ed2b9e68d6f8a
steps: steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
@@ -25,7 +25,7 @@ jobs:
fetch-depth: 0 fetch-depth: 0
- name: Prepare runner - name: Prepare runner
uses: XRPLF/actions/.github/actions/prepare-runner@7951b682e5a2973b28b0719a72f01fc4b0d0c34f uses: XRPLF/actions/.github/actions/prepare-runner@99685816bb60a95a66852f212f382580e180df3a
with: with:
disable_ccache: true disable_ccache: true
@@ -67,7 +67,7 @@ jobs:
needs: build needs: build
runs-on: heavy runs-on: heavy
container: container:
image: ghcr.io/xrplf/clio-ci:b2be4b51d1d81548ca48e2f2b8f67356b880c96d image: ghcr.io/xrplf/clio-ci:c117f470f2ef954520ab5d1c8a5ed2b9e68d6f8a
steps: steps:
- uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0 - uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0

View File

@@ -27,7 +27,7 @@ jobs:
if: github.event_name != 'push' || contains(github.event.head_commit.message, 'clang-tidy auto fixes') if: github.event_name != 'push' || contains(github.event.head_commit.message, 'clang-tidy auto fixes')
runs-on: heavy runs-on: heavy
container: container:
image: ghcr.io/xrplf/clio-ci:b2be4b51d1d81548ca48e2f2b8f67356b880c96d image: ghcr.io/xrplf/clio-ci:c117f470f2ef954520ab5d1c8a5ed2b9e68d6f8a
permissions: permissions:
contents: write contents: write
@@ -40,7 +40,7 @@ jobs:
fetch-depth: 0 fetch-depth: 0
- name: Prepare runner - name: Prepare runner
uses: XRPLF/actions/.github/actions/prepare-runner@7951b682e5a2973b28b0719a72f01fc4b0d0c34f uses: XRPLF/actions/.github/actions/prepare-runner@99685816bb60a95a66852f212f382580e180df3a
with: with:
disable_ccache: true disable_ccache: true

View File

@@ -14,7 +14,7 @@ jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: container:
image: ghcr.io/xrplf/clio-ci:b2be4b51d1d81548ca48e2f2b8f67356b880c96d image: ghcr.io/xrplf/clio-ci:c117f470f2ef954520ab5d1c8a5ed2b9e68d6f8a
steps: steps:
- name: Checkout - name: Checkout
@@ -23,7 +23,7 @@ jobs:
lfs: true lfs: true
- name: Prepare runner - name: Prepare runner
uses: XRPLF/actions/.github/actions/prepare-runner@7951b682e5a2973b28b0719a72f01fc4b0d0c34f uses: XRPLF/actions/.github/actions/prepare-runner@99685816bb60a95a66852f212f382580e180df3a
with: with:
disable_ccache: true disable_ccache: true

View File

@@ -39,17 +39,17 @@ jobs:
conan_profile: gcc conan_profile: gcc
build_type: Release build_type: Release
static: true static: true
container: '{ "image": "ghcr.io/xrplf/clio-ci:b2be4b51d1d81548ca48e2f2b8f67356b880c96d" }' container: '{ "image": "ghcr.io/xrplf/clio-ci:c117f470f2ef954520ab5d1c8a5ed2b9e68d6f8a" }'
- os: heavy - os: heavy
conan_profile: gcc conan_profile: gcc
build_type: Debug build_type: Debug
static: true static: true
container: '{ "image": "ghcr.io/xrplf/clio-ci:b2be4b51d1d81548ca48e2f2b8f67356b880c96d" }' container: '{ "image": "ghcr.io/xrplf/clio-ci:c117f470f2ef954520ab5d1c8a5ed2b9e68d6f8a" }'
- os: heavy - os: heavy
conan_profile: gcc.ubsan conan_profile: gcc.ubsan
build_type: Release build_type: Release
static: false static: false
container: '{ "image": "ghcr.io/xrplf/clio-ci:b2be4b51d1d81548ca48e2f2b8f67356b880c96d" }' container: '{ "image": "ghcr.io/xrplf/clio-ci:c117f470f2ef954520ab5d1c8a5ed2b9e68d6f8a" }'
uses: ./.github/workflows/reusable-build-test.yml uses: ./.github/workflows/reusable-build-test.yml
with: with:
@@ -73,7 +73,7 @@ jobs:
include: include:
- os: heavy - os: heavy
conan_profile: clang conan_profile: clang
container: '{ "image": "ghcr.io/xrplf/clio-ci:b2be4b51d1d81548ca48e2f2b8f67356b880c96d" }' container: '{ "image": "ghcr.io/xrplf/clio-ci:c117f470f2ef954520ab5d1c8a5ed2b9e68d6f8a" }'
static: true static: true
- os: macos15 - os: macos15
conan_profile: apple-clang conan_profile: apple-clang
@@ -115,7 +115,7 @@ jobs:
header: > header: >
> **Note:** Please remember that this is a development release and it is not recommended for production use. > **Note:** Please remember that this is a development release and it is not recommended for production use.
Changelog (including previous releases): <https://github.com/XRPLF/clio/commits/nightly> Changelog (including previous releases): <https://github.com/XRPLF/clio/commits/nightly-${{ needs.get_date.outputs.date }}>
generate_changelog: false generate_changelog: false
draft: false draft: false

View File

@@ -11,4 +11,4 @@ jobs:
uses: XRPLF/actions/.github/workflows/pre-commit.yml@34790936fae4c6c751f62ec8c06696f9c1a5753a uses: XRPLF/actions/.github/workflows/pre-commit.yml@34790936fae4c6c751f62ec8c06696f9c1a5753a
with: with:
runs_on: heavy runs_on: heavy
container: '{ "image": "ghcr.io/xrplf/clio-pre-commit:b2be4b51d1d81548ca48e2f2b8f67356b880c96d" }' container: '{ "image": "ghcr.io/xrplf/clio-pre-commit:c117f470f2ef954520ab5d1c8a5ed2b9e68d6f8a" }'

View File

@@ -29,7 +29,7 @@ jobs:
conan_profile: gcc conan_profile: gcc
build_type: Release build_type: Release
static: true static: true
container: '{ "image": "ghcr.io/xrplf/clio-ci:b2be4b51d1d81548ca48e2f2b8f67356b880c96d" }' container: '{ "image": "ghcr.io/xrplf/clio-ci:c117f470f2ef954520ab5d1c8a5ed2b9e68d6f8a" }'
uses: ./.github/workflows/reusable-build-test.yml uses: ./.github/workflows/reusable-build-test.yml
with: with:

View File

@@ -95,7 +95,7 @@ jobs:
ref: ${{ github.ref }} ref: ${{ github.ref }}
- name: Prepare runner - name: Prepare runner
uses: XRPLF/actions/.github/actions/prepare-runner@7951b682e5a2973b28b0719a72f01fc4b0d0c34f uses: XRPLF/actions/.github/actions/prepare-runner@99685816bb60a95a66852f212f382580e180df3a
with: with:
disable_ccache: ${{ !inputs.download_ccache }} disable_ccache: ${{ !inputs.download_ccache }}

View File

@@ -42,7 +42,7 @@ jobs:
release: release:
runs-on: heavy runs-on: heavy
container: container:
image: ghcr.io/xrplf/clio-ci:b2be4b51d1d81548ca48e2f2b8f67356b880c96d image: ghcr.io/xrplf/clio-ci:c117f470f2ef954520ab5d1c8a5ed2b9e68d6f8a
env: env:
GH_REPO: ${{ github.repository }} GH_REPO: ${{ github.repository }}
GH_TOKEN: ${{ github.token }} GH_TOKEN: ${{ github.token }}
@@ -56,7 +56,7 @@ jobs:
fetch-depth: 0 fetch-depth: 0
- name: Prepare runner - name: Prepare runner
uses: XRPLF/actions/.github/actions/prepare-runner@7951b682e5a2973b28b0719a72f01fc4b0d0c34f uses: XRPLF/actions/.github/actions/prepare-runner@99685816bb60a95a66852f212f382580e180df3a
with: with:
disable_ccache: true disable_ccache: true

View File

@@ -44,7 +44,7 @@ jobs:
uses: ./.github/workflows/reusable-build-test.yml uses: ./.github/workflows/reusable-build-test.yml
with: with:
runs_on: heavy runs_on: heavy
container: '{ "image": "ghcr.io/xrplf/clio-ci:b2be4b51d1d81548ca48e2f2b8f67356b880c96d" }' container: '{ "image": "ghcr.io/xrplf/clio-ci:c117f470f2ef954520ab5d1c8a5ed2b9e68d6f8a" }'
download_ccache: false download_ccache: false
upload_ccache: false upload_ccache: false
conan_profile: ${{ matrix.compiler }}${{ matrix.sanitizer_ext }} conan_profile: ${{ matrix.compiler }}${{ matrix.sanitizer_ext }}

View File

@@ -72,7 +72,7 @@ jobs:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Prepare runner - name: Prepare runner
uses: XRPLF/actions/.github/actions/prepare-runner@7951b682e5a2973b28b0719a72f01fc4b0d0c34f uses: XRPLF/actions/.github/actions/prepare-runner@99685816bb60a95a66852f212f382580e180df3a
with: with:
disable_ccache: true disable_ccache: true

View File

@@ -11,7 +11,10 @@
# #
# See https://pre-commit.com for more information # See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks # See https://pre-commit.com/hooks.html for more hooks
exclude: ^(docs/doxygen-awesome-theme/|conan\.lock$) exclude: |
(?x)^(
docs/doxygen-awesome-theme/.*
)$
repos: repos:
# `pre-commit sample-config` default hooks # `pre-commit sample-config` default hooks

View File

@@ -55,4 +55,4 @@
] ]
}, },
"config_requires": [] "config_requires": []
} }

View File

@@ -55,8 +55,11 @@ RUN pip install -q --no-cache-dir \
# lxml 6.0.0 is not compatible with our image # lxml 6.0.0 is not compatible with our image
'lxml<6.0.0' \ 'lxml<6.0.0' \
cmake \ cmake \
conan==2.20.1 \ conan==2.22.1 \
gcovr gcovr \
# We're adding pre-commit to this image as well,
# because clang-tidy workflow requires it
pre-commit
# Install LLVM tools # Install LLVM tools
ARG LLVM_TOOLS_VERSION=20 ARG LLVM_TOOLS_VERSION=20

View File

@@ -5,17 +5,17 @@ It is used in [Clio Github Actions](https://github.com/XRPLF/clio/actions) but c
The image is based on Ubuntu 20.04 and contains: The image is based on Ubuntu 20.04 and contains:
- ccache 4.11.3 - ccache 4.12.1
- Clang 19 - Clang 19
- ClangBuildAnalyzer 1.6.0 - ClangBuildAnalyzer 1.6.0
- Conan 2.20.1 - Conan 2.22.1
- Doxygen 1.14 - Doxygen 1.15.0
- GCC 15.2.0 - GCC 15.2.0
- GDB 16.3 - GDB 16.3
- gh 2.74 - gh 2.82.1
- git-cliff 2.9.1 - git-cliff 2.10.1
- mold 2.40.1 - mold 2.40.4
- Python 3.13 - Python 3.8
- and some other useful tools - and some other useful tools
Conan is set up to build Clio without any additional steps. Conan is set up to build Clio without any additional steps.

View File

@@ -1,6 +1,6 @@
services: services:
clio_develop: clio_develop:
image: ghcr.io/xrplf/clio-ci:b2be4b51d1d81548ca48e2f2b8f67356b880c96d image: ghcr.io/xrplf/clio-ci:c117f470f2ef954520ab5d1c8a5ed2b9e68d6f8a
volumes: volumes:
- clio_develop_conan_data:/root/.conan2/p - clio_develop_conan_data:/root/.conan2/p
- clio_develop_ccache:/root/.ccache - clio_develop_ccache:/root/.ccache

View File

@@ -8,7 +8,7 @@ ARG TARGETARCH
SHELL ["/bin/bash", "-o", "pipefail", "-c"] SHELL ["/bin/bash", "-o", "pipefail", "-c"]
ARG BUILD_VERSION=2 ARG BUILD_VERSION=0
RUN apt-get update \ RUN apt-get update \
&& apt-get install -y --no-install-recommends --no-install-suggests \ && apt-get install -y --no-install-recommends --no-install-suggests \
@@ -24,7 +24,7 @@ RUN apt-get update \
WORKDIR /tmp WORKDIR /tmp
ARG MOLD_VERSION=2.40.1 ARG MOLD_VERSION=2.40.4
RUN wget --progress=dot:giga "https://github.com/rui314/mold/archive/refs/tags/v${MOLD_VERSION}.tar.gz" \ RUN wget --progress=dot:giga "https://github.com/rui314/mold/archive/refs/tags/v${MOLD_VERSION}.tar.gz" \
&& tar xf "v${MOLD_VERSION}.tar.gz" \ && tar xf "v${MOLD_VERSION}.tar.gz" \
&& cd "mold-${MOLD_VERSION}" \ && cd "mold-${MOLD_VERSION}" \
@@ -34,7 +34,7 @@ RUN wget --progress=dot:giga "https://github.com/rui314/mold/archive/refs/tags/v
&& ninja install \ && ninja install \
&& rm -rf /tmp/* /var/tmp/* && rm -rf /tmp/* /var/tmp/*
ARG CCACHE_VERSION=4.11.3 ARG CCACHE_VERSION=4.12.1
RUN wget --progress=dot:giga "https://github.com/ccache/ccache/releases/download/v${CCACHE_VERSION}/ccache-${CCACHE_VERSION}.tar.gz" \ RUN wget --progress=dot:giga "https://github.com/ccache/ccache/releases/download/v${CCACHE_VERSION}/ccache-${CCACHE_VERSION}.tar.gz" \
&& tar xf "ccache-${CCACHE_VERSION}.tar.gz" \ && tar xf "ccache-${CCACHE_VERSION}.tar.gz" \
&& cd "ccache-${CCACHE_VERSION}" \ && cd "ccache-${CCACHE_VERSION}" \
@@ -51,7 +51,7 @@ RUN apt-get update \
&& apt-get clean \ && apt-get clean \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
ARG DOXYGEN_VERSION=1.14.0 ARG DOXYGEN_VERSION=1.15.0
RUN wget --progress=dot:giga "https://github.com/doxygen/doxygen/releases/download/Release_${DOXYGEN_VERSION//./_}/doxygen-${DOXYGEN_VERSION}.src.tar.gz" \ RUN wget --progress=dot:giga "https://github.com/doxygen/doxygen/releases/download/Release_${DOXYGEN_VERSION//./_}/doxygen-${DOXYGEN_VERSION}.src.tar.gz" \
&& tar xf "doxygen-${DOXYGEN_VERSION}.src.tar.gz" \ && tar xf "doxygen-${DOXYGEN_VERSION}.src.tar.gz" \
&& cd "doxygen-${DOXYGEN_VERSION}" \ && cd "doxygen-${DOXYGEN_VERSION}" \
@@ -71,13 +71,13 @@ RUN wget --progress=dot:giga "https://github.com/aras-p/ClangBuildAnalyzer/archi
&& ninja install \ && ninja install \
&& rm -rf /tmp/* /var/tmp/* && rm -rf /tmp/* /var/tmp/*
ARG GIT_CLIFF_VERSION=2.9.1 ARG GIT_CLIFF_VERSION=2.10.1
RUN wget --progress=dot:giga "https://github.com/orhun/git-cliff/releases/download/v${GIT_CLIFF_VERSION}/git-cliff-${GIT_CLIFF_VERSION}-x86_64-unknown-linux-musl.tar.gz" \ RUN wget --progress=dot:giga "https://github.com/orhun/git-cliff/releases/download/v${GIT_CLIFF_VERSION}/git-cliff-${GIT_CLIFF_VERSION}-x86_64-unknown-linux-musl.tar.gz" \
&& tar xf git-cliff-${GIT_CLIFF_VERSION}-x86_64-unknown-linux-musl.tar.gz \ && tar xf git-cliff-${GIT_CLIFF_VERSION}-x86_64-unknown-linux-musl.tar.gz \
&& mv git-cliff-${GIT_CLIFF_VERSION}/git-cliff /usr/local/bin/git-cliff \ && mv git-cliff-${GIT_CLIFF_VERSION}/git-cliff /usr/local/bin/git-cliff \
&& rm -rf /tmp/* /var/tmp/* && rm -rf /tmp/* /var/tmp/*
ARG GH_VERSION=2.74.0 ARG GH_VERSION=2.82.1
RUN wget --progress=dot:giga "https://github.com/cli/cli/releases/download/v${GH_VERSION}/gh_${GH_VERSION}_linux_${TARGETARCH}.tar.gz" \ RUN wget --progress=dot:giga "https://github.com/cli/cli/releases/download/v${GH_VERSION}/gh_${GH_VERSION}_linux_${TARGETARCH}.tar.gz" \
&& tar xf gh_${GH_VERSION}_linux_${TARGETARCH}.tar.gz \ && tar xf gh_${GH_VERSION}_linux_${TARGETARCH}.tar.gz \
&& mv gh_${GH_VERSION}_linux_${TARGETARCH}/bin/gh /usr/local/bin/gh \ && mv gh_${GH_VERSION}_linux_${TARGETARCH}/bin/gh /usr/local/bin/gh \

View File

@@ -191,7 +191,7 @@ Open the `index.html` file in your browser to see the documentation pages.
It is also possible to build Clio using [Docker](https://www.docker.com/) if you don't want to install all the dependencies on your machine. It is also possible to build Clio using [Docker](https://www.docker.com/) if you don't want to install all the dependencies on your machine.
```sh ```sh
docker run -it ghcr.io/xrplf/clio-ci:b2be4b51d1d81548ca48e2f2b8f67356b880c96d docker run -it ghcr.io/xrplf/clio-ci:c117f470f2ef954520ab5d1c8a5ed2b9e68d6f8a
git clone https://github.com/XRPLF/clio git clone https://github.com/XRPLF/clio
cd clio cd clio
``` ```

View File

@@ -36,9 +36,7 @@
#include <xrpl/protocol/LedgerFormats.h> #include <xrpl/protocol/LedgerFormats.h>
#include <xrpl/protocol/LedgerHeader.h> #include <xrpl/protocol/LedgerHeader.h>
#include <xrpl/protocol/SField.h> #include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STAmount.h>
#include <xrpl/protocol/STLedgerEntry.h> #include <xrpl/protocol/STLedgerEntry.h>
#include <xrpl/protocol/UintTypes.h>
#include <xrpl/protocol/jss.h> #include <xrpl/protocol/jss.h>
#include <cstdint> #include <cstdint>

View File

@@ -64,8 +64,8 @@ public:
std::string issuer; std::string issuer;
uint32_t sequence{}; uint32_t sequence{};
std::optional<uint16_t> transferFee{}; std::optional<uint16_t> transferFee;
std::optional<uint8_t> assetScale{}; std::optional<uint8_t> assetScale;
std::optional<std::uint64_t> maximumAmount; std::optional<std::uint64_t> maximumAmount;
std::optional<std::uint64_t> outstandingAmount; std::optional<std::uint64_t> outstandingAmount;

View File

@@ -29,6 +29,7 @@
#include <boost/json/conversion.hpp> #include <boost/json/conversion.hpp>
#include <boost/json/object.hpp> #include <boost/json/object.hpp>
#include <boost/json/value.hpp> #include <boost/json/value.hpp>
#include <boost/json/value_from.hpp>
#include <boost/json/value_to.hpp> #include <boost/json/value_to.hpp>
#include <xrpl/basics/strHex.h> #include <xrpl/basics/strHex.h>
#include <xrpl/protocol/AccountID.h> #include <xrpl/protocol/AccountID.h>
@@ -36,9 +37,7 @@
#include <xrpl/protocol/LedgerFormats.h> #include <xrpl/protocol/LedgerFormats.h>
#include <xrpl/protocol/LedgerHeader.h> #include <xrpl/protocol/LedgerHeader.h>
#include <xrpl/protocol/SField.h> #include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STAmount.h>
#include <xrpl/protocol/STLedgerEntry.h> #include <xrpl/protocol/STLedgerEntry.h>
#include <xrpl/protocol/UintTypes.h>
#include <xrpl/protocol/jss.h> #include <xrpl/protocol/jss.h>
#include <cstdint> #include <cstdint>

View File

@@ -26,6 +26,7 @@
#include "util/NameGenerator.hpp" #include "util/NameGenerator.hpp"
#include "util/TestObject.hpp" #include "util/TestObject.hpp"
#include <boost/asio/spawn.hpp>
#include <boost/json/parse.hpp> #include <boost/json/parse.hpp>
#include <boost/json/value.hpp> #include <boost/json/value.hpp>
#include <boost/json/value_to.hpp> #include <boost/json/value_to.hpp>
@@ -40,6 +41,7 @@
#include <xrpl/protocol/STObject.h> #include <xrpl/protocol/STObject.h>
#include <cstdint> #include <cstdint>
#include <functional>
#include <optional> #include <optional>
#include <string> #include <string>
#include <vector> #include <vector>
@@ -136,48 +138,54 @@ static auto
generateTestValuesForInvalidParamsTest() generateTestValuesForInvalidParamsTest()
{ {
return std::vector<AccountMPTokenIssuancesParamTestCaseBundle>{ return std::vector<AccountMPTokenIssuancesParamTestCaseBundle>{
{"NonHexLedgerHash", {.testName = "NonHexLedgerHash",
fmt::format(R"JSON({{ "account": "{}", "ledger_hash": "xxx" }})JSON", kACCOUNT), .testJson = fmt::format(R"JSON({{ "account": "{}", "ledger_hash": "xxx" }})JSON", kACCOUNT),
"invalidParams", .expectedError = "invalidParams",
"ledger_hashMalformed"}, .expectedErrorMessage = "ledger_hashMalformed"},
{"NonStringLedgerHash", {.testName = "NonStringLedgerHash",
fmt::format(R"JSON({{ "account": "{}", "ledger_hash": 123 }})JSON", kACCOUNT), .testJson = fmt::format(R"JSON({{ "account": "{}", "ledger_hash": 123 }})JSON", kACCOUNT),
"invalidParams", .expectedError = "invalidParams",
"ledger_hashNotString"}, .expectedErrorMessage = "ledger_hashNotString"},
{"InvalidLedgerIndexString", {.testName = "InvalidLedgerIndexString",
fmt::format(R"JSON({{ "account": "{}", "ledger_index": "notvalidated" }})JSON", kACCOUNT), .testJson = fmt::format(R"JSON({{ "account": "{}", "ledger_index": "notvalidated" }})JSON", kACCOUNT),
"invalidParams", .expectedError = "invalidParams",
"ledgerIndexMalformed"}, .expectedErrorMessage = "ledgerIndexMalformed"},
{"MarkerNotString", {.testName = "MarkerNotString",
fmt::format(R"JSON({{ "account": "{}", "marker": 9 }})JSON", kACCOUNT), .testJson = fmt::format(R"JSON({{ "account": "{}", "marker": 9 }})JSON", kACCOUNT),
"invalidParams", .expectedError = "invalidParams",
"markerNotString"}, .expectedErrorMessage = "markerNotString"},
{"InvalidMarkerContent", {.testName = "InvalidMarkerContent",
fmt::format(R"JSON({{ "account": "{}", "marker": "123invalid" }})JSON", kACCOUNT), .testJson = fmt::format(R"JSON({{ "account": "{}", "marker": "123invalid" }})JSON", kACCOUNT),
"invalidParams", .expectedError = "invalidParams",
"Malformed cursor."}, .expectedErrorMessage = "Malformed cursor."},
{"AccountMissing", R"JSON({ "limit": 10 })JSON", "invalidParams", "Required field 'account' missing"}, {.testName = "AccountMissing",
{"AccountNotString", R"JSON({ "account": 123 })JSON", "actMalformed", "Account malformed."}, .testJson = R"JSON({ "limit": 10 })JSON",
{"AccountMalformed", .expectedError = "invalidParams",
R"JSON({ "account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jp" })JSON", .expectedErrorMessage = "Required field 'account' missing"},
"actMalformed", {.testName = "AccountNotString",
"Account malformed."}, .testJson = R"JSON({ "account": 123 })JSON",
{"LimitNotInteger", .expectedError = "actMalformed",
fmt::format(R"JSON({{ "account": "{}", "limit": "t" }})JSON", kACCOUNT), .expectedErrorMessage = "Account malformed."},
"invalidParams", {.testName = "AccountMalformed",
"Invalid parameters."}, .testJson = R"JSON({ "account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jp" })JSON",
{"LimitNegative", .expectedError = "actMalformed",
fmt::format(R"JSON({{ "account": "{}", "limit": -1 }})JSON", kACCOUNT), .expectedErrorMessage = "Account malformed."},
"invalidParams", {.testName = "LimitNotInteger",
"Invalid parameters."}, .testJson = fmt::format(R"JSON({{ "account": "{}", "limit": "t" }})JSON", kACCOUNT),
{"LimitZero", .expectedError = "invalidParams",
fmt::format(R"JSON({{ "account": "{}", "limit": 0 }})JSON", kACCOUNT), .expectedErrorMessage = "Invalid parameters."},
"invalidParams", {.testName = "LimitNegative",
"Invalid parameters."}, .testJson = fmt::format(R"JSON({{ "account": "{}", "limit": -1 }})JSON", kACCOUNT),
{"LimitTypeInvalid", .expectedError = "invalidParams",
fmt::format(R"JSON({{ "account": "{}", "limit": true }})JSON", kACCOUNT), .expectedErrorMessage = "Invalid parameters."},
"invalidParams", {.testName = "LimitZero",
"Invalid parameters."} .testJson = fmt::format(R"JSON({{ "account": "{}", "limit": 0 }})JSON", kACCOUNT),
.expectedError = "invalidParams",
.expectedErrorMessage = "Invalid parameters."},
{.testName = "LimitTypeInvalid",
.testJson = fmt::format(R"JSON({{ "account": "{}", "limit": true }})JSON", kACCOUNT),
.expectedError = "invalidParams",
.expectedErrorMessage = "Invalid parameters."}
}; };
} }
@@ -436,7 +444,7 @@ TEST_F(RPCAccountMPTokenIssuancesHandlerTest, DefaultParameters)
TEST_F(RPCAccountMPTokenIssuancesHandlerTest, UseLimit) TEST_F(RPCAccountMPTokenIssuancesHandlerTest, UseLimit)
{ {
constexpr int limit = 20; constexpr int kLIMIT = 20;
auto ledgerHeader = createLedgerHeader(kLEDGER_HASH, 30); auto ledgerHeader = createLedgerHeader(kLEDGER_HASH, 30);
ON_CALL(*backend_, fetchLedgerBySequence).WillByDefault(Return(ledgerHeader)); ON_CALL(*backend_, fetchLedgerBySequence).WillByDefault(Return(ledgerHeader));
@@ -449,7 +457,7 @@ TEST_F(RPCAccountMPTokenIssuancesHandlerTest, UseLimit)
std::vector<Blob> bbs; std::vector<Blob> bbs;
for (int i = 0; i < 50; ++i) { for (int i = 0; i < 50; ++i) {
indexes.emplace_back(ripple::uint256{kISSUANCE_INDEX1}); indexes.emplace_back(kISSUANCE_INDEX1);
auto const issuance = createMptIssuanceObject(kACCOUNT, i); auto const issuance = createMptIssuanceObject(kACCOUNT, i);
bbs.push_back(issuance.getSerializer().peekData()); bbs.push_back(issuance.getSerializer().peekData());
} }
@@ -462,7 +470,7 @@ TEST_F(RPCAccountMPTokenIssuancesHandlerTest, UseLimit)
ON_CALL(*backend_, doFetchLedgerObjects).WillByDefault(Return(bbs)); ON_CALL(*backend_, doFetchLedgerObjects).WillByDefault(Return(bbs));
EXPECT_CALL(*backend_, doFetchLedgerObjects).Times(3); EXPECT_CALL(*backend_, doFetchLedgerObjects).Times(3);
runSpawn([this, limit](auto yield) { runSpawn([this, kLIMIT](auto yield) {
auto const input = json::parse( auto const input = json::parse(
fmt::format( fmt::format(
R"JSON({{ R"JSON({{
@@ -470,7 +478,7 @@ TEST_F(RPCAccountMPTokenIssuancesHandlerTest, UseLimit)
"limit": {} "limit": {}
}})JSON", }})JSON",
kACCOUNT, kACCOUNT,
limit kLIMIT
) )
); );
@@ -479,7 +487,7 @@ TEST_F(RPCAccountMPTokenIssuancesHandlerTest, UseLimit)
ASSERT_TRUE(output); ASSERT_TRUE(output);
auto const resultJson = (*output.result).as_object(); auto const resultJson = (*output.result).as_object();
EXPECT_EQ(resultJson.at("mpt_issuances").as_array().size(), limit); EXPECT_EQ(resultJson.at("mpt_issuances").as_array().size(), kLIMIT);
ASSERT_TRUE(resultJson.contains("marker")); ASSERT_TRUE(resultJson.contains("marker"));
EXPECT_THAT(boost::json::value_to<std::string>(resultJson.at("marker")), EndsWith(",0")); EXPECT_THAT(boost::json::value_to<std::string>(resultJson.at("marker")), EndsWith(",0"));
}); });
@@ -534,11 +542,13 @@ TEST_F(RPCAccountMPTokenIssuancesHandlerTest, MarkerOutput)
EXPECT_CALL(*backend_, doFetchLedgerObject).Times(3); EXPECT_CALL(*backend_, doFetchLedgerObject).Times(3);
std::vector<ripple::uint256> indexes; std::vector<ripple::uint256> indexes;
indexes.reserve(10);
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
indexes.emplace_back(kISSUANCE_INDEX1); indexes.emplace_back(kISSUANCE_INDEX1);
} }
std::vector<Blob> bbs; std::vector<Blob> bbs;
bbs.reserve(kLIMIT);
for (int i = 0; i < kLIMIT; ++i) { for (int i = 0; i < kLIMIT; ++i) {
bbs.push_back(createMptIssuanceObject(kACCOUNT, i).getSerializer().peekData()); bbs.push_back(createMptIssuanceObject(kACCOUNT, i).getSerializer().peekData());
} }

View File

@@ -112,48 +112,54 @@ static auto
generateTestValuesForInvalidParamsTest() generateTestValuesForInvalidParamsTest()
{ {
return std::vector<AccountMPTokensParamTestCaseBundle>{ return std::vector<AccountMPTokensParamTestCaseBundle>{
{"NonHexLedgerHash", {.testName = "NonHexLedgerHash",
fmt::format(R"JSON({{ "account": "{}", "ledger_hash": "xxx" }})JSON", kACCOUNT), .testJson = fmt::format(R"JSON({{ "account": "{}", "ledger_hash": "xxx" }})JSON", kACCOUNT),
"invalidParams", .expectedError = "invalidParams",
"ledger_hashMalformed"}, .expectedErrorMessage = "ledger_hashMalformed"},
{"NonStringLedgerHash", {.testName = "NonStringLedgerHash",
fmt::format(R"JSON({{ "account": "{}", "ledger_hash": 123 }})JSON", kACCOUNT), .testJson = fmt::format(R"JSON({{ "account": "{}", "ledger_hash": 123 }})JSON", kACCOUNT),
"invalidParams", .expectedError = "invalidParams",
"ledger_hashNotString"}, .expectedErrorMessage = "ledger_hashNotString"},
{"InvalidLedgerIndexString", {.testName = "InvalidLedgerIndexString",
fmt::format(R"JSON({{ "account": "{}", "ledger_index": "notvalidated" }})JSON", kACCOUNT), .testJson = fmt::format(R"JSON({{ "account": "{}", "ledger_index": "notvalidated" }})JSON", kACCOUNT),
"invalidParams", .expectedError = "invalidParams",
"ledgerIndexMalformed"}, .expectedErrorMessage = "ledgerIndexMalformed"},
{"MarkerNotString", {.testName = "MarkerNotString",
fmt::format(R"JSON({{ "account": "{}", "marker": 9 }})JSON", kACCOUNT), .testJson = fmt::format(R"JSON({{ "account": "{}", "marker": 9 }})JSON", kACCOUNT),
"invalidParams", .expectedError = "invalidParams",
"markerNotString"}, .expectedErrorMessage = "markerNotString"},
{"InvalidMarkerContent", {.testName = "InvalidMarkerContent",
fmt::format(R"JSON({{ "account": "{}", "marker": "123invalid" }})JSON", kACCOUNT), .testJson = fmt::format(R"JSON({{ "account": "{}", "marker": "123invalid" }})JSON", kACCOUNT),
"invalidParams", .expectedError = "invalidParams",
"Malformed cursor."}, .expectedErrorMessage = "Malformed cursor."},
{"AccountMissing", R"JSON({ "limit": 10 })JSON", "invalidParams", "Required field 'account' missing"}, {.testName = "AccountMissing",
{"AccountNotString", R"JSON({ "account": 123 })JSON", "actMalformed", "Account malformed."}, .testJson = R"JSON({ "limit": 10 })JSON",
{"AccountMalformed", .expectedError = "invalidParams",
fmt::format(R"JSON({{ "account": "{}" }})JSON", "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jp"), .expectedErrorMessage = "Required field 'account' missing"},
"actMalformed", {.testName = "AccountNotString",
"Account malformed."}, .testJson = R"JSON({ "account": 123 })JSON",
{"LimitNotInteger", .expectedError = "actMalformed",
fmt::format(R"JSON({{ "account": "{}", "limit": "t" }})JSON", kACCOUNT), .expectedErrorMessage = "Account malformed."},
"invalidParams", {.testName = "AccountMalformed",
"Invalid parameters."}, .testJson = fmt::format(R"JSON({{ "account": "{}" }})JSON", "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jp"),
{"LimitNegative", .expectedError = "actMalformed",
fmt::format(R"JSON({{ "account": "{}", "limit": -1 }})JSON", kACCOUNT), .expectedErrorMessage = "Account malformed."},
"invalidParams", {.testName = "LimitNotInteger",
"Invalid parameters."}, .testJson = fmt::format(R"JSON({{ "account": "{}", "limit": "t" }})JSON", kACCOUNT),
{"LimitZero", .expectedError = "invalidParams",
fmt::format(R"JSON({{ "account": "{}", "limit": 0 }})JSON", kACCOUNT), .expectedErrorMessage = "Invalid parameters."},
"invalidParams", {.testName = "LimitNegative",
"Invalid parameters."}, .testJson = fmt::format(R"JSON({{ "account": "{}", "limit": -1 }})JSON", kACCOUNT),
{"LimitTypeInvalid", .expectedError = "invalidParams",
fmt::format(R"JSON({{ "account": "{}", "limit": true }})JSON", kACCOUNT), .expectedErrorMessage = "Invalid parameters."},
"invalidParams", {.testName = "LimitZero",
"Invalid parameters."} .testJson = fmt::format(R"JSON({{ "account": "{}", "limit": 0 }})JSON", kACCOUNT),
.expectedError = "invalidParams",
.expectedErrorMessage = "Invalid parameters."},
{.testName = "LimitTypeInvalid",
.testJson = fmt::format(R"JSON({{ "account": "{}", "limit": true }})JSON", kACCOUNT),
.expectedError = "invalidParams",
.expectedErrorMessage = "Invalid parameters."}
}; };
} }
@@ -388,7 +394,7 @@ TEST_F(RPCAccountMPTokensHandlerTest, DefaultParameters)
TEST_F(RPCAccountMPTokensHandlerTest, UseLimit) TEST_F(RPCAccountMPTokensHandlerTest, UseLimit)
{ {
constexpr int limit = 20; constexpr int kLIMIT = 20;
auto ledgerHeader = createLedgerHeader(kLEDGER_HASH, 30); auto ledgerHeader = createLedgerHeader(kLEDGER_HASH, 30);
ON_CALL(*backend_, fetchLedgerBySequence).WillByDefault(Return(ledgerHeader)); ON_CALL(*backend_, fetchLedgerBySequence).WillByDefault(Return(ledgerHeader));
@@ -401,7 +407,7 @@ TEST_F(RPCAccountMPTokensHandlerTest, UseLimit)
std::vector<Blob> bbs; std::vector<Blob> bbs;
for (int i = 0; i < 50; ++i) { for (int i = 0; i < 50; ++i) {
indexes.emplace_back(ripple::uint256{kTOKEN_INDEX1}); indexes.emplace_back(kTOKEN_INDEX1);
auto const token = createMpTokenObject(kACCOUNT, ripple::uint192(kISSUANCE_ID_HEX), i, 0, std::nullopt); auto const token = createMpTokenObject(kACCOUNT, ripple::uint192(kISSUANCE_ID_HEX), i, 0, std::nullopt);
bbs.push_back(token.getSerializer().peekData()); bbs.push_back(token.getSerializer().peekData());
} }
@@ -414,7 +420,7 @@ TEST_F(RPCAccountMPTokensHandlerTest, UseLimit)
ON_CALL(*backend_, doFetchLedgerObjects).WillByDefault(Return(bbs)); ON_CALL(*backend_, doFetchLedgerObjects).WillByDefault(Return(bbs));
EXPECT_CALL(*backend_, doFetchLedgerObjects).Times(3); EXPECT_CALL(*backend_, doFetchLedgerObjects).Times(3);
runSpawn([this, limit](auto yield) { runSpawn([this, kLIMIT](auto yield) {
auto const input = json::parse( auto const input = json::parse(
fmt::format( fmt::format(
R"JSON({{ R"JSON({{
@@ -422,7 +428,7 @@ TEST_F(RPCAccountMPTokensHandlerTest, UseLimit)
"limit": {} "limit": {}
}})JSON", }})JSON",
kACCOUNT, kACCOUNT,
limit kLIMIT
) )
); );
@@ -431,7 +437,7 @@ TEST_F(RPCAccountMPTokensHandlerTest, UseLimit)
ASSERT_TRUE(output); ASSERT_TRUE(output);
auto const resultJson = (*output.result).as_object(); auto const resultJson = (*output.result).as_object();
EXPECT_EQ(resultJson.at("mptokens").as_array().size(), limit); EXPECT_EQ(resultJson.at("mptokens").as_array().size(), kLIMIT);
ASSERT_TRUE(resultJson.contains("marker")); ASSERT_TRUE(resultJson.contains("marker"));
EXPECT_THAT(boost::json::value_to<std::string>(resultJson.at("marker")), EndsWith(",0")); EXPECT_THAT(boost::json::value_to<std::string>(resultJson.at("marker")), EndsWith(",0"));
}); });
@@ -487,6 +493,7 @@ TEST_F(RPCAccountMPTokensHandlerTest, MarkerOutput)
ON_CALL(*backend_, doFetchLedgerObject(accountKk, _, _)).WillByDefault(Return(Blob{'f', 'a', 'k', 'e'})); ON_CALL(*backend_, doFetchLedgerObject(accountKk, _, _)).WillByDefault(Return(Blob{'f', 'a', 'k', 'e'}));
std::vector<Blob> bbs; std::vector<Blob> bbs;
bbs.reserve(kLIMIT);
for (int i = 0; i < kLIMIT; ++i) { for (int i = 0; i < kLIMIT; ++i) {
bbs.push_back(createMpTokenObject(kACCOUNT, ripple::uint192(kISSUANCE_ID_HEX), i, 0, std::nullopt) bbs.push_back(createMpTokenObject(kACCOUNT, ripple::uint192(kISSUANCE_ID_HEX), i, 0, std::nullopt)
.getSerializer() .getSerializer()
@@ -495,6 +502,7 @@ TEST_F(RPCAccountMPTokensHandlerTest, MarkerOutput)
EXPECT_CALL(*backend_, doFetchLedgerObjects).WillOnce(Return(bbs)); EXPECT_CALL(*backend_, doFetchLedgerObjects).WillOnce(Return(bbs));
std::vector<ripple::uint256> indexes1; std::vector<ripple::uint256> indexes1;
indexes1.reserve(10);
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
indexes1.emplace_back(kTOKEN_INDEX1); indexes1.emplace_back(kTOKEN_INDEX1);
} }