mirror of
https://github.com/XRPLF/rippled.git
synced 2026-06-03 00:36:48 +00:00
Merge branch 'develop' into ximinez/number-fix-maxrepcusp
This commit is contained in:
64
.github/scripts/strategy-matrix/generate.py
vendored
64
.github/scripts/strategy-matrix/generate.py
vendored
@@ -32,7 +32,32 @@ We will further set additional CMake arguments as follows:
|
||||
"""
|
||||
|
||||
|
||||
def generate_strategy_matrix(all: bool, config: Config) -> list:
|
||||
def build_config_name(os_entry: dict[str, str], platform: str, build_type: str) -> str:
|
||||
parts = [os_entry["distro_name"]]
|
||||
for key in ("distro_version", "compiler_name", "compiler_version"):
|
||||
if value := os_entry[key]:
|
||||
parts.append(value)
|
||||
parts.append("arm64" if "arm64" in platform else "amd64")
|
||||
parts.append(build_type.lower())
|
||||
return "-".join(parts)
|
||||
|
||||
|
||||
def generate_packaging_matrix(config: Config) -> list[dict]:
|
||||
"""Emit one entry per os entry with `package: true`. Architecture is
|
||||
hardcoded to linux/amd64 here (and the runner is hardcoded at the
|
||||
workflow level) until arm64 packaging is ready.
|
||||
"""
|
||||
return [
|
||||
{
|
||||
"artifact_name": f"xrpld-{build_config_name(os, 'linux/amd64', 'Release')}",
|
||||
"os": os,
|
||||
}
|
||||
for os in config.os
|
||||
if os.get("package", False)
|
||||
]
|
||||
|
||||
|
||||
def generate_strategy_matrix(all: bool, config: Config) -> list[dict]:
|
||||
configurations = []
|
||||
for architecture, os, build_type, cmake_args in itertools.product(
|
||||
config.architecture, config.os, config.build_type, config.cmake_args
|
||||
@@ -101,14 +126,15 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
|
||||
continue
|
||||
|
||||
# RHEL:
|
||||
# - 9 using GCC 12: Debug on linux/amd64.
|
||||
# - 9 using GCC 12: Debug and Release on linux/amd64
|
||||
# (Release is required for RPM packaging).
|
||||
# - 10 using Clang: Release on linux/amd64.
|
||||
if os["distro_name"] == "rhel":
|
||||
skip = True
|
||||
if os["distro_version"] == "9":
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-12"
|
||||
and build_type == "Debug"
|
||||
and build_type in ["Debug", "Release"]
|
||||
and architecture["platform"] == "linux/amd64"
|
||||
):
|
||||
skip = False
|
||||
@@ -123,7 +149,8 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
|
||||
continue
|
||||
|
||||
# Ubuntu:
|
||||
# - Jammy using GCC 12: Debug on linux/arm64.
|
||||
# - Jammy using GCC 12: Debug on linux/arm64, Release on
|
||||
# linux/amd64 (Release is required for DEB packaging).
|
||||
# - Noble using GCC 14: Release on linux/amd64.
|
||||
# - Noble using Clang 18: Debug on linux/amd64.
|
||||
# - Noble using Clang 19: Release on linux/arm64.
|
||||
@@ -136,6 +163,12 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
|
||||
and architecture["platform"] == "linux/arm64"
|
||||
):
|
||||
skip = False
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-12"
|
||||
and build_type == "Release"
|
||||
and architecture["platform"] == "linux/amd64"
|
||||
):
|
||||
skip = False
|
||||
elif os["distro_version"] == "noble":
|
||||
if (
|
||||
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-14"
|
||||
@@ -218,17 +251,7 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
|
||||
|
||||
# Generate a unique name for the configuration, e.g. macos-arm64-debug
|
||||
# or debian-bookworm-gcc-12-amd64-release.
|
||||
config_name = os["distro_name"]
|
||||
if (n := os["distro_version"]) != "":
|
||||
config_name += f"-{n}"
|
||||
if (n := os["compiler_name"]) != "":
|
||||
config_name += f"-{n}"
|
||||
if (n := os["compiler_version"]) != "":
|
||||
config_name += f"-{n}"
|
||||
config_name += (
|
||||
f"-{architecture['platform'][architecture['platform'].find('/')+1:]}"
|
||||
)
|
||||
config_name += f"-{build_type.lower()}"
|
||||
config_name = build_config_name(os, architecture["platform"], build_type)
|
||||
if "-Dcoverage=ON" in cmake_args:
|
||||
config_name += "-coverage"
|
||||
if "-Dunity=ON" in cmake_args:
|
||||
@@ -332,10 +355,19 @@ if __name__ == "__main__":
|
||||
required=False,
|
||||
type=Path,
|
||||
)
|
||||
parser.add_argument(
|
||||
"-p",
|
||||
"--packaging",
|
||||
help="Emit the packaging matrix (derived from the 'package' field on os entries) instead of the build/test matrix.",
|
||||
action="store_true",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
matrix = []
|
||||
if args.config is None or args.config == "":
|
||||
if args.packaging:
|
||||
config_path = args.config if args.config else THIS_DIR / "linux.json"
|
||||
matrix += generate_packaging_matrix(read_config(config_path))
|
||||
elif args.config is None or args.config == "":
|
||||
matrix += generate_strategy_matrix(
|
||||
args.all, read_config(THIS_DIR / "linux.json")
|
||||
)
|
||||
|
||||
6
.github/scripts/strategy-matrix/linux.json
vendored
6
.github/scripts/strategy-matrix/linux.json
vendored
@@ -127,7 +127,8 @@
|
||||
"distro_version": "9",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "12",
|
||||
"image_sha": "4c086b9"
|
||||
"image_sha": "4c086b9",
|
||||
"package": true
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
@@ -169,7 +170,8 @@
|
||||
"distro_version": "jammy",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "12",
|
||||
"image_sha": "4c086b9"
|
||||
"image_sha": "4c086b9",
|
||||
"package": true
|
||||
},
|
||||
{
|
||||
"distro_name": "ubuntu",
|
||||
|
||||
12
.github/workflows/on-pr.yml
vendored
12
.github/workflows/on-pr.yml
vendored
@@ -64,11 +64,13 @@ jobs:
|
||||
.github/workflows/reusable-build-test-config.yml
|
||||
.github/workflows/reusable-build-test.yml
|
||||
.github/workflows/reusable-clang-tidy.yml
|
||||
.github/workflows/reusable-package.yml
|
||||
.github/workflows/reusable-strategy-matrix.yml
|
||||
.github/workflows/reusable-test.yml
|
||||
.github/workflows/reusable-upload-recipe.yml
|
||||
.clang-tidy
|
||||
.codecov.yml
|
||||
cfg/**
|
||||
cmake/**
|
||||
conan/**
|
||||
external/**
|
||||
@@ -78,6 +80,10 @@ jobs:
|
||||
CMakeLists.txt
|
||||
conanfile.py
|
||||
conan.lock
|
||||
LICENSE.md
|
||||
package/**
|
||||
README.md
|
||||
|
||||
- name: Check whether to run
|
||||
# This step determines whether the rest of the workflow should
|
||||
# run. The rest of the workflow will run if this job runs AND at
|
||||
@@ -134,6 +140,11 @@ jobs:
|
||||
secrets:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
package:
|
||||
needs: [should-run, build-test]
|
||||
if: ${{ needs.should-run.outputs.go == 'true' }}
|
||||
uses: ./.github/workflows/reusable-package.yml
|
||||
|
||||
upload-recipe:
|
||||
needs:
|
||||
- should-run
|
||||
@@ -168,6 +179,7 @@ jobs:
|
||||
- check-rename
|
||||
- clang-tidy
|
||||
- build-test
|
||||
- package
|
||||
- upload-recipe
|
||||
- notify-clio
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
23
.github/workflows/on-tag.yml
vendored
23
.github/workflows/on-tag.yml
vendored
@@ -1,5 +1,5 @@
|
||||
# This workflow uploads the libxrpl recipe to the Conan remote when a versioned
|
||||
# tag is pushed.
|
||||
# This workflow uploads the libxrpl recipe to the Conan remote and builds
|
||||
# release packages when a versioned tag is pushed.
|
||||
name: Tag
|
||||
|
||||
on:
|
||||
@@ -22,3 +22,22 @@ jobs:
|
||||
secrets:
|
||||
remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }}
|
||||
remote_password: ${{ secrets.CONAN_REMOTE_PASSWORD }}
|
||||
|
||||
build-test:
|
||||
if: ${{ github.repository == 'XRPLF/rippled' }}
|
||||
uses: ./.github/workflows/reusable-build-test.yml
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
os: [linux]
|
||||
with:
|
||||
ccache_enabled: false
|
||||
os: ${{ matrix.os }}
|
||||
strategy_matrix: minimal
|
||||
secrets:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
package:
|
||||
if: ${{ github.repository == 'XRPLF/rippled' }}
|
||||
needs: build-test
|
||||
uses: ./.github/workflows/reusable-package.yml
|
||||
|
||||
9
.github/workflows/on-trigger.yml
vendored
9
.github/workflows/on-trigger.yml
vendored
@@ -21,11 +21,13 @@ on:
|
||||
- ".github/workflows/reusable-build-test-config.yml"
|
||||
- ".github/workflows/reusable-build-test.yml"
|
||||
- ".github/workflows/reusable-clang-tidy.yml"
|
||||
- ".github/workflows/reusable-package.yml"
|
||||
- ".github/workflows/reusable-strategy-matrix.yml"
|
||||
- ".github/workflows/reusable-test.yml"
|
||||
- ".github/workflows/reusable-upload-recipe.yml"
|
||||
- ".clang-tidy"
|
||||
- ".codecov.yml"
|
||||
- "cfg/**"
|
||||
- "cmake/**"
|
||||
- "conan/**"
|
||||
- "external/**"
|
||||
@@ -35,6 +37,9 @@ on:
|
||||
- "CMakeLists.txt"
|
||||
- "conanfile.py"
|
||||
- "conan.lock"
|
||||
- "LICENSE.md"
|
||||
- "package/**"
|
||||
- "README.md"
|
||||
|
||||
# Run at 06:32 UTC on every day of the week from Monday through Friday. This
|
||||
# will force all dependencies to be rebuilt, which is useful to verify that
|
||||
@@ -95,3 +100,7 @@ jobs:
|
||||
secrets:
|
||||
remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }}
|
||||
remote_password: ${{ secrets.CONAN_REMOTE_PASSWORD }}
|
||||
|
||||
package:
|
||||
needs: build-test
|
||||
uses: ./.github/workflows/reusable-package.yml
|
||||
|
||||
99
.github/workflows/reusable-package.yml
vendored
Normal file
99
.github/workflows/reusable-package.yml
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
# Build Linux packages (DEB and RPM) from pre-built binary artifacts.
|
||||
# Discovers which configurations to package from linux.json (os entries
|
||||
# with "package": true) and fans out one job per entry. Today only
|
||||
# linux/amd64 is emitted; the architecture is hardcoded both here
|
||||
# (runner) and in generate.py.
|
||||
name: Package
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
pkg_release:
|
||||
description: "Package release number. Increment when repackaging the same executable."
|
||||
required: false
|
||||
type: string
|
||||
default: "1"
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
env:
|
||||
BUILD_DIR: build
|
||||
|
||||
jobs:
|
||||
generate-matrix:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
matrix: ${{ steps.generate.outputs.matrix }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
with:
|
||||
python-version: 3.13
|
||||
|
||||
- name: Generate packaging matrix
|
||||
id: generate
|
||||
working-directory: .github/scripts/strategy-matrix
|
||||
run: |
|
||||
./generate.py --packaging --config=linux.json >> "${GITHUB_OUTPUT}"
|
||||
|
||||
generate-version:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
version: ${{ steps.version.outputs.version }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
sparse-checkout: |
|
||||
.github/actions/generate-version
|
||||
src/libxrpl/protocol/BuildInfo.cpp
|
||||
- name: Generate version
|
||||
id: version
|
||||
uses: ./.github/actions/generate-version
|
||||
|
||||
package:
|
||||
needs: [generate-matrix, generate-version]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
|
||||
name: "${{ matrix.artifact_name }}"
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: ["self-hosted", "Linux", "X64", "heavy"]
|
||||
container: ${{ format('ghcr.io/xrplf/ci/{0}-{1}:{2}-{3}-sha-{4}', matrix.os.distro_name, matrix.os.distro_version, matrix.os.compiler_name, matrix.os.compiler_version, matrix.os.image_sha) }}
|
||||
timeout-minutes: 30
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Download pre-built binary
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
with:
|
||||
name: ${{ matrix.artifact_name }}
|
||||
path: ${{ env.BUILD_DIR }}
|
||||
|
||||
- name: Make binary executable
|
||||
run: chmod +x "${BUILD_DIR}/xrpld"
|
||||
|
||||
- name: Build package
|
||||
env:
|
||||
PKG_VERSION: ${{ needs.generate-version.outputs.version }}
|
||||
PKG_RELEASE: ${{ inputs.pkg_release }}
|
||||
run: ./package/build_pkg.sh
|
||||
|
||||
- name: Upload package artifact
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
if: ${{ github.event.repository.visibility == 'public' }}
|
||||
with:
|
||||
name: ${{ matrix.artifact_name }}-pkg-${{ needs.generate-version.outputs.version }}
|
||||
path: |
|
||||
${{ env.BUILD_DIR }}/debbuild/*.deb
|
||||
${{ env.BUILD_DIR }}/debbuild/*.ddeb
|
||||
${{ env.BUILD_DIR }}/rpmbuild/RPMS/**/*.rpm
|
||||
if-no-files-found: error
|
||||
@@ -134,6 +134,7 @@ endif()
|
||||
include(XrplCore)
|
||||
include(XrplProtocolAutogen)
|
||||
include(XrplInstall)
|
||||
include(XrplPackaging)
|
||||
include(XrplValidatorKeys)
|
||||
|
||||
if(tests)
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
# https://vl.ripple.com
|
||||
# https://unl.xrplf.org
|
||||
# http://127.0.0.1:8000
|
||||
# file:///etc/opt/xrpld/vl.txt
|
||||
# file:///etc/xrpld/vl.txt
|
||||
#
|
||||
# [validator_list_keys]
|
||||
#
|
||||
|
||||
@@ -1466,10 +1466,7 @@ admin = 127.0.0.1
|
||||
protocol = http
|
||||
|
||||
[port_peer]
|
||||
# Many servers still use the legacy port of 51235, so for backward-compatibility
|
||||
# we maintain that port number here. However, for new servers we recommend
|
||||
# changing this to the default port of 2459.
|
||||
port = 51235
|
||||
port = 2459
|
||||
ip = 0.0.0.0
|
||||
# alternatively, to accept connections on IPv4 + IPv6, use:
|
||||
#ip = ::
|
||||
|
||||
44
cmake/XrplPackaging.cmake
Normal file
44
cmake/XrplPackaging.cmake
Normal file
@@ -0,0 +1,44 @@
|
||||
#[===================================================================[
|
||||
Linux packaging support: 'package' target.
|
||||
|
||||
The packaging script (package/build_pkg.sh) installs to FHS-standard
|
||||
paths (/usr/bin, /etc/xrpld, etc.) regardless of CMAKE_INSTALL_PREFIX,
|
||||
so no prefix guard is needed here.
|
||||
#]===================================================================]
|
||||
if(NOT is_linux)
|
||||
message(STATUS "Packaging not supported on non-Linux hosts")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED pkg_release)
|
||||
set(pkg_release 1)
|
||||
endif()
|
||||
|
||||
find_program(RPMBUILD_EXECUTABLE rpmbuild)
|
||||
find_program(DPKG_BUILDPACKAGE_EXECUTABLE dpkg-buildpackage)
|
||||
|
||||
if(NOT (RPMBUILD_EXECUTABLE OR DPKG_BUILDPACKAGE_EXECUTABLE))
|
||||
message(
|
||||
STATUS
|
||||
"Neither rpmbuild nor dpkg-buildpackage found; 'package' target not available"
|
||||
)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(package_env
|
||||
SRC_DIR=${CMAKE_SOURCE_DIR}
|
||||
BUILD_DIR=${CMAKE_BINARY_DIR}
|
||||
PKG_VERSION=${xrpld_version}
|
||||
PKG_RELEASE=${pkg_release}
|
||||
)
|
||||
|
||||
add_custom_target(
|
||||
package
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E env ${package_env}
|
||||
${CMAKE_SOURCE_DIR}/package/build_pkg.sh
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
DEPENDS xrpld
|
||||
COMMENT "Building Linux package (deb/rpm inferred from host tooling)"
|
||||
VERBATIM
|
||||
)
|
||||
@@ -99,12 +99,15 @@ words:
|
||||
- desync
|
||||
- desynced
|
||||
- determ
|
||||
- disablerepo
|
||||
- distro
|
||||
- doxyfile
|
||||
- dxrpl
|
||||
- enabled
|
||||
- enablerepo
|
||||
- endmacro
|
||||
- exceptioned
|
||||
- EXPECT_STREQ
|
||||
- Falco
|
||||
- fcontext
|
||||
- finalizers
|
||||
@@ -162,6 +165,7 @@ words:
|
||||
- Merkle
|
||||
- Metafuncton
|
||||
- misprediction
|
||||
- missingok
|
||||
- mptbalance
|
||||
- MPTDEX
|
||||
- mptflags
|
||||
@@ -193,7 +197,9 @@ words:
|
||||
- NOLINT
|
||||
- NOLINTNEXTLINE
|
||||
- nonxrp
|
||||
- noreplace
|
||||
- noripple
|
||||
- notifempty
|
||||
- nudb
|
||||
- nullptr
|
||||
- nunl
|
||||
@@ -213,6 +219,7 @@ words:
|
||||
- preauthorize
|
||||
- preauthorizes
|
||||
- preclaim
|
||||
- preun
|
||||
- protobuf
|
||||
- protos
|
||||
- ptrs
|
||||
@@ -247,12 +254,14 @@ words:
|
||||
- sfields
|
||||
- shamap
|
||||
- shamapitem
|
||||
- shlibs
|
||||
- sidechain
|
||||
- SIGGOOD
|
||||
- sle
|
||||
- sles
|
||||
- soci
|
||||
- socidb
|
||||
- SRPMS
|
||||
- sslws
|
||||
- statsd
|
||||
- STATSDCOLLECTOR
|
||||
@@ -280,8 +289,8 @@ words:
|
||||
- txn
|
||||
- txns
|
||||
- txs
|
||||
- UBSAN
|
||||
- ubsan
|
||||
- UBSAN
|
||||
- umant
|
||||
- unacquired
|
||||
- unambiguity
|
||||
@@ -318,7 +327,6 @@ words:
|
||||
- xbridge
|
||||
- xchain
|
||||
- ximinez
|
||||
- EXPECT_STREQ
|
||||
- XMACRO
|
||||
- xrpkuwait
|
||||
- xrpl
|
||||
|
||||
@@ -115,7 +115,7 @@ protected:
|
||||
beast::WrappedSink sink_;
|
||||
beast::Journal const j_;
|
||||
|
||||
AccountID const account_;
|
||||
AccountID const accountID_;
|
||||
XRPAmount preFeeBalance_{}; // Balance before fees.
|
||||
|
||||
public:
|
||||
|
||||
@@ -21,7 +21,7 @@ class TOffer
|
||||
private:
|
||||
SLE::pointer entry_;
|
||||
Quality quality_{};
|
||||
AccountID account_;
|
||||
AccountID accountID_;
|
||||
Asset assetIn_;
|
||||
Asset assetOut_;
|
||||
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
[[nodiscard]] AccountID const&
|
||||
owner() const
|
||||
{
|
||||
return account_;
|
||||
return accountID_;
|
||||
}
|
||||
|
||||
/** Returns the in and out amounts.
|
||||
@@ -122,7 +122,7 @@ public:
|
||||
isFunded() const
|
||||
{
|
||||
// Offer owner is issuer; they have unlimited funds if IOU
|
||||
return account_ == assetOut_.getIssuer() && assetOut_.holds<Issue>();
|
||||
return accountID_ == assetOut_.getIssuer() && assetOut_.holds<Issue>();
|
||||
}
|
||||
|
||||
static std::pair<std::uint32_t, std::uint32_t>
|
||||
@@ -159,7 +159,7 @@ public:
|
||||
|
||||
template <StepAmount TIn, StepAmount TOut>
|
||||
TOffer<TIn, TOut>::TOffer(SLE::pointer entry, Quality quality)
|
||||
: entry_(std::move(entry)), quality_(quality), account_(entry_->getAccountID(sfAccount))
|
||||
: entry_(std::move(entry)), quality_(quality), accountID_(entry_->getAccountID(sfAccount))
|
||||
{
|
||||
auto const tp = entry_->getFieldAmount(sfTakerPays);
|
||||
auto const tg = entry_->getFieldAmount(sfTakerGets);
|
||||
|
||||
@@ -22,7 +22,7 @@ public:
|
||||
|
||||
private:
|
||||
// Tx account owner is required to get the AMM trading fee in BookStep
|
||||
AccountID account_;
|
||||
AccountID accountID_;
|
||||
// true if payment has multiple paths
|
||||
bool multiPath_{false};
|
||||
// Is true if AMM offer is consumed during a payment engine iteration.
|
||||
@@ -31,7 +31,8 @@ private:
|
||||
std::uint16_t ammIters_{0};
|
||||
|
||||
public:
|
||||
AMMContext(AccountID const& account, bool multiPath) : account_(account), multiPath_(multiPath)
|
||||
AMMContext(AccountID const& account, bool multiPath)
|
||||
: accountID_(account), multiPath_(multiPath)
|
||||
{
|
||||
}
|
||||
~AMMContext() = default;
|
||||
@@ -80,7 +81,7 @@ public:
|
||||
[[nodiscard]] AccountID
|
||||
account() const
|
||||
{
|
||||
return account_;
|
||||
return accountID_;
|
||||
}
|
||||
|
||||
/** Strand execution may fail. Reset the flag at the start
|
||||
|
||||
175
package/README.md
Normal file
175
package/README.md
Normal file
@@ -0,0 +1,175 @@
|
||||
# Linux Packaging
|
||||
|
||||
This directory contains all files needed to build RPM and Debian packages for `xrpld`.
|
||||
|
||||
## Directory layout
|
||||
|
||||
```
|
||||
package/
|
||||
build_pkg.sh Staging and build script (called by CMake targets and CI)
|
||||
rpm/
|
||||
xrpld.spec RPM spec (xrpld_version/pkg_release passed via rpmbuild --define)
|
||||
debian/ Debian control files (control, rules, install, links, conffiles, ...)
|
||||
shared/
|
||||
xrpld.service systemd unit file (used by both RPM and DEB)
|
||||
xrpld.sysusers sysusers.d config (used by both RPM and DEB)
|
||||
xrpld.tmpfiles tmpfiles.d config (used by both RPM and DEB)
|
||||
xrpld.logrotate logrotate config (installed to /etc/logrotate.d/xrpld)
|
||||
update-xrpld auto-update script (installed to /usr/libexec/xrpld/, run by update-xrpld.timer)
|
||||
```
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Packaging targets and their container images are declared in
|
||||
[`.github/scripts/strategy-matrix/linux.json`](../.github/scripts/strategy-matrix/linux.json)
|
||||
via a `"package": true` field on specific os entries. Today only
|
||||
`linux/amd64` is emitted; the architecture is hardcoded in `generate.py`
|
||||
and the workflow runner. The package format
|
||||
(deb or rpm) is inferred at build time from the container's package manager
|
||||
(`apt-get` -> deb, `dnf`/`yum` -> rpm). The image tag is composed as
|
||||
`ghcr.io/xrplf/ci/{distro}-{version}:{compiler}-{cver}-sha-{image_sha}` —
|
||||
the same scheme used by `reusable-build-test.yml`. Bump `image_sha` in
|
||||
`linux.json` and both CI and local builds pick up the new image with no
|
||||
workflow edits.
|
||||
|
||||
| Package type | Image (derived from `linux.json`) | Tool required |
|
||||
| ------------ | ---------------------------------------------------- | --------------------------------------------------------------- |
|
||||
| RPM | `ghcr.io/xrplf/ci/rhel-9:gcc-12-sha-<git_sha>` | `rpmbuild` |
|
||||
| DEB | `ghcr.io/xrplf/ci/ubuntu-jammy:gcc-12-sha-<git_sha>` | `dpkg-buildpackage`, `debhelper (>= 13)`, `dh-sequence-systemd` |
|
||||
|
||||
To print the exact image tags for the current `linux.json`:
|
||||
|
||||
```bash
|
||||
./.github/scripts/strategy-matrix/generate.py --packaging --config=.github/scripts/strategy-matrix/linux.json
|
||||
```
|
||||
|
||||
## Building packages
|
||||
|
||||
### Via CI
|
||||
|
||||
Caller workflows (`on-pr.yml`, `on-tag.yml`, `on-trigger.yml`) call
|
||||
`reusable-strategy-matrix.yml` with `mode: packaging` to generate the matrix of
|
||||
`{artifact_name, os}` entries, then fan out to
|
||||
`reusable-package.yml` per entry. That workflow downloads the pre-built `xrpld`
|
||||
binary artifact, detects the package format from the container, and calls
|
||||
`build_pkg.sh` directly — no CMake configure or build step is needed inside
|
||||
the packaging job.
|
||||
|
||||
### Locally (mirrors CI)
|
||||
|
||||
With an `xrpld` binary already built at `build/xrpld`, run the packaging step
|
||||
inside the same container CI uses. The image tag is derived from `linux.json`
|
||||
so you don't need to hardcode a SHA.
|
||||
|
||||
```bash
|
||||
# From the repo root. Pick any image flagged with `"package": true` in
|
||||
# linux.json; the package format is inferred from the container's package
|
||||
# manager. Example for the rpm-producing image:
|
||||
IMAGE=$(jq -r '
|
||||
.os | map(select(.package == true))[0] |
|
||||
"ghcr.io/xrplf/ci/\(.distro_name)-\(.distro_version):\(.compiler_name)-\(.compiler_version)-sha-\(.image_sha)"
|
||||
' .github/scripts/strategy-matrix/linux.json)
|
||||
|
||||
VERSION=2.4.0-local
|
||||
PKG_RELEASE=1
|
||||
|
||||
docker run --rm \
|
||||
-v "$(pwd):/src" \
|
||||
-w /src \
|
||||
"$IMAGE" \
|
||||
./package/build_pkg.sh --pkg-version "$VERSION" --pkg-release "$PKG_RELEASE"
|
||||
|
||||
# Output:
|
||||
# build/debbuild/*.deb (DEB + dbgsym .ddeb)
|
||||
# build/rpmbuild/RPMS/x86_64/*.rpm
|
||||
```
|
||||
|
||||
### Via CMake (host-side target)
|
||||
|
||||
If you run CMake configure on a host that has `rpmbuild` or `dpkg-buildpackage`
|
||||
installed natively, you can use the CMake target directly — no container
|
||||
needed, but the host toolchain replaces the pinned CI image:
|
||||
|
||||
```bash
|
||||
cmake \
|
||||
-Dxrpld=ON \
|
||||
-Dxrpld_version=2.4.0-local \
|
||||
-Dtests=OFF \
|
||||
..
|
||||
|
||||
cmake --build . --target package # deb on Debian/Ubuntu, rpm on RHEL
|
||||
```
|
||||
|
||||
The `cmake/XrplPackaging.cmake` module defines the target only if at least one
|
||||
of `rpmbuild` / `dpkg-buildpackage` is present; `build_pkg.sh` then infers the
|
||||
package format from the host's package manager. The packaging script installs
|
||||
to FHS-standard paths (`/usr/bin`, `/etc/xrpld`, etc.) regardless of
|
||||
`CMAKE_INSTALL_PREFIX`.
|
||||
|
||||
## How `build_pkg.sh` works
|
||||
|
||||
`build_pkg.sh` accepts long-form flags, each of which can also be set via an
|
||||
environment variable. Flags override env vars; env vars override the built-in
|
||||
defaults. Run `./package/build_pkg.sh --help` for the same table:
|
||||
|
||||
| Flag | Env var | Default | Purpose |
|
||||
| -------------------------- | ------------------- | ----------------------------- | ----------------------------------- |
|
||||
| `--src-dir DIR` | `SRC_DIR` | `$PWD` | repo root |
|
||||
| `--build-dir DIR` | `BUILD_DIR` | `$PWD/build` | directory holding pre-built `xrpld` |
|
||||
| `--pkg-version STR` | `PKG_VERSION` | parsed from `xrpld --version` | version string, e.g. `3.2.0-b1` |
|
||||
| `--pkg-release N` | `PKG_RELEASE` | `1` | package release number |
|
||||
| `--source-date-epoch SECS` | `SOURCE_DATE_EPOCH` | latest git commit ctime | reproducibility timestamp |
|
||||
|
||||
The package format (`deb` or `rpm`) is inferred from the host's package
|
||||
manager (`apt-get` -> deb, `dnf`/`yum` -> rpm). Hosts without one of those
|
||||
fail early.
|
||||
|
||||
Flags are for explicit invocation; environment variables are intended for
|
||||
CMake/systemd/CI integration. The CI workflow and the CMake `package` target
|
||||
both invoke `build_pkg.sh` with no flags, configuring it entirely via env
|
||||
(see `cmake/XrplPackaging.cmake`).
|
||||
|
||||
It resolves `SRC_DIR` and `BUILD_DIR` to absolute paths, then calls
|
||||
`stage_common()` to copy the binary, config files, and shared support files
|
||||
into the staging area, and invokes the platform build tool.
|
||||
|
||||
### RPM
|
||||
|
||||
1. Creates the standard `rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}` tree inside the build directory.
|
||||
2. Copies `xrpld.spec` and all source files (binary, configs, service files) into `SOURCES/`.
|
||||
3. Runs `rpmbuild -bb --define "xrpld_version ..." --define "pkg_release ..."`. The spec uses manual `install` commands to place files.
|
||||
4. Output: `rpmbuild/RPMS/x86_64/xrpld-*.rpm`
|
||||
|
||||
### DEB
|
||||
|
||||
1. Creates a staging source tree at `debbuild/source/` inside the build directory.
|
||||
2. Stages the binary, configs, `README.md`, and `LICENSE.md`.
|
||||
3. Copies `package/debian/` control files into `debbuild/source/debian/`.
|
||||
4. Copies shared service/sysusers/tmpfiles into `debian/` where `dh_installsystemd`, `dh_installsysusers`, and `dh_installtmpfiles` pick them up automatically.
|
||||
5. Generates a minimal `debian/changelog` (pre-release versions use `~` instead of `-`).
|
||||
6. Runs `dpkg-buildpackage -b --no-sign`. `debian/rules` uses manual `install` commands.
|
||||
7. Output: `debbuild/*.deb` and `debbuild/*.ddeb` (dbgsym package)
|
||||
|
||||
## Post-build verification
|
||||
|
||||
```bash
|
||||
# DEB
|
||||
dpkg-deb -c debbuild/*.deb | grep -E 'systemd|sysusers|tmpfiles'
|
||||
lintian -I debbuild/*.deb
|
||||
|
||||
# RPM
|
||||
rpm -qlp rpmbuild/RPMS/x86_64/*.rpm
|
||||
```
|
||||
|
||||
## Reproducibility
|
||||
|
||||
The following environment variables improve build reproducibility. They are not
|
||||
set automatically by `build_pkg.sh`; set them manually if needed:
|
||||
|
||||
```bash
|
||||
export SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)
|
||||
export TZ=UTC
|
||||
export LC_ALL=C.UTF-8
|
||||
export GZIP=-n
|
||||
export DEB_BUILD_OPTIONS="noautodbgsym reproducible=+fixfilepath"
|
||||
```
|
||||
192
package/build_pkg.sh
Executable file
192
package/build_pkg.sh
Executable file
@@ -0,0 +1,192 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Build an RPM or Debian package from a pre-built xrpld binary.
|
||||
#
|
||||
# Flags override env vars; env vars override defaults. Env vars are intended
|
||||
# for CMake/systemd/CI integration; flags are for explicit invocation.
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: build_pkg.sh [options]
|
||||
|
||||
Options (each can also be set via the env var shown):
|
||||
--src-dir DIR repo root [SRC_DIR; default: $PWD]
|
||||
--build-dir DIR directory holding xrpld [BUILD_DIR; default: $PWD/build]
|
||||
--pkg-version STR version, e.g. 3.2.0-b1 [PKG_VERSION; default: parsed from xrpld --version]
|
||||
--pkg-release N package release number [PKG_RELEASE; default: 1]
|
||||
--source-date-epoch SECS reproducibility timestamp [SOURCE_DATE_EPOCH; default: latest git commit ctime]
|
||||
-h, --help show this help and exit
|
||||
EOF
|
||||
}
|
||||
|
||||
need_arg() {
|
||||
if [[ $# -lt 2 || "$2" == --* ]]; then
|
||||
echo "Missing value for $1" >&2
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
# Seed from env. CLI parsing below overrides these directly.
|
||||
SRC_DIR="${SRC_DIR:-}"
|
||||
BUILD_DIR="${BUILD_DIR:-}"
|
||||
PKG_VERSION="${PKG_VERSION:-}"
|
||||
PKG_RELEASE="${PKG_RELEASE:-}"
|
||||
SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:-}"
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--src-dir) need_arg "$@"; SRC_DIR="$2"; shift 2 ;;
|
||||
--build-dir) need_arg "$@"; BUILD_DIR="$2"; shift 2 ;;
|
||||
--pkg-version) need_arg "$@"; PKG_VERSION="$2"; shift 2 ;;
|
||||
--pkg-release) need_arg "$@"; PKG_RELEASE="$2"; shift 2 ;;
|
||||
--source-date-epoch) need_arg "$@"; SOURCE_DATE_EPOCH="$2"; shift 2 ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
*)
|
||||
echo "Unknown argument: $1" >&2
|
||||
usage >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
SRC_DIR="$(cd "${SRC_DIR:-${PWD}}" && pwd)"
|
||||
BUILD_DIR="$(cd "${BUILD_DIR:-${PWD}/build}" && pwd)"
|
||||
PKG_RELEASE="${PKG_RELEASE:-1}"
|
||||
|
||||
if [[ -z "${PKG_VERSION}" ]]; then
|
||||
PKG_VERSION="$("${BUILD_DIR}/xrpld" --version | awk 'NR==1 {print $3; exit}')"
|
||||
fi
|
||||
|
||||
if [[ -z "${PKG_VERSION}" ]]; then
|
||||
echo "PKG_VERSION is empty (not provided and could not be derived)." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VERSION="${PKG_VERSION}"
|
||||
|
||||
if command -v apt-get >/dev/null 2>&1; then
|
||||
pkg_type=deb
|
||||
elif command -v dnf >/dev/null 2>&1 || command -v yum >/dev/null 2>&1; then
|
||||
pkg_type=rpm
|
||||
else
|
||||
echo "Cannot infer pkg_type: no apt-get, dnf, or yum on PATH." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z "${SOURCE_DATE_EPOCH}" ]]; then
|
||||
if git -C "$SRC_DIR" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
||||
SOURCE_DATE_EPOCH="$(git -C "$SRC_DIR" log -1 --format=%ct)"
|
||||
else
|
||||
SOURCE_DATE_EPOCH="$(date +%s)"
|
||||
fi
|
||||
fi
|
||||
|
||||
export SOURCE_DATE_EPOCH
|
||||
CHANGELOG_DATE="$(date -u -R -d "@$SOURCE_DATE_EPOCH")"
|
||||
|
||||
# Split VERSION at the first '-' into base and optional pre-release suffix.
|
||||
# Examples: "3.2.0" -> ("3.2.0", ""); "3.2.0-b1" -> ("3.2.0", "b1").
|
||||
VER_BASE="${VERSION%%-*}"
|
||||
VER_SUFFIX="${VERSION#*-}"
|
||||
[[ "${VER_SUFFIX}" == "${VERSION}" ]] && VER_SUFFIX=""
|
||||
|
||||
# Reject multi-segment suffixes (e.g. "beta-1", "rc1-15-gabc123"). The RPM
|
||||
# Release field forbids '-', and the convention here is single-token suffixes
|
||||
# like b1 or rc2. Fail early with a clear message rather than letting either
|
||||
# rpmbuild blow up or silently mangling dashes into dots.
|
||||
if [[ "${VER_SUFFIX}" == *-* ]]; then
|
||||
echo "build_pkg.sh: multi-segment pre-release in VERSION='${VERSION}' (suffix '${VER_SUFFIX}')." >&2
|
||||
echo "Use single-token suffixes like 3.2.0-b1 or 3.2.0-rc2." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SHARED="${SRC_DIR}/package/shared"
|
||||
DEBIAN_DIR="${SRC_DIR}/package/debian"
|
||||
|
||||
# Stage files that both packaging systems consume using the same filenames.
|
||||
stage_common() {
|
||||
local dest="$1"
|
||||
mkdir -p "${dest}"
|
||||
|
||||
cp "${BUILD_DIR}/xrpld" "${dest}/xrpld"
|
||||
cp "${SRC_DIR}/cfg/xrpld-example.cfg" "${dest}/xrpld.cfg"
|
||||
cp "${SRC_DIR}/cfg/validators-example.txt" "${dest}/validators.txt"
|
||||
cp "${SRC_DIR}/LICENSE.md" "${dest}/LICENSE.md"
|
||||
cp "${SRC_DIR}/README.md" "${dest}/README.md"
|
||||
|
||||
cp "${SHARED}/xrpld.service" "${dest}/xrpld.service"
|
||||
cp "${SHARED}/xrpld.sysusers" "${dest}/xrpld.sysusers"
|
||||
cp "${SHARED}/xrpld.tmpfiles" "${dest}/xrpld.tmpfiles"
|
||||
cp "${SHARED}/xrpld.logrotate" "${dest}/xrpld.logrotate"
|
||||
cp "${SHARED}/update-xrpld" "${dest}/update-xrpld"
|
||||
cp "${SHARED}/update-xrpld.service" "${dest}/update-xrpld.service"
|
||||
cp "${SHARED}/update-xrpld.timer" "${dest}/update-xrpld.timer"
|
||||
cp "${SHARED}/50-xrpld.preset" "${dest}/50-xrpld.preset"
|
||||
}
|
||||
|
||||
build_rpm() {
|
||||
local topdir="${BUILD_DIR}/rpmbuild"
|
||||
rm -rf "${topdir}"
|
||||
mkdir -p "${topdir}"/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}
|
||||
|
||||
cp "${SRC_DIR}/package/rpm/xrpld.spec" "${topdir}/SPECS/xrpld.spec"
|
||||
stage_common "${topdir}/SOURCES"
|
||||
|
||||
# RPM Version can't contain '-'. A pre-release goes in Release with a
|
||||
# leading "0." so 3.2.0-b1 sorts before the final 3.2.0-<pkg_release>.
|
||||
local rpm_release="${PKG_RELEASE}"
|
||||
[[ -n "${VER_SUFFIX}" ]] && rpm_release="0.${VER_SUFFIX}.${PKG_RELEASE}"
|
||||
|
||||
set -x
|
||||
rpmbuild -bb \
|
||||
--define "_topdir ${topdir}" \
|
||||
--define "xrpld_version ${VER_BASE}" \
|
||||
--define "xrpld_release ${rpm_release}" \
|
||||
"${topdir}/SPECS/xrpld.spec"
|
||||
}
|
||||
|
||||
build_deb() {
|
||||
local staging="${BUILD_DIR}/debbuild/source"
|
||||
rm -rf "${staging}"
|
||||
mkdir -p "${staging}"
|
||||
|
||||
stage_common "${staging}"
|
||||
cp -r "${DEBIAN_DIR}" "${staging}/debian"
|
||||
|
||||
# Debhelper auto-discovers these only from debian/.
|
||||
cp "${staging}/xrpld.service" "${staging}/debian/xrpld.service"
|
||||
cp "${staging}/xrpld.sysusers" "${staging}/debian/xrpld.sysusers"
|
||||
cp "${staging}/xrpld.tmpfiles" "${staging}/debian/xrpld.tmpfiles"
|
||||
cp "${staging}/xrpld.logrotate" "${staging}/debian/xrpld.logrotate"
|
||||
cp "${staging}/update-xrpld.service" "${staging}/debian/xrpld.update-xrpld.service"
|
||||
cp "${staging}/update-xrpld.timer" "${staging}/debian/xrpld.update-xrpld.timer"
|
||||
|
||||
# Debian '~' marks a pre-release; 3.2.0~b1 sorts before 3.2.0.
|
||||
local deb_full_version="${VER_BASE}${VER_SUFFIX:+~${VER_SUFFIX}}-${PKG_RELEASE}"
|
||||
|
||||
# Derive release channel from the version suffix:
|
||||
# (none) -> stable (tagged release)
|
||||
# b0 -> develop (develop-branch build)
|
||||
# b<N>, rc<N> -> unstable (pre-release)
|
||||
local deb_distribution
|
||||
case "${VER_SUFFIX}" in
|
||||
"") deb_distribution="stable" ;;
|
||||
b0) deb_distribution="develop" ;;
|
||||
*) deb_distribution="unstable" ;;
|
||||
esac
|
||||
|
||||
cat > "${staging}/debian/changelog" <<EOF
|
||||
xrpld (${deb_full_version}) ${deb_distribution}; urgency=medium
|
||||
* Release ${VERSION}.
|
||||
|
||||
-- XRPL Foundation <contact@xrplf.org> ${CHANGELOG_DATE}
|
||||
EOF
|
||||
|
||||
chmod +x "${staging}/debian/rules"
|
||||
|
||||
set -x
|
||||
( cd "${staging}" && dpkg-buildpackage -b --no-sign -d )
|
||||
}
|
||||
|
||||
"build_${pkg_type}"
|
||||
23
package/debian/control
Normal file
23
package/debian/control
Normal file
@@ -0,0 +1,23 @@
|
||||
Source: xrpld
|
||||
Section: net
|
||||
Priority: optional
|
||||
Maintainer: XRPL Foundation <contact@xrplf.org>
|
||||
Rules-Requires-Root: no
|
||||
Build-Depends:
|
||||
debhelper-compat (= 13)
|
||||
Standards-Version: 4.7.0
|
||||
Homepage: https://github.com/XRPLF/rippled
|
||||
Vcs-Git: https://github.com/XRPLF/rippled.git
|
||||
Vcs-Browser: https://github.com/XRPLF/rippled
|
||||
|
||||
Package: xrpld
|
||||
Section: net
|
||||
Priority: optional
|
||||
Architecture: any
|
||||
Depends:
|
||||
${shlibs:Depends},
|
||||
${misc:Depends}
|
||||
Description: XRP Ledger daemon
|
||||
Reference implementation of the XRP Ledger protocol.
|
||||
Participates in the peer-to-peer network, processes transactions,
|
||||
and maintains a local ledger copy.
|
||||
18
package/debian/copyright
Normal file
18
package/debian/copyright
Normal file
@@ -0,0 +1,18 @@
|
||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: rippled
|
||||
Source: https://github.com/XRPLF/rippled
|
||||
|
||||
Files: *
|
||||
Copyright: 2011-present, the XRP Ledger developers
|
||||
License: ISC
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
.
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
27
package/debian/rules
Normal file
27
package/debian/rules
Normal file
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/make -f
|
||||
|
||||
export DH_VERBOSE = 1
|
||||
|
||||
%:
|
||||
dh $@
|
||||
|
||||
override_dh_auto_configure override_dh_auto_build override_dh_auto_test:
|
||||
@:
|
||||
|
||||
override_dh_installsystemd:
|
||||
dh_installsystemd --no-start xrpld.service
|
||||
dh_installsystemd --name=update-xrpld --no-start update-xrpld.service update-xrpld.timer
|
||||
|
||||
execute_before_dh_installtmpfiles:
|
||||
dh_installsysusers
|
||||
|
||||
override_dh_installsysusers:
|
||||
|
||||
override_dh_install:
|
||||
install -D -m 0755 xrpld debian/xrpld/usr/bin/xrpld
|
||||
install -D -m 0644 xrpld.cfg debian/xrpld/etc/xrpld/xrpld.cfg
|
||||
install -D -m 0644 validators.txt debian/xrpld/etc/xrpld/validators.txt
|
||||
install -D -m 0755 update-xrpld debian/xrpld/usr/libexec/xrpld/update-xrpld
|
||||
|
||||
override_dh_dwz:
|
||||
@:
|
||||
1
package/debian/source/format
Normal file
1
package/debian/source/format
Normal file
@@ -0,0 +1 @@
|
||||
3.0 (quilt)
|
||||
2
package/debian/xrpld.docs
Normal file
2
package/debian/xrpld.docs
Normal file
@@ -0,0 +1,2 @@
|
||||
README.md
|
||||
LICENSE.md
|
||||
2
package/debian/xrpld.links
Normal file
2
package/debian/xrpld.links
Normal file
@@ -0,0 +1,2 @@
|
||||
# Legacy compat symlinks (remove next major release)
|
||||
usr/bin/xrpld usr/local/bin/rippled
|
||||
100
package/rpm/xrpld.spec
Normal file
100
package/rpm/xrpld.spec
Normal file
@@ -0,0 +1,100 @@
|
||||
Name: xrpld
|
||||
Version: %{xrpld_version}
|
||||
Release: %{xrpld_release}%{?dist}
|
||||
Summary: XRP Ledger daemon
|
||||
|
||||
License: ISC
|
||||
URL: https://github.com/XRPLF/rippled
|
||||
|
||||
ExclusiveArch: x86_64 aarch64
|
||||
BuildRequires: systemd-rpm-macros
|
||||
|
||||
%undefine _debugsource_packages
|
||||
%debug_package
|
||||
|
||||
%build_mtime_policy clamp_to_source_date_epoch
|
||||
|
||||
%{?systemd_requires}
|
||||
%{?sysusers_requires_compat}
|
||||
|
||||
%description
|
||||
xrpld is the reference implementation of the XRP Ledger protocol. It
|
||||
participates in the peer-to-peer XRP Ledger network, processes
|
||||
transactions, and maintains the ledger database.
|
||||
|
||||
%prep
|
||||
:
|
||||
|
||||
%build
|
||||
:
|
||||
|
||||
%install
|
||||
install -Dm0755 %{_sourcedir}/xrpld %{buildroot}%{_bindir}/%{name}
|
||||
install -Dm0644 %{_sourcedir}/xrpld.cfg %{buildroot}%{_sysconfdir}/%{name}/xrpld.cfg
|
||||
install -Dm0644 %{_sourcedir}/validators.txt %{buildroot}%{_sysconfdir}/%{name}/validators.txt
|
||||
|
||||
# systemd units, sysusers, tmpfiles, preset
|
||||
install -Dm0644 %{_sourcedir}/xrpld.service %{buildroot}%{_unitdir}/xrpld.service
|
||||
install -Dm0644 %{_sourcedir}/update-xrpld.service %{buildroot}%{_unitdir}/update-xrpld.service
|
||||
install -Dm0644 %{_sourcedir}/update-xrpld.timer %{buildroot}%{_unitdir}/update-xrpld.timer
|
||||
install -Dm0644 %{_sourcedir}/xrpld.sysusers %{buildroot}%{_sysusersdir}/xrpld.conf
|
||||
install -Dm0644 %{_sourcedir}/xrpld.tmpfiles %{buildroot}%{_tmpfilesdir}/xrpld.conf
|
||||
install -Dm0644 %{_sourcedir}/50-xrpld.preset %{buildroot}%{_presetdir}/50-xrpld.preset
|
||||
|
||||
# Logrotate config
|
||||
install -Dm0644 %{_sourcedir}/xrpld.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/%{name}
|
||||
|
||||
# Update helper
|
||||
install -Dm0755 %{_sourcedir}/update-xrpld %{buildroot}%{_libexecdir}/%{name}/update-xrpld
|
||||
|
||||
# Docs
|
||||
install -Dm0644 %{_sourcedir}/LICENSE.md %{buildroot}%{_docdir}/%{name}/LICENSE.md
|
||||
install -Dm0644 %{_sourcedir}/README.md %{buildroot}%{_docdir}/%{name}/README.md
|
||||
|
||||
# Legacy compatibility for pre-FHS package layouts.
|
||||
# TODO: remove after rippled fully deprecated.
|
||||
install -d %{buildroot}/usr/local/bin
|
||||
ln -s %{_bindir}/%{name} %{buildroot}/usr/local/bin/rippled
|
||||
|
||||
%pre
|
||||
%sysusers_create_package %{name} %{_sourcedir}/xrpld.sysusers
|
||||
|
||||
%post
|
||||
systemd-tmpfiles --create %{_tmpfilesdir}/xrpld.conf || :
|
||||
%systemd_post xrpld.service update-xrpld.timer
|
||||
|
||||
%preun
|
||||
%systemd_preun xrpld.service update-xrpld.timer
|
||||
|
||||
%postun
|
||||
%systemd_postun_with_restart xrpld.service
|
||||
|
||||
%files
|
||||
%license %{_docdir}/%{name}/LICENSE.md
|
||||
%doc %{_docdir}/%{name}/README.md
|
||||
|
||||
%dir %{_sysconfdir}/%{name}
|
||||
%dir %{_libexecdir}/%{name}
|
||||
|
||||
%{_bindir}/%{name}
|
||||
|
||||
%config(noreplace) %{_sysconfdir}/%{name}/xrpld.cfg
|
||||
%config(noreplace) %{_sysconfdir}/%{name}/validators.txt
|
||||
%config(noreplace) %{_sysconfdir}/logrotate.d/%{name}
|
||||
|
||||
%{_libexecdir}/%{name}/update-xrpld
|
||||
|
||||
%{_unitdir}/xrpld.service
|
||||
%{_unitdir}/update-xrpld.service
|
||||
%{_unitdir}/update-xrpld.timer
|
||||
%{_presetdir}/50-xrpld.preset
|
||||
%{_sysusersdir}/xrpld.conf
|
||||
%{_tmpfilesdir}/xrpld.conf
|
||||
|
||||
%ghost %dir /var/lib/%{name}
|
||||
%ghost %dir /var/log/%{name}
|
||||
|
||||
|
||||
# Legacy compatibility for pre-FHS package layouts.
|
||||
# TODO: remove after rippled fully deprecated.
|
||||
/usr/local/bin/rippled
|
||||
4
package/shared/50-xrpld.preset
Normal file
4
package/shared/50-xrpld.preset
Normal file
@@ -0,0 +1,4 @@
|
||||
# /usr/lib/systemd/system-preset/50-xrpld.preset
|
||||
enable xrpld.service
|
||||
# Don't enable automatic updates
|
||||
disable update-xrpld.timer
|
||||
152
package/shared/update-xrpld
Executable file
152
package/shared/update-xrpld
Executable file
@@ -0,0 +1,152 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Optional: also write logs to a legacy file in addition to journald.
|
||||
# By default, this script logs to systemd/journald, viewable via:
|
||||
# journalctl -t update-xrpld
|
||||
#
|
||||
# Uncomment the line below if you need a flat file for compatibility with
|
||||
# external tooling, manual inspection, or environments where journald logs
|
||||
# are not persisted or easily accessible.
|
||||
#
|
||||
# Note: This duplicates all output (stdout/stderr) to both journald and the file.
|
||||
# It is generally not needed on modern systems and may cause log file growth
|
||||
# if left enabled long-term.
|
||||
#
|
||||
# Requires /var/log/xrpld/ to exist and be writable by the service (root).
|
||||
#
|
||||
# exec > >(tee -a /var/log/xrpld/update.log) 2>&1
|
||||
|
||||
PATH=/usr/sbin:/usr/bin:/sbin:/bin
|
||||
|
||||
PKG_NAME=${PKG_NAME:-xrpld}
|
||||
|
||||
log() {
|
||||
# If running under systemd/journald, let it handle timestamps.
|
||||
if [[ -n "${JOURNAL_STREAM:-}" ]]; then
|
||||
printf '%s\n' "$*"
|
||||
else
|
||||
printf '%s %s\n' "$(date -u +'%Y-%m-%dT%H:%M:%SZ')" "$*"
|
||||
fi
|
||||
}
|
||||
|
||||
require_root() {
|
||||
if [[ ${EUID:-$(id -u)} -ne 0 ]]; then
|
||||
log "RESULT: failed reason=not-root"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
get_installed_version() {
|
||||
if command -v dpkg-query >/dev/null 2>&1; then
|
||||
dpkg-query -W -f='${Version}' "$PKG_NAME" 2>/dev/null || printf 'unknown'
|
||||
elif command -v rpm >/dev/null 2>&1; then
|
||||
rpm -q --qf '%{VERSION}-%{RELEASE}' "$PKG_NAME" 2>/dev/null || printf 'unknown'
|
||||
else
|
||||
printf 'unknown'
|
||||
fi
|
||||
}
|
||||
|
||||
trap 'log "RESULT: failed reason=script-error exit_code=$?"' ERR
|
||||
|
||||
apt_can_update() {
|
||||
apt-get update -qq
|
||||
apt-get -s --only-upgrade install "$PKG_NAME" 2>/dev/null | grep -q "^Inst ${PKG_NAME}\b"
|
||||
}
|
||||
|
||||
apt_apply_update() {
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq \
|
||||
-o Dpkg::Options::="--force-confdef" \
|
||||
-o Dpkg::Options::="--force-confold" \
|
||||
"$PKG_NAME"
|
||||
}
|
||||
|
||||
get_rpm_pm() {
|
||||
if command -v dnf >/dev/null 2>&1; then
|
||||
printf 'dnf\n'
|
||||
elif command -v yum >/dev/null 2>&1; then
|
||||
printf 'yum\n'
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
rpm_refresh_metadata() {
|
||||
local pm=$1
|
||||
if [[ "$pm" == "dnf" ]]; then
|
||||
dnf makecache --refresh -q >/dev/null
|
||||
else
|
||||
yum clean expire-cache -q >/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
rpm_can_update() {
|
||||
local pm=$1
|
||||
|
||||
rpm_refresh_metadata "$pm"
|
||||
local rc=0
|
||||
set +e
|
||||
"$pm" check-update -q "$PKG_NAME" >/dev/null 2>&1
|
||||
rc=$?
|
||||
set -e
|
||||
|
||||
if [[ $rc -eq 100 ]]; then
|
||||
return 0
|
||||
elif [[ $rc -eq 0 ]]; then
|
||||
return 1
|
||||
else
|
||||
log "$pm check-update failed with exit code ${rc}."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
rpm_apply_update() {
|
||||
local pm=$1
|
||||
"$pm" update -y "$PKG_NAME"
|
||||
}
|
||||
|
||||
restart_service() {
|
||||
# Preserve the operator's prior service state: if xrpld was intentionally
|
||||
# stopped before the update, don't bring it back up just because the
|
||||
# auto-update timer fired.
|
||||
if systemctl is-active --quiet "${PKG_NAME}.service"; then
|
||||
systemctl restart "${PKG_NAME}.service"
|
||||
log "${PKG_NAME} service restarted successfully."
|
||||
else
|
||||
log "${PKG_NAME} service was not running; skipping restart to preserve prior state."
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
require_root
|
||||
if command -v apt-get >/dev/null 2>&1; then
|
||||
log "Checking for ${PKG_NAME} updates via apt"
|
||||
if apt_can_update; then
|
||||
log "Update available; installing."
|
||||
apt_apply_update
|
||||
restart_service
|
||||
log "RESULT: updated ${PKG_NAME}=$(get_installed_version)"
|
||||
else
|
||||
log "RESULT: no-update ${PKG_NAME}=$(get_installed_version)"
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
local rpm_pm=""
|
||||
if rpm_pm="$(get_rpm_pm)"; then
|
||||
log "Checking for ${PKG_NAME} updates via ${rpm_pm}"
|
||||
if rpm_can_update "$rpm_pm"; then
|
||||
log "Update available; installing"
|
||||
rpm_apply_update "$rpm_pm"
|
||||
restart_service
|
||||
log "RESULT: updated ${PKG_NAME}=$(get_installed_version)"
|
||||
else
|
||||
log "RESULT: no-update ${PKG_NAME}=$(get_installed_version)"
|
||||
fi
|
||||
return
|
||||
fi
|
||||
log "RESULT: failed reason=no-package-manager"
|
||||
exit 1
|
||||
}
|
||||
|
||||
main "$@"
|
||||
16
package/shared/update-xrpld.service
Normal file
16
package/shared/update-xrpld.service
Normal file
@@ -0,0 +1,16 @@
|
||||
[Unit]
|
||||
Description=Check for and install xrpld package updates
|
||||
Documentation=man:systemd.service(5)
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
ConditionPathExists=/usr/libexec/xrpld/update-xrpld
|
||||
ConditionPathExists=/usr/bin/xrpld
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/bin/flock -n /run/lock/xrpld-update.lock /usr/libexec/xrpld/update-xrpld
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
SyslogIdentifier=update-xrpld
|
||||
TimeoutStartSec=30min
|
||||
PrivateTmp=true
|
||||
10
package/shared/update-xrpld.timer
Normal file
10
package/shared/update-xrpld.timer
Normal file
@@ -0,0 +1,10 @@
|
||||
[Unit]
|
||||
Description=Daily xrpld update check
|
||||
|
||||
[Timer]
|
||||
OnCalendar=*-*-* 00:00:00
|
||||
RandomizedDelaySec=24h
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
19
package/shared/xrpld.logrotate
Normal file
19
package/shared/xrpld.logrotate
Normal file
@@ -0,0 +1,19 @@
|
||||
/var/log/xrpld/*.log {
|
||||
daily
|
||||
minsize 200M
|
||||
rotate 7
|
||||
nocreate
|
||||
missingok
|
||||
notifempty
|
||||
compress
|
||||
compresscmd /usr/bin/gzip
|
||||
compressext .gz
|
||||
postrotate
|
||||
# Only signal the daemon if it's actually running; otherwise the RPC
|
||||
# call returns a transport error and logrotate marks the rotation as
|
||||
# failed, generating recurring errors on stopped nodes.
|
||||
if systemctl is-active --quiet xrpld; then
|
||||
/usr/bin/xrpld --conf /etc/xrpld/xrpld.cfg logrotate
|
||||
fi
|
||||
endscript
|
||||
}
|
||||
22
package/shared/xrpld.service
Normal file
22
package/shared/xrpld.service
Normal file
@@ -0,0 +1,22 @@
|
||||
[Unit]
|
||||
Description=XRP Ledger Daemon
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
StartLimitIntervalSec=300
|
||||
StartLimitBurst=5
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/xrpld --net --silent --conf /etc/xrpld/xrpld.cfg
|
||||
Restart=always
|
||||
RestartSec=5s
|
||||
NoNewPrivileges=true
|
||||
ProtectSystem=full
|
||||
ProtectHome=true
|
||||
PrivateTmp=true
|
||||
User=xrpld
|
||||
Group=xrpld
|
||||
LimitNOFILE=65536
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
1
package/shared/xrpld.sysusers
Normal file
1
package/shared/xrpld.sysusers
Normal file
@@ -0,0 +1 @@
|
||||
u xrpld - "XRP Ledger daemon" /var/lib/xrpld /sbin/nologin
|
||||
2
package/shared/xrpld.tmpfiles
Normal file
2
package/shared/xrpld.tmpfiles
Normal file
@@ -0,0 +1,2 @@
|
||||
d /var/lib/xrpld 0750 xrpld xrpld -
|
||||
d /var/log/xrpld 0750 xrpld xrpld -
|
||||
@@ -262,7 +262,7 @@ Transactor::Transactor(ApplyContext& ctx)
|
||||
: ctx_(ctx)
|
||||
, sink_(ctx.journal, toShortString(ctx.tx.getTransactionID()) + " ")
|
||||
, j_(sink_)
|
||||
, account_(ctx.tx.getAccountID(sfAccount))
|
||||
, accountID_(ctx.tx.getAccountID(sfAccount))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -431,7 +431,7 @@ Transactor::payFee()
|
||||
// Deduct the fee, so it's not available during the transaction.
|
||||
// Will only write the account back if the transaction succeeds.
|
||||
sle->setFieldAmount(sfBalance, sle->getFieldAmount(sfBalance) - feePaid);
|
||||
if (feePayer != account_)
|
||||
if (feePayer != accountID_)
|
||||
view().update(sle); // done in `apply()` for the account
|
||||
|
||||
// VFALCO Should we call view().rawDestroyXRP() here as well?
|
||||
@@ -544,7 +544,7 @@ Transactor::consumeSeqProxy(SLE::pointer const& sleAccount)
|
||||
sleAccount->setFieldU32(sfSequence, seqProx.value() + 1);
|
||||
return tesSUCCESS;
|
||||
}
|
||||
return ticketDelete(view(), account_, getTicketIndex(account_, seqProx), j_);
|
||||
return ticketDelete(view(), accountID_, getTicketIndex(accountID_, seqProx), j_);
|
||||
}
|
||||
|
||||
// Remove a single Ticket from the ledger.
|
||||
@@ -617,7 +617,7 @@ Transactor::ticketDelete(
|
||||
void
|
||||
Transactor::preCompute()
|
||||
{
|
||||
XRPL_ASSERT(account_ != beast::kZero, "xrpl::Transactor::preCompute : nonzero account");
|
||||
XRPL_ASSERT(accountID_ != beast::kZero, "xrpl::Transactor::preCompute : nonzero account");
|
||||
}
|
||||
|
||||
TER
|
||||
@@ -627,12 +627,12 @@ Transactor::apply()
|
||||
|
||||
// If the transactor requires a valid account and the transaction doesn't
|
||||
// list one, preflight will have already a flagged a failure.
|
||||
auto const sle = view().peek(keylet::account(account_));
|
||||
auto const sle = view().peek(keylet::account(accountID_));
|
||||
|
||||
// sle must exist except for transactions
|
||||
// that allow zero account.
|
||||
XRPL_ASSERT(
|
||||
sle != nullptr || account_ == beast::kZero,
|
||||
sle != nullptr || accountID_ == beast::kZero,
|
||||
"xrpl::Transactor::apply : non-null SLE or zero account");
|
||||
|
||||
if (sle)
|
||||
|
||||
@@ -344,7 +344,7 @@ AccountDelete::preclaim(PreclaimContext const& ctx)
|
||||
TER
|
||||
AccountDelete::doApply()
|
||||
{
|
||||
auto src = view().peek(keylet::account(account_));
|
||||
auto src = view().peek(keylet::account(accountID_));
|
||||
XRPL_ASSERT(src, "xrpl::AccountDelete::doApply : non-null source account");
|
||||
|
||||
auto const dstID = ctx_.tx[sfDestination];
|
||||
@@ -357,12 +357,12 @@ AccountDelete::doApply()
|
||||
if (ctx_.tx.isFieldPresent(sfCredentialIDs))
|
||||
{
|
||||
if (auto err =
|
||||
verifyDepositPreauth(ctx_.tx, ctx_.view(), account_, dstID, dst, ctx_.journal);
|
||||
verifyDepositPreauth(ctx_.tx, ctx_.view(), accountID_, dstID, dst, ctx_.journal);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
}
|
||||
|
||||
Keylet const ownerDirKeylet{keylet::ownerDir(account_)};
|
||||
Keylet const ownerDirKeylet{keylet::ownerDir(accountID_)};
|
||||
auto const ter = cleanupOnAccountDelete(
|
||||
view(),
|
||||
ownerDirKeylet,
|
||||
@@ -371,7 +371,7 @@ AccountDelete::doApply()
|
||||
std::shared_ptr<SLE>& sleItem) -> std::pair<TER, SkipEntry> {
|
||||
if (auto deleter = nonObligationDeleter(nodeType))
|
||||
{
|
||||
TER const result{deleter(ctx_.registry, view(), account_, dirEntry, sleItem, j_)};
|
||||
TER const result{deleter(ctx_.registry, view(), accountID_, dirEntry, sleItem, j_)};
|
||||
|
||||
return {result, SkipEntry::No};
|
||||
}
|
||||
@@ -402,7 +402,7 @@ AccountDelete::doApply()
|
||||
// delete it.
|
||||
if (view().exists(ownerDirKeylet) && !view().emptyDirDelete(ownerDirKeylet))
|
||||
{
|
||||
JLOG(j_.error()) << "AccountDelete cannot delete root dir node of " << toBase58(account_);
|
||||
JLOG(j_.error()) << "AccountDelete cannot delete root dir node of " << toBase58(accountID_);
|
||||
return tecHAS_OBLIGATIONS;
|
||||
}
|
||||
|
||||
|
||||
@@ -279,7 +279,7 @@ AccountSet::preclaim(PreclaimContext const& ctx)
|
||||
TER
|
||||
AccountSet::doApply()
|
||||
{
|
||||
auto const sle = view().peek(keylet::account(account_));
|
||||
auto const sle = view().peek(keylet::account(accountID_));
|
||||
if (!sle)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -298,7 +298,7 @@ AccountSet::doApply()
|
||||
bool const bSetDisallowXRP{tx.isFlag(tfDisallowXRP) || (uSetFlag == asfDisallowXRP)};
|
||||
bool const bClearDisallowXRP{tx.isFlag(tfAllowXRP) || (uClearFlag == asfDisallowXRP)};
|
||||
|
||||
bool const sigWithMaster{[&tx, &acct = account_]() {
|
||||
bool const sigWithMaster{[&tx, &acct = accountID_]() {
|
||||
auto const spk = tx.getSigningPubKey();
|
||||
|
||||
if (publicKeyType(makeSlice(spk)))
|
||||
@@ -367,7 +367,7 @@ AccountSet::doApply()
|
||||
return tecNEED_MASTER_KEY;
|
||||
}
|
||||
|
||||
if ((!sle->isFieldPresent(sfRegularKey)) && (!view().peek(keylet::signers(account_))))
|
||||
if ((!sle->isFieldPresent(sfRegularKey)) && (!view().peek(keylet::signers(accountID_))))
|
||||
{
|
||||
// Account has no regular key or multi-signer signer list.
|
||||
return tecNO_ALTERNATIVE_KEY;
|
||||
|
||||
@@ -55,7 +55,7 @@ SetRegularKey::preflight(PreflightContext const& ctx)
|
||||
TER
|
||||
SetRegularKey::doApply()
|
||||
{
|
||||
auto const sle = view().peek(keylet::account(account_));
|
||||
auto const sle = view().peek(keylet::account(accountID_));
|
||||
if (!sle)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -69,7 +69,7 @@ SetRegularKey::doApply()
|
||||
else
|
||||
{
|
||||
// Account has disabled master key and no multi-signer signer list.
|
||||
if (sle->isFlag(lsfDisableMaster) && !view().peek(keylet::signers(account_)))
|
||||
if (sle->isFlag(lsfDisableMaster) && !view().peek(keylet::signers(accountID_)))
|
||||
return tecNO_ALTERNATIVE_KEY;
|
||||
|
||||
sle->makeFieldAbsent(sfRegularKey);
|
||||
|
||||
@@ -300,9 +300,9 @@ SignerListSet::validateQuorumAndSignerEntries(
|
||||
TER
|
||||
SignerListSet::replaceSignerList()
|
||||
{
|
||||
auto const accountKeylet = keylet::account(account_);
|
||||
auto const ownerDirKeylet = keylet::ownerDir(account_);
|
||||
auto const signerListKeylet = keylet::signers(account_);
|
||||
auto const accountKeylet = keylet::account(accountID_);
|
||||
auto const ownerDirKeylet = keylet::ownerDir(accountID_);
|
||||
auto const signerListKeylet = keylet::signers(accountID_);
|
||||
|
||||
// This may be either a create or a replace. Preemptively remove any
|
||||
// old signer list. May reduce the reserve, so this is done before
|
||||
@@ -337,9 +337,9 @@ SignerListSet::replaceSignerList()
|
||||
auto viewJ = ctx_.registry.get().getJournal("View");
|
||||
// Add the signer list to the account's directory.
|
||||
auto const page =
|
||||
ctx_.view().dirInsert(ownerDirKeylet, signerListKeylet, describeOwnerDir(account_));
|
||||
ctx_.view().dirInsert(ownerDirKeylet, signerListKeylet, describeOwnerDir(accountID_));
|
||||
|
||||
JLOG(j_.trace()) << "Create signer list for account " << toBase58(account_) << ": "
|
||||
JLOG(j_.trace()) << "Create signer list for account " << toBase58(accountID_) << ": "
|
||||
<< (page ? "success" : "failure");
|
||||
|
||||
if (!page)
|
||||
@@ -356,7 +356,7 @@ SignerListSet::replaceSignerList()
|
||||
TER
|
||||
SignerListSet::destroySignerList()
|
||||
{
|
||||
auto const accountKeylet = keylet::account(account_);
|
||||
auto const accountKeylet = keylet::account(accountID_);
|
||||
// Destroying the signer list is only allowed if either the master key
|
||||
// is enabled or there is a regular key.
|
||||
SLE::pointer const ledgerEntry = view().peek(accountKeylet);
|
||||
@@ -366,8 +366,8 @@ SignerListSet::destroySignerList()
|
||||
if ((ledgerEntry->isFlag(lsfDisableMaster)) && (!ledgerEntry->isFieldPresent(sfRegularKey)))
|
||||
return tecNO_ALTERNATIVE_KEY;
|
||||
|
||||
auto const ownerDirKeylet = keylet::ownerDir(account_);
|
||||
auto const signerListKeylet = keylet::signers(account_);
|
||||
auto const ownerDirKeylet = keylet::ownerDir(accountID_);
|
||||
auto const signerListKeylet = keylet::signers(accountID_);
|
||||
return removeSignersFromLedger(
|
||||
ctx_.registry, view(), accountKeylet, ownerDirKeylet, signerListKeylet, j_);
|
||||
}
|
||||
@@ -378,7 +378,7 @@ SignerListSet::writeSignersToSLE(SLE::pointer const& ledgerEntry, std::uint32_t
|
||||
// Assign the quorum, default SignerListID, and flags.
|
||||
if (ctx_.view().rules().enabled(fixIncludeKeyletFields))
|
||||
{
|
||||
ledgerEntry->setAccountID(sfOwner, account_);
|
||||
ledgerEntry->setAccountID(sfOwner, accountID_);
|
||||
}
|
||||
ledgerEntry->setFieldU32(sfSignerQuorum, quorum_);
|
||||
ledgerEntry->setFieldU32(sfSignerListID, kDefaultSignerListId);
|
||||
|
||||
@@ -1920,7 +1920,7 @@ XChainCommit::doApply()
|
||||
|
||||
// Support dipping into reserves to pay the fee
|
||||
TransferHelperSubmittingAccountInfo submittingAccountInfo{
|
||||
.account = account_,
|
||||
.account = accountID_,
|
||||
.preFeeBalance = preFeeBalance_,
|
||||
.postFeeBalance = (*sleAccount)[sfBalance]};
|
||||
|
||||
@@ -2197,7 +2197,9 @@ XChainCreateAccountCommit::doApply()
|
||||
|
||||
// Support dipping into reserves to pay the fee
|
||||
TransferHelperSubmittingAccountInfo submittingAccountInfo{
|
||||
.account = account_, .preFeeBalance = preFeeBalance_, .postFeeBalance = (*sle)[sfBalance]};
|
||||
.account = accountID_,
|
||||
.preFeeBalance = preFeeBalance_,
|
||||
.postFeeBalance = (*sle)[sfBalance]};
|
||||
STAmount const toTransfer = amount + reward;
|
||||
auto const thTer = transferHelper(
|
||||
psb,
|
||||
|
||||
@@ -294,7 +294,7 @@ CheckCash::doApply()
|
||||
}
|
||||
|
||||
AccountID const srcId{sleCheck->getAccountID(sfAccount)};
|
||||
if (!psb.exists(keylet::account(srcId)) || !psb.exists(keylet::account(account_)))
|
||||
if (!psb.exists(keylet::account(srcId)) || !psb.exists(keylet::account(accountID_)))
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
JLOG(ctx_.journal.fatal()) << "Precheck did not verify source or destination's existence.";
|
||||
@@ -315,7 +315,7 @@ CheckCash::doApply()
|
||||
auto viewJ = ctx_.registry.get().getJournal("View");
|
||||
auto const optDeliverMin = ctx_.tx[~sfDeliverMin];
|
||||
|
||||
if (srcId != account_)
|
||||
if (srcId != accountID_)
|
||||
{
|
||||
STAmount const sendMax = sleCheck->at(sfSendMax);
|
||||
|
||||
@@ -353,7 +353,7 @@ CheckCash::doApply()
|
||||
}
|
||||
|
||||
// The source account has enough XRP so make the ledger change.
|
||||
if (TER const ter{transferXRP(psb, srcId, account_, xrpDeliver, viewJ)};
|
||||
if (TER const ter{transferXRP(psb, srcId, accountID_, xrpDeliver, viewJ)};
|
||||
!isTesSuccess(ter))
|
||||
{
|
||||
// The transfer failed. Return the error code.
|
||||
@@ -383,7 +383,7 @@ CheckCash::doApply()
|
||||
// Check reserve. Return destination account SLE if enough reserve,
|
||||
// otherwise return nullptr.
|
||||
auto checkReserve = [&]() -> std::shared_ptr<SLE> {
|
||||
auto sleDst = psb.peek(keylet::account(account_));
|
||||
auto sleDst = psb.peek(keylet::account(accountID_));
|
||||
|
||||
// Can the account cover the trust line's or MPT reserve?
|
||||
if (std::uint32_t const ownerCount = {sleDst->at(sfOwnerCount)};
|
||||
@@ -405,9 +405,9 @@ CheckCash::doApply()
|
||||
[&](Issue const& issue) -> std::optional<TER> {
|
||||
// If a trust line does not exist yet create one.
|
||||
Issue const& trustLineIssue = issue;
|
||||
AccountID const truster = deliverIssuer == account_ ? srcId : account_;
|
||||
AccountID const truster = deliverIssuer == accountID_ ? srcId : accountID_;
|
||||
trustLineKey = keylet::line(truster, trustLineIssue);
|
||||
destLow = deliverIssuer > account_;
|
||||
destLow = deliverIssuer > accountID_;
|
||||
|
||||
if (!psb.exists(*trustLineKey))
|
||||
{
|
||||
@@ -433,7 +433,7 @@ CheckCash::doApply()
|
||||
psb, // payment sandbox
|
||||
destLow, // is dest low?
|
||||
deliverIssuer, // source
|
||||
account_, // destination
|
||||
accountID_, // destination
|
||||
trustLineKey->key, // ledger index
|
||||
sleDst, // Account to add to
|
||||
false, // authorize account
|
||||
@@ -441,7 +441,7 @@ CheckCash::doApply()
|
||||
false, // freeze trust line
|
||||
false, // deep freeze trust line
|
||||
initialBalance, // zero initial balance
|
||||
Issue(currency, account_), // limit of zero
|
||||
Issue(currency, accountID_), // limit of zero
|
||||
0, // quality in
|
||||
0, // quality out
|
||||
viewJ); // journal
|
||||
@@ -479,18 +479,18 @@ CheckCash::doApply()
|
||||
return std::nullopt;
|
||||
},
|
||||
[&](MPTIssue const& issue) -> std::optional<TER> {
|
||||
if (account_ != deliverIssuer)
|
||||
if (accountID_ != deliverIssuer)
|
||||
{
|
||||
auto const& mptID = issue.getMptID();
|
||||
// Create MPT if it doesn't exist
|
||||
auto const mptokenKey = keylet::mptoken(mptID, account_);
|
||||
auto const mptokenKey = keylet::mptoken(mptID, accountID_);
|
||||
if (!psb.exists(mptokenKey))
|
||||
{
|
||||
auto sleDst = checkReserve();
|
||||
if (sleDst == nullptr)
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
|
||||
if (auto const err = checkCreateMPT(psb, mptID, account_, j_);
|
||||
if (auto const err = checkCreateMPT(psb, mptID, accountID_, j_);
|
||||
!isTesSuccess(err))
|
||||
{
|
||||
return err;
|
||||
@@ -518,7 +518,7 @@ CheckCash::doApply()
|
||||
psb,
|
||||
flowDeliver,
|
||||
srcId,
|
||||
account_,
|
||||
accountID_,
|
||||
STPathSet{},
|
||||
true, // default path
|
||||
static_cast<bool>(optDeliverMin), // partial payment
|
||||
@@ -556,9 +556,9 @@ CheckCash::doApply()
|
||||
|
||||
// Check was cashed. If not a self send (and it shouldn't be), remove
|
||||
// check link from destination directory.
|
||||
if (srcId != account_ &&
|
||||
if (srcId != accountID_ &&
|
||||
!psb.dirRemove(
|
||||
keylet::ownerDir(account_), sleCheck->at(sfDestinationNode), sleCheck->key(), true))
|
||||
keylet::ownerDir(accountID_), sleCheck->at(sfDestinationNode), sleCheck->key(), true))
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
JLOG(j_.fatal()) << "Unable to delete check from destination.";
|
||||
|
||||
@@ -175,7 +175,7 @@ CheckCreate::preclaim(PreclaimContext const& ctx)
|
||||
TER
|
||||
CheckCreate::doApply()
|
||||
{
|
||||
auto const sle = view().peek(keylet::account(account_));
|
||||
auto const sle = view().peek(keylet::account(accountID_));
|
||||
if (!sle)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -192,10 +192,10 @@ CheckCreate::doApply()
|
||||
// Note that we use the value from the sequence or ticket as the
|
||||
// Check sequence. For more explanation see comments in SeqProxy.h.
|
||||
std::uint32_t const seq = ctx_.tx.getSeqValue();
|
||||
Keylet const checkKeylet = keylet::check(account_, seq);
|
||||
Keylet const checkKeylet = keylet::check(accountID_, seq);
|
||||
auto sleCheck = std::make_shared<SLE>(checkKeylet);
|
||||
|
||||
sleCheck->setAccountID(sfAccount, account_);
|
||||
sleCheck->setAccountID(sfAccount, accountID_);
|
||||
AccountID const dstAccountId = ctx_.tx[sfDestination];
|
||||
sleCheck->setAccountID(sfDestination, dstAccountId);
|
||||
sleCheck->setFieldU32(sfSequence, seq);
|
||||
@@ -214,7 +214,7 @@ CheckCreate::doApply()
|
||||
auto viewJ = ctx_.registry.get().getJournal("View");
|
||||
// If it's not a self-send (and it shouldn't be), add Check to the
|
||||
// destination's owner directory.
|
||||
if (dstAccountId != account_)
|
||||
if (dstAccountId != accountID_)
|
||||
{
|
||||
auto const page = view().dirInsert(
|
||||
keylet::ownerDir(dstAccountId), checkKeylet, describeOwnerDir(dstAccountId));
|
||||
@@ -229,8 +229,8 @@ CheckCreate::doApply()
|
||||
}
|
||||
|
||||
{
|
||||
auto const page =
|
||||
view().dirInsert(keylet::ownerDir(account_), checkKeylet, describeOwnerDir(account_));
|
||||
auto const page = view().dirInsert(
|
||||
keylet::ownerDir(accountID_), checkKeylet, describeOwnerDir(accountID_));
|
||||
|
||||
JLOG(j_.trace()) << "Adding Check to owner directory " << to_string(checkKeylet.key) << ": "
|
||||
<< (page ? "success" : "failure");
|
||||
|
||||
@@ -89,7 +89,7 @@ CredentialAccept::doApply()
|
||||
AccountID const issuer{ctx_.tx[sfIssuer]};
|
||||
|
||||
// Both exist as credential object exist itself (checked in preclaim)
|
||||
auto const sleSubject = view().peek(keylet::account(account_));
|
||||
auto const sleSubject = view().peek(keylet::account(accountID_));
|
||||
auto const sleIssuer = view().peek(keylet::account(issuer));
|
||||
|
||||
if (!sleSubject || !sleIssuer)
|
||||
@@ -103,7 +103,7 @@ CredentialAccept::doApply()
|
||||
}
|
||||
|
||||
auto const credType(ctx_.tx[sfCredentialType]);
|
||||
Keylet const credentialKey = keylet::credential(account_, issuer, credType);
|
||||
Keylet const credentialKey = keylet::credential(accountID_, issuer, credType);
|
||||
auto const sleCred = view().peek(credentialKey); // Checked in preclaim()
|
||||
if (!sleCred)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -104,7 +104,7 @@ CredentialCreate::doApply()
|
||||
{
|
||||
auto const subject = ctx_.tx[sfSubject];
|
||||
auto const credType(ctx_.tx[sfCredentialType]);
|
||||
Keylet const credentialKey = keylet::credential(subject, account_, credType);
|
||||
Keylet const credentialKey = keylet::credential(subject, accountID_, credType);
|
||||
|
||||
auto const sleCred = std::make_shared<SLE>(credentialKey);
|
||||
if (!sleCred)
|
||||
@@ -126,7 +126,7 @@ CredentialCreate::doApply()
|
||||
sleCred->setFieldU32(sfExpiration, *optExp);
|
||||
}
|
||||
|
||||
auto const sleIssuer = view().peek(keylet::account(account_));
|
||||
auto const sleIssuer = view().peek(keylet::account(accountID_));
|
||||
if (!sleIssuer)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -138,15 +138,15 @@ CredentialCreate::doApply()
|
||||
}
|
||||
|
||||
sleCred->setAccountID(sfSubject, subject);
|
||||
sleCred->setAccountID(sfIssuer, account_);
|
||||
sleCred->setAccountID(sfIssuer, accountID_);
|
||||
sleCred->setFieldVL(sfCredentialType, credType);
|
||||
|
||||
if (ctx_.tx.isFieldPresent(sfURI))
|
||||
sleCred->setFieldVL(sfURI, ctx_.tx.getFieldVL(sfURI));
|
||||
|
||||
{
|
||||
auto const page =
|
||||
view().dirInsert(keylet::ownerDir(account_), credentialKey, describeOwnerDir(account_));
|
||||
auto const page = view().dirInsert(
|
||||
keylet::ownerDir(accountID_), credentialKey, describeOwnerDir(accountID_));
|
||||
JLOG(j_.trace()) << "Adding Credential to owner directory " << to_string(credentialKey.key)
|
||||
<< ": " << (page ? "success" : "failure");
|
||||
if (!page)
|
||||
@@ -156,7 +156,7 @@ CredentialCreate::doApply()
|
||||
adjustOwnerCount(view(), sleIssuer, 1, j_);
|
||||
}
|
||||
|
||||
if (subject == account_)
|
||||
if (subject == accountID_)
|
||||
{
|
||||
sleCred->setFieldU32(sfFlags, lsfAccepted);
|
||||
}
|
||||
|
||||
@@ -78,15 +78,15 @@ CredentialDelete::preclaim(PreclaimContext const& ctx)
|
||||
TER
|
||||
CredentialDelete::doApply()
|
||||
{
|
||||
auto const subject = ctx_.tx[~sfSubject].value_or(account_);
|
||||
auto const issuer = ctx_.tx[~sfIssuer].value_or(account_);
|
||||
auto const subject = ctx_.tx[~sfSubject].value_or(accountID_);
|
||||
auto const issuer = ctx_.tx[~sfIssuer].value_or(accountID_);
|
||||
|
||||
auto const credType(ctx_.tx[sfCredentialType]);
|
||||
auto const sleCred = view().peek(keylet::credential(subject, issuer, credType));
|
||||
if (!sleCred)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
if ((subject != account_) && (issuer != account_) &&
|
||||
if ((subject != accountID_) && (issuer != accountID_) &&
|
||||
!checkExpired(*sleCred, ctx_.view().header().parentCloseTime))
|
||||
{
|
||||
JLOG(j_.trace()) << "Can't delete non-expired credential.";
|
||||
|
||||
@@ -68,12 +68,12 @@ DelegateSet::preclaim(PreclaimContext const& ctx)
|
||||
TER
|
||||
DelegateSet::doApply()
|
||||
{
|
||||
auto const sleOwner = ctx_.view().peek(keylet::account(account_));
|
||||
auto const sleOwner = ctx_.view().peek(keylet::account(accountID_));
|
||||
if (!sleOwner)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
auto const& authAccount = ctx_.tx[sfAuthorize];
|
||||
auto const delegateKey = keylet::delegate(account_, authAccount);
|
||||
auto const delegateKey = keylet::delegate(accountID_, authAccount);
|
||||
|
||||
auto sle = ctx_.view().peek(delegateKey);
|
||||
if (sle)
|
||||
@@ -101,14 +101,14 @@ DelegateSet::doApply()
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
|
||||
sle = std::make_shared<SLE>(delegateKey);
|
||||
sle->setAccountID(sfAccount, account_);
|
||||
sle->setAccountID(sfAccount, accountID_);
|
||||
sle->setAccountID(sfAuthorize, authAccount);
|
||||
|
||||
sle->setFieldArray(sfPermissions, permissions);
|
||||
|
||||
// Add to delegating account's owner directory
|
||||
auto const page =
|
||||
ctx_.view().dirInsert(keylet::ownerDir(account_), delegateKey, describeOwnerDir(account_));
|
||||
auto const page = ctx_.view().dirInsert(
|
||||
keylet::ownerDir(accountID_), delegateKey, describeOwnerDir(accountID_));
|
||||
|
||||
if (!page)
|
||||
return tecDIR_FULL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -371,7 +371,7 @@ AMMBid::doApply()
|
||||
// as we go on processing transactions.
|
||||
Sandbox sb(&ctx_.view());
|
||||
|
||||
auto const result = applyBid(ctx_, sb, account_, j_);
|
||||
auto const result = applyBid(ctx_, sb, accountID_, j_);
|
||||
if (result.second)
|
||||
sb.apply(ctx_.rawView());
|
||||
|
||||
|
||||
@@ -385,7 +385,7 @@ AMMCreate::doApply()
|
||||
// as we go on processing transactions.
|
||||
Sandbox sb(&ctx_.view());
|
||||
|
||||
auto const result = applyCreate(ctx_, sb, account_, j_);
|
||||
auto const result = applyCreate(ctx_, sb, accountID_, j_);
|
||||
if (result.second)
|
||||
sb.apply(ctx_.rawView());
|
||||
|
||||
|
||||
@@ -403,7 +403,7 @@ AMMDeposit::applyGuts(Sandbox& sb)
|
||||
auto const [amountBalance, amount2Balance, lptAMMBalance] = *expected;
|
||||
auto const tfee = (lptAMMBalance == beast::kZero)
|
||||
? ctx_.tx[~sfTradingFee].value_or(0)
|
||||
: getTradingFee(ctx_.view(), *ammSle, account_);
|
||||
: getTradingFee(ctx_.view(), *ammSle, accountID_);
|
||||
|
||||
auto const subTxType = ctx_.tx.getFlags() & tfDepositSubTx;
|
||||
|
||||
@@ -474,7 +474,7 @@ AMMDeposit::applyGuts(Sandbox& sb)
|
||||
// LP depositing into AMM empty state gets the auction slot
|
||||
// and the voting
|
||||
if (lptAMMBalance == beast::kZero)
|
||||
initializeFeeAuctionVote(sb, ammSle, account_, lptAMMBalance.asset(), tfee);
|
||||
initializeFeeAuctionVote(sb, ammSle, accountID_, lptAMMBalance.asset(), tfee);
|
||||
|
||||
sb.update(ammSle);
|
||||
}
|
||||
@@ -519,14 +519,14 @@ AMMDeposit::deposit(
|
||||
{
|
||||
auto const& lpIssue = lpTokensDeposit.get<Issue>();
|
||||
// Adjust the reserve if LP doesn't have LPToken trustline
|
||||
auto const sle = view.read(keylet::line(account_, lpIssue.account, lpIssue.currency));
|
||||
if (xrpLiquid(view, account_, !sle, j_) >= depositAmount)
|
||||
auto const sle = view.read(keylet::line(accountID_, lpIssue.account, lpIssue.currency));
|
||||
if (xrpLiquid(view, accountID_, !sle, j_) >= depositAmount)
|
||||
return tesSUCCESS;
|
||||
}
|
||||
else if (
|
||||
accountFunds(
|
||||
view,
|
||||
account_,
|
||||
accountID_,
|
||||
depositAmount,
|
||||
FreezeHandling::IgnoreFreeze,
|
||||
AuthHandling::IgnoreAuth,
|
||||
@@ -574,7 +574,7 @@ AMMDeposit::deposit(
|
||||
}
|
||||
|
||||
auto res = accountSend(
|
||||
view, account_, ammAccount, amountDepositActual, ctx_.journal, WaiveTransferFee::Yes);
|
||||
view, accountID_, ammAccount, amountDepositActual, ctx_.journal, WaiveTransferFee::Yes);
|
||||
if (!isTesSuccess(res))
|
||||
{
|
||||
JLOG(ctx_.journal.debug()) << "AMM Deposit: failed to deposit " << amountDepositActual;
|
||||
@@ -593,7 +593,12 @@ AMMDeposit::deposit(
|
||||
}
|
||||
|
||||
res = accountSend(
|
||||
view, account_, ammAccount, *amount2DepositActual, ctx_.journal, WaiveTransferFee::Yes);
|
||||
view,
|
||||
accountID_,
|
||||
ammAccount,
|
||||
*amount2DepositActual,
|
||||
ctx_.journal,
|
||||
WaiveTransferFee::Yes);
|
||||
if (!isTesSuccess(res))
|
||||
{
|
||||
JLOG(ctx_.journal.debug())
|
||||
@@ -603,7 +608,7 @@ AMMDeposit::deposit(
|
||||
}
|
||||
|
||||
// Deposit LP tokens
|
||||
res = accountSend(view, ammAccount, account_, lpTokensDepositActual, ctx_.journal);
|
||||
res = accountSend(view, ammAccount, accountID_, lpTokensDepositActual, ctx_.journal);
|
||||
if (!isTesSuccess(res))
|
||||
{
|
||||
JLOG(ctx_.journal.debug()) << "AMM Deposit: failed to deposit LPTokens";
|
||||
|
||||
@@ -241,7 +241,7 @@ AMMVote::doApply()
|
||||
// as we go on processing transactions.
|
||||
Sandbox sb(&ctx_.view());
|
||||
|
||||
auto const result = applyVote(ctx_, sb, account_, j_);
|
||||
auto const result = applyVote(ctx_, sb, accountID_, j_);
|
||||
if (result.second)
|
||||
sb.apply(ctx_.rawView());
|
||||
|
||||
|
||||
@@ -329,11 +329,11 @@ AMMWithdraw::applyGuts(Sandbox& sb)
|
||||
// might not match the LP's trustline balance
|
||||
if (sb.rules().enabled(fixAMMv1_1))
|
||||
{
|
||||
if (auto const res = verifyAndAdjustLPTokenBalance(sb, lpTokens, ammSle, account_); !res)
|
||||
if (auto const res = verifyAndAdjustLPTokenBalance(sb, lpTokens, ammSle, accountID_); !res)
|
||||
return {res.error(), false};
|
||||
}
|
||||
|
||||
auto const tfee = getTradingFee(ctx_.view(), *ammSle, account_);
|
||||
auto const tfee = getTradingFee(ctx_.view(), *ammSle, accountID_);
|
||||
|
||||
auto const expected = ammHolds(
|
||||
sb,
|
||||
@@ -458,7 +458,7 @@ AMMWithdraw::withdraw(
|
||||
view,
|
||||
ammSle,
|
||||
ammAccount,
|
||||
account_,
|
||||
accountID_,
|
||||
amountBalance,
|
||||
amountWithdraw,
|
||||
amount2Withdraw,
|
||||
@@ -748,7 +748,7 @@ AMMWithdraw::equalWithdrawTokens(
|
||||
std::tie(ter, newLPTokenBalance, std::ignore, std::ignore) = equalWithdrawTokens(
|
||||
view,
|
||||
ammSle,
|
||||
account_,
|
||||
accountID_,
|
||||
ammAccount,
|
||||
amountBalance,
|
||||
amount2Balance,
|
||||
|
||||
@@ -55,11 +55,11 @@ OfferCancel::doApply()
|
||||
{
|
||||
auto const offerSequence = ctx_.tx[sfOfferSequence];
|
||||
|
||||
auto const sle = view().read(keylet::account(account_));
|
||||
auto const sle = view().read(keylet::account(accountID_));
|
||||
if (!sle)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
if (auto sleOffer = view().peek(keylet::offer(account_, offerSequence)))
|
||||
if (auto sleOffer = view().peek(keylet::offer(accountID_, offerSequence)))
|
||||
{
|
||||
JLOG(j_.debug()) << "Trying to cancel offer #" << offerSequence;
|
||||
return offerDelete(view(), sleOffer, ctx_.registry.get().getJournal("View"));
|
||||
|
||||
@@ -341,14 +341,14 @@ OfferCreate::flowCross(
|
||||
// below the reserve) so we check this case again.
|
||||
STAmount const inStartBalance = accountFunds(
|
||||
psb,
|
||||
account_,
|
||||
accountID_,
|
||||
takerAmount.in,
|
||||
FreezeHandling::ZeroIfFrozen,
|
||||
AuthHandling::ZeroIfUnauthorized,
|
||||
j_);
|
||||
// Allow unfunded MPT issuer
|
||||
auto const disallowUnfunded =
|
||||
!inStartBalance.holds<MPTIssue>() || inStartBalance.getIssuer() != account_;
|
||||
!inStartBalance.holds<MPTIssue>() || inStartBalance.getIssuer() != accountID_;
|
||||
if (disallowUnfunded && inStartBalance <= beast::kZero)
|
||||
{
|
||||
// The account balance can't cover even part of the offer.
|
||||
@@ -361,7 +361,7 @@ OfferCreate::flowCross(
|
||||
// offer taker. Set sendMax to allow for the gateway's cut.
|
||||
Rate gatewayXferRate{QUALITY_ONE};
|
||||
STAmount sendMax = takerAmount.in;
|
||||
if (!sendMax.native() && (account_ != sendMax.getIssuer()))
|
||||
if (!sendMax.native() && (accountID_ != sendMax.getIssuer()))
|
||||
{
|
||||
gatewayXferRate = transferRate(psb, sendMax);
|
||||
if (gatewayXferRate.value != QUALITY_ONE)
|
||||
@@ -428,8 +428,8 @@ OfferCreate::flowCross(
|
||||
auto const result = flow(
|
||||
psb,
|
||||
deliver,
|
||||
account_,
|
||||
account_,
|
||||
accountID_,
|
||||
accountID_,
|
||||
paths,
|
||||
true, // default path
|
||||
!ctx_.tx.isFlag(tfFillOrKill), // partial payment
|
||||
@@ -455,7 +455,7 @@ OfferCreate::flowCross(
|
||||
{
|
||||
STAmount const takerInBalance = accountFunds(
|
||||
psb,
|
||||
account_,
|
||||
accountID_,
|
||||
takerAmount.in,
|
||||
FreezeHandling::ZeroIfFrozen,
|
||||
AuthHandling::ZeroIfUnauthorized,
|
||||
@@ -619,7 +619,7 @@ OfferCreate::applyGuts(Sandbox& sb, Sandbox& sbCancel)
|
||||
// Process a cancellation request that's passed along with an offer.
|
||||
if (cancelSequence)
|
||||
{
|
||||
auto const sleCancel = sb.peek(keylet::offer(account_, *cancelSequence));
|
||||
auto const sleCancel = sb.peek(keylet::offer(accountID_, *cancelSequence));
|
||||
|
||||
// It's not an error to not find the offer to cancel: it might have
|
||||
// been consumed or removed. If it is found, however, it's an error
|
||||
@@ -810,7 +810,7 @@ OfferCreate::applyGuts(Sandbox& sb, Sandbox& sbCancel)
|
||||
return {tesSUCCESS, true};
|
||||
}
|
||||
|
||||
auto const sleCreator = sb.peek(keylet::account(account_));
|
||||
auto const sleCreator = sb.peek(keylet::account(accountID_));
|
||||
if (!sleCreator)
|
||||
return {tefINTERNAL, false};
|
||||
|
||||
@@ -836,11 +836,11 @@ OfferCreate::applyGuts(Sandbox& sb, Sandbox& sbCancel)
|
||||
}
|
||||
|
||||
// We need to place the remainder of the offer into its order book.
|
||||
auto const offerIndex = keylet::offer(account_, offerSequence);
|
||||
auto const offerIndex = keylet::offer(accountID_, offerSequence);
|
||||
|
||||
// Add offer to owner's directory.
|
||||
auto const ownerNode =
|
||||
sb.dirInsert(keylet::ownerDir(account_), offerIndex, describeOwnerDir(account_));
|
||||
sb.dirInsert(keylet::ownerDir(accountID_), offerIndex, describeOwnerDir(accountID_));
|
||||
|
||||
if (!ownerNode)
|
||||
{
|
||||
@@ -905,7 +905,7 @@ OfferCreate::applyGuts(Sandbox& sb, Sandbox& sbCancel)
|
||||
}
|
||||
|
||||
auto sleOffer = std::make_shared<SLE>(offerIndex);
|
||||
sleOffer->setAccountID(sfAccount, account_);
|
||||
sleOffer->setAccountID(sfAccount, accountID_);
|
||||
sleOffer->setFieldU32(sfSequence, offerSequence);
|
||||
sleOffer->setFieldH256(sfBookDirectory, dir.key);
|
||||
sleOffer->setFieldAmount(sfTakerPays, saTakerPays);
|
||||
|
||||
@@ -67,7 +67,7 @@ DIDDelete::deleteSLE(
|
||||
TER
|
||||
DIDDelete::doApply()
|
||||
{
|
||||
return deleteSLE(ctx_, keylet::did(account_), account_);
|
||||
return deleteSLE(ctx_, keylet::did(accountID_), accountID_);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -99,7 +99,7 @@ TER
|
||||
DIDSet::doApply()
|
||||
{
|
||||
// Edit ledger object if it already exists
|
||||
Keylet const didKeylet = keylet::did(account_);
|
||||
Keylet const didKeylet = keylet::did(accountID_);
|
||||
if (auto const sleDID = ctx_.view().peek(didKeylet))
|
||||
{
|
||||
auto update = [&](auto const& sField) {
|
||||
@@ -130,7 +130,7 @@ DIDSet::doApply()
|
||||
|
||||
// Create new ledger object otherwise
|
||||
auto const sleDID = std::make_shared<SLE>(didKeylet);
|
||||
(*sleDID)[sfAccount] = account_;
|
||||
(*sleDID)[sfAccount] = accountID_;
|
||||
|
||||
auto set = [&](auto const& sField) {
|
||||
if (auto const field = ctx_.tx[~sField]; field && !field->empty())
|
||||
@@ -146,7 +146,7 @@ DIDSet::doApply()
|
||||
return tecEMPTY_DID;
|
||||
}
|
||||
|
||||
return addSLE(ctx_, sleDID, account_);
|
||||
return addSLE(ctx_, sleDID, accountID_);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -178,13 +178,13 @@ EscrowCancel::doApply()
|
||||
return temDISABLED; // LCOV_EXCL_LINE
|
||||
|
||||
auto const issuer = amount.getIssuer();
|
||||
bool const createAsset = account == account_;
|
||||
bool const createAsset = account == accountID_;
|
||||
if (auto const ret = std::visit(
|
||||
[&]<typename T>(T const&) {
|
||||
return escrowUnlockApplyHelper<T>(
|
||||
ctx_.view(),
|
||||
kParityRate,
|
||||
slep,
|
||||
ctx_.view().rules().enabled(fixCleanup3_2_0) ? sle : slep,
|
||||
preFeeBalance_,
|
||||
amount,
|
||||
issuer,
|
||||
|
||||
@@ -417,7 +417,7 @@ EscrowCreate::doApply()
|
||||
if (ctx_.tx[~sfFinishAfter] && after(closeTime, ctx_.tx[sfFinishAfter]))
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
auto const sle = ctx_.view().peek(keylet::account(account_));
|
||||
auto const sle = ctx_.view().peek(keylet::account(accountID_));
|
||||
if (!sle)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -448,10 +448,10 @@ EscrowCreate::doApply()
|
||||
|
||||
// Create escrow in ledger. Note that we use the value from the
|
||||
// sequence or ticket. For more explanation see comments in SeqProxy.h.
|
||||
Keylet const escrowKeylet = keylet::escrow(account_, ctx_.tx.getSeqValue());
|
||||
Keylet const escrowKeylet = keylet::escrow(accountID_, ctx_.tx.getSeqValue());
|
||||
auto const slep = std::make_shared<SLE>(escrowKeylet);
|
||||
(*slep)[sfAmount] = amount;
|
||||
(*slep)[sfAccount] = account_;
|
||||
(*slep)[sfAccount] = accountID_;
|
||||
(*slep)[~sfCondition] = ctx_.tx[~sfCondition];
|
||||
(*slep)[~sfSourceTag] = ctx_.tx[~sfSourceTag];
|
||||
(*slep)[sfDestination] = ctx_.tx[sfDestination];
|
||||
@@ -476,7 +476,7 @@ EscrowCreate::doApply()
|
||||
// Add escrow to sender's owner directory
|
||||
{
|
||||
auto page = ctx_.view().dirInsert(
|
||||
keylet::ownerDir(account_), escrowKeylet, describeOwnerDir(account_));
|
||||
keylet::ownerDir(accountID_), escrowKeylet, describeOwnerDir(accountID_));
|
||||
if (!page)
|
||||
return tecDIR_FULL; // LCOV_EXCL_LINE
|
||||
(*slep)[sfOwnerNode] = *page;
|
||||
@@ -484,7 +484,7 @@ EscrowCreate::doApply()
|
||||
|
||||
// If it's not a self-send, add escrow to recipient's owner directory.
|
||||
AccountID const dest = ctx_.tx[sfDestination];
|
||||
if (dest != account_)
|
||||
if (dest != accountID_)
|
||||
{
|
||||
auto page =
|
||||
ctx_.view().dirInsert(keylet::ownerDir(dest), escrowKeylet, describeOwnerDir(dest));
|
||||
@@ -497,7 +497,7 @@ EscrowCreate::doApply()
|
||||
// track the total locked balance. For MPT, this isn't necessary because the
|
||||
// locked balance is already stored directly in the MPTokenIssuance object.
|
||||
AccountID const issuer = amount.getIssuer();
|
||||
if (!isXRP(amount) && issuer != account_ && issuer != dest && !amount.holds<MPTIssue>())
|
||||
if (!isXRP(amount) && issuer != accountID_ && issuer != dest && !amount.holds<MPTIssue>())
|
||||
{
|
||||
auto page =
|
||||
ctx_.view().dirInsert(keylet::ownerDir(issuer), escrowKeylet, describeOwnerDir(issuer));
|
||||
@@ -515,7 +515,7 @@ EscrowCreate::doApply()
|
||||
{
|
||||
if (auto const ret = std::visit(
|
||||
[&]<typename T>(T const&) {
|
||||
return escrowLockApplyHelper<T>(ctx_.view(), issuer, account_, amount, j_);
|
||||
return escrowLockApplyHelper<T>(ctx_.view(), issuer, accountID_, amount, j_);
|
||||
},
|
||||
amount.asset().value());
|
||||
!isTesSuccess(ret))
|
||||
|
||||
@@ -310,7 +310,8 @@ EscrowFinish::doApply()
|
||||
if (!sled)
|
||||
return tecNO_DST;
|
||||
|
||||
if (auto err = verifyDepositPreauth(ctx_.tx, ctx_.view(), account_, destID, sled, ctx_.journal);
|
||||
if (auto err =
|
||||
verifyDepositPreauth(ctx_.tx, ctx_.view(), accountID_, destID, sled, ctx_.journal);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
|
||||
@@ -355,7 +356,7 @@ EscrowFinish::doApply()
|
||||
? xrpl::Rate(slep->getFieldU32(sfTransferRate))
|
||||
: kParityRate;
|
||||
auto const issuer = amount.getIssuer();
|
||||
bool const createAsset = destID == account_;
|
||||
bool const createAsset = destID == accountID_;
|
||||
if (auto const ret = std::visit(
|
||||
[&]<typename T>(T const&) {
|
||||
return escrowUnlockApplyHelper<T>(
|
||||
|
||||
@@ -121,7 +121,8 @@ LoanBrokerCoverDeposit::doApply()
|
||||
auto const brokerPseudoID = broker->at(sfAccount);
|
||||
|
||||
// Transfer assets from depositor to pseudo-account.
|
||||
if (auto ter = accountSend(view(), account_, brokerPseudoID, amount, j_, WaiveTransferFee::Yes))
|
||||
if (auto ter =
|
||||
accountSend(view(), accountID_, brokerPseudoID, amount, j_, WaiveTransferFee::Yes))
|
||||
return ter;
|
||||
|
||||
// Increase the LoanBroker's CoverAvailable by Amount
|
||||
|
||||
@@ -163,7 +163,7 @@ LoanBrokerCoverWithdraw::doApply()
|
||||
|
||||
auto const brokerID = tx[sfLoanBrokerID];
|
||||
auto const amount = tx[sfAmount];
|
||||
auto const dstAcct = tx[~sfDestination].value_or(account_);
|
||||
auto const dstAcct = tx[~sfDestination].value_or(accountID_);
|
||||
|
||||
auto broker = view().peek(keylet::loanbroker(brokerID));
|
||||
if (!broker)
|
||||
@@ -183,7 +183,7 @@ LoanBrokerCoverWithdraw::doApply()
|
||||
|
||||
associateAsset(*broker, vaultAsset);
|
||||
|
||||
return doWithdraw(view(), tx, account_, dstAcct, brokerPseudoID, preFeeBalance_, amount, j_);
|
||||
return doWithdraw(view(), tx, accountID_, dstAcct, brokerPseudoID, preFeeBalance_, amount, j_);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -130,7 +130,7 @@ LoanBrokerDelete::doApply()
|
||||
auto const brokerPseudoID = broker->at(sfAccount);
|
||||
|
||||
if (!view().dirRemove(
|
||||
keylet::ownerDir(account_), broker->at(sfOwnerNode), broker->key(), false))
|
||||
keylet::ownerDir(accountID_), broker->at(sfOwnerNode), broker->key(), false))
|
||||
{
|
||||
return tefBAD_LEDGER; // LCOV_EXCL_LINE
|
||||
}
|
||||
@@ -143,7 +143,7 @@ LoanBrokerDelete::doApply()
|
||||
{
|
||||
auto const coverAvailable = STAmount{vaultAsset, broker->at(sfCoverAvailable)};
|
||||
if (auto const ter = accountSend(
|
||||
view(), brokerPseudoID, account_, coverAvailable, j_, WaiveTransferFee::Yes))
|
||||
view(), brokerPseudoID, accountID_, coverAvailable, j_, WaiveTransferFee::Yes))
|
||||
return ter;
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ LoanBrokerDelete::doApply()
|
||||
view().erase(broker);
|
||||
|
||||
{
|
||||
auto owner = view().peek(keylet::account(account_));
|
||||
auto owner = view().peek(keylet::account(accountID_));
|
||||
if (!owner)
|
||||
return tefBAD_LEDGER; // LCOV_EXCL_LINE
|
||||
|
||||
|
||||
@@ -220,7 +220,7 @@ LoanBrokerSet::doApply()
|
||||
auto const vaultAsset = sleVault->at(sfAsset);
|
||||
auto const sequence = tx.getSeqValue();
|
||||
|
||||
auto owner = view.peek(keylet::account(account_));
|
||||
auto owner = view.peek(keylet::account(accountID_));
|
||||
if (!owner)
|
||||
{
|
||||
// This should be impossible
|
||||
@@ -229,9 +229,9 @@ LoanBrokerSet::doApply()
|
||||
return tefBAD_LEDGER;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
auto broker = std::make_shared<SLE>(keylet::loanbroker(account_, sequence));
|
||||
auto broker = std::make_shared<SLE>(keylet::loanbroker(accountID_, sequence));
|
||||
|
||||
if (auto const ter = dirLink(view, account_, broker))
|
||||
if (auto const ter = dirLink(view, accountID_, broker))
|
||||
return ter; // LCOV_EXCL_LINE
|
||||
if (auto const ter = dirLink(view, vaultPseudoID, broker, sfVaultNode))
|
||||
return ter; // LCOV_EXCL_LINE
|
||||
@@ -255,7 +255,7 @@ LoanBrokerSet::doApply()
|
||||
// Initialize data fields:
|
||||
broker->at(sfSequence) = sequence;
|
||||
broker->at(sfVaultID) = vaultID;
|
||||
broker->at(sfOwner) = account_;
|
||||
broker->at(sfOwner) = accountID_;
|
||||
broker->at(sfAccount) = pseudoId;
|
||||
// The LoanSequence indexes loans created by this broker, starting at 1
|
||||
broker->at(sfLoanSequence) = 1;
|
||||
|
||||
@@ -581,13 +581,13 @@ LoanPay::doApply()
|
||||
// These three values are used to check that funds are conserved after the transfers
|
||||
auto const accountBalanceBefore = accountHolds(
|
||||
view,
|
||||
account_,
|
||||
accountID_,
|
||||
asset,
|
||||
FreezeHandling::IgnoreFreeze,
|
||||
AuthHandling::IgnoreAuth,
|
||||
j_,
|
||||
SpendableHandling::FullBalance);
|
||||
auto const vaultBalanceBefore = account_ == vaultPseudoAccount
|
||||
auto const vaultBalanceBefore = accountID_ == vaultPseudoAccount
|
||||
? STAmount{asset, 0}
|
||||
: accountHolds(
|
||||
view,
|
||||
@@ -597,15 +597,16 @@ LoanPay::doApply()
|
||||
AuthHandling::IgnoreAuth,
|
||||
j_,
|
||||
SpendableHandling::FullBalance);
|
||||
auto const brokerBalanceBefore = account_ == brokerPayee ? STAmount{asset, 0}
|
||||
: accountHolds(
|
||||
view,
|
||||
brokerPayee,
|
||||
asset,
|
||||
FreezeHandling::IgnoreFreeze,
|
||||
AuthHandling::IgnoreAuth,
|
||||
j_,
|
||||
SpendableHandling::FullBalance);
|
||||
auto const brokerBalanceBefore = accountID_ == brokerPayee
|
||||
? STAmount{asset, 0}
|
||||
: accountHolds(
|
||||
view,
|
||||
brokerPayee,
|
||||
asset,
|
||||
FreezeHandling::IgnoreFreeze,
|
||||
AuthHandling::IgnoreAuth,
|
||||
j_,
|
||||
SpendableHandling::FullBalance);
|
||||
|
||||
if (totalPaidToVaultRounded != beast::kZero)
|
||||
{
|
||||
@@ -615,7 +616,7 @@ LoanPay::doApply()
|
||||
|
||||
if (totalPaidToBroker != beast::kZero)
|
||||
{
|
||||
if (brokerPayee == account_)
|
||||
if (brokerPayee == accountID_)
|
||||
{
|
||||
// The broker may have deleted their holding. Recreate it if needed
|
||||
if (auto const ter = addEmptyHolding(
|
||||
@@ -633,7 +634,7 @@ LoanPay::doApply()
|
||||
|
||||
if (auto const ter = accountSendMulti(
|
||||
view,
|
||||
account_,
|
||||
accountID_,
|
||||
asset,
|
||||
{{vaultPseudoAccount, totalPaidToVaultRounded}, {brokerPayee, totalPaidToBroker}},
|
||||
j_,
|
||||
@@ -659,13 +660,13 @@ LoanPay::doApply()
|
||||
// Check that funds are conserved
|
||||
auto const accountBalanceAfter = accountHolds(
|
||||
view,
|
||||
account_,
|
||||
accountID_,
|
||||
asset,
|
||||
FreezeHandling::IgnoreFreeze,
|
||||
AuthHandling::IgnoreAuth,
|
||||
j_,
|
||||
SpendableHandling::FullBalance);
|
||||
auto const vaultBalanceAfter = account_ == vaultPseudoAccount
|
||||
auto const vaultBalanceAfter = accountID_ == vaultPseudoAccount
|
||||
? STAmount{asset, 0}
|
||||
: accountHolds(
|
||||
view,
|
||||
@@ -675,15 +676,15 @@ LoanPay::doApply()
|
||||
AuthHandling::IgnoreAuth,
|
||||
j_,
|
||||
SpendableHandling::FullBalance);
|
||||
auto const brokerBalanceAfter = account_ == brokerPayee ? STAmount{asset, 0}
|
||||
: accountHolds(
|
||||
view,
|
||||
brokerPayee,
|
||||
asset,
|
||||
FreezeHandling::IgnoreFreeze,
|
||||
AuthHandling::IgnoreAuth,
|
||||
j_,
|
||||
SpendableHandling::FullBalance);
|
||||
auto const brokerBalanceAfter = accountID_ == brokerPayee ? STAmount{asset, 0}
|
||||
: accountHolds(
|
||||
view,
|
||||
brokerPayee,
|
||||
asset,
|
||||
FreezeHandling::IgnoreFreeze,
|
||||
AuthHandling::IgnoreAuth,
|
||||
j_,
|
||||
SpendableHandling::FullBalance);
|
||||
auto const balanceScale = [&]() {
|
||||
// Find a reasonable scale to use for the balance comparisons.
|
||||
//
|
||||
@@ -800,7 +801,7 @@ LoanPay::doApply()
|
||||
goodRounding, "xrpl::LoanPay::doApply", "funds are conserved (with rounding)");
|
||||
|
||||
XRPL_ASSERT_PARTS(
|
||||
accountBalanceAfter < accountBalanceBefore || account_ == asset.getIssuer(),
|
||||
accountBalanceAfter < accountBalanceBefore || accountID_ == asset.getIssuer(),
|
||||
"xrpl::LoanPay::doApply",
|
||||
"account balance decreased");
|
||||
XRPL_ASSERT_PARTS(
|
||||
|
||||
@@ -388,7 +388,7 @@ LoanSet::doApply()
|
||||
Asset const vaultAsset = vaultSle->at(sfAsset);
|
||||
|
||||
auto const counterparty = tx[~sfCounterparty].value_or(brokerOwner);
|
||||
auto const borrower = counterparty == brokerOwner ? account_ : counterparty;
|
||||
auto const borrower = counterparty == brokerOwner ? accountID_ : counterparty;
|
||||
auto const borrowerSle = view.peek(keylet::account(borrower));
|
||||
if (!borrowerSle)
|
||||
{
|
||||
@@ -508,7 +508,7 @@ LoanSet::doApply()
|
||||
{
|
||||
auto const ownerCount = borrowerSle->at(sfOwnerCount);
|
||||
auto const balance =
|
||||
account_ == borrower ? preFeeBalance_ : borrowerSle->at(sfBalance).value().xrp();
|
||||
accountID_ == borrower ? preFeeBalance_ : borrowerSle->at(sfBalance).value().xrp();
|
||||
if (balance < view.fees().accountReserve(ownerCount))
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
}
|
||||
@@ -520,7 +520,7 @@ LoanSet::doApply()
|
||||
// Create a holding for the borrower if one does not already exist.
|
||||
|
||||
XRPL_ASSERT_PARTS(
|
||||
borrower == account_ || borrower == counterparty,
|
||||
borrower == accountID_ || borrower == counterparty,
|
||||
"xrpl::LoanSet::doApply",
|
||||
"borrower signed transaction");
|
||||
if (auto const ter = addEmptyHolding(
|
||||
@@ -542,7 +542,7 @@ LoanSet::doApply()
|
||||
// Create the holding if it doesn't already exist (necessary for MPTs).
|
||||
// The owner may have deleted their MPT / line at some point.
|
||||
XRPL_ASSERT_PARTS(
|
||||
brokerOwner == account_ || brokerOwner == counterparty,
|
||||
brokerOwner == accountID_ || brokerOwner == counterparty,
|
||||
"xrpl::LoanSet::doApply",
|
||||
"broker owner signed transaction");
|
||||
|
||||
|
||||
@@ -407,8 +407,8 @@ NFTokenAcceptOffer::acceptOffer(std::shared_ptr<SLE> const& offer)
|
||||
{
|
||||
bool const isSell = offer->isFlag(lsfSellNFToken);
|
||||
AccountID const owner = (*offer)[sfOwner];
|
||||
AccountID const& seller = isSell ? owner : account_;
|
||||
AccountID const& buyer = isSell ? account_ : owner;
|
||||
AccountID const& seller = isSell ? owner : accountID_;
|
||||
AccountID const& buyer = isSell ? accountID_ : owner;
|
||||
|
||||
auto const nftokenID = (*offer)[sfNFTokenID];
|
||||
|
||||
@@ -528,7 +528,7 @@ NFTokenAcceptOffer::doApply()
|
||||
// Send the broker the amount they requested.
|
||||
if (auto const cut = ctx_.tx[~sfNFTokenBrokerFee]; cut && cut.value() != beast::kZero)
|
||||
{
|
||||
if (auto const r = pay(buyer, account_, cut.value()); !isTesSuccess(r))
|
||||
if (auto const r = pay(buyer, accountID_, cut.value()); !isTesSuccess(r))
|
||||
return r;
|
||||
|
||||
amount -= cut.value();
|
||||
|
||||
@@ -222,7 +222,7 @@ NFTokenMint::preclaim(PreclaimContext const& ctx)
|
||||
TER
|
||||
NFTokenMint::doApply()
|
||||
{
|
||||
auto const issuer = ctx_.tx[~sfIssuer].value_or(account_);
|
||||
auto const issuer = ctx_.tx[~sfIssuer].value_or(accountID_);
|
||||
|
||||
auto const tokenSeq = [this, &issuer]() -> Expected<std::uint32_t, TER> {
|
||||
auto const root = view().peek(keylet::account(issuer));
|
||||
@@ -279,7 +279,7 @@ NFTokenMint::doApply()
|
||||
return (tokenSeq.error());
|
||||
|
||||
std::uint32_t const ownerCountBefore =
|
||||
view().read(keylet::account(account_))->getFieldU32(sfOwnerCount);
|
||||
view().read(keylet::account(accountID_))->getFieldU32(sfOwnerCount);
|
||||
|
||||
// Assemble the new NFToken.
|
||||
SOTemplate const* nfTokenTemplate =
|
||||
@@ -305,7 +305,7 @@ NFTokenMint::doApply()
|
||||
object.setFieldVL(sfURI, *uri);
|
||||
});
|
||||
|
||||
if (TER const ret = nft::insertToken(ctx_.view(), account_, std::move(newToken));
|
||||
if (TER const ret = nft::insertToken(ctx_.view(), accountID_, std::move(newToken));
|
||||
!isTesSuccess(ret))
|
||||
return ret;
|
||||
|
||||
@@ -333,7 +333,7 @@ NFTokenMint::doApply()
|
||||
// requiring the reserve to be met each time. The reserve is
|
||||
// only managed when a new NFT page or sell offer is added.
|
||||
if (auto const ownerCountAfter =
|
||||
view().read(keylet::account(account_))->getFieldU32(sfOwnerCount);
|
||||
view().read(keylet::account(accountID_))->getFieldU32(sfOwnerCount);
|
||||
ownerCountAfter > ownerCountBefore)
|
||||
{
|
||||
if (auto const reserve = view().fees().accountReserve(ownerCountAfter);
|
||||
|
||||
@@ -82,8 +82,8 @@ OracleDelete::deleteOracle(
|
||||
TER
|
||||
OracleDelete::doApply()
|
||||
{
|
||||
if (auto sle = ctx_.view().peek(keylet::oracle(account_, ctx_.tx[sfOracleDocumentID])))
|
||||
return deleteOracle(ctx_.view(), sle, account_, j_);
|
||||
if (auto sle = ctx_.view().peek(keylet::oracle(accountID_, ctx_.tx[sfOracleDocumentID])))
|
||||
return deleteOracle(ctx_.view(), sle, accountID_, j_);
|
||||
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
}
|
||||
|
||||
@@ -201,7 +201,7 @@ setPriceDataInnerObjTemplate(STObject& obj)
|
||||
TER
|
||||
OracleSet::doApply()
|
||||
{
|
||||
auto const oracleID = keylet::oracle(account_, ctx_.tx[sfOracleDocumentID]);
|
||||
auto const oracleID = keylet::oracle(accountID_, ctx_.tx[sfOracleDocumentID]);
|
||||
|
||||
auto populatePriceData = [](STObject& priceData, STObject const& entry) {
|
||||
setPriceDataInnerObjTemplate(priceData);
|
||||
@@ -311,7 +311,7 @@ OracleSet::doApply()
|
||||
sle->setFieldU32(sfLastUpdateTime, ctx_.tx[sfLastUpdateTime]);
|
||||
|
||||
auto page = ctx_.view().dirInsert(
|
||||
keylet::ownerDir(account_), sle->key(), describeOwnerDir(account_));
|
||||
keylet::ownerDir(accountID_), sle->key(), describeOwnerDir(accountID_));
|
||||
if (!page)
|
||||
return tecDIR_FULL; // LCOV_EXCL_LINE
|
||||
|
||||
|
||||
@@ -153,7 +153,7 @@ DepositPreauth::doApply()
|
||||
{
|
||||
if (ctx_.tx.isFieldPresent(sfAuthorize))
|
||||
{
|
||||
auto const sleOwner = view().peek(keylet::account(account_));
|
||||
auto const sleOwner = view().peek(keylet::account(accountID_));
|
||||
if (!sleOwner)
|
||||
return {tefINTERNAL};
|
||||
|
||||
@@ -171,15 +171,15 @@ DepositPreauth::doApply()
|
||||
// Preclaim already verified that the Preauth entry does not yet exist.
|
||||
// Create and populate the Preauth entry.
|
||||
AccountID const auth{ctx_.tx[sfAuthorize]};
|
||||
Keylet const preauthKeylet = keylet::depositPreauth(account_, auth);
|
||||
Keylet const preauthKeylet = keylet::depositPreauth(accountID_, auth);
|
||||
auto slePreauth = std::make_shared<SLE>(preauthKeylet);
|
||||
|
||||
slePreauth->setAccountID(sfAccount, account_);
|
||||
slePreauth->setAccountID(sfAccount, accountID_);
|
||||
slePreauth->setAccountID(sfAuthorize, auth);
|
||||
view().insert(slePreauth);
|
||||
|
||||
auto const page =
|
||||
view().dirInsert(keylet::ownerDir(account_), preauthKeylet, describeOwnerDir(account_));
|
||||
auto const page = view().dirInsert(
|
||||
keylet::ownerDir(accountID_), preauthKeylet, describeOwnerDir(accountID_));
|
||||
|
||||
JLOG(j_.trace()) << "Adding DepositPreauth to owner directory "
|
||||
<< to_string(preauthKeylet.key) << ": " << (page ? "success" : "failure");
|
||||
@@ -194,13 +194,13 @@ DepositPreauth::doApply()
|
||||
}
|
||||
else if (ctx_.tx.isFieldPresent(sfUnauthorize))
|
||||
{
|
||||
auto const preauth = keylet::depositPreauth(account_, ctx_.tx[sfUnauthorize]);
|
||||
auto const preauth = keylet::depositPreauth(accountID_, ctx_.tx[sfUnauthorize]);
|
||||
|
||||
return DepositPreauth::removeFromLedger(view(), preauth.key, j_);
|
||||
}
|
||||
else if (ctx_.tx.isFieldPresent(sfAuthorizeCredentials))
|
||||
{
|
||||
auto const sleOwner = view().peek(keylet::account(account_));
|
||||
auto const sleOwner = view().peek(keylet::account(accountID_));
|
||||
if (!sleOwner)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -229,18 +229,18 @@ DepositPreauth::doApply()
|
||||
sortedLE.pushBack(std::move(cred));
|
||||
}
|
||||
|
||||
Keylet const preauthKey = keylet::depositPreauth(account_, sortedTX);
|
||||
Keylet const preauthKey = keylet::depositPreauth(accountID_, sortedTX);
|
||||
auto slePreauth = std::make_shared<SLE>(preauthKey);
|
||||
if (!slePreauth)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
slePreauth->setAccountID(sfAccount, account_);
|
||||
slePreauth->setAccountID(sfAccount, accountID_);
|
||||
slePreauth->peekFieldArray(sfAuthorizeCredentials) = std::move(sortedLE);
|
||||
|
||||
view().insert(slePreauth);
|
||||
|
||||
auto const page =
|
||||
view().dirInsert(keylet::ownerDir(account_), preauthKey, describeOwnerDir(account_));
|
||||
auto const page = view().dirInsert(
|
||||
keylet::ownerDir(accountID_), preauthKey, describeOwnerDir(accountID_));
|
||||
|
||||
JLOG(j_.trace()) << "Adding DepositPreauth to owner directory " << to_string(preauthKey.key)
|
||||
<< ": " << (page ? "success" : "failure");
|
||||
@@ -256,7 +256,7 @@ DepositPreauth::doApply()
|
||||
else if (ctx_.tx.isFieldPresent(sfUnauthorizeCredentials))
|
||||
{
|
||||
auto const preauthKey = keylet::depositPreauth(
|
||||
account_, credentials::makeSorted(ctx_.tx.getFieldArray(sfUnauthorizeCredentials)));
|
||||
accountID_, credentials::makeSorted(ctx_.tx.getFieldArray(sfUnauthorizeCredentials)));
|
||||
return DepositPreauth::removeFromLedger(view(), preauthKey.key, j_);
|
||||
}
|
||||
|
||||
|
||||
@@ -410,7 +410,7 @@ Payment::doApply()
|
||||
AccountID const dstAccountID(ctx_.tx.getAccountID(sfDestination));
|
||||
STAmount const dstAmount(ctx_.tx.getFieldAmount(sfAmount));
|
||||
bool const isDstMPT = dstAmount.holds<MPTIssue>();
|
||||
STAmount const maxSourceAmount = getMaxSourceAmount(account_, dstAmount, sendMax);
|
||||
STAmount const maxSourceAmount = getMaxSourceAmount(accountID_, dstAmount, sendMax);
|
||||
|
||||
JLOG(j_.trace()) << "maxSourceAmount=" << maxSourceAmount.getFullText()
|
||||
<< " dstAmount=" << dstAmount.getFullText();
|
||||
@@ -453,7 +453,7 @@ Payment::doApply()
|
||||
// 2. If Account is deposit preauthorized by destination.
|
||||
|
||||
if (auto err = verifyDepositPreauth(
|
||||
ctx_.tx, ctx_.view(), account_, dstAccountID, sleDst, ctx_.journal);
|
||||
ctx_.tx, ctx_.view(), accountID_, dstAccountID, sleDst, ctx_.journal);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
|
||||
@@ -472,7 +472,7 @@ Payment::doApply()
|
||||
maxSourceAmount,
|
||||
dstAmount,
|
||||
dstAccountID,
|
||||
account_,
|
||||
accountID_,
|
||||
ctx_.tx.getFieldPathSet(sfPaths),
|
||||
ctx_.tx[~sfDomainID],
|
||||
ctx_.registry,
|
||||
@@ -512,18 +512,18 @@ Payment::doApply()
|
||||
JLOG(j_.trace()) << " dstAmount=" << dstAmount.getFullText();
|
||||
auto const& mptIssue = dstAmount.get<MPTIssue>();
|
||||
|
||||
if (auto const ter = requireAuth(view(), mptIssue, account_); !isTesSuccess(ter))
|
||||
if (auto const ter = requireAuth(view(), mptIssue, accountID_); !isTesSuccess(ter))
|
||||
return ter;
|
||||
|
||||
if (auto const ter = requireAuth(view(), mptIssue, dstAccountID); !isTesSuccess(ter))
|
||||
return ter;
|
||||
|
||||
if (auto const ter = canTransfer(view(), mptIssue, account_, dstAccountID);
|
||||
if (auto const ter = canTransfer(view(), mptIssue, accountID_, dstAccountID);
|
||||
!isTesSuccess(ter))
|
||||
return ter;
|
||||
|
||||
if (auto err = verifyDepositPreauth(
|
||||
ctx_.tx, ctx_.view(), account_, dstAccountID, sleDst, ctx_.journal);
|
||||
ctx_.tx, ctx_.view(), accountID_, dstAccountID, sleDst, ctx_.journal);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
|
||||
@@ -532,13 +532,13 @@ Payment::doApply()
|
||||
// Transfer rate
|
||||
Rate rate{QUALITY_ONE};
|
||||
// Payment between the holders
|
||||
if (account_ != issuer && dstAccountID != issuer)
|
||||
if (accountID_ != issuer && dstAccountID != issuer)
|
||||
{
|
||||
// If globally/individually locked then
|
||||
// - can't send between holders
|
||||
// - holder can send back to issuer
|
||||
// - issuer can send to holder
|
||||
if (isAnyFrozen(view(), {account_, dstAccountID}, mptIssue))
|
||||
if (isAnyFrozen(view(), {accountID_, dstAccountID}, mptIssue))
|
||||
return tecLOCKED;
|
||||
|
||||
// Get the rate for a payment between the holders.
|
||||
@@ -566,7 +566,7 @@ Payment::doApply()
|
||||
return tecPATH_PARTIAL;
|
||||
|
||||
PaymentSandbox pv(&view());
|
||||
auto res = accountSend(pv, account_, dstAccountID, amountDeliver, ctx_.journal);
|
||||
auto res = accountSend(pv, accountID_, dstAccountID, amountDeliver, ctx_.journal);
|
||||
if (isTesSuccess(res))
|
||||
{
|
||||
pv.apply(ctx_.rawView());
|
||||
@@ -589,7 +589,7 @@ Payment::doApply()
|
||||
|
||||
// Direct XRP payment.
|
||||
|
||||
auto const sleSrc = view().peek(keylet::account(account_));
|
||||
auto const sleSrc = view().peek(keylet::account(accountID_));
|
||||
if (!sleSrc)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -601,10 +601,10 @@ Payment::doApply()
|
||||
auto const reserve = view().fees().accountReserve(ownerCount);
|
||||
|
||||
// In a delegated payment, the fee payer is the delegated account,
|
||||
// not the source account (account_).
|
||||
bool const accountIsPayer = (ctx_.tx.getFeePayer() == account_);
|
||||
// not the source account (accountID_).
|
||||
bool const accountIsPayer = (ctx_.tx.getFeePayer() == accountID_);
|
||||
|
||||
// preFeeBalance_ is the balance on the source account (account_) BEFORE the fees
|
||||
// preFeeBalance_ is the balance on the source account (accountID_) BEFORE the fees
|
||||
// were charged. If source account is the fee payer, it must also cover the fee.
|
||||
// The final spend may use the reserve to cover fees.
|
||||
auto const minRequiredFunds =
|
||||
@@ -656,7 +656,7 @@ Payment::doApply()
|
||||
if (dstAmount > dstReserve || sleDst->getFieldAmount(sfBalance) > dstReserve)
|
||||
{
|
||||
if (auto err = verifyDepositPreauth(
|
||||
ctx_.tx, ctx_.view(), account_, dstAccountID, sleDst, ctx_.journal);
|
||||
ctx_.tx, ctx_.view(), accountID_, dstAccountID, sleDst, ctx_.journal);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ PermissionedDomainDelete::doApply()
|
||||
auto const slePd = view().peek(keylet::permissionedDomain(ctx_.tx.at(sfDomainID)));
|
||||
auto const page = (*slePd)[sfOwnerNode];
|
||||
|
||||
if (!view().dirRemove(keylet::ownerDir(account_), page, slePd->key(), true))
|
||||
if (!view().dirRemove(keylet::ownerDir(accountID_), page, slePd->key(), true))
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
JLOG(j_.fatal()) << "Unable to delete permissioned domain directory entry.";
|
||||
@@ -63,7 +63,7 @@ PermissionedDomainDelete::doApply()
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
auto const ownerSle = view().peek(keylet::account(account_));
|
||||
auto const ownerSle = view().peek(keylet::account(accountID_));
|
||||
XRPL_ASSERT(
|
||||
ownerSle && ownerSle->getFieldU32(sfOwnerCount) > 0,
|
||||
"xrpl::PermissionedDomainDelete::doApply : nonzero owner count");
|
||||
|
||||
@@ -77,7 +77,7 @@ PermissionedDomainSet::preclaim(PreclaimContext const& ctx)
|
||||
TER
|
||||
PermissionedDomainSet::doApply()
|
||||
{
|
||||
auto const ownerSle = view().peek(keylet::account(account_));
|
||||
auto const ownerSle = view().peek(keylet::account(accountID_));
|
||||
if (!ownerSle)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -112,14 +112,14 @@ PermissionedDomainSet::doApply()
|
||||
|
||||
bool const fixEnabled = view().rules().enabled(fixCleanup3_1_3);
|
||||
auto const seq = fixEnabled ? ctx_.tx.getSeqValue() : ctx_.tx.getFieldU32(sfSequence);
|
||||
Keylet const pdKeylet = keylet::permissionedDomain(account_, seq);
|
||||
Keylet const pdKeylet = keylet::permissionedDomain(accountID_, seq);
|
||||
auto slePd = std::make_shared<SLE>(pdKeylet);
|
||||
|
||||
slePd->setAccountID(sfOwner, account_);
|
||||
slePd->setAccountID(sfOwner, accountID_);
|
||||
slePd->setFieldU32(sfSequence, seq);
|
||||
slePd->peekFieldArray(sfAcceptedCredentials) = std::move(sortedLE);
|
||||
auto const page =
|
||||
view().dirInsert(keylet::ownerDir(account_), pdKeylet, describeOwnerDir(account_));
|
||||
view().dirInsert(keylet::ownerDir(accountID_), pdKeylet, describeOwnerDir(accountID_));
|
||||
if (!page)
|
||||
return tecDIR_FULL; // LCOV_EXCL_LINE
|
||||
|
||||
|
||||
@@ -154,7 +154,7 @@ Change::doApply()
|
||||
void
|
||||
Change::preCompute()
|
||||
{
|
||||
XRPL_ASSERT(account_ == beast::kZero, "xrpl::Change::preCompute : zero account");
|
||||
XRPL_ASSERT(accountID_ == beast::kZero, "xrpl::Change::preCompute : zero account");
|
||||
}
|
||||
|
||||
TER
|
||||
|
||||
@@ -67,7 +67,7 @@ TicketCreate::preclaim(PreclaimContext const& ctx)
|
||||
TER
|
||||
TicketCreate::doApply()
|
||||
{
|
||||
SLE::pointer const sleAccountRoot = view().peek(keylet::account(account_));
|
||||
SLE::pointer const sleAccountRoot = view().peek(keylet::account(accountID_));
|
||||
if (!sleAccountRoot)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -100,15 +100,15 @@ TicketCreate::doApply()
|
||||
for (std::uint32_t i = 0; i < ticketCount; ++i)
|
||||
{
|
||||
std::uint32_t const curTicketSeq = firstTicketSeq + i;
|
||||
Keylet const ticketKeylet = keylet::kTicket(account_, curTicketSeq);
|
||||
Keylet const ticketKeylet = keylet::kTicket(accountID_, curTicketSeq);
|
||||
SLE::pointer const sleTicket = std::make_shared<SLE>(ticketKeylet);
|
||||
|
||||
sleTicket->setAccountID(sfAccount, account_);
|
||||
sleTicket->setAccountID(sfAccount, accountID_);
|
||||
sleTicket->setFieldU32(sfTicketSequence, curTicketSeq);
|
||||
view().insert(sleTicket);
|
||||
|
||||
auto const page =
|
||||
view().dirInsert(keylet::ownerDir(account_), ticketKeylet, describeOwnerDir(account_));
|
||||
auto const page = view().dirInsert(
|
||||
keylet::ownerDir(accountID_), ticketKeylet, describeOwnerDir(accountID_));
|
||||
|
||||
JLOG(j_.trace()) << "Creating ticket " << to_string(ticketKeylet.key) << ": "
|
||||
<< (page ? "success" : "failure");
|
||||
|
||||
@@ -148,7 +148,7 @@ MPTokenAuthorize::doApply()
|
||||
ctx_.view(),
|
||||
preFeeBalance_,
|
||||
tx[sfMPTokenIssuanceID],
|
||||
account_,
|
||||
accountID_,
|
||||
ctx_.journal,
|
||||
tx.getFlags(),
|
||||
tx[~sfHolder]);
|
||||
|
||||
@@ -159,7 +159,7 @@ MPTokenIssuanceCreate::doApply()
|
||||
j_,
|
||||
{
|
||||
.priorBalance = preFeeBalance_,
|
||||
.account = account_,
|
||||
.account = accountID_,
|
||||
.sequence = tx.getSeqValue(),
|
||||
.flags = tx.getFlags(),
|
||||
.maxAmount = tx[~sfMaximumAmount],
|
||||
|
||||
@@ -45,15 +45,15 @@ TER
|
||||
MPTokenIssuanceDestroy::doApply()
|
||||
{
|
||||
auto const mpt = view().peek(keylet::mptIssuance(ctx_.tx[sfMPTokenIssuanceID]));
|
||||
if (account_ != mpt->getAccountID(sfIssuer))
|
||||
if (accountID_ != mpt->getAccountID(sfIssuer))
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
if (!view().dirRemove(keylet::ownerDir(account_), (*mpt)[sfOwnerNode], mpt->key(), false))
|
||||
if (!view().dirRemove(keylet::ownerDir(accountID_), (*mpt)[sfOwnerNode], mpt->key(), false))
|
||||
return tefBAD_LEDGER; // LCOV_EXCL_LINE
|
||||
|
||||
view().erase(mpt);
|
||||
|
||||
adjustOwnerCount(view(), view().peek(keylet::account(account_)), -1, j_);
|
||||
adjustOwnerCount(view(), view().peek(keylet::account(accountID_)), -1, j_);
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
@@ -336,9 +336,9 @@ TrustSet::doApply()
|
||||
AccountID const uDstAccountID(saLimitAmount.getIssuer());
|
||||
|
||||
// true, if current is high account.
|
||||
bool const bHigh = account_ > uDstAccountID;
|
||||
bool const bHigh = accountID_ > uDstAccountID;
|
||||
|
||||
auto const sle = view().peek(keylet::account(account_));
|
||||
auto const sle = view().peek(keylet::account(accountID_));
|
||||
if (!sle)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -391,10 +391,10 @@ TrustSet::doApply()
|
||||
}
|
||||
|
||||
STAmount saLimitAllow = saLimitAmount;
|
||||
saLimitAllow.get<Issue>().account = account_;
|
||||
saLimitAllow.get<Issue>().account = accountID_;
|
||||
|
||||
SLE::pointer const sleRippleState =
|
||||
view().peek(keylet::line(account_, uDstAccountID, currency));
|
||||
view().peek(keylet::line(accountID_, uDstAccountID, currency));
|
||||
|
||||
if (sleRippleState)
|
||||
{
|
||||
@@ -406,8 +406,8 @@ TrustSet::doApply()
|
||||
std::uint32_t uLowQualityOut = 0;
|
||||
std::uint32_t uHighQualityIn = 0;
|
||||
std::uint32_t uHighQualityOut = 0;
|
||||
auto const& uLowAccountID = !bHigh ? account_ : uDstAccountID;
|
||||
auto const& uHighAccountID = bHigh ? account_ : uDstAccountID;
|
||||
auto const& uLowAccountID = !bHigh ? accountID_ : uDstAccountID;
|
||||
auto const& uHighAccountID = bHigh ? accountID_ : uDstAccountID;
|
||||
SLE::ref sleLowAccount = !bHigh ? sle : sleDst;
|
||||
SLE::ref sleHighAccount = bHigh ? sle : sleDst;
|
||||
|
||||
@@ -642,7 +642,7 @@ TrustSet::doApply()
|
||||
// Zero balance in currency.
|
||||
STAmount const saBalance(Issue{currency, noAccount()});
|
||||
|
||||
auto const k = keylet::line(account_, uDstAccountID, currency);
|
||||
auto const k = keylet::line(accountID_, uDstAccountID, currency);
|
||||
|
||||
JLOG(j_.trace()) << "doTrustSet: Creating ripple line: " << to_string(k.key);
|
||||
|
||||
@@ -650,7 +650,7 @@ TrustSet::doApply()
|
||||
terResult = trustCreate(
|
||||
view(),
|
||||
bHigh,
|
||||
account_,
|
||||
accountID_,
|
||||
uDstAccountID,
|
||||
k.key,
|
||||
sle,
|
||||
|
||||
@@ -349,7 +349,7 @@ VaultClawback::doApply()
|
||||
MPTIssue const share{mptIssuanceID};
|
||||
|
||||
Asset const vaultAsset = vault->at(sfAsset);
|
||||
STAmount const amount = clawbackAmount(vault, tx[~sfAmount], account_);
|
||||
STAmount const amount = clawbackAmount(vault, tx[~sfAmount], accountID_);
|
||||
|
||||
auto assetsAvailable = vault->at(sfAssetsAvailable);
|
||||
auto assetsTotal = vault->at(sfAssetsTotal);
|
||||
@@ -364,7 +364,7 @@ VaultClawback::doApply()
|
||||
STAmount assetsRecovered = {vault->at(sfAsset)};
|
||||
|
||||
// The Owner is burning shares
|
||||
if (account_ == vault->at(sfOwner) && amount.asset() == share)
|
||||
if (accountID_ == vault->at(sfOwner) && amount.asset() == share)
|
||||
{
|
||||
sharesDestroyed = accountHolds(
|
||||
view(), holder, share, FreezeHandling::IgnoreFreeze, AuthHandling::IgnoreAuth, j_);
|
||||
@@ -426,7 +426,7 @@ VaultClawback::doApply()
|
||||
{
|
||||
// Transfer assets from vault to issuer.
|
||||
if (auto const ter = accountSend(
|
||||
view(), vaultAccount, account_, assetsRecovered, j_, WaiveTransferFee::Yes);
|
||||
view(), vaultAccount, accountID_, assetsRecovered, j_, WaiveTransferFee::Yes);
|
||||
!isTesSuccess(ter))
|
||||
return ter;
|
||||
|
||||
|
||||
@@ -145,13 +145,13 @@ VaultCreate::doApply()
|
||||
|
||||
auto const& tx = ctx_.tx;
|
||||
auto const sequence = tx.getSeqValue();
|
||||
auto const owner = view().peek(keylet::account(account_));
|
||||
auto const owner = view().peek(keylet::account(accountID_));
|
||||
if (owner == nullptr)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
auto vault = std::make_shared<SLE>(keylet::vault(account_, sequence));
|
||||
auto vault = std::make_shared<SLE>(keylet::vault(accountID_, sequence));
|
||||
|
||||
if (auto ter = dirLink(view(), account_, vault))
|
||||
if (auto ter = dirLink(view(), accountID_, vault))
|
||||
return ter;
|
||||
// We will create Vault and PseudoAccount, hence increase OwnerCount by 2
|
||||
adjustOwnerCount(view(), owner, 2, j_);
|
||||
@@ -204,7 +204,7 @@ VaultCreate::doApply()
|
||||
vault->setFieldIssue(sfAsset, STIssue{sfAsset, asset});
|
||||
vault->at(sfFlags) = tx.getFlags() & tfVaultPrivate;
|
||||
vault->at(sfSequence) = sequence;
|
||||
vault->at(sfOwner) = account_;
|
||||
vault->at(sfOwner) = accountID_;
|
||||
vault->at(sfAccount) = pseudoId;
|
||||
vault->at(sfAssetsTotal) = Number(0);
|
||||
vault->at(sfAssetsAvailable) = Number(0);
|
||||
@@ -230,7 +230,7 @@ VaultCreate::doApply()
|
||||
|
||||
// Explicitly create MPToken for the vault owner
|
||||
if (auto const err =
|
||||
authorizeMPToken(view(), preFeeBalance_, mptIssuanceID, account_, ctx_.journal);
|
||||
authorizeMPToken(view(), preFeeBalance_, mptIssuanceID, accountID_, ctx_.journal);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
|
||||
@@ -238,7 +238,7 @@ VaultCreate::doApply()
|
||||
if (tx.isFlag(tfVaultPrivate))
|
||||
{
|
||||
if (auto const err = authorizeMPToken(
|
||||
view(), preFeeBalance_, mptIssuanceID, pseudoId, ctx_.journal, {}, account_);
|
||||
view(), preFeeBalance_, mptIssuanceID, pseudoId, ctx_.journal, {}, accountID_);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -122,16 +122,16 @@ VaultDelete::doApply()
|
||||
}
|
||||
|
||||
// Try to remove MPToken for vault shares for the vault owner if it exists.
|
||||
if (auto const mptoken = view().peek(keylet::mptoken(shareMPTID, account_)))
|
||||
if (auto const mptoken = view().peek(keylet::mptoken(shareMPTID, accountID_)))
|
||||
{
|
||||
if (auto const ter = removeEmptyHolding(view(), account_, MPTIssue(shareMPTID), j_);
|
||||
if (auto const ter = removeEmptyHolding(view(), accountID_, MPTIssue(shareMPTID), j_);
|
||||
!isTesSuccess(ter))
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
JLOG(j_.error()) //
|
||||
<< "VaultDelete: failed to remove vault owner's MPToken"
|
||||
<< " MPTID=" << to_string(shareMPTID) //
|
||||
<< " account=" << toBase58(account_) //
|
||||
<< " MPTID=" << to_string(shareMPTID) //
|
||||
<< " account=" << toBase58(accountID_) //
|
||||
<< " with result: " << transToken(ter);
|
||||
return ter;
|
||||
// LCOV_EXCL_STOP
|
||||
|
||||
@@ -156,20 +156,20 @@ VaultDeposit::doApply()
|
||||
|
||||
auto const& vaultAccount = vault->at(sfAccount);
|
||||
// Note, vault owner is always authorized
|
||||
if (vault->isFlag(lsfVaultPrivate) && account_ != vault->at(sfOwner))
|
||||
if (vault->isFlag(lsfVaultPrivate) && accountID_ != vault->at(sfOwner))
|
||||
{
|
||||
if (auto const err = enforceMPTokenAuthorization(
|
||||
ctx_.view(), mptIssuanceID, account_, preFeeBalance_, j_);
|
||||
ctx_.view(), mptIssuanceID, accountID_, preFeeBalance_, j_);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
}
|
||||
else // !vault->isFlag(lsfVaultPrivate) || account_ == vault->at(sfOwner)
|
||||
else // !vault->isFlag(lsfVaultPrivate) || accountID_ == vault->at(sfOwner)
|
||||
{
|
||||
// No authorization needed, but must ensure there is MPToken
|
||||
if (!view().exists(keylet::mptoken(mptIssuanceID, account_)))
|
||||
if (!view().exists(keylet::mptoken(mptIssuanceID, accountID_)))
|
||||
{
|
||||
if (auto const err = authorizeMPToken(
|
||||
view(), preFeeBalance_, mptIssuanceID->value(), account_, ctx_.journal);
|
||||
view(), preFeeBalance_, mptIssuanceID->value(), accountID_, ctx_.journal);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
}
|
||||
@@ -179,15 +179,15 @@ VaultDeposit::doApply()
|
||||
{
|
||||
// This follows from the reverse of the outer enclosing if condition
|
||||
XRPL_ASSERT(
|
||||
account_ == vault->at(sfOwner), "xrpl::VaultDeposit::doApply : account is owner");
|
||||
accountID_ == vault->at(sfOwner), "xrpl::VaultDeposit::doApply : account is owner");
|
||||
if (auto const err = authorizeMPToken(
|
||||
view(),
|
||||
preFeeBalance_, // priorBalance
|
||||
mptIssuanceID->value(), // mptIssuanceID
|
||||
sleIssuance->at(sfIssuer), // account
|
||||
ctx_.journal,
|
||||
{}, // flags
|
||||
account_ // holderID
|
||||
{}, // flags
|
||||
accountID_ // holderID
|
||||
);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
@@ -247,15 +247,15 @@ VaultDeposit::doApply()
|
||||
return tecLIMIT_EXCEEDED;
|
||||
|
||||
// Transfer assets from depositor to vault.
|
||||
if (auto const ter =
|
||||
accountSend(view(), account_, vaultAccount, assetsDeposited, j_, WaiveTransferFee::Yes);
|
||||
if (auto const ter = accountSend(
|
||||
view(), accountID_, vaultAccount, assetsDeposited, j_, WaiveTransferFee::Yes);
|
||||
!isTesSuccess(ter))
|
||||
return ter;
|
||||
|
||||
// Sanity check
|
||||
if (accountHolds(
|
||||
view(),
|
||||
account_,
|
||||
accountID_,
|
||||
assetsDeposited.asset(),
|
||||
FreezeHandling::IgnoreFreeze,
|
||||
AuthHandling::IgnoreAuth,
|
||||
@@ -269,7 +269,7 @@ VaultDeposit::doApply()
|
||||
|
||||
// Transfer shares from vault to depositor.
|
||||
if (auto const ter =
|
||||
accountSend(view(), vaultAccount, account_, sharesCreated, j_, WaiveTransferFee::Yes);
|
||||
accountSend(view(), vaultAccount, accountID_, sharesCreated, j_, WaiveTransferFee::Yes);
|
||||
!isTesSuccess(ter))
|
||||
return ter;
|
||||
|
||||
|
||||
@@ -222,7 +222,7 @@ VaultWithdraw::doApply()
|
||||
}
|
||||
|
||||
if (accountHolds(
|
||||
view(), account_, share, FreezeHandling::ZeroIfFrozen, AuthHandling::IgnoreAuth, j_) <
|
||||
view(), accountID_, share, FreezeHandling::ZeroIfFrozen, AuthHandling::IgnoreAuth, j_) <
|
||||
sharesRedeemed)
|
||||
{
|
||||
JLOG(j_.debug()) << "VaultWithdraw: account doesn't hold enough shares";
|
||||
@@ -251,23 +251,23 @@ VaultWithdraw::doApply()
|
||||
|
||||
auto const& vaultAccount = vault->at(sfAccount);
|
||||
// Transfer shares from depositor to vault.
|
||||
if (auto const ter =
|
||||
accountSend(view(), account_, vaultAccount, sharesRedeemed, j_, WaiveTransferFee::Yes);
|
||||
if (auto const ter = accountSend(
|
||||
view(), accountID_, vaultAccount, sharesRedeemed, j_, WaiveTransferFee::Yes);
|
||||
!isTesSuccess(ter))
|
||||
return ter;
|
||||
|
||||
// Try to remove MPToken for shares, if the account balance is zero. Vault
|
||||
// pseudo-account will never set lsfMPTAuthorized, so we ignore flags.
|
||||
// Keep MPToken if holder is the vault owner.
|
||||
if (account_ != vault->at(sfOwner))
|
||||
if (accountID_ != vault->at(sfOwner))
|
||||
{
|
||||
if (auto const ter = removeEmptyHolding(view(), account_, sharesRedeemed.asset(), j_);
|
||||
if (auto const ter = removeEmptyHolding(view(), accountID_, sharesRedeemed.asset(), j_);
|
||||
isTesSuccess(ter))
|
||||
{
|
||||
JLOG(j_.debug()) //
|
||||
<< "VaultWithdraw: removed empty MPToken for vault shares"
|
||||
<< " MPTID=" << to_string(mptIssuanceID) //
|
||||
<< " account=" << toBase58(account_);
|
||||
<< " account=" << toBase58(accountID_);
|
||||
}
|
||||
else if (ter != tecHAS_OBLIGATIONS)
|
||||
{
|
||||
@@ -275,7 +275,7 @@ VaultWithdraw::doApply()
|
||||
JLOG(j_.error()) //
|
||||
<< "VaultWithdraw: failed to remove MPToken for vault shares"
|
||||
<< " MPTID=" << to_string(mptIssuanceID) //
|
||||
<< " account=" << toBase58(account_) //
|
||||
<< " account=" << toBase58(accountID_) //
|
||||
<< " with result: " << transToken(ter);
|
||||
return ter;
|
||||
// LCOV_EXCL_STOP
|
||||
@@ -283,12 +283,12 @@ VaultWithdraw::doApply()
|
||||
// else quietly ignore, account balance is not zero
|
||||
}
|
||||
|
||||
auto const dstAcct = ctx_.tx[~sfDestination].value_or(account_);
|
||||
auto const dstAcct = ctx_.tx[~sfDestination].value_or(accountID_);
|
||||
|
||||
associateAsset(*vault, vaultAsset);
|
||||
|
||||
return doWithdraw(
|
||||
view(), ctx_.tx, account_, dstAcct, vaultAccount, preFeeBalance_, assetsWithdrawn, j_);
|
||||
view(), ctx_.tx, accountID_, dstAcct, vaultAccount, preFeeBalance_, assetsWithdrawn, j_);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -886,6 +886,70 @@ struct EscrowToken_test : public beast::unit_test::Suite
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testIOUCancelDoApply(FeatureBitset features)
|
||||
{
|
||||
testcase("IOU Cancel DoApply");
|
||||
using namespace jtx;
|
||||
using namespace std::literals;
|
||||
|
||||
{
|
||||
Env env{*this, features};
|
||||
auto const baseFee = env.current()->fees().base;
|
||||
auto const alice = Account("alice");
|
||||
auto const bob = Account("bob");
|
||||
auto const gw = Account("gw");
|
||||
auto const usd = gw["USD"];
|
||||
|
||||
env.fund(XRP(10'000), alice, bob, gw);
|
||||
env.close();
|
||||
|
||||
env(fset(gw, asfAllowTrustLineLocking));
|
||||
env.close();
|
||||
|
||||
env.trust(usd(100'000), alice);
|
||||
env.trust(usd(100'000), bob);
|
||||
env.close();
|
||||
|
||||
env(pay(gw, alice, usd(10'000)));
|
||||
env.close();
|
||||
|
||||
auto const seq = env.seq(alice);
|
||||
env(escrow::create(alice, bob, usd(1'000)),
|
||||
escrow::kFinishTime(env.now() + 1s),
|
||||
escrow::kCancelTime(env.now() + 2s),
|
||||
Fee(baseFee));
|
||||
env.close();
|
||||
|
||||
BEAST_EXPECT(env.balance(alice, usd) == usd(9'000));
|
||||
|
||||
env(pay(alice, gw, usd(9'000)));
|
||||
env.close();
|
||||
|
||||
env(trust(alice, usd(0)));
|
||||
env.close();
|
||||
|
||||
auto const trustLineKey = keylet::line(alice.id(), gw.id(), usd.currency);
|
||||
BEAST_EXPECT(!env.current()->exists(trustLineKey));
|
||||
|
||||
env.close();
|
||||
env.close();
|
||||
|
||||
auto const expectedResult = env.current()->rules().enabled(fixCleanup3_2_0)
|
||||
? Ter(tesSUCCESS)
|
||||
: Ter(tefEXCEPTION);
|
||||
env(escrow::cancel(alice, alice, seq), Fee(baseFee), expectedResult);
|
||||
env.close();
|
||||
|
||||
if (env.current()->rules().enabled(fixCleanup3_2_0))
|
||||
{
|
||||
BEAST_EXPECT(!env.le(keylet::escrow(alice.id(), seq)));
|
||||
BEAST_EXPECT(env.current()->exists(trustLineKey));
|
||||
BEAST_EXPECT(env.balance(alice, usd) == usd(1'000));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testIOUBalances(FeatureBitset features)
|
||||
{
|
||||
@@ -3886,6 +3950,7 @@ struct EscrowToken_test : public beast::unit_test::Suite
|
||||
testIOUFinishPreclaim(features);
|
||||
testIOUFinishDoApply(features);
|
||||
testIOUCancelPreclaim(features);
|
||||
testIOUCancelDoApply(features);
|
||||
testIOUBalances(features);
|
||||
testIOUMetaAndOwnership(features);
|
||||
testIOURippleState(features);
|
||||
@@ -3927,6 +3992,7 @@ public:
|
||||
{all - featureSingleAssetVault - featureLendingProtocol, all})
|
||||
{
|
||||
testIOUWithFeats(feats);
|
||||
testIOUWithFeats(feats - fixCleanup3_2_0);
|
||||
testMPTWithFeats(feats);
|
||||
testMPTWithFeats(feats - fixTokenEscrowV1);
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ private:
|
||||
"http://207.261.33.37:8080/validators",
|
||||
"https://ripple.com/validators",
|
||||
"https://ripple.com:443/validators",
|
||||
"file:///etc/opt/xrpld/validators.txt",
|
||||
"file:///etc/xrpld/validators.txt",
|
||||
"file:///C:/Lib/validators.txt"
|
||||
#if !_MSC_VER
|
||||
,
|
||||
|
||||
@@ -372,8 +372,8 @@ Config::setup(std::string const& strConf, bool bQuiet, bool bSilent, bool bStand
|
||||
}
|
||||
|
||||
// As a last resort, check the system config directory.
|
||||
dataDir = "/var/opt/" + systemName();
|
||||
CONFIG_DIR = "/etc/opt/" + systemName();
|
||||
dataDir = "/var/lib/" + systemName();
|
||||
CONFIG_DIR = "/etc/" + systemName();
|
||||
CONFIG_FILE_ = CONFIG_DIR / kConfigFileName;
|
||||
if (boost::filesystem::exists(CONFIG_FILE_))
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user