mirror of
https://github.com/Xahau/xahaud.git
synced 2026-08-27 18:20:53 +00:00
Compare commits
345 Commits
jshookz
...
HookAPISer
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f244d888d | ||
|
|
3c49f80013 | ||
|
|
090e4ad25e | ||
|
|
7a0c914ce9 | ||
|
|
d712345c84 | ||
|
|
cc70d48e91 | ||
|
|
01e7ee4f03 | ||
|
|
222772d99b | ||
|
|
9e6135ba42 | ||
|
|
f0329b4054 | ||
|
|
5a9baed9d0 | ||
|
|
8d1aadd23d | ||
|
|
8d2a5e3c4e | ||
|
|
f6fe33103c | ||
|
|
b9d966dd32 | ||
|
|
7e92374436 | ||
|
|
7ef8473c85 | ||
|
|
64fb39d033 | ||
|
|
859391327d | ||
|
|
9ec631b1d8 | ||
|
|
b9ed90e08b | ||
|
|
066f8ed9ef | ||
|
|
3487e2de67 | ||
|
|
1da00892d3 | ||
|
|
75636ee5c4 | ||
|
|
d1528021e2 | ||
|
|
d1395d0f41 | ||
|
|
b4f79257cb | ||
|
|
43a4a3a3e2 | ||
|
|
117bdb1c42 | ||
|
|
87e41a7888 | ||
|
|
df3bf8a958 | ||
|
|
c5fa112e16 | ||
|
|
d2e21da7a3 | ||
|
|
1f0bbdb288 | ||
|
|
5cc56d5f15 | ||
|
|
0a9d3d3d75 | ||
|
|
0d192d48ce | ||
|
|
574dc20641 | ||
|
|
3367f40ef5 | ||
|
|
7080d292e6 | ||
|
|
85a1eb5dba | ||
|
|
534ed875a2 | ||
|
|
72b85d75c9 | ||
|
|
9229ed779f | ||
|
|
e9f671043d | ||
|
|
37669452f6 | ||
|
|
d4fd40c471 | ||
|
|
51aae2ce36 | ||
|
|
c4106a2752 | ||
|
|
e955909a40 | ||
|
|
396587c160 | ||
|
|
c065bc4938 | ||
|
|
2470926a1d | ||
|
|
c35890d5f8 | ||
|
|
248d485aed | ||
|
|
846965e77c | ||
|
|
bf1f4e1a6f | ||
|
|
f8c4639ff4 | ||
|
|
2451d78ae0 | ||
|
|
092f907724 | ||
|
|
33d4a989a2 | ||
|
|
348dab7491 | ||
|
|
6728221831 | ||
|
|
65f4945f22 | ||
|
|
aff89c3457 | ||
|
|
52e1766fb3 | ||
|
|
3166ddc460 | ||
|
|
db1591950d | ||
|
|
0d8c997867 | ||
|
|
41405706b0 | ||
|
|
d7480c6474 | ||
|
|
7b46e26d78 | ||
|
|
5f5a73acbc | ||
|
|
c24f5b10b8 | ||
|
|
601bb7ed0f | ||
|
|
0d3dd400f0 | ||
|
|
4d763b7340 | ||
|
|
63665a6673 | ||
|
|
cbd7d5dc3a | ||
|
|
3e49ee604e | ||
|
|
5e542f5215 | ||
|
|
bdc404837c | ||
|
|
a62919a9cc | ||
|
|
41dcc0fb23 | ||
|
|
b109dbf10f | ||
|
|
01372a67a8 | ||
|
|
2b59176cfd | ||
|
|
a0505ce47d | ||
|
|
91aabaa4aa | ||
|
|
a63008b1be | ||
|
|
33b5ed931c | ||
|
|
ce5c3c98c9 | ||
|
|
aeadad26cb | ||
|
|
74c50ebdab | ||
|
|
1e2c92290d | ||
|
|
0617dc221d | ||
|
|
a4a8295567 | ||
|
|
2a836cbbb8 | ||
|
|
79935d4db8 | ||
|
|
7088c64427 | ||
|
|
27ddfae5e1 | ||
|
|
cf957db8da | ||
|
|
ac532d9d16 | ||
|
|
37614773bb | ||
|
|
c329d71717 | ||
|
|
7de6a70221 | ||
|
|
0fa542f672 | ||
|
|
68705eee2c | ||
|
|
fdbb24d898 | ||
|
|
60a8f3c05b | ||
|
|
5a3a71ecb8 | ||
|
|
16b3221f80 | ||
|
|
dd4b060f09 | ||
|
|
ee78f8d566 | ||
|
|
952ce55223 | ||
|
|
e6893a9422 | ||
|
|
0ba16ef3d6 | ||
|
|
479dd8b57b | ||
|
|
e626b096a3 | ||
|
|
329c0ab1e1 | ||
|
|
997836906c | ||
|
|
71554dce3a | ||
|
|
2395d17a1f | ||
|
|
e862f40636 | ||
|
|
4f8096f378 | ||
|
|
d8a3e65d78 | ||
|
|
c3cc6494dd | ||
|
|
76397fea5c | ||
|
|
291fb21d45 | ||
|
|
727fc8e084 | ||
|
|
acc95ecc56 | ||
|
|
f7592641d1 | ||
|
|
1338b67964 | ||
|
|
9ee638fe7f | ||
|
|
9c1ed41879 | ||
|
|
ab1c217e8d | ||
|
|
e140a0fd0b | ||
|
|
7f3281ff54 | ||
|
|
17d0e23720 | ||
|
|
5675408c51 | ||
|
|
48bb555f92 | ||
|
|
2227a382d6 | ||
|
|
088c1deaf5 | ||
|
|
632f94a8e7 | ||
|
|
6bf4adf42f | ||
|
|
db9af3a8c9 | ||
|
|
ef7e743a0e | ||
|
|
c97f32cbcc | ||
|
|
187634272d | ||
|
|
be49b22c2f | ||
|
|
fd1908f5b6 | ||
|
|
d27bc94249 | ||
|
|
16b4550d93 | ||
|
|
b51411f728 | ||
|
|
6a17c6be3f | ||
|
|
881c5c8b96 | ||
|
|
eaf63accbe | ||
|
|
a26bcf1328 | ||
|
|
b5e309347a | ||
|
|
f04b4e066f | ||
|
|
b0c8296dc0 | ||
|
|
d8d55c2397 | ||
|
|
d62a3ec724 | ||
|
|
f1687f0e1b | ||
|
|
a5787f78a5 | ||
|
|
62c17828d7 | ||
|
|
1dee7d6c4d | ||
|
|
3e95f07a25 | ||
|
|
463dd92c9e | ||
|
|
95e16b0eed | ||
|
|
cb641e4733 | ||
|
|
3cb60afde6 | ||
|
|
a6a71bcc3f | ||
|
|
6c1bc9052d | ||
|
|
6b5a7ec905 | ||
|
|
7e639a1a9d | ||
|
|
cd0141d781 | ||
|
|
34be0ce4fe | ||
|
|
01971ab1b9 | ||
|
|
7996d08d0c | ||
|
|
11ff672df8 | ||
|
|
00fc12faa9 | ||
|
|
f97bf81b16 | ||
|
|
29abe2ae46 | ||
|
|
bb271020df | ||
|
|
a5fb634d53 | ||
|
|
8896ea7220 | ||
|
|
837dd8c4b9 | ||
|
|
323fba5c17 | ||
|
|
723a51921d | ||
|
|
8b83693235 | ||
|
|
beaf794938 | ||
|
|
21a383eeaf | ||
|
|
06394e9d17 | ||
|
|
ea2e503ef8 | ||
|
|
447e6c6c1e | ||
|
|
e5e4925a39 | ||
|
|
3ff7f34d7c | ||
|
|
e1f2e62c08 | ||
|
|
10dcdd87d4 | ||
|
|
6419eaae42 | ||
|
|
1f28001aae | ||
|
|
9d0b94029a | ||
|
|
c3d51f85af | ||
|
|
f15412acb5 | ||
|
|
eea44ad6cb | ||
|
|
2380633d9a | ||
|
|
4400a6eef6 | ||
|
|
17c9e967fd | ||
|
|
3b96cac31c | ||
|
|
fda0b67d9d | ||
|
|
58a24ac1a2 | ||
|
|
0213db8a08 | ||
|
|
fcd0e23326 | ||
|
|
2827748bcf | ||
|
|
4319b1a097 | ||
|
|
6af0cb9bb4 | ||
|
|
2abb48a618 | ||
|
|
8eead5c99c | ||
|
|
3055029ded | ||
|
|
ec23db00e7 | ||
|
|
39b84e073b | ||
|
|
a9afc6c690 | ||
|
|
f9d544caef | ||
|
|
6cf6b42c57 | ||
|
|
534e9989a8 | ||
|
|
7fc312b271 | ||
|
|
8cfea5a9d1 | ||
|
|
c1cb2765ee | ||
|
|
fc305f974b | ||
|
|
04f36c8d63 | ||
|
|
70a3be5ebe | ||
|
|
842f8b0ede | ||
|
|
87368f7f0e | ||
|
|
69e3cdce53 | ||
|
|
37cc0709c7 | ||
|
|
7e64d49bd0 | ||
|
|
bb463bc62f | ||
|
|
a0accf3d6a | ||
|
|
9a1888cc2d | ||
|
|
a342b510e7 | ||
|
|
b588f1a06e | ||
|
|
833a75f57a | ||
|
|
20812b4a2c | ||
|
|
5109b1a117 | ||
|
|
08abc9490d | ||
|
|
71ffc69819 | ||
|
|
c29a632d0c | ||
|
|
a8fe0f62e2 | ||
|
|
59070b4f3e | ||
|
|
880d8a7be8 | ||
|
|
b8854c7437 | ||
|
|
5ab9e2fed5 | ||
|
|
eb7e17e4f8 | ||
|
|
e9287a3d3d | ||
|
|
2572b3204c | ||
|
|
b3de0b6329 | ||
|
|
fe5bf9c12d | ||
|
|
bb2712dd20 | ||
|
|
0a97b9f471 | ||
|
|
469d4e81e4 | ||
|
|
4aa8259353 | ||
|
|
614382cb7e | ||
|
|
2c6dff314b | ||
|
|
b83e66882c | ||
|
|
c569651f83 | ||
|
|
999fc61230 | ||
|
|
9899eda7c2 | ||
|
|
41daa9f64c | ||
|
|
d75a6edc58 | ||
|
|
cc60747344 | ||
|
|
65c7f6f7d0 | ||
|
|
c3a36ad748 | ||
|
|
0a3ce6cf36 | ||
|
|
bedafe5cff | ||
|
|
d7b7bf7a10 | ||
|
|
446a1fdaac | ||
|
|
18ccbf4a53 | ||
|
|
9f2fd23575 | ||
|
|
20a422076d | ||
|
|
7fded60cc9 | ||
|
|
136508e56c | ||
|
|
ef1c26f9f5 | ||
|
|
a8e8d50cb8 | ||
|
|
73933a366b | ||
|
|
92f0efb064 | ||
|
|
11849215b4 | ||
|
|
e9f83a7808 | ||
|
|
8b0cb51d24 | ||
|
|
9838bdf214 | ||
|
|
6cf6416f15 | ||
|
|
5e1dd22bf3 | ||
|
|
dc08a666f9 | ||
|
|
07dda63bd5 | ||
|
|
53cdb040cf | ||
|
|
01890e863a | ||
|
|
6057c65027 | ||
|
|
0815ec39f8 | ||
|
|
c60eb416d2 | ||
|
|
3ea653cccb | ||
|
|
9605fa0e53 | ||
|
|
5741a0d5cb | ||
|
|
11b1602814 | ||
|
|
8667480406 | ||
|
|
cff548bcc8 | ||
|
|
acf7486c8d | ||
|
|
6de5de02cb | ||
|
|
2c5ecfa75d | ||
|
|
bbc943ca10 | ||
|
|
5d3b8976f7 | ||
|
|
cabb9cfd50 | ||
|
|
27c1ab5fba | ||
|
|
0f4bc92f77 | ||
|
|
5f02b98066 | ||
|
|
52d3babf1b | ||
|
|
9a82bf9ec2 | ||
|
|
f94e1c1be2 | ||
|
|
9e1831cacf | ||
|
|
3eb8a64e64 | ||
|
|
61fd0d0164 | ||
|
|
314cf50863 | ||
|
|
00a6922045 | ||
|
|
cd9facd7fa | ||
|
|
39b2e3334a | ||
|
|
f19e254366 | ||
|
|
5e083121da | ||
|
|
683e9ccc1a | ||
|
|
8dbc6db079 | ||
|
|
b7a29cad94 | ||
|
|
7054bf64e9 | ||
|
|
3ddf1c99d5 | ||
|
|
6d5e7e519b | ||
|
|
224ae4e70f | ||
|
|
8531ba5838 | ||
|
|
73550a4bfc | ||
|
|
e353c9d6eb | ||
|
|
b733d274a0 | ||
|
|
346544e371 | ||
|
|
5d2d1d4497 | ||
|
|
0f0ffda053 | ||
|
|
37f7734b25 | ||
|
|
f8dc0cab65 | ||
|
|
3c4731a676 | ||
|
|
995e70c2b0 |
40
.codecov.yml
40
.codecov.yml
@@ -1,40 +0,0 @@
|
||||
codecov:
|
||||
require_ci_to_pass: true
|
||||
# This integration branch uploads the normal suite and JSHookz E2E coverage.
|
||||
notify:
|
||||
after_n_builds: 2
|
||||
|
||||
comment:
|
||||
behavior: default
|
||||
layout: reach,diff,flags,tree,reach
|
||||
show_carryforward_flags: false
|
||||
|
||||
coverage:
|
||||
range: "60..80"
|
||||
precision: 1
|
||||
round: nearest
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
target: 60%
|
||||
threshold: 2%
|
||||
patch:
|
||||
default:
|
||||
target: auto
|
||||
threshold: 2%
|
||||
changes: false
|
||||
|
||||
github_checks:
|
||||
annotations: true
|
||||
|
||||
parsers:
|
||||
cobertura:
|
||||
partials_as_hits: true
|
||||
handle_missing_conditions : true
|
||||
|
||||
slack_app: false
|
||||
|
||||
ignore:
|
||||
- "src/test/"
|
||||
- "include/xrpl/beast/test/"
|
||||
- "include/xrpl/beast/unit_test/"
|
||||
@@ -1,25 +1,8 @@
|
||||
# This feature requires Git >= 2.24
|
||||
# To use it by default in git blame:
|
||||
# git config blame.ignoreRevsFile .git-blame-ignore-revs
|
||||
# Format first-party source according to .clang-format
|
||||
50760c693510894ca368e90369b0cc2dabfd07f3
|
||||
# Reintroduce Clang-Format & Levelization
|
||||
da1d20d6d5d862716125d60899b80fab5302954a
|
||||
# Consolidate external libraries
|
||||
da1d20d6d5d862716125d60899b80fab5302954a
|
||||
# Rename .hpp to .h
|
||||
0345a2645d0f5ad900f4fbbcaff96040d3a887fc
|
||||
# Format formerly .hpp files
|
||||
5a227dc719016e10045e17c9396ad401118044f1
|
||||
# Rewrite includes
|
||||
e61880699997398f5a746e6c4034edc7632661f5
|
||||
# Move CMake directory (#4997)
|
||||
e47b1c1b3b97c3f6d11858ee02f463596e29e7f0
|
||||
# Rearrange sources (#4997)
|
||||
bfafa2bb39e562901736d656806bd700c3699a2f
|
||||
# Rewrite includes (#4997)
|
||||
e61880699997398f5a746e6c4034edc7632661f5
|
||||
# Recompute loops (#4997)
|
||||
d25b5dcd568bb96c18e347d55fac10fe901a1bfb
|
||||
# Reformat code with clang-format-18
|
||||
02749feea88ce61c1f7eeb2d61a57d8ecf07ab11
|
||||
e2384885f5f630c8f0ffe4bf21a169b433a16858
|
||||
241b9ddde9e11beb7480600fd5ed90e1ef109b21
|
||||
760f16f56835663d9286bd29294d074de26a7ba6
|
||||
0eebe6a5f4246fced516d52b83ec4e7f47373edd
|
||||
|
||||
6
.gitattributes
vendored
6
.gitattributes
vendored
@@ -11,9 +11,3 @@ LICENSE binary
|
||||
*.vcxproj text eol=crlf
|
||||
*.props text eol=crlf
|
||||
*.filters text eol=crlf
|
||||
|
||||
# JSHookz projections checked for freshness by the integration workflow.
|
||||
external/quickjs-provider/jshookz_provider.manifest.cmake linguist-generated=true
|
||||
external/quickjs-provider/jshookz_provider.manifest.json linguist-generated=true
|
||||
external/quickjs-provider/jshookz_provider.native-abi.json linguist-generated=true
|
||||
src/test/app/JSHooks_test_hooks.h linguist-generated=true
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Pre-commit hook that runs the suspicious patterns check on staged files
|
||||
|
||||
# Get the repository's root directory
|
||||
repo_root=$(git rev-parse --show-toplevel)
|
||||
|
||||
# Run the suspicious patterns script in pre-commit mode
|
||||
"$repo_root/suspicious_patterns.sh" --pre-commit
|
||||
|
||||
# Exit with the same code as the script
|
||||
exit $?
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "Configuring git to use .githooks directory..."
|
||||
git config core.hooksPath .githooks
|
||||
29
.github/actions/xahau-ga-build/action.yml
vendored
29
.github/actions/xahau-ga-build/action.yml
vendored
@@ -2,14 +2,6 @@ name: build
|
||||
description: 'Builds the project with ccache integration'
|
||||
|
||||
inputs:
|
||||
cmake-target:
|
||||
description: 'CMake target to build'
|
||||
required: false
|
||||
default: all
|
||||
cmake-args:
|
||||
description: 'Additional CMake arguments'
|
||||
required: false
|
||||
default: null
|
||||
generator:
|
||||
description: 'CMake generator to use'
|
||||
required: true
|
||||
@@ -28,10 +20,6 @@ inputs:
|
||||
description: 'C++ compiler to use'
|
||||
required: false
|
||||
default: ''
|
||||
gcov:
|
||||
description: 'Gcov to use'
|
||||
required: false
|
||||
default: ''
|
||||
compiler-id:
|
||||
description: 'Unique identifier: compiler-version-stdlib[-gccversion] (e.g. clang-14-libstdcxx-gcc11, gcc-13-libstdcxx)'
|
||||
required: false
|
||||
@@ -53,11 +41,10 @@ inputs:
|
||||
required: false
|
||||
default: 'dev'
|
||||
stdlib:
|
||||
description: 'C++ standard library to use (default = compiler default, e.g. GCC always uses libstdc++)'
|
||||
description: 'C++ standard library to use'
|
||||
required: true
|
||||
type: choice
|
||||
options:
|
||||
- default
|
||||
- libstdcxx
|
||||
- libcxx
|
||||
clang_gcc_toolchain:
|
||||
@@ -100,6 +87,11 @@ runs:
|
||||
export CCACHE_CONFIGPATH="$HOME/.config/ccache/ccache.conf"
|
||||
echo "CCACHE_CONFIGPATH=$CCACHE_CONFIGPATH" >> $GITHUB_ENV
|
||||
|
||||
# Keep config separate from cache_dir so configs aren't swapped when CCACHE_DIR changes between steps
|
||||
mkdir -p ~/.config/ccache
|
||||
export CCACHE_CONFIGPATH="$HOME/.config/ccache/ccache.conf"
|
||||
echo "CCACHE_CONFIGPATH=$CCACHE_CONFIGPATH" >> $GITHUB_ENV
|
||||
|
||||
# Configure ccache settings AFTER cache restore (prevents stale cached config)
|
||||
ccache --set-config=max_size=${{ inputs.ccache_max_size }}
|
||||
ccache --set-config=hash_dir=${{ inputs.ccache_hash_dir }}
|
||||
@@ -130,10 +122,6 @@ runs:
|
||||
export CXX="${{ inputs.cxx }}"
|
||||
fi
|
||||
|
||||
if [ -n "${{ inputs.gcov }}" ]; then
|
||||
ln -sf /usr/bin/${{ inputs.gcov }} /usr/local/bin/gcov
|
||||
fi
|
||||
|
||||
# Create wrapper toolchain that overlays ccache on top of Conan's toolchain
|
||||
# This enables ccache for the main app build without affecting Conan dependency builds
|
||||
if [ "${{ inputs.ccache_enabled }}" = "true" ]; then
|
||||
@@ -197,8 +185,7 @@ runs:
|
||||
-DCMAKE_TOOLCHAIN_FILE:FILEPATH=${TOOLCHAIN_FILE} \
|
||||
-DCMAKE_BUILD_TYPE=${{ inputs.configuration }} \
|
||||
-Dtests=TRUE \
|
||||
-Dxrpld=TRUE \
|
||||
${{ inputs.cmake-args }}
|
||||
-Dxrpld=TRUE
|
||||
|
||||
- name: Show ccache config before build
|
||||
if: inputs.ccache_enabled == 'true'
|
||||
@@ -222,7 +209,7 @@ runs:
|
||||
VERBOSE_FLAG="-- -v"
|
||||
fi
|
||||
|
||||
cmake --build . --config ${{ inputs.configuration }} --parallel $(nproc) --target ${{ inputs.cmake-target }} ${VERBOSE_FLAG}
|
||||
cmake --build . --config ${{ inputs.configuration }} --parallel $(nproc) ${VERBOSE_FLAG}
|
||||
|
||||
- name: Show ccache statistics
|
||||
if: inputs.ccache_enabled == 'true'
|
||||
|
||||
@@ -145,9 +145,6 @@ runs:
|
||||
# Export wasmedge if not already exported
|
||||
conan list wasmedge/0.11.2@xahaud/stable 2>/dev/null | (grep -q "not found" && exit 1 || exit 0) || \
|
||||
conan export external/wasmedge --version 0.11.2 --user xahaud --channel stable
|
||||
|
||||
# Keep the cached recipe in sync with this checkout; package binaries remain cached.
|
||||
conan export external/wasmtime --version 47.0.3 --user xahaud --channel stable
|
||||
- name: Install dependencies
|
||||
shell: bash
|
||||
env:
|
||||
@@ -162,6 +159,4 @@ runs:
|
||||
--output-folder . \
|
||||
--build missing \
|
||||
--settings build_type=${{ inputs.configuration }} \
|
||||
--options '&:xrpld=True' \
|
||||
--options '&:tests=True' \
|
||||
..
|
||||
|
||||
1
.github/workflows/build-in-docker.yml
vendored
1
.github/workflows/build-in-docker.yml
vendored
@@ -33,7 +33,6 @@ jobs:
|
||||
fetch-depth: 2 # Only get the last 2 commits, to avoid fetching all history
|
||||
|
||||
build:
|
||||
if: github.head_ref != 'jshookz'
|
||||
runs-on: [self-hosted, xahaud-build]
|
||||
needs: [checkout]
|
||||
defaults:
|
||||
|
||||
110
.github/workflows/check-genesis-hooks.yml
vendored
110
.github/workflows/check-genesis-hooks.yml
vendored
@@ -1,110 +0,0 @@
|
||||
name: Check Genesis Hooks
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
check-genesis-hooks:
|
||||
runs-on: ubuntu-24.04
|
||||
env:
|
||||
CLANG_VERSION: 18
|
||||
name: Verify xahau.h is in sync with genesis hooks
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
# Install binaryen from GitHub Releases (pinned to version 100)
|
||||
- name: Install binaryen (version 100)
|
||||
run: |
|
||||
curl -LO https://github.com/WebAssembly/binaryen/releases/download/version_100/binaryen-version_100-x86_64-linux.tar.gz
|
||||
tar -xzf binaryen-version_100-x86_64-linux.tar.gz
|
||||
sudo cp binaryen-version_100/bin/* /usr/local/bin/
|
||||
wasm-opt --version
|
||||
|
||||
- name: Install clang-format
|
||||
run: |
|
||||
codename=$( lsb_release --codename --short )
|
||||
sudo tee /etc/apt/sources.list.d/llvm.list >/dev/null <<EOF
|
||||
deb http://apt.llvm.org/${codename}/ llvm-toolchain-${codename}-${CLANG_VERSION} main
|
||||
deb-src http://apt.llvm.org/${codename}/ llvm-toolchain-${codename}-${CLANG_VERSION} main
|
||||
EOF
|
||||
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add
|
||||
sudo apt-get update
|
||||
sudo apt-get install clang-format-${CLANG_VERSION}
|
||||
clang-format --version
|
||||
|
||||
# Install wasienv (WebAssembly SDK)
|
||||
- name: Install wasienv
|
||||
run: |
|
||||
# Download install.sh
|
||||
curl -o /tmp/wasienv-install.sh https://raw.githubusercontent.com/wasienv/wasienv/master/install.sh
|
||||
|
||||
# Replace /bin to /local/bin
|
||||
sed -i 's|/bin|/local/bin|g' /tmp/wasienv-install.sh
|
||||
|
||||
# Execute the installed script
|
||||
bash /tmp/wasienv-install.sh
|
||||
|
||||
# Add wasienv to PATH for subsequent steps
|
||||
- name: Setup wasienv
|
||||
run: |
|
||||
echo "$HOME/.wasienv/bin" >> $GITHUB_PATH
|
||||
wasmcc -v || true
|
||||
|
||||
# Build and install hook-cleaner tool
|
||||
- name: Build and install hook-cleaner
|
||||
run: |
|
||||
git clone https://github.com/richardah/hook-cleaner-c.git /tmp/hook-cleaner
|
||||
cd /tmp/hook-cleaner
|
||||
make
|
||||
cp hook-cleaner /usr/local/bin/
|
||||
chmod +x /usr/local/bin/hook-cleaner
|
||||
|
||||
# Build and install guard_checker tool
|
||||
- name: Build and install guard_checker
|
||||
run: |
|
||||
cd include/xrpl/hook
|
||||
make
|
||||
cp guard_checker /usr/local/bin/
|
||||
chmod +x /usr/local/bin/guard_checker
|
||||
|
||||
# Verify all required tools are available
|
||||
- name: Verify required tools
|
||||
run: |
|
||||
echo "Checking tool availability..."
|
||||
command -v wasmcc || (echo "Error: wasmcc not found" && exit 1)
|
||||
command -v wasm-opt || (echo "Error: wasm-opt not found" && exit 1)
|
||||
command -v hook-cleaner || (echo "Error: hook-cleaner not found" && exit 1)
|
||||
command -v guard_checker || (echo "Error: guard_checker not found" && exit 1)
|
||||
command -v xxd || (echo "Error: xxd not found" && exit 1)
|
||||
command -v clang-format || (echo "Error: clang-format not found" && exit 1)
|
||||
echo "All tools verified successfully"
|
||||
|
||||
- name: Verify independent Wasmtime host catalogue fixture
|
||||
run: src/test/app/jshooks/raw-catalogue/generate.py --check
|
||||
|
||||
# Execute build script to regenerate xahau.h
|
||||
- name: Run build_xahau_h.sh
|
||||
run: |
|
||||
cd hook/genesis
|
||||
./build_xahau_h.sh
|
||||
|
||||
# Check if xahau.h has changed (fail if out of sync)
|
||||
- name: Verify xahau.h is in sync
|
||||
run: |
|
||||
if ! git diff --exit-code include/xrpl/hook/xahau.h; then
|
||||
echo ""
|
||||
echo "❌ ERROR: xahau.h is out of sync with genesis hooks"
|
||||
echo ""
|
||||
echo "The generated xahau.h differs from the committed version."
|
||||
echo "Please run the following command and commit the changes:"
|
||||
echo ""
|
||||
echo " cd hook/genesis && ./build_xahau_h.sh"
|
||||
echo ""
|
||||
echo "Diff:"
|
||||
git diff include/xrpl/hook/xahau.h
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ xahau.h is in sync with genesis hooks"
|
||||
2
.github/workflows/clang-format.yml
vendored
2
.github/workflows/clang-format.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
||||
sudo apt-get update
|
||||
sudo apt-get install clang-format-${CLANG_VERSION}
|
||||
- name: Format first-party sources
|
||||
run: find include src -type f \( -name '*.cpp' -o -name '*.hpp' -o -name '*.h' -o -name '*.ipp' \) -exec clang-format-${CLANG_VERSION} -i {} +
|
||||
run: find include src -type f \( -name '*.cpp' -o -name '*.hpp' -o -name '*.h' -o -name '*.ipp' \) -not -path "src/magic/magic_enum.h" -exec clang-format-${CLANG_VERSION} -i {} +
|
||||
- name: Check for differences
|
||||
id: assert
|
||||
run: |
|
||||
|
||||
236
.github/workflows/jshookz-e2e.yml
vendored
236
.github/workflows/jshookz-e2e.yml
vendored
@@ -1,236 +0,0 @@
|
||||
# End-to-end proof for the external jshookz toolchain and real Xahau Env.
|
||||
name: JSHookz end to end
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [jshookz]
|
||||
# PRs targeting jshookz/dev currently duplicate the branch-push e2e
|
||||
# (different github.ref, so concurrency does not cancel). Re-enable later.
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
|
||||
concurrency:
|
||||
group: jshookz-e2e-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
JSHOOKZ_REF: xahaud-pinned
|
||||
HOOKZ_REF: 846f5f0f80861985dceb41ad6f02ff914f8a0c3d
|
||||
XAHAUD_SCRIPTS_REF: e41a712c68a613d95a8911cbf89711db2d95aa3b
|
||||
WASI_SDK_VERSION: "32"
|
||||
WASI_SDK_SHA256: 55fc523ebfbc98f69d1034fcfcb83d1ff5610cd9ab7eceef6cd097a30ba4ef93
|
||||
BINARYEN_VERSION: "128"
|
||||
BINARYEN_SHA256: 4ce79586d1c4762502eebe9a1db071fa5e446ef8897f2f766eb1cce5ec6dee9e
|
||||
WIZER_VERSION: "10.0.0"
|
||||
WIZER_SHA256: 1e9dfaa2f6c436ca7acfdbb82c166f5b8a0062068f12916a554e82c97ca8d371
|
||||
WASI_SDK_PATH: ${{ github.workspace }}/.tools/wasi-sdk
|
||||
HOOKZ_WASI_SDK: ${{ github.workspace }}/.tools/wasi-sdk
|
||||
BINARYEN_HOME: ${{ github.workspace }}/.tools/binaryen
|
||||
JSHOOKZ_PROVIDER_BUNDLE: ${{ github.workspace }}/.deps/jshookz/build/xahau-provider
|
||||
XAHAU_QJS_PROVIDER_WASM: ${{ github.workspace }}/.deps/jshookz/build/xahau-provider/jshookz_provider.wasm
|
||||
XAHAU_REQUIRE_QJS_PROVIDER_TESTS: "1"
|
||||
CC: gcc-13
|
||||
CXX: g++-13
|
||||
CCACHE_DIR: /github/home/.ccache-cache
|
||||
CMAKE_BUILD_PARALLEL_LEVEL: "2"
|
||||
|
||||
jobs:
|
||||
env-proof:
|
||||
runs-on: [self-hosted, generic, 20.04]
|
||||
timeout-minutes: 120
|
||||
container:
|
||||
image: ubuntu:24.04
|
||||
volumes:
|
||||
- /home/runner/.conan-cache:/.conan-cache
|
||||
- /home/runner/.ccache-cache:/github/home/.ccache-cache
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
steps:
|
||||
- name: Install checkout prerequisite
|
||||
run: |
|
||||
apt-get update
|
||||
apt-get install -y git
|
||||
|
||||
- name: Check out Xahau integration
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Check out public jshookz
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: sublimator/jshookz
|
||||
ref: ${{ env.JSHOOKZ_REF }}
|
||||
path: .deps/jshookz
|
||||
persist-credentials: false
|
||||
|
||||
- name: Check out public hookz
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: sublimator/hookz
|
||||
ref: ${{ env.HOOKZ_REF }}
|
||||
path: .deps/hookz
|
||||
persist-credentials: false
|
||||
|
||||
- name: Check out public xahaud-scripts
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: sublimator/xahaud-scripts
|
||||
ref: ${{ env.XAHAUD_SCRIPTS_REF }}
|
||||
path: .deps/xahaud-scripts
|
||||
persist-credentials: false
|
||||
|
||||
- uses: astral-sh/setup-uv@v7
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "22"
|
||||
|
||||
- name: Install native and TypeScript tools
|
||||
run: |
|
||||
apt-get install -y \
|
||||
build-essential ccache clang-format-18 cmake curl g++-13 gcc-13 \
|
||||
libsqlite3-dev ninja-build pkg-config xz-utils
|
||||
ln -sf /usr/bin/clang-format-18 /usr/local/bin/clang-format
|
||||
ln -sf /usr/bin/gcov-13 /usr/local/bin/gcov
|
||||
npm install --global typescript@6.0.3
|
||||
uv python install 3.13
|
||||
uv tool install --python 3.13 conan==2.21.0
|
||||
uv tool install --python 3.13 'gcovr>=7,<9'
|
||||
|
||||
- name: Install wasi-sdk and Binaryen
|
||||
run: |
|
||||
mkdir -p .tools
|
||||
curl --fail --location --retry 3 \
|
||||
--output /tmp/wasi-sdk.tar.gz \
|
||||
"https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_VERSION}/wasi-sdk-${WASI_SDK_VERSION}.0-x86_64-linux.tar.gz"
|
||||
echo "$WASI_SDK_SHA256 /tmp/wasi-sdk.tar.gz" | sha256sum --check
|
||||
tar -xzf /tmp/wasi-sdk.tar.gz -C .tools
|
||||
mv ".tools/wasi-sdk-${WASI_SDK_VERSION}.0-x86_64-linux" "$WASI_SDK_PATH"
|
||||
|
||||
curl --fail --location --retry 3 \
|
||||
--output /tmp/binaryen.tar.gz \
|
||||
"https://github.com/WebAssembly/binaryen/releases/download/version_${BINARYEN_VERSION}/binaryen-version_${BINARYEN_VERSION}-x86_64-linux.tar.gz"
|
||||
echo "$BINARYEN_SHA256 /tmp/binaryen.tar.gz" | sha256sum --check
|
||||
tar -xzf /tmp/binaryen.tar.gz -C .tools
|
||||
mv ".tools/binaryen-version_${BINARYEN_VERSION}" "$BINARYEN_HOME"
|
||||
echo "$BINARYEN_HOME/bin" >> "$GITHUB_PATH"
|
||||
|
||||
- name: Install Wizer
|
||||
run: |
|
||||
curl --fail --location --retry 3 \
|
||||
--output /tmp/wizer.tar.xz \
|
||||
"https://github.com/bytecodealliance/wizer/releases/download/v${WIZER_VERSION}/wizer-v${WIZER_VERSION}-x86_64-linux.tar.xz"
|
||||
echo "$WIZER_SHA256 /tmp/wizer.tar.xz" | sha256sum --check
|
||||
tar -xJf /tmp/wizer.tar.xz -C .tools
|
||||
echo "$GITHUB_WORKSPACE/.tools/wizer-v${WIZER_VERSION}-x86_64-linux" >> "$GITHUB_PATH"
|
||||
|
||||
- name: Install the Hook toolchain
|
||||
run: |
|
||||
if [ -f .deps/jshookz/python/jshookz/pyproject.toml ]; then
|
||||
jshookz_project=.deps/jshookz/python/jshookz
|
||||
else
|
||||
jshookz_project=.deps/jshookz/packages/jshookz
|
||||
fi
|
||||
uv sync --project "$jshookz_project" \
|
||||
--locked --group dev --python 3.13
|
||||
uv tool install --python 3.13 --force --from .deps/hookz hookz
|
||||
uv tool install --python 3.13 --force \
|
||||
--from .deps/xahaud-scripts xahaud-scripts
|
||||
jshookz_cmd="$jshookz_project/.venv/bin/jshookz"
|
||||
echo "JSHOOKZ_CMD=$jshookz_cmd" >> "$GITHUB_ENV"
|
||||
echo "JSHOOKZ_HOOK_COMPILER=$jshookz_cmd compile-hook" >> "$GITHUB_ENV"
|
||||
"$jshookz_cmd" info
|
||||
hookz --version
|
||||
x-run-tests --help >/dev/null
|
||||
|
||||
- name: Build and verify the sealed provider
|
||||
run: |
|
||||
"$JSHOOKZ_CMD" build provider
|
||||
test -s "$XAHAU_QJS_PROVIDER_WASM"
|
||||
cmp external/quickjs-provider/jshookz_provider.manifest.json \
|
||||
"$JSHOOKZ_PROVIDER_BUNDLE/jshookz_provider.manifest.json"
|
||||
cmp external/quickjs-provider/jshookz_provider.manifest.cmake \
|
||||
"$JSHOOKZ_PROVIDER_BUNDLE/jshookz_provider.manifest.cmake"
|
||||
cmp external/quickjs-provider/jshookz_provider.native-abi.json \
|
||||
"$JSHOOKZ_PROVIDER_BUNDLE/jshookz_provider.native-abi.json"
|
||||
cp "$XAHAU_QJS_PROVIDER_WASM" \
|
||||
external/quickjs-provider/jshookz_provider.wasm
|
||||
|
||||
- name: Prove generator-lock mutation reds
|
||||
run: python3 cmake/test_generate_quickjs_provider_bundle.py
|
||||
|
||||
- name: Configure Conan for Xahau
|
||||
run: |
|
||||
mkdir -p \
|
||||
/.conan-cache/conan2 \
|
||||
/.conan-cache/conan2_download \
|
||||
/.conan-cache/conan2_sources
|
||||
mkdir -p "$HOME/.conan2"
|
||||
printf '%s\n' \
|
||||
'core.cache:storage_path=/.conan-cache/conan2' \
|
||||
'core.download:download_cache=/.conan-cache/conan2_download' \
|
||||
'core.sources:download_cache=/.conan-cache/conan2_sources' \
|
||||
> "$HOME/.conan2/global.conf"
|
||||
mkdir -p "$HOME/.conan2/profiles"
|
||||
cat > "$HOME/.conan2/profiles/default" <<'EOF'
|
||||
[settings]
|
||||
arch=x86_64
|
||||
build_type=Debug
|
||||
compiler=gcc
|
||||
compiler.cppstd=20
|
||||
compiler.libcxx=libstdc++11
|
||||
compiler.version=13
|
||||
os=Linux
|
||||
|
||||
[buildenv]
|
||||
CC=/usr/bin/gcc-13
|
||||
CXX=/usr/bin/g++-13
|
||||
|
||||
[conf]
|
||||
tools.build:compiler_executables={"c": "/usr/bin/gcc-13", "cpp": "/usr/bin/g++-13"}
|
||||
|
||||
[options]
|
||||
&:xrpld=True
|
||||
&:tests=True
|
||||
date/*:use_system_tz_db=True
|
||||
EOF
|
||||
conan remote add --force xrplf https://conan.ripplex.io
|
||||
conan profile show
|
||||
conan export external/snappy --version 1.1.10 \
|
||||
--user xahaud --channel stable
|
||||
conan export external/soci --version 4.0.3 \
|
||||
--user xahaud --channel stable
|
||||
conan export external/wasmedge --version 0.11.2 \
|
||||
--user xahaud --channel stable
|
||||
conan export external/wasmtime --version 47.0.3 \
|
||||
--user xahaud --channel stable
|
||||
|
||||
- name: Build Xahau and run the authoritative Env suite
|
||||
run: |
|
||||
x-run-tests \
|
||||
--compile-hooks src/test/app/JSHooks_test.cpp \
|
||||
--build-type Coverage \
|
||||
--build-dir build-jshookz-e2e \
|
||||
--reconfigure-build \
|
||||
--ccache \
|
||||
-j 2 \
|
||||
-- \
|
||||
ripple.app.JSHooks,ripple.app.QuickJSHostPolicy,ripple.app.HookGuestMemory,ripple.app.HookAPI,ripple.app.HookWasmtimeHostCatalogue,ripple.app.HookArtifact
|
||||
|
||||
- name: Upload JSHookz coverage
|
||||
uses: codecov/codecov-action@v5
|
||||
with:
|
||||
files: build-jshookz-e2e/coverage/coverage.json
|
||||
fail_ci_if_error: true
|
||||
disable_search: true
|
||||
verbose: true
|
||||
plugins: noop
|
||||
use_oidc: true
|
||||
|
||||
- name: Verify the checked-in fixture header is current
|
||||
run: git diff --exit-code -- src/test/app/JSHooks_test_hooks.h
|
||||
4
.github/workflows/levelization.yml
vendored
4
.github/workflows/levelization.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Check levelization
|
||||
run: python Builds/levelization/levelization.py
|
||||
run: Builds/levelization/levelization.sh
|
||||
- name: Check for differences
|
||||
id: assert
|
||||
run: |
|
||||
@@ -40,7 +40,7 @@ jobs:
|
||||
To fix it, you can do one of two things:
|
||||
1. Download and apply the patch generated as an artifact of this
|
||||
job to your repo, commit, and push.
|
||||
2. Run 'python Builds/levelization/levelization.py' in your repo,
|
||||
2. Run './Builds/levelization/levelization.sh' in your repo,
|
||||
commit, and push.
|
||||
|
||||
See Builds/levelization/README.md for more info.
|
||||
|
||||
@@ -18,10 +18,6 @@ jobs:
|
||||
generator: bash ./hook/generate_sfcodes.sh
|
||||
- target: hook/tts.h
|
||||
generator: ./hook/generate_tts.sh
|
||||
- target: hook/ls_flags.h
|
||||
generator: ./hook/generate_lsflags.sh
|
||||
- target: hook/tx_flags.h
|
||||
generator: ./hook/generate_txflags.sh
|
||||
runs-on: ubuntu-24.04
|
||||
env:
|
||||
CLANG_VERSION: 18
|
||||
|
||||
7
.github/workflows/xahau-ga-macos.yml
vendored
7
.github/workflows/xahau-ga-macos.yml
vendored
@@ -4,8 +4,7 @@ on:
|
||||
push:
|
||||
branches: ["dev", "candidate", "release"]
|
||||
pull_request:
|
||||
branches: ["**"]
|
||||
types: [opened, synchronize, reopened, labeled, unlabeled]
|
||||
branches: ["dev", "candidate", "release"]
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
|
||||
@@ -15,10 +14,6 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
if: >
|
||||
github.event_name != 'pull_request' ||
|
||||
contains(fromJson('["dev","candidate","release"]'), github.base_ref) ||
|
||||
contains(join(github.event.pull_request.labels.*.name, ','), 'ci-full-build')
|
||||
strategy:
|
||||
matrix:
|
||||
generator:
|
||||
|
||||
168
.github/workflows/xahau-ga-nix.yml
vendored
168
.github/workflows/xahau-ga-nix.yml
vendored
@@ -4,16 +4,9 @@ on:
|
||||
push:
|
||||
branches: ["dev", "candidate", "release"]
|
||||
pull_request:
|
||||
branches: ["**"]
|
||||
types: [opened, synchronize, reopened, labeled, unlabeled]
|
||||
branches: ["dev", "candidate", "release"]
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
full_matrix:
|
||||
description: "Force full matrix (6 configs)"
|
||||
required: false
|
||||
default: "false"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
@@ -21,10 +14,6 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
matrix-setup:
|
||||
if: >
|
||||
github.event_name != 'pull_request' ||
|
||||
contains(fromJson('["dev","candidate","release"]'), github.base_ref) ||
|
||||
contains(join(github.event.pull_request.labels.*.name, ','), 'ci-full-build')
|
||||
runs-on: [self-hosted, generic, 20.04]
|
||||
container: python:3-slim
|
||||
outputs:
|
||||
@@ -57,9 +46,8 @@ jobs:
|
||||
"cc": "gcc-11",
|
||||
"cxx": "g++-11",
|
||||
"compiler_version": 11,
|
||||
"stdlib": "default",
|
||||
"configuration": "Debug",
|
||||
"job_type": "build"
|
||||
"stdlib": "libstdcxx",
|
||||
"configuration": "Debug"
|
||||
},
|
||||
{
|
||||
"compiler_id": "gcc-13-libstdcxx",
|
||||
@@ -67,20 +55,8 @@ jobs:
|
||||
"cc": "gcc-13",
|
||||
"cxx": "g++-13",
|
||||
"compiler_version": 13,
|
||||
"stdlib": "default",
|
||||
"configuration": "Debug",
|
||||
"job_type": "build"
|
||||
},
|
||||
{
|
||||
"compiler_id": "gcc-13-libstdcxx",
|
||||
"compiler": "gcc",
|
||||
"cc": "gcc-13",
|
||||
"cxx": "g++-13",
|
||||
"gcov": "gcov-13",
|
||||
"compiler_version": 13,
|
||||
"stdlib": "default",
|
||||
"configuration": "Debug",
|
||||
"job_type": "coverage"
|
||||
"stdlib": "libstdcxx",
|
||||
"configuration": "Debug"
|
||||
},
|
||||
{
|
||||
"compiler_id": "clang-14-libstdcxx-gcc11",
|
||||
@@ -90,8 +66,7 @@ jobs:
|
||||
"compiler_version": 14,
|
||||
"stdlib": "libstdcxx",
|
||||
"clang_gcc_toolchain": 11,
|
||||
"configuration": "Debug",
|
||||
"job_type": "build"
|
||||
"configuration": "Debug"
|
||||
},
|
||||
{
|
||||
"compiler_id": "clang-16-libstdcxx-gcc13",
|
||||
@@ -101,8 +76,7 @@ jobs:
|
||||
"compiler_version": 16,
|
||||
"stdlib": "libstdcxx",
|
||||
"clang_gcc_toolchain": 13,
|
||||
"configuration": "Debug",
|
||||
"job_type": "build"
|
||||
"configuration": "Debug"
|
||||
},
|
||||
{
|
||||
"compiler_id": "clang-17-libcxx",
|
||||
@@ -111,8 +85,7 @@ jobs:
|
||||
"cxx": "clang++-17",
|
||||
"compiler_version": 17,
|
||||
"stdlib": "libcxx",
|
||||
"configuration": "Debug",
|
||||
"job_type": "build"
|
||||
"configuration": "Debug"
|
||||
},
|
||||
{
|
||||
# Clang 18 - testing if it's faster than Clang 17 with libc++
|
||||
@@ -123,16 +96,14 @@ jobs:
|
||||
"cxx": "clang++-18",
|
||||
"compiler_version": 18,
|
||||
"stdlib": "libcxx",
|
||||
"configuration": "Debug",
|
||||
"job_type": "build"
|
||||
"configuration": "Debug"
|
||||
}
|
||||
]
|
||||
|
||||
# Minimal matrix for PRs and feature branches
|
||||
minimal_matrix = [
|
||||
full_matrix[1], # gcc-13 (middle-ground gcc)
|
||||
full_matrix[2], # gcc-13 coverage
|
||||
full_matrix[3] # clang-14 (mature, stable clang)
|
||||
full_matrix[2] # clang-14 (mature, stable clang)
|
||||
]
|
||||
|
||||
# Determine which matrix to use based on the target branch
|
||||
@@ -140,7 +111,6 @@ jobs:
|
||||
base_ref = "${{ github.base_ref }}" # For PRs, this is the target branch
|
||||
event_name = "${{ github.event_name }}"
|
||||
pr_title = """${{ steps.escape.outputs.title }}"""
|
||||
pr_labels = """${{ join(github.event.pull_request.labels.*.name, ',') }}"""
|
||||
pr_head_sha = "${{ github.event.pull_request.head.sha }}"
|
||||
|
||||
# Get commit message - for PRs, fetch via API since head_commit.message is empty
|
||||
@@ -166,24 +136,11 @@ jobs:
|
||||
print(f"Base ref: {base_ref}")
|
||||
print(f"PR head SHA: {pr_head_sha}")
|
||||
print(f"PR title: {pr_title}")
|
||||
print(f"PR labels: {pr_labels}")
|
||||
print(f"Commit message: {commit_message}")
|
||||
|
||||
# Manual trigger input to force full matrix.
|
||||
manual_full = "${{ github.event.inputs.full_matrix || 'false' }}" == "true"
|
||||
|
||||
# Label/manual overrides, while preserving existing title/commit behavior.
|
||||
force_full = (
|
||||
manual_full
|
||||
or "[ci-nix-full-matrix]" in commit_message
|
||||
or "[ci-nix-full-matrix]" in pr_title
|
||||
or ("ci-full-build" in pr_labels and "ci-nix-full-matrix" in pr_labels)
|
||||
)
|
||||
force_min = (
|
||||
"ci-full-build" in pr_labels
|
||||
)
|
||||
# Check for override tags in commit message or PR title
|
||||
force_full = "[ci-nix-full-matrix]" in commit_message or "[ci-nix-full-matrix]" in pr_title
|
||||
print(f"Force full matrix: {force_full}")
|
||||
print(f"Force min matrix: {force_min}")
|
||||
|
||||
# Check if this is targeting a main branch
|
||||
# For PRs: check base_ref (target branch)
|
||||
@@ -191,11 +148,8 @@ jobs:
|
||||
main_branches = ["refs/heads/dev", "refs/heads/release", "refs/heads/candidate"]
|
||||
|
||||
if force_full:
|
||||
# Override: always use full matrix if forced by manual input or label.
|
||||
# Override: always use full matrix if tag is present
|
||||
use_full = True
|
||||
elif force_min:
|
||||
# Override: always use minimal matrix if ci-full-build label is present.
|
||||
use_full = False
|
||||
elif event_name == "pull_request":
|
||||
# For PRs, base_ref is just the branch name (e.g., "dev", not "refs/heads/dev")
|
||||
# Check if the PR targets release or candidate (more critical branches)
|
||||
@@ -207,21 +161,14 @@ jobs:
|
||||
# Select the appropriate matrix
|
||||
if use_full:
|
||||
if force_full:
|
||||
print(f"Using FULL matrix (7 configs) - forced by [ci-nix-full-matrix] tag")
|
||||
print(f"Using FULL matrix (6 configs) - forced by [ci-nix-full-matrix] tag")
|
||||
else:
|
||||
print(f"Using FULL matrix (7 configs) - targeting main branch")
|
||||
print(f"Using FULL matrix (6 configs) - targeting main branch")
|
||||
matrix = full_matrix
|
||||
else:
|
||||
print(f"Using MINIMAL matrix (3 configs) - feature branch/PR")
|
||||
print(f"Using MINIMAL matrix (2 configs) - feature branch/PR")
|
||||
matrix = minimal_matrix
|
||||
|
||||
# Add runs_on based on job_type
|
||||
for entry in matrix:
|
||||
if entry.get("job_type") == "coverage":
|
||||
entry["runs_on"] = '["self-hosted", "generic", 24.04]'
|
||||
else:
|
||||
entry["runs_on"] = '["self-hosted", "generic", 20.04]'
|
||||
|
||||
|
||||
# Output the matrix as JSON
|
||||
output = json.dumps({"include": matrix})
|
||||
with open(os.environ['GITHUB_OUTPUT'], 'a') as f:
|
||||
@@ -229,10 +176,7 @@ jobs:
|
||||
|
||||
build:
|
||||
needs: matrix-setup
|
||||
runs-on: ${{ fromJSON(matrix.runs_on) }}
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: read
|
||||
runs-on: [self-hosted, generic, 20.04]
|
||||
container:
|
||||
image: ubuntu:24.04
|
||||
volumes:
|
||||
@@ -261,7 +205,7 @@ jobs:
|
||||
apt-get install -y software-properties-common
|
||||
add-apt-repository ppa:ubuntu-toolchain-r/test -y
|
||||
apt-get update
|
||||
apt-get install -y git python3 python-is-python3 pipx
|
||||
apt-get install -y python3 python-is-python3 pipx
|
||||
pipx ensurepath
|
||||
apt-get install -y cmake ninja-build ${{ matrix.cc }} ${{ matrix.cxx }} ccache
|
||||
apt-get install -y perl # for openssl build
|
||||
@@ -332,12 +276,6 @@ jobs:
|
||||
pipx install "conan>=2.0,<3"
|
||||
echo "$HOME/.local/bin" >> $GITHUB_PATH
|
||||
|
||||
# Install gcovr for coverage jobs
|
||||
if [ "${{ matrix.job_type }}" = "coverage" ]; then
|
||||
pipx install "gcovr>=7,<9"
|
||||
apt-get install -y curl lcov
|
||||
fi
|
||||
|
||||
- name: Check environment
|
||||
run: |
|
||||
echo "PATH:"
|
||||
@@ -347,13 +285,6 @@ jobs:
|
||||
which ${{ matrix.cc }} && ${{ matrix.cc }} --version || echo "${{ matrix.cc }} not found"
|
||||
which ${{ matrix.cxx }} && ${{ matrix.cxx }} --version || echo "${{ matrix.cxx }} not found"
|
||||
which ccache && ccache --version || echo "ccache not found"
|
||||
|
||||
# Check gcovr for coverage jobs
|
||||
if [ "${{ matrix.job_type }}" = "coverage" ]; then
|
||||
which gcov && gcov --version || echo "gcov not found"
|
||||
which gcovr && gcovr --version || echo "gcovr not found"
|
||||
fi
|
||||
|
||||
echo "---- Full Environment ----"
|
||||
env
|
||||
|
||||
@@ -381,7 +312,6 @@ jobs:
|
||||
gha_cache_enabled: 'false' # Disable caching for self hosted runner
|
||||
|
||||
- name: Build
|
||||
if: matrix.job_type == 'build'
|
||||
uses: ./.github/actions/xahau-ga-build
|
||||
with:
|
||||
generator: Ninja
|
||||
@@ -396,27 +326,7 @@ jobs:
|
||||
clang_gcc_toolchain: ${{ matrix.clang_gcc_toolchain || '' }}
|
||||
ccache_max_size: '100G'
|
||||
|
||||
- name: Build (Coverage)
|
||||
if: matrix.job_type == 'coverage'
|
||||
uses: ./.github/actions/xahau-ga-build
|
||||
with:
|
||||
generator: Ninja
|
||||
configuration: ${{ matrix.configuration }}
|
||||
build_dir: ${{ env.build_dir }}
|
||||
cc: ${{ matrix.cc }}
|
||||
cxx: ${{ matrix.cxx }}
|
||||
gcov: ${{ matrix.gcov }}
|
||||
compiler-id: ${{ matrix.compiler_id }}
|
||||
cache_version: ${{ env.CACHE_VERSION }}
|
||||
main_branch: ${{ env.MAIN_BRANCH_NAME }}
|
||||
stdlib: ${{ matrix.stdlib }}
|
||||
# Coverage builds are slower due to instrumentation; use fewer parallel jobs to avoid flakiness
|
||||
cmake-args: '-Dcoverage=ON -Dcoverage_format=xml -Dcoverage_test_parallelism=$(($(nproc)/2)) -DCODE_COVERAGE_VERBOSE=ON -DCMAKE_CXX_FLAGS="-O0" -DCMAKE_C_FLAGS="-O0"'
|
||||
cmake-target: 'coverage'
|
||||
ccache_max_size: '100G'
|
||||
|
||||
- name: Set artifact name
|
||||
if: matrix.job_type == 'build'
|
||||
id: set-artifact-name
|
||||
run: |
|
||||
ARTIFACT_NAME="build-output-nix-${{ github.run_id }}-${{ matrix.compiler }}-${{ matrix.configuration }}"
|
||||
@@ -429,7 +339,6 @@ jobs:
|
||||
ls -la ${{ env.build_dir }} || echo "Build directory not found or empty"
|
||||
|
||||
- name: Run tests
|
||||
if: matrix.job_type == 'build'
|
||||
run: |
|
||||
# Ensure the binary exists before trying to run
|
||||
if [ -f "${{ env.build_dir }}/rippled" ]; then
|
||||
@@ -438,42 +347,3 @@ jobs:
|
||||
echo "Error: rippled executable not found in ${{ env.build_dir }}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Coverage-specific steps
|
||||
- name: Move coverage report
|
||||
if: matrix.job_type == 'coverage'
|
||||
shell: bash
|
||||
run: |
|
||||
mv "${{ env.build_dir }}/coverage.xml" ./
|
||||
|
||||
- name: Archive coverage report
|
||||
if: matrix.job_type == 'coverage'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coverage.xml
|
||||
path: coverage.xml
|
||||
retention-days: 30
|
||||
|
||||
- name: Upload coverage report
|
||||
if: matrix.job_type == 'coverage'
|
||||
uses: codecov/codecov-action@v5
|
||||
with:
|
||||
files: coverage.xml
|
||||
fail_ci_if_error: true
|
||||
disable_search: true
|
||||
verbose: true
|
||||
plugins: noop
|
||||
use_oidc: true
|
||||
|
||||
- name: Export server definitions
|
||||
if: matrix.job_type == 'build' && matrix.compiler_id == 'gcc-13-libstdcxx'
|
||||
run: |
|
||||
${{ env.build_dir }}/rippled --definitions | python3 -m json.tool > server_definitions.json
|
||||
|
||||
- name: Upload server definitions
|
||||
if: matrix.job_type == 'build' && matrix.compiler_id == 'gcc-13-libstdcxx'
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: server-definitions
|
||||
path: server_definitions.json
|
||||
archive: false
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -53,9 +53,6 @@ Builds/levelization/results/paths.txt
|
||||
Builds/levelization/results/includes/
|
||||
Builds/levelization/results/includedby/
|
||||
|
||||
# Python
|
||||
__pycache__
|
||||
|
||||
# Ignore tmp directory.
|
||||
tmp
|
||||
|
||||
@@ -79,7 +76,6 @@ docs/html_doc
|
||||
# Xcode
|
||||
.DS_Store
|
||||
*/build/*
|
||||
!/docs/build/
|
||||
*.pbxuser
|
||||
!default.pbxuser
|
||||
*.mode1v3
|
||||
|
||||
2
.mise.toml
Normal file
2
.mise.toml
Normal file
@@ -0,0 +1,2 @@
|
||||
[tools]
|
||||
clang-format = "18"
|
||||
77
BUILD.md
77
BUILD.md
@@ -10,7 +10,7 @@
|
||||
## Branches
|
||||
|
||||
For a stable release, choose the `master` branch or one of the [tagged
|
||||
releases](https://github.com/Xahau/xahaud/releases).
|
||||
releases](https://github.com/ripple/rippled/releases).
|
||||
|
||||
```
|
||||
git checkout master
|
||||
@@ -35,11 +35,17 @@ See [System Requirements](https://xrpl.org/system-requirements.html).
|
||||
|
||||
Building rippled generally requires git, Python, Conan, CMake, and a C++ compiler. Some guidance on setting up such a [C++ development environment can be found here](./docs/build/environment.md).
|
||||
|
||||
- [Python 3.7](https://www.python.org/downloads/) (configure also uses it to project the QuickJS provider)
|
||||
- [Python 3.7](https://www.python.org/downloads/)
|
||||
- [Conan 2.x](https://conan.io/downloads)
|
||||
- [CMake 3.16](https://cmake.org/download/)
|
||||
|
||||
`xahaud` is written in the C++20 dialect and includes the `<concepts>` header.
|
||||
[^1]: It is possible to build with Conan 2.x,
|
||||
but the instructions are significantly different,
|
||||
which is why we are not recommending it yet.
|
||||
Notably, the `conan profile update` command is removed in 2.x.
|
||||
Profiles must be edited by hand.
|
||||
|
||||
`rippled` is written in the C++20 dialect and includes the `<concepts>` header.
|
||||
The [minimum compiler versions][2] required are:
|
||||
|
||||
| Compiler | Version |
|
||||
@@ -58,19 +64,17 @@ Here are [sample instructions for setting up a C++ development environment on Li
|
||||
|
||||
### Mac
|
||||
|
||||
Many xahaud engineers use macOS for development.
|
||||
Many rippled engineers use macOS for development.
|
||||
|
||||
Here are [sample instructions for setting up a C++ development environment on macOS](./docs/build/environment.md#macos).
|
||||
|
||||
### Windows
|
||||
|
||||
We don't recommend Windows for `xahaud` production at this time. As of
|
||||
November 2025, Ubuntu has the highest level of quality assurance, testing,
|
||||
and support.
|
||||
Windows is not recommended for production use at this time.
|
||||
|
||||
Windows developers should use Visual Studio 2019. `xahaud` isn't
|
||||
compatible with [Boost](https://www.boost.org/) 1.78 or 1.79, and Conan
|
||||
can't build earlier Boost versions.
|
||||
- Additionally, 32-bit Windows development is not supported.
|
||||
|
||||
[Boost]: https://www.boost.org/
|
||||
|
||||
## Steps
|
||||
|
||||
@@ -140,8 +144,8 @@ conan profile show default
|
||||
An easy way to do that is to run the shortcut "x64 Native Tools Command
|
||||
Prompt" for the version of Visual Studio that you have installed.
|
||||
|
||||
Windows developers must also build `xahaud` and its dependencies for the x64
|
||||
architecture.
|
||||
Windows developers must also build `rippled` and its dependencies for the x64
|
||||
architecture:
|
||||
|
||||
```
|
||||
# In ~/.conan2/profiles/default, ensure:
|
||||
@@ -149,7 +153,10 @@ Prompt" for the version of Visual Studio that you have installed.
|
||||
arch=x86_64
|
||||
```
|
||||
|
||||
### Multiple compilers
|
||||
3. (Optional) If you have multiple compilers installed on your platform,
|
||||
make sure that Conan and CMake select the one you want to use.
|
||||
This setting will set the correct variables (`CMAKE_<LANG>_COMPILER`)
|
||||
in the generated CMake toolchain file.
|
||||
|
||||
```
|
||||
# In ~/.conan2/profiles/default, add under [conf] section:
|
||||
@@ -166,17 +173,9 @@ Prompt" for the version of Visual Studio that you have installed.
|
||||
CXX=<path>
|
||||
```
|
||||
|
||||
It should choose the compiler for dependencies as well,
|
||||
but not all of them have a Conan recipe that respects this setting (yet).
|
||||
For the rest, you can set these environment variables.
|
||||
Replace `<path>` with paths to the desired compilers:
|
||||
|
||||
- `conan profile update env.CC=<path> default`
|
||||
- `conan profile update env.CXX=<path> default`
|
||||
|
||||
Export our [Conan recipe for Snappy](./external/snappy).
|
||||
It does not explicitly link the C++ standard library,
|
||||
which allows you to statically link it with GCC, if you want.
|
||||
4. Export our [Conan recipe for Snappy](./external/snappy).
|
||||
It doesn't explicitly link the C++ standard library,
|
||||
which allows you to statically link it with GCC, if you want.
|
||||
|
||||
```
|
||||
conan export external/snappy --version 1.1.10 --user xahaud --channel stable
|
||||
@@ -185,16 +184,6 @@ which allows you to statically link it with GCC, if you want.
|
||||
Export our [Conan recipe for RocksDB](./external/rocksdb).
|
||||
It does not override paths to dependencies when building with Visual Studio.
|
||||
|
||||
```
|
||||
# Conan 1.x
|
||||
conan export external/rocksdb rocksdb/6.29.5@
|
||||
# Conan 2.x
|
||||
conan export --version 6.29.5 external/rocksdb
|
||||
```
|
||||
|
||||
Export our [Conan recipe for SOCI](./external/soci).
|
||||
It patches their CMake to correctly import its dependencies.
|
||||
|
||||
```
|
||||
conan export external/soci --version 4.0.3 --user xahaud --channel stable
|
||||
```
|
||||
@@ -205,17 +194,6 @@ It patches their CMake to correctly import its dependencies.
|
||||
conan export external/wasmedge --version 0.11.2 --user xahaud --channel stable
|
||||
```
|
||||
|
||||
Export our [Conan recipe for NuDB](./external/nudb).
|
||||
It fixes some source files to add missing `#include`s.
|
||||
|
||||
|
||||
```
|
||||
# Conan 1.x
|
||||
conan export external/nudb nudb/2.0.8@
|
||||
# Conan 2.x
|
||||
conan export --version 2.0.8 external/nudb
|
||||
```
|
||||
|
||||
### Build and Test
|
||||
|
||||
1. Create a build directory and move into it.
|
||||
@@ -289,14 +267,13 @@ It fixes some source files to add missing `#include`s.
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake -Dxrpld=ON -Dtests=ON ..
|
||||
```
|
||||
|
||||
**Note:** You can pass build options for `xahaud` in this step.
|
||||
**Note:** You can pass build options for `rippled` in this step.
|
||||
|
||||
4. Build `xahaud`.
|
||||
5. Build `rippled`.
|
||||
|
||||
For a single-configuration generator, it will build whatever configuration
|
||||
you passed for `CMAKE_BUILD_TYPE`. For a multi-configuration generator,
|
||||
you must pass the option `--config` to select the build configuration.
|
||||
The output file is currently named 'rippled'.
|
||||
|
||||
Single-config generators:
|
||||
|
||||
@@ -311,7 +288,7 @@ It fixes some source files to add missing `#include`s.
|
||||
cmake --build . --config Debug
|
||||
```
|
||||
|
||||
5. Test xahaud.
|
||||
6. Test rippled.
|
||||
|
||||
Single-config generators:
|
||||
|
||||
@@ -326,7 +303,7 @@ It fixes some source files to add missing `#include`s.
|
||||
./Debug/rippled --unittest
|
||||
```
|
||||
|
||||
The location of `xahaud` in your build directory depends on your CMake
|
||||
The location of `rippled` in your build directory depends on your CMake
|
||||
generator. Pass `--help` to see the rest of the command line options.
|
||||
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ that `test` code should *never* be included in `ripple` code.)
|
||||
|
||||
## Validation
|
||||
|
||||
The [levelization.py](levelization.py) script takes no parameters,
|
||||
The [levelization.sh](levelization.sh) script takes no parameters,
|
||||
reads no environment variables, and can be run from any directory,
|
||||
as long as it is in the expected location in the rippled repo.
|
||||
It can be run at any time from within a checked out repo, and will
|
||||
@@ -84,7 +84,7 @@ It generates many files of [results](results):
|
||||
Github Actions workflow to test that levelization loops haven't
|
||||
changed. Unfortunately, if changes are detected, it can't tell if
|
||||
they are improvements or not, so if you have resolved any issues or
|
||||
done anything else to improve levelization, run `levelization.py`,
|
||||
done anything else to improve levelization, run `levelization.sh`,
|
||||
and commit the updated results.
|
||||
|
||||
The `loops.txt` and `ordering.txt` files relate the modules
|
||||
@@ -108,7 +108,7 @@ The committed files hide the detailed values intentionally, to
|
||||
prevent false alarms and merging issues, and because it's easy to
|
||||
get those details locally.
|
||||
|
||||
1. Run `levelization.py`
|
||||
1. Run `levelization.sh`
|
||||
2. Grep the modules in `paths.txt`.
|
||||
* For example, if a cycle is found `A ~= B`, simply `grep -w
|
||||
A Builds/levelization/results/paths.txt | grep -w B`
|
||||
|
||||
@@ -1,283 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
Usage: levelization.py
|
||||
This script takes no parameters, and can be called from any directory in the file system.
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from collections import defaultdict
|
||||
from pathlib import Path
|
||||
|
||||
# Compile regex patterns once at module level
|
||||
INCLUDE_PATTERN = re.compile(r"^\s*#include.*/.*\.h")
|
||||
INCLUDE_PATH_PATTERN = re.compile(r'[<"]([^>"]+)[>"]')
|
||||
|
||||
|
||||
def dictionary_sort_key(s):
|
||||
"""
|
||||
Create a sort key that mimics 'sort -d' (dictionary order).
|
||||
Dictionary order only considers blanks and alphanumeric characters.
|
||||
"""
|
||||
return "".join(c for c in s if c.isalnum() or c.isspace())
|
||||
|
||||
|
||||
def get_level(file_path):
|
||||
"""
|
||||
Extract the level from a file path (second and third directory components).
|
||||
Equivalent to bash: cut -d/ -f 2,3
|
||||
|
||||
Examples:
|
||||
src/ripple/app/main.cpp -> ripple.app
|
||||
src/test/app/Import_test.cpp -> test.app
|
||||
"""
|
||||
parts = file_path.split("/")
|
||||
|
||||
if len(parts) >= 3:
|
||||
level = f"{parts[1]}/{parts[2]}"
|
||||
elif len(parts) >= 2:
|
||||
level = f"{parts[1]}/toplevel"
|
||||
else:
|
||||
level = file_path
|
||||
|
||||
# If the "level" indicates a file, cut off the filename
|
||||
if "." in level.split("/")[-1]:
|
||||
# Use the "toplevel" label as a workaround for `sort`
|
||||
# inconsistencies between different utility versions
|
||||
level = level.rsplit("/", 1)[0] + "/toplevel"
|
||||
|
||||
return level.replace("/", ".")
|
||||
|
||||
|
||||
def extract_include_level(include_line):
|
||||
"""
|
||||
Extract the include path from an #include directive.
|
||||
Gets the first two directory components from the include path.
|
||||
Equivalent to bash: cut -d/ -f 1,2
|
||||
|
||||
Examples:
|
||||
#include <ripple/basics/base_uint.h> -> ripple.basics
|
||||
#include "ripple/app/main/Application.h" -> ripple.app
|
||||
"""
|
||||
match = INCLUDE_PATH_PATTERN.search(include_line)
|
||||
if not match:
|
||||
return None
|
||||
|
||||
include_path = match.group(1)
|
||||
parts = include_path.split("/")
|
||||
|
||||
if len(parts) >= 2:
|
||||
include_level = f"{parts[0]}/{parts[1]}"
|
||||
else:
|
||||
include_level = include_path
|
||||
|
||||
# If the "includelevel" indicates a file, cut off the filename
|
||||
if "." in include_level.split("/")[-1]:
|
||||
include_level = include_level.rsplit("/", 1)[0] + "/toplevel"
|
||||
|
||||
return include_level.replace("/", ".")
|
||||
|
||||
|
||||
def find_repository_directories(start_path, depth_limit=10):
|
||||
"""
|
||||
Find the repository root by looking for src or include folders.
|
||||
Walks up the directory tree from the start path.
|
||||
"""
|
||||
current = start_path.resolve()
|
||||
|
||||
for _ in range(depth_limit):
|
||||
src_path = current / "src"
|
||||
include_path = current / "include"
|
||||
has_src = src_path.exists()
|
||||
has_include = include_path.exists()
|
||||
|
||||
if has_src or has_include:
|
||||
dirs = []
|
||||
if has_src:
|
||||
dirs.append(src_path)
|
||||
if has_include:
|
||||
dirs.append(include_path)
|
||||
return current, dirs
|
||||
|
||||
parent = current.parent
|
||||
if parent == current:
|
||||
break
|
||||
current = parent
|
||||
|
||||
raise RuntimeError(
|
||||
"Could not find repository root. "
|
||||
"Expected to find a directory containing 'src' and/or 'include' folders."
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
script_dir = Path(__file__).parent.resolve()
|
||||
os.chdir(script_dir)
|
||||
|
||||
# Clean up and create results directory.
|
||||
results_dir = script_dir / "results"
|
||||
if results_dir.exists():
|
||||
import shutil
|
||||
|
||||
shutil.rmtree(results_dir)
|
||||
results_dir.mkdir()
|
||||
|
||||
# Find the repository root.
|
||||
try:
|
||||
repo_root, scan_dirs = find_repository_directories(script_dir)
|
||||
print(f"Found repository root: {repo_root}")
|
||||
for scan_dir in scan_dirs:
|
||||
print(f" Scanning: {scan_dir.relative_to(repo_root)}")
|
||||
except RuntimeError as e:
|
||||
print(f"Error: {e}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
# Find all #include directives.
|
||||
print("\nScanning for raw includes...")
|
||||
raw_includes = []
|
||||
rawincludes_file = results_dir / "rawincludes.txt"
|
||||
|
||||
with open(rawincludes_file, "w", buffering=8192) as raw_f:
|
||||
for dir_path in scan_dirs:
|
||||
for file_path in dir_path.rglob("*"):
|
||||
if not file_path.is_file():
|
||||
continue
|
||||
try:
|
||||
rel_path_str = str(file_path.relative_to(repo_root))
|
||||
with open(
|
||||
file_path, "r", encoding="utf-8", errors="ignore", buffering=8192
|
||||
) as f:
|
||||
for line in f:
|
||||
if "#include" not in line or "boost" in line:
|
||||
continue
|
||||
if INCLUDE_PATTERN.match(line):
|
||||
line_stripped = line.strip()
|
||||
entry = f"{rel_path_str}:{line_stripped}\n"
|
||||
print(entry, end="")
|
||||
raw_f.write(entry)
|
||||
raw_includes.append((rel_path_str, line_stripped))
|
||||
except Exception as e:
|
||||
print(f"Error reading {file_path}: {e}", file=sys.stderr)
|
||||
|
||||
# Build levelization paths and count directly.
|
||||
print("Build levelization paths")
|
||||
path_counts = defaultdict(int)
|
||||
|
||||
for file_path, include_line in raw_includes:
|
||||
include_level = extract_include_level(include_line)
|
||||
if not include_level:
|
||||
continue
|
||||
level = get_level(file_path)
|
||||
if level != include_level:
|
||||
path_counts[(level, include_level)] += 1
|
||||
|
||||
# Sort and deduplicate paths.
|
||||
print("Sort and deduplicate paths")
|
||||
sorted_items = sorted(
|
||||
path_counts.items(),
|
||||
key=lambda x: (dictionary_sort_key(x[0][0]), dictionary_sort_key(x[0][1])),
|
||||
)
|
||||
|
||||
paths_file = results_dir / "paths.txt"
|
||||
with open(paths_file, "w") as f:
|
||||
for (level, include_level), count in sorted_items:
|
||||
line = f"{count:7} {level} {include_level}\n"
|
||||
print(line.rstrip())
|
||||
f.write(line)
|
||||
|
||||
# Split into flat-file database.
|
||||
print("Split into flat-file database")
|
||||
includes_dir = results_dir / "includes"
|
||||
includedby_dir = results_dir / "includedby"
|
||||
includes_dir.mkdir()
|
||||
includedby_dir.mkdir()
|
||||
|
||||
includes_data = defaultdict(list)
|
||||
includedby_data = defaultdict(list)
|
||||
|
||||
for (level, include_level), count in sorted_items:
|
||||
includes_data[level].append((include_level, count))
|
||||
includedby_data[include_level].append((level, count))
|
||||
|
||||
for level in sorted(includes_data.keys(), key=dictionary_sort_key):
|
||||
with open(includes_dir / level, "w") as f:
|
||||
for include_level, count in includes_data[level]:
|
||||
line = f"{include_level} {count}\n"
|
||||
print(line.rstrip())
|
||||
f.write(line)
|
||||
|
||||
for include_level in sorted(includedby_data.keys(), key=dictionary_sort_key):
|
||||
with open(includedby_dir / include_level, "w") as f:
|
||||
for level, count in includedby_data[include_level]:
|
||||
line = f"{level} {count}\n"
|
||||
print(line.rstrip())
|
||||
f.write(line)
|
||||
|
||||
# Search for loops.
|
||||
print("Search for loops")
|
||||
loops_file = results_dir / "loops.txt"
|
||||
ordering_file = results_dir / "ordering.txt"
|
||||
|
||||
# Pre-load all include files into memory for fast lookup.
|
||||
includes_cache = {}
|
||||
includes_lookup = {}
|
||||
|
||||
for include_file in sorted(includes_dir.iterdir(), key=lambda p: p.name):
|
||||
if not include_file.is_file():
|
||||
continue
|
||||
includes_cache[include_file.name] = []
|
||||
includes_lookup[include_file.name] = {}
|
||||
with open(include_file, "r") as f:
|
||||
for line in f:
|
||||
parts = line.strip().split()
|
||||
if len(parts) >= 2:
|
||||
name, count = parts[0], int(parts[1])
|
||||
includes_cache[include_file.name].append((name, count))
|
||||
includes_lookup[include_file.name][name] = count
|
||||
|
||||
loops_found = set()
|
||||
|
||||
with open(loops_file, "w", buffering=8192) as loops_f, open(
|
||||
ordering_file, "w", buffering=8192
|
||||
) as ordering_f:
|
||||
for source in sorted(includes_cache.keys()):
|
||||
for include, include_freq in includes_cache[source]:
|
||||
if include not in includes_lookup:
|
||||
continue
|
||||
|
||||
source_freq = includes_lookup[include].get(source)
|
||||
|
||||
if source_freq is not None:
|
||||
loop_key = tuple(sorted([source, include]))
|
||||
if loop_key in loops_found:
|
||||
continue
|
||||
loops_found.add(loop_key)
|
||||
|
||||
loops_f.write(f"Loop: {source} {include}\n")
|
||||
|
||||
diff = include_freq - source_freq
|
||||
if diff > 3:
|
||||
loops_f.write(f" {source} > {include}\n\n")
|
||||
elif diff < -3:
|
||||
loops_f.write(f" {include} > {source}\n\n")
|
||||
elif source_freq == include_freq:
|
||||
loops_f.write(f" {include} == {source}\n\n")
|
||||
else:
|
||||
loops_f.write(f" {include} ~= {source}\n\n")
|
||||
else:
|
||||
ordering_f.write(f"{source} > {include}\n")
|
||||
|
||||
# Print results.
|
||||
print("\nOrdering:")
|
||||
with open(ordering_file, "r") as f:
|
||||
print(f.read(), end="")
|
||||
|
||||
print("\nLoops:")
|
||||
with open(loops_file, "r") as f:
|
||||
print(f.read(), end="")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
130
Builds/levelization/levelization.sh
Executable file
130
Builds/levelization/levelization.sh
Executable file
@@ -0,0 +1,130 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Usage: levelization.sh
|
||||
# This script takes no parameters, reads no environment variables,
|
||||
# and can be run from any directory, as long as it is in the expected
|
||||
# location in the repo.
|
||||
|
||||
pushd $( dirname $0 )
|
||||
|
||||
if [ -v PS1 ]
|
||||
then
|
||||
# if the shell is interactive, clean up any flotsam before analyzing
|
||||
git clean -ix
|
||||
fi
|
||||
|
||||
# Ensure all sorting is ASCII-order consistently across platforms.
|
||||
export LANG=C
|
||||
|
||||
rm -rfv results
|
||||
mkdir results
|
||||
includes="$( pwd )/results/rawincludes.txt"
|
||||
pushd ../..
|
||||
echo Raw includes:
|
||||
grep -r '^[ ]*#include.*/.*\.h' include src | \
|
||||
grep -v boost | tee ${includes}
|
||||
popd
|
||||
pushd results
|
||||
|
||||
oldifs=${IFS}
|
||||
IFS=:
|
||||
mkdir includes
|
||||
mkdir includedby
|
||||
echo Build levelization paths
|
||||
exec 3< ${includes} # open rawincludes.txt for input
|
||||
while read -r -u 3 file include
|
||||
do
|
||||
level=$( echo ${file} | cut -d/ -f 2,3 )
|
||||
# If the "level" indicates a file, cut off the filename
|
||||
if [[ "${level##*.}" != "${level}" ]]
|
||||
then
|
||||
# Use the "toplevel" label as a workaround for `sort`
|
||||
# inconsistencies between different utility versions
|
||||
level="$( dirname ${level} )/toplevel"
|
||||
fi
|
||||
level=$( echo ${level} | tr '/' '.' )
|
||||
|
||||
includelevel=$( echo ${include} | sed 's/.*["<]//; s/[">].*//' | \
|
||||
cut -d/ -f 1,2 )
|
||||
if [[ "${includelevel##*.}" != "${includelevel}" ]]
|
||||
then
|
||||
# Use the "toplevel" label as a workaround for `sort`
|
||||
# inconsistencies between different utility versions
|
||||
includelevel="$( dirname ${includelevel} )/toplevel"
|
||||
fi
|
||||
includelevel=$( echo ${includelevel} | tr '/' '.' )
|
||||
|
||||
if [[ "$level" != "$includelevel" ]]
|
||||
then
|
||||
echo $level $includelevel | tee -a paths.txt
|
||||
fi
|
||||
done
|
||||
echo Sort and dedup paths
|
||||
sort -ds paths.txt | uniq -c | tee sortedpaths.txt
|
||||
mv sortedpaths.txt paths.txt
|
||||
exec 3>&- #close fd 3
|
||||
IFS=${oldifs}
|
||||
unset oldifs
|
||||
|
||||
echo Split into flat-file database
|
||||
exec 4<paths.txt # open paths.txt for input
|
||||
while read -r -u 4 count level include
|
||||
do
|
||||
echo ${include} ${count} | tee -a includes/${level}
|
||||
echo ${level} ${count} | tee -a includedby/${include}
|
||||
done
|
||||
exec 4>&- #close fd 4
|
||||
|
||||
loops="$( pwd )/loops.txt"
|
||||
ordering="$( pwd )/ordering.txt"
|
||||
pushd includes
|
||||
echo Search for loops
|
||||
# Redirect stdout to a file
|
||||
exec 4>&1
|
||||
exec 1>"${loops}"
|
||||
for source in *
|
||||
do
|
||||
if [[ -f "$source" ]]
|
||||
then
|
||||
exec 5<"${source}" # open for input
|
||||
while read -r -u 5 include includefreq
|
||||
do
|
||||
if [[ -f $include ]]
|
||||
then
|
||||
if grep -q -w $source $include
|
||||
then
|
||||
if grep -q -w "Loop: $include $source" "${loops}"
|
||||
then
|
||||
continue
|
||||
fi
|
||||
sourcefreq=$( grep -w $source $include | cut -d\ -f2 )
|
||||
echo "Loop: $source $include"
|
||||
# If the counts are close, indicate that the two modules are
|
||||
# on the same level, though they shouldn't be
|
||||
if [[ $(( $includefreq - $sourcefreq )) -gt 3 ]]
|
||||
then
|
||||
echo -e " $source > $include\n"
|
||||
elif [[ $(( $sourcefreq - $includefreq )) -gt 3 ]]
|
||||
then
|
||||
echo -e " $include > $source\n"
|
||||
elif [[ $sourcefreq -eq $includefreq ]]
|
||||
then
|
||||
echo -e " $include == $source\n"
|
||||
else
|
||||
echo -e " $include ~= $source\n"
|
||||
fi
|
||||
else
|
||||
echo "$source > $include" >> "${ordering}"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
exec 5>&- #close fd 5
|
||||
fi
|
||||
done
|
||||
exec 1>&4 #close fd 1
|
||||
exec 4>&- #close fd 4
|
||||
cat "${ordering}"
|
||||
cat "${loops}"
|
||||
popd
|
||||
popd
|
||||
popd
|
||||
@@ -10,6 +10,9 @@ Loop: test.jtx test.toplevel
|
||||
Loop: test.jtx test.unit_test
|
||||
test.unit_test == test.jtx
|
||||
|
||||
Loop: xrpl.hook xrpld.app
|
||||
xrpld.app > xrpl.hook
|
||||
|
||||
Loop: xrpl.protocol xrpld.app
|
||||
xrpld.app > xrpl.protocol
|
||||
|
||||
|
||||
@@ -84,7 +84,6 @@ test.nodestore > xrpl.basics
|
||||
test.nodestore > xrpld.core
|
||||
test.nodestore > xrpld.nodestore
|
||||
test.nodestore > xrpld.unity
|
||||
test.nodestore > xrpl.protocol
|
||||
test.overlay > test.jtx
|
||||
test.overlay > test.toplevel
|
||||
test.overlay > test.unit_test
|
||||
@@ -119,7 +118,6 @@ test.rpc > xrpld.core
|
||||
test.rpc > xrpld.net
|
||||
test.rpc > xrpld.overlay
|
||||
test.rpc > xrpld.rpc
|
||||
test.rpc > xrpld.shamap
|
||||
test.rpc > xrpl.hook
|
||||
test.rpc > xrpl.json
|
||||
test.rpc > xrpl.protocol
|
||||
@@ -157,7 +155,6 @@ xrpld.app > xrpl.basics
|
||||
xrpld.app > xrpld.conditions
|
||||
xrpld.app > xrpld.consensus
|
||||
xrpld.app > xrpld.perflog
|
||||
xrpld.app > xrpl.hook
|
||||
xrpld.app > xrpl.json
|
||||
xrpld.app > xrpl.resource
|
||||
xrpld.conditions > xrpl.basics
|
||||
|
||||
142
CMakeLists.txt
142
CMakeLists.txt
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
cmake_minimum_required (VERSION 3.16)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
@@ -18,52 +18,41 @@ if(POLICY CMP0144)
|
||||
cmake_policy(SET CMP0144 NEW)
|
||||
endif()
|
||||
|
||||
project(xrpl)
|
||||
project (xrpl)
|
||||
set(Boost_NO_BOOST_CMAKE ON)
|
||||
|
||||
# make GIT_COMMIT_HASH define available to all sources
|
||||
find_package(Git)
|
||||
if(Git_FOUND)
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} --git-dir=${CMAKE_CURRENT_SOURCE_DIR}/.git
|
||||
rev-parse HEAD
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
OUTPUT_VARIABLE gch)
|
||||
if(gch)
|
||||
set(GIT_COMMIT_HASH "${gch}")
|
||||
message(STATUS gch: ${GIT_COMMIT_HASH})
|
||||
add_definitions(-DGIT_COMMIT_HASH="${GIT_COMMIT_HASH}")
|
||||
endif()
|
||||
execute_process(COMMAND ${GIT_EXECUTABLE} --git-dir=${CMAKE_CURRENT_SOURCE_DIR}/.git rev-parse HEAD
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE gch)
|
||||
if(gch)
|
||||
set(GIT_COMMIT_HASH "${gch}")
|
||||
message(STATUS gch: ${GIT_COMMIT_HASH})
|
||||
add_definitions(-DGIT_COMMIT_HASH="${GIT_COMMIT_HASH}")
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} --git-dir=${CMAKE_CURRENT_SOURCE_DIR}/.git
|
||||
rev-parse --abbrev-ref HEAD
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
OUTPUT_VARIABLE gb)
|
||||
if(gb)
|
||||
set(GIT_BRANCH "${gb}")
|
||||
message(STATUS gb: ${GIT_BRANCH})
|
||||
add_definitions(-DGIT_BRANCH="${GIT_BRANCH}")
|
||||
endif()
|
||||
endif() # git
|
||||
execute_process(COMMAND ${GIT_EXECUTABLE} --git-dir=${CMAKE_CURRENT_SOURCE_DIR}/.git rev-parse --abbrev-ref HEAD
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE gb)
|
||||
if(gb)
|
||||
set(GIT_BRANCH "${gb}")
|
||||
message(STATUS gb: ${GIT_BRANCH})
|
||||
add_definitions(-DGIT_BRANCH="${GIT_BRANCH}")
|
||||
endif()
|
||||
endif() #git
|
||||
|
||||
# make SOURCE_ROOT_PATH define available for logging
|
||||
set(SOURCE_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/src/")
|
||||
add_definitions(-DSOURCE_ROOT_PATH="${SOURCE_ROOT_PATH}")
|
||||
|
||||
# BEAST_ENHANCED_LOGGING - adds file:line numbers and formatting to logs
|
||||
# Automatically enabled for Debug builds via generator expression Can be
|
||||
# explicitly controlled with -DBEAST_ENHANCED_LOGGING=ON/OFF
|
||||
option(
|
||||
BEAST_ENHANCED_LOGGING
|
||||
"Include file and line numbers in log messages (auto: Debug=ON, Release=OFF)"
|
||||
OFF)
|
||||
# Automatically enabled for Debug builds via generator expression
|
||||
# Can be explicitly controlled with -DBEAST_ENHANCED_LOGGING=ON/OFF
|
||||
option(BEAST_ENHANCED_LOGGING "Include file and line numbers in log messages (auto: Debug=ON, Release=OFF)" OFF)
|
||||
message(STATUS "BEAST_ENHANCED_LOGGING option: ${BEAST_ENHANCED_LOGGING}")
|
||||
|
||||
if(thread_safety_analysis)
|
||||
add_compile_options(
|
||||
-Wthread-safety -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
|
||||
-DRIPPLE_ENABLE_THREAD_SAFETY_ANNOTATIONS)
|
||||
add_compile_options(-Wthread-safety -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS -DRIPPLE_ENABLE_THREAD_SAFETY_ANNOTATIONS)
|
||||
add_compile_options("-stdlib=libc++")
|
||||
add_link_options("-stdlib=libc++")
|
||||
endif()
|
||||
@@ -73,48 +62,40 @@ option(USE_CONAN "Use Conan package manager for dependencies" OFF)
|
||||
if(CMAKE_TOOLCHAIN_FILE)
|
||||
# Check if the toolchain file path contains "conan_toolchain"
|
||||
if(CMAKE_TOOLCHAIN_FILE MATCHES "conan_toolchain")
|
||||
set(USE_CONAN
|
||||
ON
|
||||
CACHE BOOL "Using Conan detected from toolchain file" FORCE)
|
||||
set(USE_CONAN ON CACHE BOOL "Using Conan detected from toolchain file" FORCE)
|
||||
message(STATUS "Conan toolchain detected: ${CMAKE_TOOLCHAIN_FILE}")
|
||||
message(STATUS "Building with Conan dependencies")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include(CheckCXXCompilerFlag)
|
||||
include(FetchContent)
|
||||
include(ExternalProject)
|
||||
include(CMakeFuncs) # must come *after* ExternalProject b/c it overrides one
|
||||
# function in EP
|
||||
if(target)
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"The target option has been removed - use native cmake options to control build"
|
||||
)
|
||||
endif()
|
||||
include (CheckCXXCompilerFlag)
|
||||
include (FetchContent)
|
||||
include (ExternalProject)
|
||||
include (CMakeFuncs) # must come *after* ExternalProject b/c it overrides one function in EP
|
||||
if (target)
|
||||
message (FATAL_ERROR "The target option has been removed - use native cmake options to control build")
|
||||
endif ()
|
||||
|
||||
include(RippledSanity)
|
||||
include(RippledVersion)
|
||||
include(RippledSettings)
|
||||
|
||||
# this check has to remain in the top-level cmake because of the early return
|
||||
# statement
|
||||
if(packages_only)
|
||||
if(NOT TARGET rpm)
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"packages_only requested, but targets were not created - is docker installed?"
|
||||
)
|
||||
# this check has to remain in the top-level cmake
|
||||
# because of the early return statement
|
||||
if (packages_only)
|
||||
if (NOT TARGET rpm)
|
||||
message (FATAL_ERROR "packages_only requested, but targets were not created - is docker installed?")
|
||||
endif()
|
||||
return()
|
||||
endif()
|
||||
return ()
|
||||
endif ()
|
||||
include(RippledCompiler)
|
||||
include(RippledInterface)
|
||||
|
||||
include(deps/Boost)
|
||||
find_package(OpenSSL 1.1.1 REQUIRED)
|
||||
set_target_properties(OpenSSL::SSL PROPERTIES INTERFACE_COMPILE_DEFINITIONS
|
||||
OPENSSL_NO_SSL2)
|
||||
set_target_properties(OpenSSL::SSL PROPERTIES
|
||||
INTERFACE_COMPILE_DEFINITIONS OPENSSL_NO_SSL2
|
||||
)
|
||||
set(SECP256K1_INSTALL TRUE)
|
||||
add_subdirectory(external/secp256k1)
|
||||
add_library(secp256k1::secp256k1 ALIAS secp256k1)
|
||||
@@ -122,33 +103,25 @@ add_subdirectory(external/ed25519-donna)
|
||||
add_subdirectory(external/antithesis-sdk)
|
||||
find_package(gRPC REQUIRED)
|
||||
find_package(lz4 REQUIRED)
|
||||
# Target names with :: are not allowed in a generator expression. We need to
|
||||
# pull the include directories and imported location properties from separate
|
||||
# targets.
|
||||
# Target names with :: are not allowed in a generator expression.
|
||||
# We need to pull the include directories and imported location properties
|
||||
# from separate targets.
|
||||
find_package(LibArchive REQUIRED)
|
||||
find_package(SOCI REQUIRED)
|
||||
find_package(SQLite3 REQUIRED)
|
||||
|
||||
include(deps/WasmEdge)
|
||||
option(rocksdb "Enable RocksDB" ON)
|
||||
if(rocksdb)
|
||||
find_package(RocksDB REQUIRED)
|
||||
set_target_properties(
|
||||
RocksDB::rocksdb PROPERTIES INTERFACE_COMPILE_DEFINITIONS
|
||||
RIPPLE_ROCKSDB_AVAILABLE=1)
|
||||
set_target_properties(RocksDB::rocksdb PROPERTIES
|
||||
INTERFACE_COMPILE_DEFINITIONS RIPPLE_ROCKSDB_AVAILABLE=1
|
||||
)
|
||||
target_link_libraries(ripple_libs INTERFACE RocksDB::rocksdb)
|
||||
endif()
|
||||
|
||||
find_package(nudb REQUIRED)
|
||||
find_package(date REQUIRED)
|
||||
find_package(xxHash REQUIRED)
|
||||
find_package(magic_enum REQUIRED)
|
||||
|
||||
include(deps/WasmEdge)
|
||||
if(xrpld)
|
||||
include(deps/Wasmtime)
|
||||
include(QuickJSProvider)
|
||||
endif()
|
||||
if(TARGET nudb::core)
|
||||
if(TARGET nudb::core)
|
||||
set(nudb nudb::core)
|
||||
elseif(TARGET NuDB::nudb)
|
||||
set(nudb NuDB::nudb)
|
||||
@@ -157,16 +130,17 @@ else()
|
||||
endif()
|
||||
target_link_libraries(ripple_libs INTERFACE ${nudb})
|
||||
|
||||
target_link_libraries(
|
||||
ripple_libs
|
||||
INTERFACE ed25519::ed25519
|
||||
LibArchive::LibArchive
|
||||
lz4::lz4
|
||||
OpenSSL::Crypto
|
||||
OpenSSL::SSL
|
||||
secp256k1::secp256k1
|
||||
soci::soci
|
||||
SQLite::SQLite3)
|
||||
target_link_libraries(ripple_libs INTERFACE
|
||||
ed25519::ed25519
|
||||
lz4::lz4
|
||||
OpenSSL::Crypto
|
||||
OpenSSL::SSL
|
||||
# Ripple::grpc_pbufs
|
||||
# Ripple::pbufs
|
||||
secp256k1::secp256k1
|
||||
soci::soci
|
||||
SQLite::SQLite3
|
||||
)
|
||||
|
||||
if(coverage)
|
||||
include(RippledCov)
|
||||
|
||||
@@ -57,12 +57,12 @@ Ensure that your code compiles according to the build instructions in the
|
||||
[`documentation`](https://docs.xahau.network/infrastructure/building-xahau).
|
||||
If you create new source files, they must go under `src/ripple`.
|
||||
You will need to add them to one of the
|
||||
[source lists](./Builds/CMake/RippledCore.cmake) in CMake.
|
||||
[source lists](./cmake/RippledCore.cmake) in CMake.
|
||||
|
||||
Please write tests for your code.
|
||||
If you create new test source files, they must go under `src/test`.
|
||||
You will need to add them to one of the
|
||||
[source lists](./Builds/CMake/RippledCore.cmake) in CMake.
|
||||
[source lists](./cmake/RippledCore.cmake) in CMake.
|
||||
If your test can be run offline, in under 60 seconds, then it can be an
|
||||
automatic test run by `rippled --unittest`.
|
||||
Otherwise, it must be a manual test.
|
||||
|
||||
@@ -12,7 +12,7 @@ The server software that powers Xahau is called `xahaud` and is available in thi
|
||||
|
||||
### Build from Source
|
||||
|
||||
* [Read the build instructions in our documentation](https://xahau.network/docs/infrastructure/build-xahaud/)
|
||||
* [Read the build instructions in our documentation](https://xahau.network/infrastructure/building-xahau)
|
||||
* If you encounter any issues, please [open an issue](https://github.com/xahau/xahaud/issues)
|
||||
|
||||
## Highlights of Xahau
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
set -o errexit
|
||||
|
||||
marker_base=f62f74da10c5936c64bd16cd509a8b68f1464e41
|
||||
marker_base=34be0ce4fef20c978df2923c29321ad6cc17facc
|
||||
marker_commit=${1:-${marker_base}}
|
||||
|
||||
if [ $(git merge-base ${marker_commit} ${marker_base}) != ${marker_base} ]; then
|
||||
|
||||
@@ -1,148 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Build and import one committed jshookz provider snapshot into Xahau."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import shlex
|
||||
import shutil
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
SNAPSHOT_FILES = (
|
||||
"jshookz_provider.manifest.cmake",
|
||||
"jshookz_provider.manifest.json",
|
||||
"jshookz_provider.native-abi.json",
|
||||
"jshookz_provider.wasm",
|
||||
)
|
||||
API_SNAPSHOT_FILES = {
|
||||
"python/jshookz/src/jshookz/types/api-artifacts.json": "api-artifacts.json",
|
||||
"python/jshookz/src/jshookz/types/hooks-api.d.ts": "hooks-api.d.ts",
|
||||
"python/jshookz/src/jshookz/types/xahau-quickjs-v1.d.ts":
|
||||
"xahau-quickjs-v1.d.ts",
|
||||
"python/jshookz/src/jshookz/types/xahau-quickjs-v1.surface.json":
|
||||
"xahau-quickjs-v1.surface.json",
|
||||
}
|
||||
|
||||
|
||||
def run(*args: str, cwd: Path, capture: bool = False) -> str:
|
||||
completed = subprocess.run(
|
||||
args,
|
||||
cwd=cwd,
|
||||
check=True,
|
||||
text=True,
|
||||
stdout=subprocess.PIPE if capture else None,
|
||||
)
|
||||
return completed.stdout.strip() if capture else ""
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(
|
||||
description=(
|
||||
"Build a committed jshookz checkout and copy its sealed "
|
||||
"provider lock into Xahau. CI tracks jshookz main; the lock "
|
||||
"is what must match."
|
||||
)
|
||||
)
|
||||
parser.add_argument("jshookz_checkout", type=Path)
|
||||
parser.add_argument(
|
||||
"--no-build",
|
||||
action="store_true",
|
||||
help="import an already-built build/xahau-provider bundle",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
xahau_root = Path(__file__).resolve().parents[1]
|
||||
jshookz_root = args.jshookz_checkout.expanduser().resolve()
|
||||
cli = next(
|
||||
(
|
||||
candidate
|
||||
for candidate in (
|
||||
jshookz_root / "python/jshookz/.venv/bin/jshookz",
|
||||
jshookz_root / "packages/jshookz/.venv/bin/jshookz",
|
||||
)
|
||||
if candidate.is_file()
|
||||
),
|
||||
None,
|
||||
)
|
||||
if cli is None:
|
||||
parser.error(
|
||||
"missing jshookz CLI under python/jshookz/.venv or "
|
||||
"packages/jshookz/.venv"
|
||||
)
|
||||
bundle = jshookz_root / "build/xahau-provider"
|
||||
destination = xahau_root / "external/quickjs-provider"
|
||||
|
||||
dirty = run(
|
||||
"git",
|
||||
"status",
|
||||
"--porcelain",
|
||||
"--untracked-files=no",
|
||||
cwd=jshookz_root,
|
||||
capture=True,
|
||||
)
|
||||
if dirty:
|
||||
parser.error(
|
||||
"jshookz checkout has uncommitted tracked changes; commit them "
|
||||
"before creating a pinned snapshot"
|
||||
)
|
||||
|
||||
commit = run("git", "rev-parse", "HEAD", cwd=jshookz_root, capture=True)
|
||||
if not args.no_build:
|
||||
run(str(cli), "build", "provider", cwd=jshookz_root)
|
||||
|
||||
missing = [name for name in SNAPSHOT_FILES if not (bundle / name).is_file()]
|
||||
missing.extend(
|
||||
source for source in API_SNAPSHOT_FILES if not (jshookz_root / source).is_file()
|
||||
)
|
||||
if missing:
|
||||
parser.error(f"incomplete provider bundle: {', '.join(missing)}")
|
||||
|
||||
for name in SNAPSHOT_FILES:
|
||||
shutil.copy2(bundle / name, destination / name)
|
||||
for source, name in API_SNAPSHOT_FILES.items():
|
||||
shutil.copy2(jshookz_root / source, destination / name)
|
||||
|
||||
manifest = json.loads((bundle / "jshookz_provider.manifest.json").read_text())
|
||||
wasi_sdk = os.environ.get("HOOKZ_WASI_SDK")
|
||||
if not wasi_sdk:
|
||||
try:
|
||||
wasi_sdk = str(
|
||||
Path(
|
||||
run(
|
||||
"mise",
|
||||
"where",
|
||||
"wasi-sdk",
|
||||
cwd=jshookz_root,
|
||||
capture=True,
|
||||
)
|
||||
)
|
||||
/ "wasi-sdk"
|
||||
)
|
||||
except (FileNotFoundError, subprocess.CalledProcessError):
|
||||
wasi_sdk = "/path/to/wasi-sdk"
|
||||
|
||||
print(f"jshookz commit: {commit}")
|
||||
print(f"provider sha256: {manifest['provider']['sha256']}")
|
||||
print(f"bytecode ABI: {manifest['bytecode_abi_id']}")
|
||||
print(f"runtime profile: {manifest['runtime_profile_id']}")
|
||||
print("snapshot imported; regenerate fixtures and run the focused suite with:")
|
||||
print(
|
||||
" env "
|
||||
f"JSHOOKZ_HOOK_COMPILER={shlex.quote(f'{cli} compile-hook')} "
|
||||
f"HOOKZ_WASI_SDK={shlex.quote(wasi_sdk)} "
|
||||
f"XAHAU_QJS_PROVIDER_WASM={shlex.quote(str(bundle / 'jshookz_provider.wasm'))} "
|
||||
"XAHAU_REQUIRE_QJS_PROVIDER_TESTS=1 "
|
||||
"x-run-tests --compile-hooks src/test/app/JSHooks_test.cpp "
|
||||
"--build-dir build --ccache -- "
|
||||
"ripple.app.JSHooks,ripple.app.QuickJSHostPolicy,"
|
||||
"ripple.app.HookGuestMemory,ripple.app.HookAPI"
|
||||
)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -51,9 +51,10 @@ export CMAKE_STATIC_LINKER_FLAGS="-static-libstdc++"
|
||||
|
||||
git config --global --add safe.directory /io &&
|
||||
git checkout src/libxrpl/protocol/BuildInfo.cpp &&
|
||||
sed -i s/\"0.0.0\"/\"$(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)$(if [ -n "$4" ]; then echo "+$4"; fi)\"/g src/libxrpl/protocol/BuildInfo.cpp &&
|
||||
sed -i s/\"0.0.0\"/\"$(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)$(if [ -n "$4" ]; then echo "+$4"; fi)\"/g src/libxrpl/protocol/BuildInfo.cpp &&
|
||||
conan export external/snappy --version 1.1.10 --user xahaud --channel stable &&
|
||||
conan export external/soci --version 4.0.3 --user xahaud --channel stable &&
|
||||
conan export external/wasmedge --version 0.11.2 --user xahaud --channel stable &&
|
||||
cd release-build &&
|
||||
# Install dependencies - tool_requires in conanfile.py handles glibc 2.28 compatibility
|
||||
# for build tools (protoc, grpc plugins, b2) in HBB environment
|
||||
@@ -71,7 +72,6 @@ cmake .. -G Ninja \
|
||||
-Dxrpld=TRUE \
|
||||
-Dtests=TRUE &&
|
||||
ccache -z &&
|
||||
ccache -p &&
|
||||
ninja -j $3 && echo "=== Re-running final link with verbose output ===" && rm -f rippled && ninja -v rippled &&
|
||||
ccache -s &&
|
||||
strip -s rippled &&
|
||||
@@ -95,16 +95,8 @@ if [[ "$4" == "" ]]; then
|
||||
echo "Non GH, local building, no Action runner magic"
|
||||
else
|
||||
# GH Action, runner
|
||||
if [[ "$(git rev-parse --abbrev-ref HEAD)" == "release" ]]; then
|
||||
echo "building on the release branch... placing it in builds/candidate"
|
||||
mkdir /data/builds/candidate
|
||||
cp /io/release-build/xahaud /data/builds/candidate/$(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4
|
||||
cp /io/release-build/release.info /data/builds/candidate/$(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4.releaseinfo
|
||||
else
|
||||
echo "building non-release branch, placing it in builds root"
|
||||
cp /io/release-build/xahaud /data/builds/$(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4
|
||||
cp /io/release-build/release.info /data/builds/$(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4.releaseinfo
|
||||
fi
|
||||
cp /io/release-build/xahaud /data/builds/$(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4
|
||||
cp /io/release-build/release.info /data/builds/$(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4.releaseinfo
|
||||
echo "Published build to: http://build.xahau.tech/"
|
||||
echo $(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4
|
||||
fi
|
||||
|
||||
@@ -12,16 +12,17 @@ echo "-- GITHUB_REPOSITORY: $1"
|
||||
echo "-- GITHUB_SHA: $2"
|
||||
echo "-- GITHUB_RUN_NUMBER: $4"
|
||||
|
||||
umask 0000
|
||||
umask 0000;
|
||||
|
||||
####
|
||||
|
||||
cd /io
|
||||
mkdir -p src/certs
|
||||
curl --silent -k https://raw.githubusercontent.com/RichardAH/rippled-release-builder/main/ca-bundle/certbundle.h -o src/certs/certbundle.h
|
||||
if [ "$(grep certbundle.h src/xrpld/net/detail/RegisterSSLCerts.cpp | wc -l)" -eq "0" ]; then
|
||||
cp src/xrpld/net/detail/RegisterSSLCerts.cpp src/xrpld/net/detail/RegisterSSLCerts.cpp.old
|
||||
perl -i -pe "s/^{/{
|
||||
cd /io;
|
||||
mkdir -p src/certs;
|
||||
curl --silent -k https://raw.githubusercontent.com/RichardAH/rippled-release-builder/main/ca-bundle/certbundle.h -o src/certs/certbundle.h;
|
||||
if [ "`grep certbundle.h src/xrpld/net/detail/RegisterSSLCerts.cpp | wc -l`" -eq "0" ]
|
||||
then
|
||||
cp src/xrpld/net/detail/RegisterSSLCerts.cpp src/xrpld/net/detail/RegisterSSLCerts.cpp.old
|
||||
perl -i -pe "s/^{/{
|
||||
#ifdef EMBEDDED_CA_BUNDLE
|
||||
BIO *cbio = BIO_new_mem_buf(ca_bundle.data(), ca_bundle.size());
|
||||
X509_STORE *cts = SSL_CTX_get_cert_store(ctx.native_handle());
|
||||
@@ -67,14 +68,15 @@ fi
|
||||
source /opt/rh/gcc-toolset-11/enable
|
||||
export PATH=/usr/local/bin:$PATH
|
||||
export CC='/usr/lib64/ccache/gcc' &&
|
||||
export CXX='/usr/lib64/ccache/g++' &&
|
||||
echo "-- Build Rippled --" &&
|
||||
pwd &&
|
||||
echo "MOVING TO [ build-core.sh ]"
|
||||
export CXX='/usr/lib64/ccache/g++' &&
|
||||
echo "-- Build Rippled --" &&
|
||||
pwd &&
|
||||
|
||||
printenv >.env.temp
|
||||
cat .env.temp | grep '=' | sed s/\\\(^[^=]\\+=\\\)/\\1\\\"/g | sed s/\$/\\\"/g >.env
|
||||
rm .env.temp
|
||||
echo "MOVING TO [ build-core.sh ]";
|
||||
|
||||
printenv > .env.temp;
|
||||
cat .env.temp | grep '=' | sed s/\\\(^[^=]\\+=\\\)/\\1\\\"/g|sed s/\$/\\\"/g > .env;
|
||||
rm .env.temp;
|
||||
|
||||
echo "Persisting ENV:"
|
||||
cat .env
|
||||
|
||||
@@ -394,7 +394,7 @@
|
||||
# true - enables compression
|
||||
# false - disables compression [default].
|
||||
#
|
||||
# The rippled server can save bandwidth by compressing its peer-to-peer communications,
|
||||
# The xahaud server can save bandwidth by compressing its peer-to-peer communications,
|
||||
# at a cost of greater CPU usage. If you enable link compression,
|
||||
# the server automatically compresses communications with peer servers
|
||||
# that also have link compression enabled.
|
||||
@@ -477,19 +477,6 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
# [sntp_servers]
|
||||
#
|
||||
# IP address or domain of NTP servers to use for time synchronization.
|
||||
#
|
||||
# These NTP servers are suitable for xahaud servers located in the United
|
||||
# States:
|
||||
# time.windows.com
|
||||
# time.apple.com
|
||||
# time.nist.gov
|
||||
# pool.ntp.org
|
||||
#
|
||||
#
|
||||
#
|
||||
# [max_transactions]
|
||||
#
|
||||
# Configure the maximum number of transactions to have in the job queue
|
||||
@@ -954,12 +941,6 @@
|
||||
#
|
||||
# path Location to store the database
|
||||
#
|
||||
# Required keys for RWDB:
|
||||
#
|
||||
# online_delete Required. RWDB stores data in memory and will
|
||||
# grow unbounded without online_delete. See the
|
||||
# online_delete section below.
|
||||
#
|
||||
# Optional keys
|
||||
#
|
||||
# cache_size Size of cache for database records. Default is 16384.
|
||||
@@ -1450,7 +1431,7 @@
|
||||
#
|
||||
# ETL commands for Clio. We recommend setting secure_gateway
|
||||
# in this section to a comma-separated list of the addresses
|
||||
# of your Clio servers, in order to bypass rippled's rate limiting.
|
||||
# of your Clio servers, in order to bypass xahaud's rate limiting.
|
||||
#
|
||||
# This port is commented out but can be enabled by removing
|
||||
# the '#' from each corresponding line including the entry under [server]
|
||||
@@ -1524,13 +1505,10 @@ secure_gateway = 127.0.0.1
|
||||
# when the node has approximately two times the "online_delete" value of
|
||||
# ledgers. No external administrative command is required to initiate
|
||||
# deletion.
|
||||
[ledger_history]
|
||||
256
|
||||
|
||||
[node_db]
|
||||
type=NuDB
|
||||
path=/opt/xahaud/db/nudb
|
||||
online_delete=256
|
||||
online_delete=512
|
||||
advisory_delete=0
|
||||
|
||||
[database_path]
|
||||
@@ -1542,18 +1520,7 @@ advisory_delete=0
|
||||
[debug_logfile]
|
||||
/var/log/xahaud/debug.log
|
||||
|
||||
[sntp_servers]
|
||||
time.windows.com
|
||||
time.apple.com
|
||||
time.nist.gov
|
||||
pool.ntp.org
|
||||
|
||||
# Use the following [ips] section for the main network:
|
||||
[ips]
|
||||
bacab.alloy.ee 21337
|
||||
hubs.xahau.as16089.net 21337
|
||||
|
||||
# To use the Xahau Test Network
|
||||
# To use the Xahau test network
|
||||
# (see https://xahau.network/docs/infrastructure/installing-xahaud),
|
||||
# use the following [ips] section:
|
||||
# [ips]
|
||||
@@ -1579,10 +1546,3 @@ validators-xahau.txt
|
||||
# set to ssl_verify to 0.
|
||||
[ssl_verify]
|
||||
1
|
||||
|
||||
# Define which network xahaud is connecting to
|
||||
# 21337 for the Main Xahau Network
|
||||
# 21338 for the Test Xahau Network
|
||||
[network_id]
|
||||
21337
|
||||
# 21338
|
||||
|
||||
@@ -95,9 +95,6 @@
|
||||
# - replace both functions setup_target_for_coverage_gcovr_* with a single setup_target_for_coverage_gcovr
|
||||
# - add support for all gcovr output formats
|
||||
#
|
||||
# 2024-04-03, Bronek Kozicki
|
||||
# - add support for output formats: jacoco, clover, lcov
|
||||
#
|
||||
# USAGE:
|
||||
#
|
||||
# 1. Copy this file into your cmake modules path.
|
||||
@@ -259,10 +256,10 @@ endif()
|
||||
# BASE_DIRECTORY "../" # Base directory for report
|
||||
# # (defaults to PROJECT_SOURCE_DIR)
|
||||
# FORMAT "cobertura" # Output format, one of:
|
||||
# # xml cobertura sonarqube jacoco clover
|
||||
# # json-summary json-details coveralls csv
|
||||
# # txt html-single html-nested html-details
|
||||
# # lcov (xml is an alias to cobertura;
|
||||
# # xml cobertura sonarqube json-summary
|
||||
# # json-details coveralls csv txt
|
||||
# # html-single html-nested html-details
|
||||
# # (xml is an alias to cobertura;
|
||||
# # if no format is set, defaults to xml)
|
||||
# EXCLUDE "src/dir1/*" "src/dir2/*" # Patterns to exclude (can be relative
|
||||
# # to BASE_DIRECTORY, with CMake 3.4+)
|
||||
@@ -311,8 +308,6 @@ function(setup_target_for_coverage_gcovr)
|
||||
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.txt)
|
||||
elseif(Coverage_FORMAT STREQUAL "csv")
|
||||
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.csv)
|
||||
elseif(Coverage_FORMAT STREQUAL "lcov")
|
||||
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.lcov)
|
||||
else()
|
||||
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.xml)
|
||||
endif()
|
||||
@@ -325,14 +320,6 @@ function(setup_target_for_coverage_gcovr)
|
||||
set(Coverage_FORMAT cobertura) # overwrite xml
|
||||
elseif(Coverage_FORMAT STREQUAL "sonarqube")
|
||||
list(APPEND GCOVR_ADDITIONAL_ARGS --sonarqube "${GCOVR_OUTPUT_FILE}" )
|
||||
elseif(Coverage_FORMAT STREQUAL "jacoco")
|
||||
list(APPEND GCOVR_ADDITIONAL_ARGS --jacoco "${GCOVR_OUTPUT_FILE}" )
|
||||
list(APPEND GCOVR_ADDITIONAL_ARGS --jacoco-pretty )
|
||||
elseif(Coverage_FORMAT STREQUAL "clover")
|
||||
list(APPEND GCOVR_ADDITIONAL_ARGS --clover "${GCOVR_OUTPUT_FILE}" )
|
||||
list(APPEND GCOVR_ADDITIONAL_ARGS --clover-pretty )
|
||||
elseif(Coverage_FORMAT STREQUAL "lcov")
|
||||
list(APPEND GCOVR_ADDITIONAL_ARGS --lcov "${GCOVR_OUTPUT_FILE}" )
|
||||
elseif(Coverage_FORMAT STREQUAL "json-summary")
|
||||
list(APPEND GCOVR_ADDITIONAL_ARGS --json-summary "${GCOVR_OUTPUT_FILE}" )
|
||||
list(APPEND GCOVR_ADDITIONAL_ARGS --json-summary-pretty)
|
||||
@@ -393,7 +380,6 @@ function(setup_target_for_coverage_gcovr)
|
||||
${GCOVR_PATH}
|
||||
--gcov-executable ${GCOV_TOOL}
|
||||
--gcov-ignore-parse-errors=negative_hits.warn_once_per_file
|
||||
--gcov-ignore-parse-errors=suspicious_hits.warn_once_per_file
|
||||
-r ${BASEDIR}
|
||||
${GCOVR_ADDITIONAL_ARGS}
|
||||
${GCOVR_EXCLUDE_ARGS}
|
||||
|
||||
@@ -1,928 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Project the sealed QuickJS bundle into one C++ translation unit."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
CHUNK = 64
|
||||
CMAKE_SET = re.compile(r'^set\(XAHAU_QUICKJS_([A-Z0-9_]+) "([^"]*)"\)\s*$')
|
||||
WASM_VALTYPE = {"i32", "i64"}
|
||||
WASM_BYTE = {"i32": "0x7f", "i64": "0x7e"}
|
||||
WASM_STACK_BYTES = 131072
|
||||
WASM_PAGE_BYTES = 65536
|
||||
PROVIDER_MEMORY_MINIMUM_PAGES = 7
|
||||
PROVIDER_MEMORY_MAXIMUM_PAGES = 512
|
||||
PROVIDER_MEMORY_MAX_BYTES = PROVIDER_MEMORY_MAXIMUM_PAGES * WASM_PAGE_BYTES
|
||||
SEALED_MANIFEST_SHA256 = (
|
||||
"1673b27d21063957cece9095cceb7e2dbfa53b6f49a5b7f824a486d7d90b2391"
|
||||
)
|
||||
SEALED_PROVIDER_SHA256 = (
|
||||
"f60ab333acb547e50d7d087960839bd11833cb133d496af98e0b72a1bb3b84df"
|
||||
)
|
||||
SEALED_PROVIDER_SIZE = 1116638
|
||||
SEALED_NATIVE_ABI_SHA256 = (
|
||||
"328ec938dcad875f3bdf25b8d779dd77f3571589818ca9271cb98c64c7018f99"
|
||||
)
|
||||
SEALED_BYTECODE_ABI_ID = (
|
||||
"75ea54f357d397c4b33899e495bb385dad975a43b1c4a7a2cead30474327d33e"
|
||||
)
|
||||
SEALED_RUNTIME_PROFILE_ID = (
|
||||
"29acf12e170436e5ccadfbc118d02a60909f86a88262106652b2f71994b0ea25"
|
||||
)
|
||||
SEALED_WASMTIME_VERSION = "47.0.3"
|
||||
SEALED_HOOK_API_VERSION = 1
|
||||
SEALED_HOST_ADAPTER_POLICY = "xahau-raw-hook-host-v1"
|
||||
SEALED_BROAD_DECLARATION_SHA256 = (
|
||||
"649079b831bc68eff0f440644649a505addafb08a3f5174e4031c8de6aedffa0"
|
||||
)
|
||||
SEALED_EXACT_V1_DECLARATION_SHA256 = (
|
||||
"20881232f0602e35de0fcbb8b5a3c1511606392749a0f79daebb386204f4f4da"
|
||||
)
|
||||
SEALED_SURFACE_SHA256 = (
|
||||
"96a9218bf38abbf1bc9f2839408700d03572e0b065d625263f70477bc32597ac"
|
||||
)
|
||||
SEALED_API_ARTIFACT_MANIFEST_SHA256 = (
|
||||
"95babf622bf5edff76fdcbd9746bad8f1f8b275a3d4bacdc320ff4deae543eba"
|
||||
)
|
||||
API_ARTIFACT_SCHEMA = "jshookz.api-artifacts.v1"
|
||||
SEALED_API_ARTIFACTS = {
|
||||
"python/jshookz/src/jshookz/types/hooks-api.d.ts": (
|
||||
"broad_declaration",
|
||||
"hooks-api.d.ts",
|
||||
SEALED_BROAD_DECLARATION_SHA256,
|
||||
),
|
||||
"python/jshookz/src/jshookz/types/xahau-quickjs-v1.d.ts": (
|
||||
"exact_v1_declaration",
|
||||
"xahau-quickjs-v1.d.ts",
|
||||
SEALED_EXACT_V1_DECLARATION_SHA256,
|
||||
),
|
||||
"python/jshookz/src/jshookz/types/xahau-quickjs-v1.surface.json": (
|
||||
"selected_surface",
|
||||
"xahau-quickjs-v1.surface.json",
|
||||
SEALED_SURFACE_SHA256,
|
||||
),
|
||||
}
|
||||
SEALED_LIMITS = {
|
||||
"host_work_base_per_call": 1,
|
||||
"host_work_budget": 1000000,
|
||||
"host_work_meter": "base-plus-addressed-byte-v1",
|
||||
"host_work_per_addressed_byte": 1,
|
||||
"quickjs_heap_bytes": 16777216,
|
||||
"quickjs_stack_bytes": 65536,
|
||||
"serialized_object_max_bytes": 1048576,
|
||||
"serialized_object_max_fields": 32768,
|
||||
"serialized_object_max_scopes": 32769,
|
||||
"serialized_object_max_depth": 10,
|
||||
"wasmtime_fuel_per_initialization": 5000000,
|
||||
"wasmtime_fuel_per_invocation": 50000000,
|
||||
}
|
||||
SEALED_HOST_WORK_ADDRESSED_LENGTH_INDICES = {
|
||||
"accept": [1],
|
||||
"emit": [1, 3],
|
||||
"hook_account": [1],
|
||||
"ledger_last_hash": [1],
|
||||
"prepare": [1, 3],
|
||||
"rollback": [1],
|
||||
"state": [1, 3],
|
||||
"state_set": [1, 3],
|
||||
"trace": [1, 3],
|
||||
}
|
||||
SEALED_ENGINE_CONFIGURATION = {
|
||||
"consume_fuel": True,
|
||||
"cranelift_nan_canonicalization": True,
|
||||
"wasi": False,
|
||||
"wasm_memory64": False,
|
||||
"wasm_multi_memory": False,
|
||||
"wasm_relaxed_simd": False,
|
||||
"wasm_tail_call": False,
|
||||
"wasm_threads": False,
|
||||
}
|
||||
IMPORT_KEYS = frozenset({"module", "name", "params", "results"})
|
||||
FUNCTION_EXPORT_KEYS = frozenset({"kind", "name", "params", "results"})
|
||||
MEMORY_EXPORT_KEYS = frozenset(
|
||||
{"kind", "name", "minimum_pages", "maximum_pages", "memory64", "shared"}
|
||||
)
|
||||
SURFACE_KEYS = frozenset(
|
||||
{"declaration", "declaration_sha256", "manifest", "schema", "sha256"}
|
||||
)
|
||||
NESTED_SURFACE_KEYS = frozenset({"declaration", "manifest", "schema"})
|
||||
|
||||
|
||||
def _import_row(name: str, params: list[str], results: list[str]) -> dict[str, Any]:
|
||||
return {"module": "env", "name": name, "params": params, "results": results}
|
||||
|
||||
|
||||
def _function_export(name: str, params: list[str], results: list[str]) -> dict[str, Any]:
|
||||
return {"kind": "function", "name": name, "params": params, "results": results}
|
||||
|
||||
|
||||
SEALED_IMPORTS = [
|
||||
_import_row("accept", ["i32", "i32", "i64"], ["i64"]),
|
||||
_import_row("emit", ["i32", "i32", "i32", "i32"], ["i64"]),
|
||||
_import_row("etxn_reserve", ["i32"], ["i64"]),
|
||||
_import_row("hook_account", ["i32", "i32"], ["i64"]),
|
||||
_import_row("ledger_last_hash", ["i32", "i32"], ["i64"]),
|
||||
_import_row("ledger_last_time", [], ["i64"]),
|
||||
_import_row("ledger_seq", [], ["i64"]),
|
||||
_import_row("otxn_type", [], ["i64"]),
|
||||
_import_row("prepare", ["i32", "i32", "i32", "i32"], ["i64"]),
|
||||
_import_row("rollback", ["i32", "i32", "i64"], ["i64"]),
|
||||
_import_row("state", ["i32", "i32", "i32", "i32"], ["i64"]),
|
||||
_import_row("state_set", ["i32", "i32", "i32", "i32"], ["i64"]),
|
||||
_import_row("trace", ["i32", "i32", "i32", "i32", "i32"], ["i64"]),
|
||||
]
|
||||
SEALED_EXPORTS = [
|
||||
_function_export("_initialize", [], []),
|
||||
_function_export("free", ["i32"], []),
|
||||
_function_export("malloc", ["i32"], ["i32"]),
|
||||
{
|
||||
"kind": "memory",
|
||||
"maximum_pages": 512,
|
||||
"memory64": False,
|
||||
"minimum_pages": 7,
|
||||
"name": "memory",
|
||||
"shared": False,
|
||||
},
|
||||
_function_export("qjs_cbak", ["i32", "i32", "i32"], ["i32"]),
|
||||
_function_export("qjs_compile", ["i32", "i32"], ["i32"]),
|
||||
_function_export("qjs_compile_module", ["i32", "i32"], ["i32"]),
|
||||
_function_export("qjs_destroy", [], []),
|
||||
_function_export("qjs_enable_coverage", ["i32"], []),
|
||||
_function_export("qjs_eval", ["i32", "i32"], ["i32"]),
|
||||
_function_export("qjs_eval_bytecode", ["i32", "i32"], ["i32"]),
|
||||
_function_export("qjs_eval_module", ["i32", "i32"], ["i32"]),
|
||||
_function_export("qjs_get_bytecode_len", [], ["i32"]),
|
||||
_function_export("qjs_get_bytecode_ptr", [], ["i32"]),
|
||||
_function_export("qjs_get_result_len", [], ["i32"]),
|
||||
_function_export("qjs_get_result_ptr", [], ["i32"]),
|
||||
_function_export("qjs_hook", ["i32", "i32", "i32"], ["i32"]),
|
||||
_function_export("qjs_init", [], []),
|
||||
_function_export("qjs_set_max_stack_size", ["i32"], []),
|
||||
_function_export("qjs_set_memory_limit", ["i32"], []),
|
||||
_function_export("qjs_set_seed", ["i32"], []),
|
||||
_function_export("qjs_validate_hook_module", ["i32", "i32"], ["i32"]),
|
||||
]
|
||||
|
||||
|
||||
class LockError(ValueError):
|
||||
"""A sealed QuickJS lock identity failed a fail-closed check."""
|
||||
|
||||
|
||||
def quote(value: str) -> str:
|
||||
if not isinstance(value, str) or any(c in value for c in "\n\r"):
|
||||
raise LockError(f"invalid QuickJS policy string: {value!r}")
|
||||
return json.dumps(value)
|
||||
|
||||
|
||||
def parse_cmake(path: Path) -> dict[str, str]:
|
||||
values: dict[str, str] = {}
|
||||
for line in path.read_text().splitlines():
|
||||
match = CMAKE_SET.match(line)
|
||||
if match:
|
||||
values[match.group(1)] = match.group(2)
|
||||
return values
|
||||
|
||||
|
||||
def hex_bytes(value: str) -> str:
|
||||
if len(value) != 64 or any(c not in "0123456789abcdefABCDEF" for c in value):
|
||||
raise LockError(f"QuickJS identity must be 32 hexadecimal bytes: {value!r}")
|
||||
return ", ".join(f"0x{value[i:i + 2]}" for i in range(0, 64, 2))
|
||||
|
||||
|
||||
def require(cmake: dict[str, str], key: str) -> str:
|
||||
if key not in cmake:
|
||||
raise LockError(f"QuickJS cmake projection missing {key}")
|
||||
return cmake[key]
|
||||
|
||||
|
||||
def require_int(cmake: dict[str, str], key: str) -> int:
|
||||
return int(require(cmake, key))
|
||||
|
||||
|
||||
def require_hex(value: object, label: str) -> str:
|
||||
text = str(value).lower()
|
||||
if len(text) != 64 or any(c not in "0123456789abcdef" for c in text):
|
||||
raise LockError(f"{label} is not a SHA-256 hex digest: {value!r}")
|
||||
return text
|
||||
|
||||
|
||||
def require_sealed(actual: object, expected: object, label: str) -> None:
|
||||
if actual != expected:
|
||||
raise LockError(
|
||||
f"{label} disagrees with the sealed F0 table: "
|
||||
f"{actual!r} != {expected!r}"
|
||||
)
|
||||
|
||||
|
||||
def validate_api_artifacts(bundle: Path) -> dict[str, str]:
|
||||
manifest_path = bundle / "api-artifacts.json"
|
||||
manifest = json.loads(manifest_path.read_text())
|
||||
if not isinstance(manifest, dict) or set(manifest) != {"artifacts", "schema"}:
|
||||
raise LockError("API artifact manifest has extra or missing keys")
|
||||
if manifest.get("schema") != API_ARTIFACT_SCHEMA:
|
||||
raise LockError("API artifact manifest schema disagrees with the sealed F0 table")
|
||||
artifacts = manifest.get("artifacts")
|
||||
if not isinstance(artifacts, dict) or set(artifacts) != set(SEALED_API_ARTIFACTS):
|
||||
raise LockError("API artifact manifest file set disagrees with the sealed F0 table")
|
||||
|
||||
identities: dict[str, str] = {}
|
||||
for source_path, artifact in SEALED_API_ARTIFACTS.items():
|
||||
identity_name, local_name, sealed_digest = artifact
|
||||
actual_digest = hashlib.sha256((bundle / local_name).read_bytes()).hexdigest()
|
||||
declared_digest = require_hex(
|
||||
artifacts.get(source_path), f"API artifact {source_path} SHA-256"
|
||||
)
|
||||
if actual_digest != declared_digest:
|
||||
raise LockError(
|
||||
f"API artifact {source_path} disagrees with its manifest digest"
|
||||
)
|
||||
require_sealed(actual_digest, sealed_digest, f"API artifact {source_path}")
|
||||
identities[identity_name] = actual_digest
|
||||
|
||||
actual_manifest = hashlib.sha256(manifest_path.read_bytes()).hexdigest()
|
||||
require_sealed(
|
||||
actual_manifest,
|
||||
SEALED_API_ARTIFACT_MANIFEST_SHA256,
|
||||
"API artifact manifest SHA-256",
|
||||
)
|
||||
identities["api_artifact_manifest"] = actual_manifest
|
||||
return identities
|
||||
|
||||
|
||||
def cpp_bool(value: object) -> str:
|
||||
if value is True:
|
||||
return "true"
|
||||
if value is False:
|
||||
return "false"
|
||||
raise LockError(f"expected JSON boolean, got {value!r}")
|
||||
|
||||
|
||||
def join_types(values: object, label: str) -> str:
|
||||
if not isinstance(values, list) or not all(isinstance(item, str) for item in values):
|
||||
raise LockError(f"{label} is not a list of wasm value types: {values!r}")
|
||||
for item in values:
|
||||
if item not in WASM_VALTYPE:
|
||||
raise LockError(f"{label} has unsupported wasm value type {item!r}")
|
||||
return ",".join(values)
|
||||
|
||||
|
||||
def wasm_signature(params: object, results: object, label: str) -> list[str]:
|
||||
join_types(params, f"{label} params")
|
||||
join_types(results, f"{label} results")
|
||||
assert isinstance(params, list) and isinstance(results, list)
|
||||
return [WASM_BYTE[item] for item in results] + [WASM_BYTE[item] for item in params]
|
||||
|
||||
|
||||
def embed_body(data: bytes | None) -> str:
|
||||
if data is None:
|
||||
return (
|
||||
"std::span<std::uint8_t const>\n"
|
||||
"embeddedQuickJSProvider()\n"
|
||||
"{\n"
|
||||
" return {};\n"
|
||||
"}\n"
|
||||
)
|
||||
lines = []
|
||||
for offset in range(0, len(data), CHUNK):
|
||||
chunk = data[offset : offset + CHUNK]
|
||||
lines.append(' "' + "".join(f"\\x{b:02x}" for b in chunk) + '"')
|
||||
return (
|
||||
"namespace {\n"
|
||||
"\n"
|
||||
"constexpr char const sealedProvider[] =\n"
|
||||
+ "\n".join(lines)
|
||||
+ ";\n"
|
||||
"\n"
|
||||
"static_assert(\n"
|
||||
f" sizeof(sealedProvider) - 1 == {len(data)},\n"
|
||||
' "embedded provider size disagrees with its manifest");\n'
|
||||
"\n"
|
||||
"} // namespace\n"
|
||||
"\n"
|
||||
"std::span<std::uint8_t const>\n"
|
||||
"embeddedQuickJSProvider()\n"
|
||||
"{\n"
|
||||
" return {\n"
|
||||
" reinterpret_cast<std::uint8_t const*>(sealedProvider),\n"
|
||||
" sizeof(sealedProvider) - 1};\n"
|
||||
"}\n"
|
||||
)
|
||||
|
||||
|
||||
def format_export_row(item: dict[str, Any]) -> str:
|
||||
kind = item["kind"]
|
||||
name = item["name"]
|
||||
if kind == "memory":
|
||||
fields = (
|
||||
quote(kind),
|
||||
quote(name),
|
||||
quote(""),
|
||||
quote(""),
|
||||
f"{int(item['minimum_pages'])}U",
|
||||
f"{int(item['maximum_pages'])}U",
|
||||
cpp_bool(item["memory64"]),
|
||||
cpp_bool(item["shared"]),
|
||||
)
|
||||
elif kind == "function":
|
||||
fields = (
|
||||
quote(kind),
|
||||
quote(name),
|
||||
quote(join_types(item["params"], f"export {name} params")),
|
||||
quote(join_types(item["results"], f"export {name} results")),
|
||||
"0U",
|
||||
"0U",
|
||||
"false",
|
||||
"false",
|
||||
)
|
||||
else:
|
||||
raise LockError(f"unsupported provider export kind: {kind!r}")
|
||||
return "{" + ", ".join(fields) + "}"
|
||||
|
||||
|
||||
def require_typed_exports(exports: object, label: str) -> list[dict[str, Any]]:
|
||||
if not isinstance(exports, list) or not all(isinstance(item, dict) for item in exports):
|
||||
raise LockError(f"{label} must be a list of typed export rows")
|
||||
names: list[str] = []
|
||||
memory_rows: list[dict[str, Any]] = []
|
||||
for item in exports:
|
||||
kind = item.get("kind")
|
||||
name = item.get("name")
|
||||
if not isinstance(kind, str) or not isinstance(name, str) or not name:
|
||||
raise LockError(f"{label} row is missing kind/name: {item!r}")
|
||||
if kind == "function":
|
||||
if set(item) != FUNCTION_EXPORT_KEYS:
|
||||
raise LockError(f"{label} function {name} has extra or missing keys")
|
||||
join_types(item.get("params"), f"{label} {name} params")
|
||||
join_types(item.get("results"), f"{label} {name} results")
|
||||
elif kind == "memory":
|
||||
if set(item) != MEMORY_EXPORT_KEYS:
|
||||
raise LockError(f"{label} memory row has extra or missing keys")
|
||||
for key in ("minimum_pages", "maximum_pages"):
|
||||
if not isinstance(item.get(key), int):
|
||||
raise LockError(f"{label} memory row missing integer {key}")
|
||||
if item.get("memory64") is not False or item.get("shared") is not False:
|
||||
raise LockError(
|
||||
f"{label} memory row is not memory64=false / shared=false"
|
||||
)
|
||||
memory_rows.append(item)
|
||||
else:
|
||||
raise LockError(f"{label} has unsupported export kind {kind!r}")
|
||||
names.append(name)
|
||||
if len(names) != len(set(names)):
|
||||
raise LockError(f"{label} contains duplicate export names")
|
||||
if names != sorted(names):
|
||||
raise LockError(f"{label} must be normalized by export name")
|
||||
if len(memory_rows) != 1 or memory_rows[0].get("name") != "memory":
|
||||
raise LockError(f"{label} must export exactly one memory named memory")
|
||||
return exports
|
||||
|
||||
|
||||
def require_typed_imports(imports: object, label: str) -> list[dict[str, Any]]:
|
||||
if not isinstance(imports, list) or not all(isinstance(item, dict) for item in imports):
|
||||
raise LockError(f"{label} must be a list of typed import rows")
|
||||
names: list[str] = []
|
||||
for item in imports:
|
||||
module = item.get("module")
|
||||
name = item.get("name")
|
||||
if not isinstance(module, str) or not isinstance(name, str) or not name:
|
||||
raise LockError(f"{label} row is missing module/name: {item!r}")
|
||||
if set(item) != IMPORT_KEYS:
|
||||
raise LockError(f"{label} {name} has extra or missing keys")
|
||||
wasm_signature(item.get("params"), item.get("results"), f"{label} {name}")
|
||||
names.append(name)
|
||||
if len(names) != len(set(names)):
|
||||
raise LockError(f"{label} contains duplicate import names")
|
||||
return imports
|
||||
|
||||
|
||||
def require_build(build: object, label: str) -> dict[str, Any]:
|
||||
if not isinstance(build, dict):
|
||||
raise LockError(f"{label} is missing build metadata")
|
||||
stack = build.get("wasm_stack_bytes")
|
||||
memory = build.get("wasm_memory_max_bytes")
|
||||
if stack != WASM_STACK_BYTES:
|
||||
raise LockError(
|
||||
f"{label} wasm_stack_bytes is {stack!r}, expected {WASM_STACK_BYTES}"
|
||||
)
|
||||
if memory != PROVIDER_MEMORY_MAX_BYTES:
|
||||
raise LockError(
|
||||
f"{label} wasm_memory_max_bytes is {memory!r}, "
|
||||
f"expected {PROVIDER_MEMORY_MAX_BYTES}"
|
||||
)
|
||||
return build
|
||||
|
||||
|
||||
def cross_compare_int(cmake: dict[str, str], key: str, actual: object, label: str) -> int:
|
||||
expected = require_int(cmake, key)
|
||||
if actual != expected:
|
||||
raise LockError(
|
||||
f"{label} disagrees between JSON ({actual!r}) and CMake {key} ({expected!r})"
|
||||
)
|
||||
return expected
|
||||
|
||||
|
||||
def cross_compare_str(cmake: dict[str, str], key: str, actual: object, label: str) -> str:
|
||||
expected = require(cmake, key)
|
||||
if str(actual) != expected:
|
||||
raise LockError(
|
||||
f"{label} disagrees between JSON ({actual!r}) and CMake {key} ({expected!r})"
|
||||
)
|
||||
return expected
|
||||
|
||||
|
||||
def validate_lock(
|
||||
profile: dict[str, Any],
|
||||
native: dict[str, Any],
|
||||
cmake: dict[str, str],
|
||||
wasmtime_version: str,
|
||||
api_identities: dict[str, str],
|
||||
) -> tuple[list[dict[str, Any]], list[dict[str, Any]], dict[str, Any], str, str, int]:
|
||||
schema = require(cmake, "MANIFEST_SCHEMA")
|
||||
if schema != "xahau.quickjs.runtime-profile-lock.v1" or profile.get("schema") != schema:
|
||||
raise LockError(f"unsupported QuickJS provider manifest schema: {schema}")
|
||||
|
||||
expected_sha = require_hex(require(cmake, "PROVIDER_SHA256"), "CMake provider SHA-256")
|
||||
json_sha = require_hex(profile.get("provider", {}).get("sha256"), "JSON provider SHA-256")
|
||||
if json_sha != expected_sha:
|
||||
raise LockError("provider sha256 disagrees between JSON lock and cmake")
|
||||
require_sealed(expected_sha, SEALED_PROVIDER_SHA256, "provider SHA-256")
|
||||
expected_size = require_int(cmake, "PROVIDER_SIZE")
|
||||
json_size = profile.get("provider", {}).get("size")
|
||||
if json_size != expected_size:
|
||||
raise LockError("provider size disagrees between JSON lock and cmake")
|
||||
require_sealed(expected_size, SEALED_PROVIDER_SIZE, "provider size")
|
||||
|
||||
bytecode = require_hex(require(cmake, "BYTECODE_ABI_ID"), "CMake bytecode ABI")
|
||||
if require_hex(profile.get("bytecode_abi_id"), "JSON bytecode ABI") != bytecode:
|
||||
raise LockError("bytecode ABI disagrees between JSON lock and cmake")
|
||||
require_sealed(bytecode, SEALED_BYTECODE_ABI_ID, "bytecode ABI")
|
||||
runtime_profile = require_hex(
|
||||
require(cmake, "RUNTIME_PROFILE_ID"), "CMake runtime-profile ID"
|
||||
)
|
||||
if require_hex(profile.get("runtime_profile_id"), "JSON runtime-profile ID") != runtime_profile:
|
||||
raise LockError("runtime-profile ID disagrees between JSON lock and cmake")
|
||||
require_sealed(
|
||||
runtime_profile, SEALED_RUNTIME_PROFILE_ID, "runtime-profile ID"
|
||||
)
|
||||
|
||||
pinned_wasmtime = require(cmake, "WASMTIME_VERSION")
|
||||
engine = profile.get("source", {}).get("engine", {})
|
||||
engine_version = engine.get("version")
|
||||
if wasmtime_version != pinned_wasmtime or engine_version != pinned_wasmtime:
|
||||
raise LockError(
|
||||
f"QuickJS provider requires Wasmtime {pinned_wasmtime}, "
|
||||
f"but CMake resolved {wasmtime_version} and JSON has {engine_version!r}"
|
||||
)
|
||||
require_sealed(pinned_wasmtime, SEALED_WASMTIME_VERSION, "Wasmtime version")
|
||||
require_sealed(
|
||||
engine.get("configuration"),
|
||||
SEALED_ENGINE_CONFIGURATION,
|
||||
"Wasmtime engine configuration",
|
||||
)
|
||||
|
||||
limits = profile.get("source", {}).get("limits")
|
||||
if not isinstance(limits, dict):
|
||||
raise LockError("JSON runtime-profile source is missing limits")
|
||||
cross_compare_int(
|
||||
cmake, "SERIALIZED_OBJECT_MAX_BYTES", limits.get("serialized_object_max_bytes"),
|
||||
"serialized_object_max_bytes",
|
||||
)
|
||||
cross_compare_int(
|
||||
cmake, "SERIALIZED_OBJECT_MAX_FIELDS", limits.get("serialized_object_max_fields"),
|
||||
"serialized_object_max_fields",
|
||||
)
|
||||
cross_compare_int(
|
||||
cmake, "SERIALIZED_OBJECT_MAX_SCOPES", limits.get("serialized_object_max_scopes"),
|
||||
"serialized_object_max_scopes",
|
||||
)
|
||||
cross_compare_int(
|
||||
cmake, "SERIALIZED_OBJECT_MAX_DEPTH", limits.get("serialized_object_max_depth"),
|
||||
"serialized_object_max_depth",
|
||||
)
|
||||
for key, expected in SEALED_LIMITS.items():
|
||||
require_sealed(limits.get(key), expected, key)
|
||||
require_sealed(
|
||||
limits.get("host_work_addressed_length_indices"),
|
||||
SEALED_HOST_WORK_ADDRESSED_LENGTH_INDICES,
|
||||
"host_work_addressed_length_indices",
|
||||
)
|
||||
cross_compare_int(cmake, "HEAP_BYTES", limits.get("quickjs_heap_bytes"), "quickjs_heap_bytes")
|
||||
cross_compare_int(cmake, "STACK_BYTES", limits.get("quickjs_stack_bytes"), "quickjs_stack_bytes")
|
||||
cross_compare_int(
|
||||
cmake, "INITIALIZATION_FUEL", limits.get("wasmtime_fuel_per_initialization"),
|
||||
"initialization fuel",
|
||||
)
|
||||
cross_compare_int(
|
||||
cmake, "INVOCATION_FUEL", limits.get("wasmtime_fuel_per_invocation"),
|
||||
"invocation fuel",
|
||||
)
|
||||
cross_compare_int(cmake, "HOST_WORK_BUDGET", limits.get("host_work_budget"), "host_work_budget")
|
||||
cross_compare_int(
|
||||
cmake, "HOST_WORK_BASE_PER_CALL", limits.get("host_work_base_per_call"),
|
||||
"host_work_base_per_call",
|
||||
)
|
||||
cross_compare_int(
|
||||
cmake, "HOST_WORK_PER_ADDRESSED_BYTE", limits.get("host_work_per_addressed_byte"),
|
||||
"host_work_per_addressed_byte",
|
||||
)
|
||||
cross_compare_str(cmake, "HOST_WORK_METER", limits.get("host_work_meter"), "host_work_meter")
|
||||
host_adapter_policy = cross_compare_str(
|
||||
cmake, "HOST_ADAPTER_POLICY",
|
||||
profile.get("source", {}).get("execution", {}).get("host_adapter_policy"),
|
||||
"host_adapter_policy",
|
||||
)
|
||||
require_sealed(
|
||||
host_adapter_policy, SEALED_HOST_ADAPTER_POLICY, "host_adapter_policy"
|
||||
)
|
||||
hook_api_version = cross_compare_int(
|
||||
cmake, "HOOK_API_VERSION",
|
||||
profile.get("source", {}).get("artifact", {}).get("hook_api_version"),
|
||||
"hook_api_version",
|
||||
)
|
||||
require_sealed(hook_api_version, SEALED_HOOK_API_VERSION, "hook_api_version")
|
||||
|
||||
provider = profile.get("provider")
|
||||
source_provider = profile.get("source", {}).get("provider")
|
||||
if not isinstance(provider, dict) or not isinstance(source_provider, dict):
|
||||
raise LockError("JSON lock is missing provider or source.provider")
|
||||
require_build(provider.get("build"), "provider.build")
|
||||
require_build(source_provider.get("build"), "source.provider.build")
|
||||
require_sealed(
|
||||
source_provider.get("forbidden_import_modules"),
|
||||
["wasi_snapshot_preview1"],
|
||||
"forbidden provider import modules",
|
||||
)
|
||||
|
||||
expected_import_count = require_int(cmake, "PROVIDER_IMPORT_COUNT")
|
||||
provider_imports = require_typed_imports(provider.get("imports"), "provider.imports")
|
||||
source_imports = require_typed_imports(
|
||||
source_provider.get("imports"), "source.provider.imports"
|
||||
)
|
||||
native_imports = native.get("selected")
|
||||
if not isinstance(native_imports, list):
|
||||
raise LockError("native ABI snapshot is missing selected imports")
|
||||
if provider_imports != source_imports:
|
||||
raise LockError("provider import signatures disagree between JSON copies")
|
||||
if provider_imports != SEALED_IMPORTS:
|
||||
raise LockError(
|
||||
"provider import signatures disagree with the sealed F0 table"
|
||||
)
|
||||
if (
|
||||
len(provider_imports) != expected_import_count
|
||||
or len(native_imports) != expected_import_count
|
||||
):
|
||||
raise LockError("QuickJS provider/native ABI import counts differ")
|
||||
provider_names = [item["name"] for item in provider_imports]
|
||||
native_names = [item["name"] for item in native_imports]
|
||||
if len(set(provider_names)) != expected_import_count or set(provider_names) != set(
|
||||
native_names
|
||||
):
|
||||
raise LockError("QuickJS provider/native ABI import sets differ")
|
||||
native_by_name = {item["name"]: item for item in native_imports}
|
||||
for item in provider_imports:
|
||||
native_item = native_by_name[item["name"]]
|
||||
expected_sig = wasm_signature(
|
||||
item["params"], item["results"], f"import {item['name']}"
|
||||
)
|
||||
if native_item.get("wasm_signature") != expected_sig:
|
||||
raise LockError(
|
||||
f"import {item['name']} wasm signature disagrees between JSON and native ABI"
|
||||
)
|
||||
|
||||
expected_export_count = require_int(cmake, "PROVIDER_EXPORT_COUNT")
|
||||
provider_exports = require_typed_exports(provider.get("exports"), "provider.exports")
|
||||
allowed_exports = require_typed_exports(
|
||||
source_provider.get("allowed_exports"), "source.provider.allowed_exports"
|
||||
)
|
||||
if len(provider_exports) != expected_export_count:
|
||||
raise LockError("QuickJS provider export count disagrees with its CMake lock")
|
||||
if provider_exports != allowed_exports:
|
||||
raise LockError("provider export signatures disagree between JSON copies")
|
||||
memory = next(item for item in provider_exports if item["kind"] == "memory")
|
||||
if (
|
||||
int(memory["minimum_pages"]) != PROVIDER_MEMORY_MINIMUM_PAGES
|
||||
or int(memory["maximum_pages"]) != PROVIDER_MEMORY_MAXIMUM_PAGES
|
||||
or memory["memory64"] is not False
|
||||
or memory["shared"] is not False
|
||||
):
|
||||
raise LockError(
|
||||
"QuickJS provider memory shape is not min 7 / max 512 / "
|
||||
"memory64=false / shared=false"
|
||||
)
|
||||
if provider_exports != SEALED_EXPORTS:
|
||||
raise LockError(
|
||||
"provider export signatures disagree with the sealed F0 table"
|
||||
)
|
||||
|
||||
surface = profile.get("javascript_surface")
|
||||
nested_surface = profile.get("source", {}).get("javascript_surface")
|
||||
if not isinstance(surface, dict) or not isinstance(nested_surface, dict):
|
||||
raise LockError("JSON lock is missing javascript_surface")
|
||||
if set(surface) != SURFACE_KEYS or set(nested_surface) != NESTED_SURFACE_KEYS:
|
||||
raise LockError("javascript_surface has extra or missing keys")
|
||||
declaration_sha = require_hex(
|
||||
surface.get("declaration_sha256"), "javascript surface declaration SHA-256"
|
||||
)
|
||||
surface_sha = require_hex(surface.get("sha256"), "javascript surface SHA-256")
|
||||
require_sealed(
|
||||
declaration_sha,
|
||||
api_identities["exact_v1_declaration"],
|
||||
"exact-v1 declaration SHA-256",
|
||||
)
|
||||
require_sealed(
|
||||
surface_sha, api_identities["selected_surface"], "selected surface SHA-256"
|
||||
)
|
||||
for key in ("declaration", "manifest", "schema"):
|
||||
if surface.get(key) != nested_surface.get(key):
|
||||
raise LockError(f"javascript_surface.{key} disagrees between JSON copies")
|
||||
|
||||
return (
|
||||
provider_imports,
|
||||
provider_exports,
|
||||
native_imports,
|
||||
declaration_sha,
|
||||
surface_sha,
|
||||
expected_size,
|
||||
)
|
||||
|
||||
|
||||
def render_source(
|
||||
*,
|
||||
provenance: str,
|
||||
cmake: dict[str, str],
|
||||
native: dict[str, Any],
|
||||
provider_imports: list[dict[str, Any]],
|
||||
provider_exports: list[dict[str, Any]],
|
||||
native_imports: list[dict[str, Any]],
|
||||
declaration_sha: str,
|
||||
surface_sha: str,
|
||||
broad_declaration_sha: str,
|
||||
api_artifact_manifest_sha: str,
|
||||
manifest_sha: str,
|
||||
expected_sha: str,
|
||||
expected_size: int,
|
||||
wasm_bytes: bytes | None,
|
||||
actual_native: str,
|
||||
) -> str:
|
||||
provider_names = [item["name"] for item in provider_imports]
|
||||
provider_rows = ",\n ".join(
|
||||
"{"
|
||||
+ ", ".join(
|
||||
(
|
||||
quote(item["module"]),
|
||||
quote(item["name"]),
|
||||
quote(join_types(item["params"], f"import {item['name']} params")),
|
||||
quote(join_types(item["results"], f"import {item['name']} results")),
|
||||
)
|
||||
)
|
||||
+ "}"
|
||||
for item in provider_imports
|
||||
)
|
||||
native_rows = ",\n ".join(
|
||||
"{"
|
||||
+ ", ".join(
|
||||
(
|
||||
quote(item["name"]),
|
||||
quote(item["return_type"]),
|
||||
quote(",".join(item["param_types"])),
|
||||
quote(item["amendment"] or ""),
|
||||
)
|
||||
)
|
||||
+ "}"
|
||||
for item in native_imports
|
||||
)
|
||||
export_rows = ",\n ".join(format_export_row(item) for item in provider_exports)
|
||||
source = native["source"]
|
||||
memory = next(item for item in provider_exports if item["kind"] == "memory")
|
||||
return f"""// Generated by cmake/GenerateQuickJSProviderBundle.py; do not edit.
|
||||
// Source: {provenance}
|
||||
#include <xrpld/app/hook/QuickJSHookRuntime.h>
|
||||
#include <xrpld/app/hook/detail/QuickJSProviderProfile.h>
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <span>
|
||||
#include <string_view>
|
||||
|
||||
namespace hook::artifact::generated {{
|
||||
|
||||
std::array<std::uint8_t, 32> const providerSHA256 = {{
|
||||
{hex_bytes(expected_sha)}}};
|
||||
std::array<std::uint8_t, 32> const bytecodeABI = {{
|
||||
{hex_bytes(require(cmake, "BYTECODE_ABI_ID"))}}};
|
||||
std::array<std::uint8_t, 32> const runtimeProfile = {{
|
||||
{hex_bytes(require(cmake, "RUNTIME_PROFILE_ID"))}}};
|
||||
std::string_view const providerManifestSHA256 = {quote(manifest_sha)};
|
||||
std::size_t const providerSize = {expected_size};
|
||||
std::uint16_t const hookApiVersion = {require(cmake, "HOOK_API_VERSION")};
|
||||
std::uint64_t const initializationFuel = {require(cmake, "INITIALIZATION_FUEL")}ULL;
|
||||
std::uint64_t const invocationFuel = {require(cmake, "INVOCATION_FUEL")}ULL;
|
||||
std::string_view const hostWorkMeter = {quote(require(cmake, "HOST_WORK_METER"))};
|
||||
std::uint64_t const hostWorkBudget = {require(cmake, "HOST_WORK_BUDGET")}ULL;
|
||||
std::uint64_t const hostWorkBasePerCall = {require(cmake, "HOST_WORK_BASE_PER_CALL")}ULL;
|
||||
std::uint64_t const hostWorkPerAddressedByte =
|
||||
{require(cmake, "HOST_WORK_PER_ADDRESSED_BYTE")}ULL;
|
||||
std::string_view const hostAdapterPolicy = {quote(require(cmake, "HOST_ADAPTER_POLICY"))};
|
||||
std::uint32_t const heapBytes = {require(cmake, "HEAP_BYTES")}U;
|
||||
std::uint32_t const stackBytes = {require(cmake, "STACK_BYTES")}U;
|
||||
std::uint32_t const wasmStackBytes = {WASM_STACK_BYTES}U;
|
||||
std::uint32_t const serializedObjectMaxBytes =
|
||||
{require(cmake, "SERIALIZED_OBJECT_MAX_BYTES")}U;
|
||||
std::uint32_t const serializedObjectMaxFields =
|
||||
{require(cmake, "SERIALIZED_OBJECT_MAX_FIELDS")}U;
|
||||
std::uint32_t const serializedObjectMaxScopes =
|
||||
{require(cmake, "SERIALIZED_OBJECT_MAX_SCOPES")}U;
|
||||
std::uint32_t const serializedObjectMaxDepth =
|
||||
{require(cmake, "SERIALIZED_OBJECT_MAX_DEPTH")}U;
|
||||
std::uint32_t const providerMemoryMinimumPages = {int(memory["minimum_pages"])}U;
|
||||
std::uint32_t const providerMemoryMaximumPages = {int(memory["maximum_pages"])}U;
|
||||
bool const providerMemory64 = false;
|
||||
bool const providerMemoryShared = false;
|
||||
std::string_view const javascriptBroadDeclarationSHA256 =
|
||||
{quote(broad_declaration_sha)};
|
||||
std::string_view const javascriptExactV1DeclarationSHA256 =
|
||||
{quote(declaration_sha)};
|
||||
std::string_view const javascriptSurfaceSHA256 = {quote(surface_sha)};
|
||||
std::string_view const javascriptAPIArtifactManifestSHA256 =
|
||||
{quote(api_artifact_manifest_sha)};
|
||||
|
||||
namespace {{
|
||||
|
||||
std::string_view const providerImportNames[] = {{
|
||||
{", ".join(quote(name) for name in provider_names)}}};
|
||||
std::string_view const providerExportNames[] = {{
|
||||
{", ".join(quote(item["name"]) for item in provider_exports)}}};
|
||||
ProviderImportSignature const providerImportSignatureData[] = {{
|
||||
{provider_rows}}};
|
||||
ProviderExportSignature const providerExportSignatureData[] = {{
|
||||
{export_rows}}};
|
||||
NativeImportSignature const nativeImportSignatureData[] = {{
|
||||
{native_rows}}};
|
||||
|
||||
}} // namespace
|
||||
|
||||
std::span<std::string_view const> const providerImports{{providerImportNames}};
|
||||
std::span<std::string_view const> const providerExports{{providerExportNames}};
|
||||
std::span<ProviderImportSignature const> const providerImportSignatures{{
|
||||
providerImportSignatureData}};
|
||||
std::span<ProviderExportSignature const> const providerExportSignatures{{
|
||||
providerExportSignatureData}};
|
||||
std::span<NativeImportSignature const> const nativeImportSignatures{{
|
||||
nativeImportSignatureData}};
|
||||
std::string_view const nativeABISourceRepository = {quote(source["repository"])};
|
||||
std::string_view const nativeABISourceCommit = {quote(source["commit"])};
|
||||
std::string_view const nativeABISourcePath = {quote(source["path"])};
|
||||
std::string_view const nativeABISHA256 = {quote(actual_native)};
|
||||
std::size_t const nativeABICatalogueCount = {source["macro_function_count"]};
|
||||
|
||||
}} // namespace hook::artifact::generated
|
||||
|
||||
namespace hook {{
|
||||
|
||||
{embed_body(wasm_bytes)}
|
||||
}} // namespace hook
|
||||
"""
|
||||
|
||||
|
||||
def project_bundle(bundle: Path, wasmtime_version: str, output: Path) -> int:
|
||||
profile_path = bundle / "jshookz_provider.manifest.json"
|
||||
cmake_path = bundle / "jshookz_provider.manifest.cmake"
|
||||
native_path = bundle / "jshookz_provider.native-abi.json"
|
||||
api_manifest_path = bundle / "api-artifacts.json"
|
||||
api_paths = tuple(
|
||||
bundle / local_name
|
||||
for _, local_name, _ in SEALED_API_ARTIFACTS.values()
|
||||
)
|
||||
for path in (profile_path, cmake_path, native_path, api_manifest_path, *api_paths):
|
||||
if not path.is_file():
|
||||
print(f"missing sealed QuickJS bundle file: {path}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
cmake = parse_cmake(cmake_path)
|
||||
actual_manifest = hashlib.sha256(profile_path.read_bytes()).hexdigest()
|
||||
if actual_manifest != require(cmake, "MANIFEST_SHA256"):
|
||||
print(
|
||||
"QuickJS provider JSON manifest does not match its CMake projection",
|
||||
file=sys.stderr,
|
||||
)
|
||||
return 1
|
||||
|
||||
actual_native = hashlib.sha256(native_path.read_bytes()).hexdigest()
|
||||
if actual_native != require(cmake, "NATIVE_ABI_SHA256"):
|
||||
print(
|
||||
"QuickJS native ABI snapshot does not match its sealed digest",
|
||||
file=sys.stderr,
|
||||
)
|
||||
return 1
|
||||
|
||||
try:
|
||||
profile = json.loads(profile_path.read_text())
|
||||
native = json.loads(native_path.read_text())
|
||||
api_identities = validate_api_artifacts(bundle)
|
||||
(
|
||||
provider_imports,
|
||||
provider_exports,
|
||||
native_imports,
|
||||
declaration_sha,
|
||||
surface_sha,
|
||||
expected_size,
|
||||
) = validate_lock(
|
||||
profile, native, cmake, wasmtime_version, api_identities
|
||||
)
|
||||
require_sealed(
|
||||
actual_manifest, SEALED_MANIFEST_SHA256, "provider manifest SHA-256"
|
||||
)
|
||||
require_sealed(
|
||||
actual_native, SEALED_NATIVE_ABI_SHA256, "native ABI SHA-256"
|
||||
)
|
||||
except LockError as error:
|
||||
print(str(error), file=sys.stderr)
|
||||
return 1
|
||||
|
||||
wasm_name = require(cmake, "PROVIDER_FILE")
|
||||
wasm_path = bundle / wasm_name
|
||||
expected_sha = require(cmake, "PROVIDER_SHA256").lower()
|
||||
fingerprint = hashlib.sha256()
|
||||
for path in (
|
||||
profile_path,
|
||||
cmake_path,
|
||||
native_path,
|
||||
api_manifest_path,
|
||||
*api_paths,
|
||||
Path(__file__),
|
||||
):
|
||||
fingerprint.update(path.read_bytes())
|
||||
fingerprint.update(wasmtime_version.encode())
|
||||
wasm_bytes: bytes | None = None
|
||||
if wasm_path.is_file():
|
||||
wasm_bytes = wasm_path.read_bytes()
|
||||
digest = hashlib.sha256(wasm_bytes).hexdigest()
|
||||
if digest != expected_sha or len(wasm_bytes) != expected_size:
|
||||
print(
|
||||
"QuickJS provider WASM does not match its generated manifest",
|
||||
file=sys.stderr,
|
||||
)
|
||||
return 1
|
||||
fingerprint.update(b"wasm")
|
||||
fingerprint.update(bytes.fromhex(digest))
|
||||
provenance = f"{wasm_path} sha256={digest} size={len(wasm_bytes)}"
|
||||
else:
|
||||
fingerprint.update(b"absent")
|
||||
provenance = "no provider binary was present in the bundle directory"
|
||||
|
||||
stamp_path = output.with_name(output.name + ".stamp")
|
||||
stamp = fingerprint.hexdigest()
|
||||
if output.is_file() and stamp_path.is_file() and stamp_path.read_text() == stamp:
|
||||
return 0
|
||||
|
||||
if wasm_bytes is None:
|
||||
print(
|
||||
f"No QuickJS provider WASM at {wasm_path}; nothing is embedded "
|
||||
"and the daemon will refuse to start",
|
||||
file=sys.stderr,
|
||||
)
|
||||
|
||||
text = render_source(
|
||||
provenance=provenance,
|
||||
cmake=cmake,
|
||||
native=native,
|
||||
provider_imports=provider_imports,
|
||||
provider_exports=provider_exports,
|
||||
native_imports=native_imports,
|
||||
declaration_sha=declaration_sha,
|
||||
surface_sha=surface_sha,
|
||||
broad_declaration_sha=api_identities["broad_declaration"],
|
||||
api_artifact_manifest_sha=api_identities["api_artifact_manifest"],
|
||||
manifest_sha=actual_manifest,
|
||||
expected_sha=expected_sha,
|
||||
expected_size=expected_size,
|
||||
wasm_bytes=wasm_bytes,
|
||||
actual_native=actual_native,
|
||||
)
|
||||
output.parent.mkdir(parents=True, exist_ok=True)
|
||||
output.write_text(text)
|
||||
stamp_path.write_text(stamp)
|
||||
return 0
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--bundle-dir", type=Path, required=True)
|
||||
parser.add_argument("--wasmtime-version", required=True)
|
||||
parser.add_argument("--output", type=Path, required=True)
|
||||
args = parser.parse_args()
|
||||
try:
|
||||
return project_bundle(args.bundle_dir, args.wasmtime_version, args.output)
|
||||
except LockError as error:
|
||||
print(str(error), file=sys.stderr)
|
||||
return 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -1,90 +0,0 @@
|
||||
set(XAHAU_QUICKJS_PROVIDER_BUNDLE_DIR
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/external/quickjs-provider"
|
||||
CACHE PATH
|
||||
"Directory containing the sealed QuickJS provider WASM and generated manifests")
|
||||
get_filename_component(XAHAU_QUICKJS_PROVIDER_BUNDLE_DIR
|
||||
"${XAHAU_QUICKJS_PROVIDER_BUNDLE_DIR}"
|
||||
ABSOLUTE
|
||||
BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
set(XAHAU_QUICKJS_PROVIDER_MANIFEST
|
||||
"${XAHAU_QUICKJS_PROVIDER_BUNDLE_DIR}/jshookz_provider.manifest.cmake")
|
||||
set(XAHAU_QUICKJS_PROVIDER_PROFILE_LOCK
|
||||
"${XAHAU_QUICKJS_PROVIDER_BUNDLE_DIR}/jshookz_provider.manifest.json")
|
||||
set(XAHAU_QUICKJS_NATIVE_ABI
|
||||
"${XAHAU_QUICKJS_PROVIDER_BUNDLE_DIR}/jshookz_provider.native-abi.json")
|
||||
set(XAHAU_QUICKJS_API_ARTIFACT_MANIFEST
|
||||
"${XAHAU_QUICKJS_PROVIDER_BUNDLE_DIR}/api-artifacts.json")
|
||||
set(XAHAU_QUICKJS_BROAD_DECLARATION
|
||||
"${XAHAU_QUICKJS_PROVIDER_BUNDLE_DIR}/hooks-api.d.ts")
|
||||
set(XAHAU_QUICKJS_EXACT_V1_DECLARATION
|
||||
"${XAHAU_QUICKJS_PROVIDER_BUNDLE_DIR}/xahau-quickjs-v1.d.ts")
|
||||
set(XAHAU_QUICKJS_SELECTED_SURFACE
|
||||
"${XAHAU_QUICKJS_PROVIDER_BUNDLE_DIR}/xahau-quickjs-v1.surface.json")
|
||||
|
||||
foreach(_bundle_file
|
||||
"${XAHAU_QUICKJS_PROVIDER_MANIFEST}"
|
||||
"${XAHAU_QUICKJS_PROVIDER_PROFILE_LOCK}"
|
||||
"${XAHAU_QUICKJS_NATIVE_ABI}"
|
||||
"${XAHAU_QUICKJS_API_ARTIFACT_MANIFEST}"
|
||||
"${XAHAU_QUICKJS_BROAD_DECLARATION}"
|
||||
"${XAHAU_QUICKJS_EXACT_V1_DECLARATION}"
|
||||
"${XAHAU_QUICKJS_SELECTED_SURFACE}")
|
||||
if(NOT EXISTS "${_bundle_file}")
|
||||
message(FATAL_ERROR
|
||||
"Missing sealed QuickJS provider bundle file: ${_bundle_file}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(NOT DEFINED wasmtime_VERSION_STRING OR wasmtime_VERSION_STRING STREQUAL "")
|
||||
message(FATAL_ERROR
|
||||
"QuickJS provider requires an exact Wasmtime version, but the resolved "
|
||||
"package did not publish one")
|
||||
endif()
|
||||
|
||||
find_program(XAHAU_QUICKJS_PYTHON NAMES python3 python)
|
||||
if(NOT XAHAU_QUICKJS_PYTHON)
|
||||
message(FATAL_ERROR
|
||||
"Python is required to project the sealed QuickJS provider bundle")
|
||||
endif()
|
||||
|
||||
set(XAHAU_QUICKJS_GENERATED_INCLUDE_DIR
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/generated")
|
||||
set(XAHAU_QUICKJS_PROVIDER_VALUES_SOURCE
|
||||
"${XAHAU_QUICKJS_GENERATED_INCLUDE_DIR}/xrpld/app/hook/detail/QuickJSProviderValues.cpp")
|
||||
set(XAHAU_QUICKJS_BUNDLE_SCRIPT
|
||||
"${CMAKE_CURRENT_LIST_DIR}/GenerateQuickJSProviderBundle.py")
|
||||
|
||||
# The gitignored wasm is not a CMake depend (ninja cannot name a missing
|
||||
# file). Refresh on every rippled build; the script no-ops when inputs
|
||||
# including wasm existence/digest are unchanged.
|
||||
add_custom_target(xahau_quickjs_refresh_provider
|
||||
COMMAND
|
||||
"${XAHAU_QUICKJS_PYTHON}"
|
||||
"${XAHAU_QUICKJS_BUNDLE_SCRIPT}"
|
||||
--bundle-dir "${XAHAU_QUICKJS_PROVIDER_BUNDLE_DIR}"
|
||||
--wasmtime-version "${wasmtime_VERSION_STRING}"
|
||||
--output "${XAHAU_QUICKJS_PROVIDER_VALUES_SOURCE}"
|
||||
BYPRODUCTS "${XAHAU_QUICKJS_PROVIDER_VALUES_SOURCE}"
|
||||
DEPENDS
|
||||
"${XAHAU_QUICKJS_PROVIDER_PROFILE_LOCK}"
|
||||
"${XAHAU_QUICKJS_PROVIDER_MANIFEST}"
|
||||
"${XAHAU_QUICKJS_NATIVE_ABI}"
|
||||
"${XAHAU_QUICKJS_API_ARTIFACT_MANIFEST}"
|
||||
"${XAHAU_QUICKJS_BROAD_DECLARATION}"
|
||||
"${XAHAU_QUICKJS_EXACT_V1_DECLARATION}"
|
||||
"${XAHAU_QUICKJS_SELECTED_SURFACE}"
|
||||
"${XAHAU_QUICKJS_BUNDLE_SCRIPT}"
|
||||
COMMENT "Projecting sealed QuickJS provider values"
|
||||
VERBATIM)
|
||||
|
||||
message(STATUS
|
||||
"QuickJS provider values: ${XAHAU_QUICKJS_PROVIDER_VALUES_SOURCE}")
|
||||
|
||||
add_custom_target(xahau_quickjs_lock_mutations
|
||||
COMMAND
|
||||
"${XAHAU_QUICKJS_PYTHON}"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/test_generate_quickjs_provider_bundle.py"
|
||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||
COMMENT "Proving sealed QuickJS lock mutation reds"
|
||||
VERBATIM)
|
||||
@@ -54,7 +54,6 @@ add_library(xrpl.imports.main INTERFACE)
|
||||
target_link_libraries(xrpl.imports.main
|
||||
INTERFACE
|
||||
LibArchive::LibArchive
|
||||
magic_enum::magic_enum
|
||||
OpenSSL::Crypto
|
||||
Ripple::boost
|
||||
wasmedge::wasmedge
|
||||
@@ -69,17 +68,6 @@ target_link_libraries(xrpl.imports.main
|
||||
$<$<BOOL:${voidstar}>:antithesis-sdk-cpp>
|
||||
)
|
||||
|
||||
# date-tz for enhanced logging (always linked, code is #ifdef guarded)
|
||||
if(TARGET date::date-tz)
|
||||
target_link_libraries(xrpl.imports.main INTERFACE date::date-tz)
|
||||
endif()
|
||||
|
||||
# BEAST_ENHANCED_LOGGING: enable for Debug builds OR when explicitly requested
|
||||
# Uses generator expression so it works with multi-config generators (Xcode, VS, Ninja Multi-Config)
|
||||
target_compile_definitions(xrpl.imports.main INTERFACE
|
||||
$<$<OR:$<CONFIG:Debug>,$<BOOL:${BEAST_ENHANCED_LOGGING}>>:BEAST_ENHANCED_LOGGING=1>
|
||||
)
|
||||
|
||||
include(add_module)
|
||||
include(target_link_modules)
|
||||
|
||||
@@ -90,6 +78,12 @@ target_link_libraries(xrpl.libxrpl.beast PUBLIC
|
||||
xrpl.libpb
|
||||
)
|
||||
|
||||
# Conditionally add enhanced logging source when BEAST_ENHANCED_LOGGING is enabled
|
||||
if(DEFINED BEAST_ENHANCED_LOGGING AND BEAST_ENHANCED_LOGGING)
|
||||
target_sources(xrpl.libxrpl.beast PRIVATE
|
||||
src/libxrpl/beast/utility/src/beast_EnhancedLogging.cpp)
|
||||
endif()
|
||||
|
||||
# Level 02
|
||||
add_module(xrpl basics)
|
||||
target_link_libraries(xrpl.libxrpl.basics PUBLIC xrpl.libxrpl.beast)
|
||||
@@ -174,106 +168,18 @@ if(xrpld)
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/xrpld/*.cpp"
|
||||
)
|
||||
target_sources(rippled PRIVATE ${sources})
|
||||
add_dependencies(rippled xahau_quickjs_refresh_provider)
|
||||
target_sources(rippled PRIVATE "${XAHAU_QUICKJS_PROVIDER_VALUES_SOURCE}")
|
||||
|
||||
if(tests)
|
||||
file(GLOB_RECURSE sources CONFIGURE_DEPENDS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/test/*.cpp"
|
||||
)
|
||||
if(HOOKS_TEST_ONLY OR DEFINED ENV{HOOKS_TEST_ONLY})
|
||||
list(FILTER sources EXCLUDE REGEX "_test\\.cpp$")
|
||||
message(STATUS "HOOKS_TEST_ONLY: excluded *_test.cpp from src/test/")
|
||||
endif()
|
||||
target_sources(rippled PRIVATE ${sources})
|
||||
|
||||
# External Env tests live next to the producer. Point at a directory of
|
||||
# *_test.cpp files (typically jshookz/env-tests). hookz build-test-hooks
|
||||
# must be on PATH. Coverage is not wired here.
|
||||
if(NOT HOOKS_TEST_DIR AND DEFINED ENV{HOOKS_TEST_DIR})
|
||||
set(HOOKS_TEST_DIR $ENV{HOOKS_TEST_DIR})
|
||||
endif()
|
||||
if(NOT HOOKS_SOURCE_DIR AND DEFINED ENV{HOOKS_SOURCE_DIR})
|
||||
set(HOOKS_SOURCE_DIR $ENV{HOOKS_SOURCE_DIR})
|
||||
endif()
|
||||
if(HOOKS_TEST_DIR AND EXISTS "${HOOKS_TEST_DIR}")
|
||||
file(GLOB EXTERNAL_HOOK_TESTS CONFIGURE_DEPENDS
|
||||
"${HOOKS_TEST_DIR}/*_test.cpp"
|
||||
)
|
||||
if(EXTERNAL_HOOK_TESTS)
|
||||
set(_hooks_extra_args "")
|
||||
set(_hooks_source_deps "")
|
||||
if(HOOKS_SOURCE_DIR)
|
||||
foreach(_dir ${HOOKS_SOURCE_DIR})
|
||||
list(APPEND _hooks_extra_args "--hooks-c-dir" "${_dir}")
|
||||
string(REGEX REPLACE "^[^=]+=" "" _hook_dir "${_dir}")
|
||||
if(EXISTS "${_hook_dir}")
|
||||
file(GLOB_RECURSE _hook_dir_deps CONFIGURE_DEPENDS
|
||||
"${_hook_dir}/*.c"
|
||||
"${_hook_dir}/*.h"
|
||||
"${_hook_dir}/*.ts"
|
||||
"${_hook_dir}/*.js"
|
||||
)
|
||||
if(HOOKS_TEST_DIR)
|
||||
list(FILTER _hook_dir_deps EXCLUDE REGEX "^${HOOKS_TEST_DIR}/")
|
||||
endif()
|
||||
list(APPEND _hooks_source_deps ${_hook_dir_deps})
|
||||
endif()
|
||||
endforeach()
|
||||
list(REMOVE_DUPLICATES _hooks_source_deps)
|
||||
endif()
|
||||
set(_hooks_always_run OFF)
|
||||
if(HOOKS_FORCE_RECOMPILE OR DEFINED ENV{HOOKS_FORCE_RECOMPILE})
|
||||
list(APPEND _hooks_extra_args "--force-write" "--no-cache")
|
||||
set(_hooks_always_run ON)
|
||||
message(STATUS "Hook force recompile enabled (cache bypassed)")
|
||||
endif()
|
||||
foreach(_test_file ${EXTERNAL_HOOK_TESTS})
|
||||
get_filename_component(_stem ${_test_file} NAME_WE)
|
||||
set(_hooks_header "${HOOKS_TEST_DIR}/${_stem}_hooks.h")
|
||||
if(_hooks_always_run)
|
||||
add_custom_target(compile_hooks_${_stem} ALL
|
||||
COMMAND hookz build-test-hooks "${_test_file}" ${_hooks_extra_args}
|
||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||
COMMENT "Compiling hooks for ${_stem} (forced)"
|
||||
VERBATIM
|
||||
)
|
||||
list(APPEND EXTERNAL_HOOK_TARGETS compile_hooks_${_stem})
|
||||
else()
|
||||
add_custom_command(
|
||||
OUTPUT "${_hooks_header}"
|
||||
COMMAND hookz build-test-hooks "${_test_file}" ${_hooks_extra_args}
|
||||
DEPENDS "${_test_file}" ${_hooks_source_deps}
|
||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||
COMMENT "Compiling hooks for ${_stem}"
|
||||
VERBATIM
|
||||
)
|
||||
list(APPEND EXTERNAL_HOOK_HEADERS "${_hooks_header}")
|
||||
endif()
|
||||
endforeach()
|
||||
if(_hooks_always_run)
|
||||
foreach(_tgt ${EXTERNAL_HOOK_TARGETS})
|
||||
add_dependencies(rippled ${_tgt})
|
||||
endforeach()
|
||||
else()
|
||||
add_custom_target(compile_external_hooks DEPENDS ${EXTERNAL_HOOK_HEADERS})
|
||||
add_dependencies(rippled compile_external_hooks)
|
||||
endif()
|
||||
target_sources(rippled PRIVATE ${EXTERNAL_HOOK_TESTS})
|
||||
set_property(
|
||||
SOURCE ${EXTERNAL_HOOK_TESTS}
|
||||
APPEND PROPERTY INCLUDE_DIRECTORIES "${HOOKS_TEST_DIR}"
|
||||
)
|
||||
message(STATUS "Including external hook tests from: ${HOOKS_TEST_DIR}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_link_libraries(rippled
|
||||
Ripple::boost
|
||||
Ripple::opts
|
||||
Ripple::libs
|
||||
wasmtime::wasmtime
|
||||
xrpl.libxrpl
|
||||
# Workaround for a Conan 1.x bug that prevents static linking of libstdc++
|
||||
# when a dependency (snappy) modifies system_libs. See the comment in
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
find_package(Boost 1.86 REQUIRED
|
||||
find_package(Boost 1.83 REQUIRED
|
||||
COMPONENTS
|
||||
chrono
|
||||
container
|
||||
@@ -7,7 +7,6 @@ find_package(Boost 1.86 REQUIRED
|
||||
date_time
|
||||
filesystem
|
||||
json
|
||||
json
|
||||
program_options
|
||||
regex
|
||||
system
|
||||
@@ -32,6 +31,7 @@ target_link_libraries(ripple_boost
|
||||
Boost::date_time
|
||||
Boost::filesystem
|
||||
Boost::json
|
||||
Boost::iostreams
|
||||
Boost::program_options
|
||||
Boost::regex
|
||||
Boost::system
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
find_package(wasmtime REQUIRED)
|
||||
@@ -8,7 +8,7 @@
|
||||
# those warnings.
|
||||
if (RIPPLED_SOURCE)
|
||||
execute_process( COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${RIPPLED_SOURCE}/Builds/CMake/SociConfig.cmake.patched
|
||||
${RIPPLED_SOURCE}/cmake/SociConfig.cmake.patched
|
||||
cmake/SociConfig.cmake )
|
||||
endif ()
|
||||
|
||||
|
||||
@@ -1,756 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Fail-closed generator/checker mutation reds for the sealed QuickJS lock."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
SCRIPT = Path(__file__).with_name("GenerateQuickJSProviderBundle.py")
|
||||
BUNDLE = ROOT / "external" / "quickjs-provider"
|
||||
WASM_VERSION = "47.0.3"
|
||||
CMAKE_SET = re.compile(r'^set\(XAHAU_QUICKJS_([A-Z0-9_]+) "([^"]*)"\)\s*$')
|
||||
|
||||
PIN = {
|
||||
"provider_sha256": "f60ab333acb547e50d7d087960839bd11833cb133d496af98e0b72a1bb3b84df",
|
||||
"provider_size": "1116638",
|
||||
"manifest_sha256": "1673b27d21063957cece9095cceb7e2dbfa53b6f49a5b7f824a486d7d90b2391",
|
||||
"runtime_profile_id": "29acf12e170436e5ccadfbc118d02a60909f86a88262106652b2f71994b0ea25",
|
||||
"broad_declaration_sha256": "649079b831bc68eff0f440644649a505addafb08a3f5174e4031c8de6aedffa0",
|
||||
"exact_v1_declaration_sha256": "20881232f0602e35de0fcbb8b5a3c1511606392749a0f79daebb386204f4f4da",
|
||||
"surface_sha256": "96a9218bf38abbf1bc9f2839408700d03572e0b065d625263f70477bc32597ac",
|
||||
"api_artifact_manifest_sha256": "95babf622bf5edff76fdcbd9746bad8f1f8b275a3d4bacdc320ff4deae543eba",
|
||||
"bytecode_abi": "75ea54f357d397c4b33899e495bb385dad975a43b1c4a7a2cead30474327d33e",
|
||||
"native_abi": "328ec938dcad875f3bdf25b8d779dd77f3571589818ca9271cb98c64c7018f99",
|
||||
"wasm_stack_bytes": "131072",
|
||||
}
|
||||
|
||||
RECEIPT_B = {
|
||||
"provider_sha256": "40f9ac0203afa9296196c627bc94e669ad789322ddc1e4ab58ba0cf6d32a5e21",
|
||||
"provider_size": "1101461",
|
||||
"runtime_profile_id": "60950ca8b6fe4dd2a35559367051998bc04f75e8aa41934dd4caad0de5a1c3ba",
|
||||
"declaration_sha256": "56b4b2974b8a63a550721abd60350e392990762e76666f050b1a7c810e584957",
|
||||
"surface_sha256": "b112346b95da74d04930ba86bd597e56a428e41e11581804ccc49907ae206eb0",
|
||||
}
|
||||
|
||||
TYPED_IMPORT_ROWS = (
|
||||
'{"env", "accept", "i32,i32,i64", "i64"}',
|
||||
'{"env", "emit", "i32,i32,i32,i32", "i64"}',
|
||||
'{"env", "etxn_reserve", "i32", "i64"}',
|
||||
'{"env", "hook_account", "i32,i32", "i64"}',
|
||||
'{"env", "ledger_last_hash", "i32,i32", "i64"}',
|
||||
'{"env", "ledger_last_time", "", "i64"}',
|
||||
'{"env", "ledger_seq", "", "i64"}',
|
||||
'{"env", "otxn_type", "", "i64"}',
|
||||
'{"env", "prepare", "i32,i32,i32,i32", "i64"}',
|
||||
'{"env", "rollback", "i32,i32,i64", "i64"}',
|
||||
'{"env", "state", "i32,i32,i32,i32", "i64"}',
|
||||
'{"env", "state_set", "i32,i32,i32,i32", "i64"}',
|
||||
'{"env", "trace", "i32,i32,i32,i32,i32", "i64"}',
|
||||
)
|
||||
|
||||
TYPED_EXPORT_ROWS = (
|
||||
'{"function", "_initialize", "", "", 0U, 0U, false, false}',
|
||||
'{"function", "free", "i32", "", 0U, 0U, false, false}',
|
||||
'{"function", "malloc", "i32", "i32", 0U, 0U, false, false}',
|
||||
'{"memory", "memory", "", "", 7U, 512U, false, false}',
|
||||
'{"function", "qjs_cbak", "i32,i32,i32", "i32", 0U, 0U, false, false}',
|
||||
'{"function", "qjs_compile", "i32,i32", "i32", 0U, 0U, false, false}',
|
||||
'{"function", "qjs_compile_module", "i32,i32", "i32", 0U, 0U, false, false}',
|
||||
'{"function", "qjs_destroy", "", "", 0U, 0U, false, false}',
|
||||
'{"function", "qjs_enable_coverage", "i32", "", 0U, 0U, false, false}',
|
||||
'{"function", "qjs_eval", "i32,i32", "i32", 0U, 0U, false, false}',
|
||||
'{"function", "qjs_eval_bytecode", "i32,i32", "i32", 0U, 0U, false, false}',
|
||||
'{"function", "qjs_eval_module", "i32,i32", "i32", 0U, 0U, false, false}',
|
||||
'{"function", "qjs_get_bytecode_len", "", "i32", 0U, 0U, false, false}',
|
||||
'{"function", "qjs_get_bytecode_ptr", "", "i32", 0U, 0U, false, false}',
|
||||
'{"function", "qjs_get_result_len", "", "i32", 0U, 0U, false, false}',
|
||||
'{"function", "qjs_get_result_ptr", "", "i32", 0U, 0U, false, false}',
|
||||
'{"function", "qjs_hook", "i32,i32,i32", "i32", 0U, 0U, false, false}',
|
||||
'{"function", "qjs_init", "", "", 0U, 0U, false, false}',
|
||||
'{"function", "qjs_set_max_stack_size", "i32", "", 0U, 0U, false, false}',
|
||||
'{"function", "qjs_set_memory_limit", "i32", "", 0U, 0U, false, false}',
|
||||
'{"function", "qjs_set_seed", "i32", "", 0U, 0U, false, false}',
|
||||
'{"function", "qjs_validate_hook_module", "i32,i32", "i32", 0U, 0U, false, false}',
|
||||
)
|
||||
|
||||
|
||||
def json_path(bundle: Path) -> Path:
|
||||
return bundle / "jshookz_provider.manifest.json"
|
||||
|
||||
|
||||
def cmake_path(bundle: Path) -> Path:
|
||||
return bundle / "jshookz_provider.manifest.cmake"
|
||||
|
||||
|
||||
def native_path(bundle: Path) -> Path:
|
||||
return bundle / "jshookz_provider.native-abi.json"
|
||||
|
||||
|
||||
def wasm_path(bundle: Path) -> Path:
|
||||
return bundle / "jshookz_provider.wasm"
|
||||
|
||||
|
||||
def api_manifest_path(bundle: Path) -> Path:
|
||||
return bundle / "api-artifacts.json"
|
||||
|
||||
|
||||
def broad_declaration_path(bundle: Path) -> Path:
|
||||
return bundle / "hooks-api.d.ts"
|
||||
|
||||
|
||||
def exact_v1_declaration_path(bundle: Path) -> Path:
|
||||
return bundle / "xahau-quickjs-v1.d.ts"
|
||||
|
||||
|
||||
def surface_path(bundle: Path) -> Path:
|
||||
return bundle / "xahau-quickjs-v1.surface.json"
|
||||
|
||||
|
||||
def load_json(bundle: Path) -> dict:
|
||||
return json.loads(json_path(bundle).read_text())
|
||||
|
||||
|
||||
def write_json(bundle: Path, data: dict) -> None:
|
||||
json_path(bundle).write_text(json.dumps(data, indent=2) + "\n")
|
||||
|
||||
|
||||
def set_cmake(bundle: Path, key: str, value: str) -> None:
|
||||
path = cmake_path(bundle)
|
||||
lines = []
|
||||
replaced = False
|
||||
for line in path.read_text().splitlines():
|
||||
match = CMAKE_SET.match(line)
|
||||
if match and match.group(1) == key:
|
||||
lines.append(f'set(XAHAU_QUICKJS_{key} "{value}")')
|
||||
replaced = True
|
||||
else:
|
||||
lines.append(line)
|
||||
if not replaced:
|
||||
raise AssertionError(f"CMake lock is missing {key}")
|
||||
path.write_text("\n".join(lines) + "\n")
|
||||
|
||||
|
||||
def rehash_manifest(bundle: Path) -> None:
|
||||
digest = hashlib.sha256(json_path(bundle).read_bytes()).hexdigest()
|
||||
set_cmake(bundle, "MANIFEST_SHA256", digest)
|
||||
|
||||
|
||||
def rehash_native(bundle: Path) -> None:
|
||||
digest = hashlib.sha256(native_path(bundle).read_bytes()).hexdigest()
|
||||
set_cmake(bundle, "NATIVE_ABI_SHA256", digest)
|
||||
|
||||
|
||||
def load_api_manifest(bundle: Path) -> dict:
|
||||
return json.loads(api_manifest_path(bundle).read_text())
|
||||
|
||||
|
||||
def write_api_manifest(bundle: Path, data: dict) -> None:
|
||||
api_manifest_path(bundle).write_text(json.dumps(data, indent=2) + "\n")
|
||||
|
||||
|
||||
def clone_bundle(root: Path) -> Path:
|
||||
dest = root / "bundle"
|
||||
shutil.copytree(BUNDLE, dest, ignore=shutil.ignore_patterns("README.md"))
|
||||
return dest
|
||||
|
||||
|
||||
def generate(
|
||||
bundle: Path, work: Path, wasmtime_version: str = WASM_VERSION
|
||||
) -> tuple[int, str, str]:
|
||||
output = work / "QuickJSProviderValues.cpp"
|
||||
completed = subprocess.run(
|
||||
[
|
||||
sys.executable,
|
||||
str(SCRIPT),
|
||||
"--bundle-dir",
|
||||
str(bundle),
|
||||
"--wasmtime-version",
|
||||
wasmtime_version,
|
||||
"--output",
|
||||
str(output),
|
||||
],
|
||||
check=False,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
cpp = output.read_text() if output.is_file() else ""
|
||||
return completed.returncode, completed.stderr, cpp
|
||||
|
||||
|
||||
def hex_bytes(value: str) -> str:
|
||||
return ", ".join(f"0x{value[i:i + 2]}" for i in range(0, 64, 2))
|
||||
|
||||
|
||||
def pin_holds(returncode: int, cpp: str) -> bool:
|
||||
if returncode != 0 or not cpp:
|
||||
return False
|
||||
required = [
|
||||
hex_bytes(PIN["provider_sha256"]),
|
||||
f"std::size_t const providerSize = {PIN['provider_size']};",
|
||||
f'"{PIN["manifest_sha256"]}"',
|
||||
hex_bytes(PIN["runtime_profile_id"]),
|
||||
f'"{PIN["broad_declaration_sha256"]}"',
|
||||
f'"{PIN["exact_v1_declaration_sha256"]}"',
|
||||
f'"{PIN["surface_sha256"]}"',
|
||||
f'"{PIN["api_artifact_manifest_sha256"]}"',
|
||||
hex_bytes(PIN["bytecode_abi"]),
|
||||
f'"{PIN["native_abi"]}"',
|
||||
f"std::uint32_t const wasmStackBytes = {PIN['wasm_stack_bytes']}U;",
|
||||
"std::uint32_t const serializedObjectMaxBytes =\n 1048576U;",
|
||||
"std::uint32_t const serializedObjectMaxFields =\n 32768U;",
|
||||
"std::uint32_t const serializedObjectMaxScopes =\n 32769U;",
|
||||
"std::uint32_t const serializedObjectMaxDepth =\n 10U;",
|
||||
"std::uint32_t const providerMemoryMinimumPages = 7U;",
|
||||
"std::uint32_t const providerMemoryMaximumPages = 512U;",
|
||||
"constexpr char const sealedProvider[] =",
|
||||
f"sizeof(sealedProvider) - 1 == {PIN['provider_size']}",
|
||||
]
|
||||
if any(item not in cpp for item in required):
|
||||
return False
|
||||
return all(row in cpp for row in (*TYPED_IMPORT_ROWS, *TYPED_EXPORT_ROWS))
|
||||
|
||||
|
||||
class GenerateQuickJSProviderBundleTest(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls) -> None:
|
||||
missing = [
|
||||
path.name
|
||||
for path in (
|
||||
json_path(BUNDLE),
|
||||
cmake_path(BUNDLE),
|
||||
native_path(BUNDLE),
|
||||
wasm_path(BUNDLE),
|
||||
api_manifest_path(BUNDLE),
|
||||
broad_declaration_path(BUNDLE),
|
||||
exact_v1_declaration_path(BUNDLE),
|
||||
surface_path(BUNDLE),
|
||||
SCRIPT,
|
||||
)
|
||||
if not path.is_file()
|
||||
]
|
||||
if missing:
|
||||
raise AssertionError(
|
||||
"sealed QuickJS bundle is incomplete: " + ", ".join(missing)
|
||||
)
|
||||
|
||||
def mutate(
|
||||
self, mutator, wasmtime_version: str = WASM_VERSION
|
||||
) -> tuple[int, str, str]:
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
work = Path(tmp)
|
||||
bundle = clone_bundle(work)
|
||||
mutator(bundle)
|
||||
return generate(bundle, work / "out", wasmtime_version)
|
||||
|
||||
def assert_generator_red(
|
||||
self, mutator, fragment: str, wasmtime_version: str = WASM_VERSION
|
||||
) -> None:
|
||||
returncode, stderr, cpp = self.mutate(mutator, wasmtime_version)
|
||||
self.assertNotEqual(returncode, 0, stderr)
|
||||
self.assertIn(fragment, stderr)
|
||||
self.assertFalse(pin_holds(returncode, cpp), stderr)
|
||||
|
||||
def test_unmutated_lock_projects_pin_and_typed_exports(self) -> None:
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
work = Path(tmp)
|
||||
returncode, stderr, cpp = generate(clone_bundle(work), work / "out")
|
||||
self.assertEqual(returncode, 0, stderr)
|
||||
self.assertTrue(pin_holds(returncode, cpp), stderr)
|
||||
self.assertEqual(cpp.count("ProviderExportSignature const"), 2)
|
||||
|
||||
def test_provider_bytes_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
path = wasm_path(bundle)
|
||||
data = bytearray(path.read_bytes())
|
||||
data[-1] ^= 0xFF
|
||||
path.write_bytes(data)
|
||||
|
||||
self.assert_generator_red(mutate, "WASM does not match")
|
||||
|
||||
def test_provider_size_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
set_cmake(bundle, "PROVIDER_SIZE", "1116637")
|
||||
|
||||
self.assert_generator_red(mutate, "provider size disagrees")
|
||||
|
||||
def test_coordinated_provider_size_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
value = 1116637
|
||||
data = load_json(bundle)
|
||||
data["provider"]["size"] = value
|
||||
write_json(bundle, data)
|
||||
rehash_manifest(bundle)
|
||||
set_cmake(bundle, "PROVIDER_SIZE", str(value))
|
||||
|
||||
self.assert_generator_red(mutate, "provider size disagrees with the sealed F0")
|
||||
|
||||
def test_provider_sha_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
set_cmake(
|
||||
bundle,
|
||||
"PROVIDER_SHA256",
|
||||
"00" + PIN["provider_sha256"][2:],
|
||||
)
|
||||
|
||||
self.assert_generator_red(mutate, "provider sha256 disagrees")
|
||||
|
||||
def test_coordinated_provider_sha_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
value = "00" + PIN["provider_sha256"][2:]
|
||||
data = load_json(bundle)
|
||||
data["provider"]["sha256"] = value
|
||||
write_json(bundle, data)
|
||||
rehash_manifest(bundle)
|
||||
set_cmake(bundle, "PROVIDER_SHA256", value)
|
||||
|
||||
self.assert_generator_red(mutate, "provider SHA-256 disagrees with the sealed F0")
|
||||
|
||||
def test_manifest_sha_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
set_cmake(
|
||||
bundle,
|
||||
"MANIFEST_SHA256",
|
||||
"00" + PIN["manifest_sha256"][2:],
|
||||
)
|
||||
|
||||
self.assert_generator_red(mutate, "JSON manifest does not match")
|
||||
|
||||
def test_coordinated_manifest_identity_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
data = load_json(bundle)
|
||||
data["diagnostic_note"] = "not F0"
|
||||
write_json(bundle, data)
|
||||
rehash_manifest(bundle)
|
||||
|
||||
self.assert_generator_red(mutate, "provider manifest SHA-256")
|
||||
|
||||
def test_runtime_profile_id_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
set_cmake(
|
||||
bundle,
|
||||
"RUNTIME_PROFILE_ID",
|
||||
"00" + PIN["runtime_profile_id"][2:],
|
||||
)
|
||||
|
||||
self.assert_generator_red(mutate, "runtime-profile ID disagrees")
|
||||
|
||||
def test_coordinated_runtime_profile_id_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
value = "00" + PIN["runtime_profile_id"][2:]
|
||||
data = load_json(bundle)
|
||||
data["runtime_profile_id"] = value
|
||||
write_json(bundle, data)
|
||||
rehash_manifest(bundle)
|
||||
set_cmake(bundle, "RUNTIME_PROFILE_ID", value)
|
||||
|
||||
self.assert_generator_red(mutate, "runtime-profile ID disagrees with the sealed F0")
|
||||
|
||||
def _coordinated_api_artifact_mutation(
|
||||
self, source_path: str, local_path, fragment: str
|
||||
) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
path = local_path(bundle)
|
||||
path.write_bytes(path.read_bytes() + b"\n")
|
||||
manifest = load_api_manifest(bundle)
|
||||
manifest["artifacts"][source_path] = hashlib.sha256(
|
||||
path.read_bytes()
|
||||
).hexdigest()
|
||||
write_api_manifest(bundle, manifest)
|
||||
|
||||
self.assert_generator_red(mutate, fragment)
|
||||
|
||||
def test_broad_declaration_identity_mutation(self) -> None:
|
||||
self._coordinated_api_artifact_mutation(
|
||||
"python/jshookz/src/jshookz/types/hooks-api.d.ts",
|
||||
broad_declaration_path,
|
||||
"hooks-api.d.ts disagrees with the sealed F0 table",
|
||||
)
|
||||
|
||||
def test_exact_v1_declaration_identity_mutation(self) -> None:
|
||||
self._coordinated_api_artifact_mutation(
|
||||
"python/jshookz/src/jshookz/types/xahau-quickjs-v1.d.ts",
|
||||
exact_v1_declaration_path,
|
||||
"xahau-quickjs-v1.d.ts disagrees with the sealed F0 table",
|
||||
)
|
||||
|
||||
def test_selected_surface_identity_mutation(self) -> None:
|
||||
self._coordinated_api_artifact_mutation(
|
||||
"python/jshookz/src/jshookz/types/xahau-quickjs-v1.surface.json",
|
||||
surface_path,
|
||||
"xahau-quickjs-v1.surface.json disagrees with the sealed F0 table",
|
||||
)
|
||||
|
||||
def test_api_artifact_manifest_identity_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
data = load_api_manifest(bundle)
|
||||
api_manifest_path(bundle).write_text(json.dumps(data, indent=4) + "\n")
|
||||
|
||||
self.assert_generator_red(mutate, "API artifact manifest SHA-256")
|
||||
|
||||
def test_declaration_sha_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
data = load_json(bundle)
|
||||
data["javascript_surface"]["declaration_sha256"] = (
|
||||
"00" + PIN["exact_v1_declaration_sha256"][2:]
|
||||
)
|
||||
write_json(bundle, data)
|
||||
rehash_manifest(bundle)
|
||||
|
||||
self.assert_generator_red(mutate, "declaration SHA-256 disagrees")
|
||||
|
||||
def test_surface_sha_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
data = load_json(bundle)
|
||||
data["javascript_surface"]["sha256"] = "00" + PIN["surface_sha256"][2:]
|
||||
write_json(bundle, data)
|
||||
rehash_manifest(bundle)
|
||||
|
||||
self.assert_generator_red(mutate, "surface SHA-256 disagrees")
|
||||
|
||||
def test_bytecode_abi_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
set_cmake(bundle, "BYTECODE_ABI_ID", "00" + PIN["bytecode_abi"][2:])
|
||||
|
||||
self.assert_generator_red(mutate, "bytecode ABI disagrees")
|
||||
|
||||
def test_coordinated_bytecode_abi_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
value = "00" + PIN["bytecode_abi"][2:]
|
||||
data = load_json(bundle)
|
||||
data["bytecode_abi_id"] = value
|
||||
write_json(bundle, data)
|
||||
rehash_manifest(bundle)
|
||||
set_cmake(bundle, "BYTECODE_ABI_ID", value)
|
||||
|
||||
self.assert_generator_red(mutate, "bytecode ABI disagrees with the sealed F0")
|
||||
|
||||
def test_native_abi_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
set_cmake(bundle, "NATIVE_ABI_SHA256", "00" + PIN["native_abi"][2:])
|
||||
|
||||
self.assert_generator_red(mutate, "native ABI snapshot does not match")
|
||||
|
||||
def test_coordinated_native_abi_identity_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
path = native_path(bundle)
|
||||
path.write_bytes(path.read_bytes() + b"\n")
|
||||
rehash_native(bundle)
|
||||
|
||||
self.assert_generator_red(mutate, "native ABI SHA-256")
|
||||
|
||||
def test_import_signature_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
data = load_json(bundle)
|
||||
data["provider"]["imports"][0]["params"].append("i32")
|
||||
write_json(bundle, data)
|
||||
rehash_manifest(bundle)
|
||||
|
||||
self.assert_generator_red(mutate, "import signatures disagree")
|
||||
|
||||
def test_export_signature_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
data = load_json(bundle)
|
||||
for item in data["provider"]["exports"]:
|
||||
if item["name"] == "qjs_hook":
|
||||
item["params"].append("i32")
|
||||
break
|
||||
write_json(bundle, data)
|
||||
rehash_manifest(bundle)
|
||||
|
||||
self.assert_generator_red(mutate, "export signatures disagree")
|
||||
|
||||
def test_coordinated_export_signature_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
data = load_json(bundle)
|
||||
for collection in (
|
||||
data["provider"]["exports"],
|
||||
data["source"]["provider"]["allowed_exports"],
|
||||
):
|
||||
for item in collection:
|
||||
if item["name"] == "qjs_hook":
|
||||
item["params"].append("i32")
|
||||
write_json(bundle, data)
|
||||
rehash_manifest(bundle)
|
||||
|
||||
self.assert_generator_red(mutate, "sealed F0 table")
|
||||
|
||||
def test_coordinated_wasi_import_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
data = load_json(bundle)
|
||||
for collection in (
|
||||
data["provider"]["imports"],
|
||||
data["source"]["provider"]["imports"],
|
||||
):
|
||||
for item in collection:
|
||||
if item["name"] == "accept":
|
||||
item["module"] = "wasi_snapshot_preview1"
|
||||
write_json(bundle, data)
|
||||
rehash_manifest(bundle)
|
||||
|
||||
self.assert_generator_red(mutate, "sealed F0 table")
|
||||
|
||||
def test_coordinated_import_signature_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
data = load_json(bundle)
|
||||
for collection in (
|
||||
data["provider"]["imports"],
|
||||
data["source"]["provider"]["imports"],
|
||||
):
|
||||
for item in collection:
|
||||
if item["name"] == "accept":
|
||||
item["params"].append("i32")
|
||||
write_json(bundle, data)
|
||||
rehash_manifest(bundle)
|
||||
|
||||
self.assert_generator_red(mutate, "sealed F0 table")
|
||||
|
||||
def test_export_extra_key_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
data = load_json(bundle)
|
||||
for collection in (
|
||||
data["provider"]["exports"],
|
||||
data["source"]["provider"]["allowed_exports"],
|
||||
):
|
||||
for item in collection:
|
||||
if item["name"] == "qjs_init":
|
||||
item["note"] = "extra"
|
||||
write_json(bundle, data)
|
||||
rehash_manifest(bundle)
|
||||
|
||||
self.assert_generator_red(mutate, "extra or missing keys")
|
||||
|
||||
def _memory_shape_mutation(self, key: str, value) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
data = load_json(bundle)
|
||||
for collection in (
|
||||
data["provider"]["exports"],
|
||||
data["source"]["provider"]["allowed_exports"],
|
||||
):
|
||||
for item in collection:
|
||||
if item["kind"] == "memory":
|
||||
item[key] = value
|
||||
write_json(bundle, data)
|
||||
rehash_manifest(bundle)
|
||||
|
||||
self.assert_generator_red(mutate, "memory")
|
||||
|
||||
def test_memory_minimum_shape_mutation(self) -> None:
|
||||
self._memory_shape_mutation("minimum_pages", 6)
|
||||
|
||||
def test_memory_maximum_shape_mutation(self) -> None:
|
||||
self._memory_shape_mutation("maximum_pages", 511)
|
||||
|
||||
def test_memory64_shape_mutation(self) -> None:
|
||||
self._memory_shape_mutation("memory64", True)
|
||||
|
||||
def test_shared_memory_shape_mutation(self) -> None:
|
||||
self._memory_shape_mutation("shared", True)
|
||||
|
||||
def test_serialized_object_max_bytes_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
set_cmake(bundle, "SERIALIZED_OBJECT_MAX_BYTES", "1048577")
|
||||
|
||||
self.assert_generator_red(mutate, "serialized_object_max_bytes")
|
||||
|
||||
def test_serialized_object_max_fields_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
set_cmake(bundle, "SERIALIZED_OBJECT_MAX_FIELDS", "32769")
|
||||
|
||||
self.assert_generator_red(mutate, "serialized_object_max_fields")
|
||||
|
||||
def test_serialized_object_max_scopes_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
set_cmake(bundle, "SERIALIZED_OBJECT_MAX_SCOPES", "32770")
|
||||
|
||||
self.assert_generator_red(mutate, "serialized_object_max_scopes")
|
||||
|
||||
def test_serialized_object_max_depth_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
set_cmake(bundle, "SERIALIZED_OBJECT_MAX_DEPTH", "11")
|
||||
|
||||
self.assert_generator_red(mutate, "serialized_object_max_depth")
|
||||
|
||||
def _coordinated_limit(self, json_key: str, cmake_key: str, value: int) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
data = load_json(bundle)
|
||||
data["source"]["limits"][json_key] = value
|
||||
write_json(bundle, data)
|
||||
rehash_manifest(bundle)
|
||||
set_cmake(bundle, cmake_key, str(value))
|
||||
|
||||
self.assert_generator_red(mutate, "sealed F0 table")
|
||||
|
||||
def test_coordinated_serialized_object_max_bytes_mutation(self) -> None:
|
||||
self._coordinated_limit(
|
||||
"serialized_object_max_bytes", "SERIALIZED_OBJECT_MAX_BYTES", 1048578
|
||||
)
|
||||
|
||||
def test_coordinated_serialized_object_max_fields_mutation(self) -> None:
|
||||
self._coordinated_limit(
|
||||
"serialized_object_max_fields", "SERIALIZED_OBJECT_MAX_FIELDS", 1
|
||||
)
|
||||
|
||||
def test_coordinated_serialized_object_max_scopes_mutation(self) -> None:
|
||||
self._coordinated_limit(
|
||||
"serialized_object_max_scopes", "SERIALIZED_OBJECT_MAX_SCOPES", 1
|
||||
)
|
||||
|
||||
def test_coordinated_serialized_object_max_depth_mutation(self) -> None:
|
||||
self._coordinated_limit(
|
||||
"serialized_object_max_depth", "SERIALIZED_OBJECT_MAX_DEPTH", 1
|
||||
)
|
||||
|
||||
def test_coordinated_heap_limit_mutation(self) -> None:
|
||||
self._coordinated_limit("quickjs_heap_bytes", "HEAP_BYTES", 16777215)
|
||||
|
||||
def test_coordinated_stack_limit_mutation(self) -> None:
|
||||
self._coordinated_limit("quickjs_stack_bytes", "STACK_BYTES", 65535)
|
||||
|
||||
def test_coordinated_initialization_fuel_mutation(self) -> None:
|
||||
self._coordinated_limit(
|
||||
"wasmtime_fuel_per_initialization", "INITIALIZATION_FUEL", 4999999
|
||||
)
|
||||
|
||||
def test_coordinated_invocation_fuel_mutation(self) -> None:
|
||||
self._coordinated_limit(
|
||||
"wasmtime_fuel_per_invocation", "INVOCATION_FUEL", 49999999
|
||||
)
|
||||
|
||||
def test_coordinated_host_work_budget_mutation(self) -> None:
|
||||
self._coordinated_limit("host_work_budget", "HOST_WORK_BUDGET", 999999)
|
||||
|
||||
def test_coordinated_host_work_base_mutation(self) -> None:
|
||||
self._coordinated_limit(
|
||||
"host_work_base_per_call", "HOST_WORK_BASE_PER_CALL", 2
|
||||
)
|
||||
|
||||
def test_coordinated_host_work_per_byte_mutation(self) -> None:
|
||||
self._coordinated_limit(
|
||||
"host_work_per_addressed_byte", "HOST_WORK_PER_ADDRESSED_BYTE", 2
|
||||
)
|
||||
|
||||
def test_coordinated_host_work_meter_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
data = load_json(bundle)
|
||||
data["source"]["limits"]["host_work_meter"] = "other-meter"
|
||||
write_json(bundle, data)
|
||||
rehash_manifest(bundle)
|
||||
set_cmake(bundle, "HOST_WORK_METER", "other-meter")
|
||||
|
||||
self.assert_generator_red(mutate, "host_work_meter")
|
||||
|
||||
def test_host_work_address_mapping_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
data = load_json(bundle)
|
||||
data["source"]["limits"]["host_work_addressed_length_indices"][
|
||||
"accept"
|
||||
] = [0]
|
||||
write_json(bundle, data)
|
||||
rehash_manifest(bundle)
|
||||
|
||||
self.assert_generator_red(mutate, "host_work_addressed_length_indices")
|
||||
|
||||
def test_coordinated_host_adapter_policy_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
data = load_json(bundle)
|
||||
data["source"]["execution"]["host_adapter_policy"] = "other-policy"
|
||||
write_json(bundle, data)
|
||||
rehash_manifest(bundle)
|
||||
set_cmake(bundle, "HOST_ADAPTER_POLICY", "other-policy")
|
||||
|
||||
self.assert_generator_red(mutate, "host_adapter_policy")
|
||||
|
||||
def test_coordinated_hook_api_version_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
data = load_json(bundle)
|
||||
data["source"]["artifact"]["hook_api_version"] = 2
|
||||
write_json(bundle, data)
|
||||
rehash_manifest(bundle)
|
||||
set_cmake(bundle, "HOOK_API_VERSION", "2")
|
||||
|
||||
self.assert_generator_red(mutate, "hook_api_version")
|
||||
|
||||
def test_wasmtime_engine_configuration_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
data = load_json(bundle)
|
||||
data["source"]["engine"]["configuration"]["wasi"] = True
|
||||
write_json(bundle, data)
|
||||
rehash_manifest(bundle)
|
||||
|
||||
self.assert_generator_red(mutate, "Wasmtime engine configuration")
|
||||
|
||||
def test_coordinated_wasmtime_version_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
data = load_json(bundle)
|
||||
data["source"]["engine"]["version"] = "48.0.0"
|
||||
write_json(bundle, data)
|
||||
rehash_manifest(bundle)
|
||||
set_cmake(bundle, "WASMTIME_VERSION", "48.0.0")
|
||||
|
||||
self.assert_generator_red(
|
||||
mutate, "Wasmtime version disagrees with the sealed F0", "48.0.0"
|
||||
)
|
||||
|
||||
def test_provider_memory_max_bytes_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
data = load_json(bundle)
|
||||
data["provider"]["build"]["wasm_memory_max_bytes"] = 33554431
|
||||
data["source"]["provider"]["build"][
|
||||
"wasm_memory_max_bytes"
|
||||
] = 33554431
|
||||
write_json(bundle, data)
|
||||
rehash_manifest(bundle)
|
||||
|
||||
self.assert_generator_red(mutate, "wasm_memory_max_bytes")
|
||||
|
||||
def test_wasm_stack_bytes_mutation(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
data = load_json(bundle)
|
||||
data["provider"]["build"]["wasm_stack_bytes"] = 65536
|
||||
data["source"]["provider"]["build"]["wasm_stack_bytes"] = 65536
|
||||
write_json(bundle, data)
|
||||
rehash_manifest(bundle)
|
||||
|
||||
self.assert_generator_red(mutate, "wasm_stack_bytes")
|
||||
|
||||
def test_stale_receipt_b_lock_control(self) -> None:
|
||||
def mutate(bundle: Path) -> None:
|
||||
data = load_json(bundle)
|
||||
data["provider"]["sha256"] = RECEIPT_B["provider_sha256"]
|
||||
data["provider"]["size"] = int(RECEIPT_B["provider_size"])
|
||||
data["runtime_profile_id"] = RECEIPT_B["runtime_profile_id"]
|
||||
data["javascript_surface"]["declaration_sha256"] = RECEIPT_B[
|
||||
"declaration_sha256"
|
||||
]
|
||||
data["javascript_surface"]["sha256"] = RECEIPT_B["surface_sha256"]
|
||||
for collection in (
|
||||
data["provider"]["exports"],
|
||||
data["source"]["provider"]["allowed_exports"],
|
||||
):
|
||||
for item in collection:
|
||||
if item["kind"] == "memory":
|
||||
item["minimum_pages"] = 6
|
||||
write_json(bundle, data)
|
||||
rehash_manifest(bundle)
|
||||
set_cmake(bundle, "PROVIDER_SHA256", RECEIPT_B["provider_sha256"])
|
||||
set_cmake(bundle, "PROVIDER_SIZE", RECEIPT_B["provider_size"])
|
||||
set_cmake(
|
||||
bundle, "RUNTIME_PROFILE_ID", RECEIPT_B["runtime_profile_id"]
|
||||
)
|
||||
|
||||
self.assert_generator_red(
|
||||
mutate, "provider SHA-256 disagrees with the sealed F0"
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
261
conanfile.py
261
conanfile.py
@@ -2,162 +2,157 @@ from conan import ConanFile
|
||||
from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout
|
||||
import re
|
||||
|
||||
|
||||
class Xrpl(ConanFile):
|
||||
name = "xrpl"
|
||||
name = 'xrpl'
|
||||
|
||||
license = "ISC"
|
||||
author = "John Freeman <jfreeman@ripple.com>"
|
||||
url = "https://github.com/xrplf/rippled"
|
||||
description = "The XRP Ledger"
|
||||
settings = "os", "compiler", "build_type", "arch"
|
||||
license = 'ISC'
|
||||
author = 'John Freeman <jfreeman@ripple.com>'
|
||||
url = 'https://github.com/xrplf/rippled'
|
||||
description = 'The XRP Ledger'
|
||||
settings = 'os', 'compiler', 'build_type', 'arch'
|
||||
options = {
|
||||
"assertions": [True, False],
|
||||
"coverage": [True, False],
|
||||
"fPIC": [True, False],
|
||||
"jemalloc": [True, False],
|
||||
"rocksdb": [True, False],
|
||||
"shared": [True, False],
|
||||
"static": [True, False],
|
||||
"tests": [True, False],
|
||||
"unity": [True, False],
|
||||
"xrpld": [True, False],
|
||||
"with_wasmedge": [True, False],
|
||||
"tool_requires_b2": [True, False],
|
||||
'assertions': [True, False],
|
||||
'coverage': [True, False],
|
||||
'fPIC': [True, False],
|
||||
'jemalloc': [True, False],
|
||||
'rocksdb': [True, False],
|
||||
'shared': [True, False],
|
||||
'static': [True, False],
|
||||
'tests': [True, False],
|
||||
'unity': [True, False],
|
||||
'xrpld': [True, False],
|
||||
'with_wasmedge': [True, False],
|
||||
'tool_requires_b2': [True, False],
|
||||
}
|
||||
|
||||
requires = [
|
||||
"date/3.0.3",
|
||||
"grpc/1.50.1",
|
||||
"libarchive/3.7.6",
|
||||
"magic_enum/0.9.5",
|
||||
"nudb/2.0.8",
|
||||
"openssl/3.6.0",
|
||||
"soci/4.0.3@xahaud/stable",
|
||||
"xxhash/0.8.2",
|
||||
"zlib/1.3.1",
|
||||
'date/3.0.3',
|
||||
'grpc/1.50.1',
|
||||
'libarchive/3.7.6',
|
||||
'nudb/2.0.8',
|
||||
'openssl/3.6.0',
|
||||
'soci/4.0.3@xahaud/stable',
|
||||
'xxhash/0.8.2',
|
||||
'zlib/1.3.1',
|
||||
]
|
||||
|
||||
tool_requires = [
|
||||
"protobuf/3.21.12",
|
||||
'protobuf/3.21.12',
|
||||
]
|
||||
|
||||
default_options = {
|
||||
"assertions": False,
|
||||
"coverage": False,
|
||||
"fPIC": True,
|
||||
"jemalloc": False,
|
||||
"rocksdb": True,
|
||||
"shared": False,
|
||||
"static": True,
|
||||
"tests": False,
|
||||
"unity": False,
|
||||
"xrpld": False,
|
||||
"with_wasmedge": True,
|
||||
"tool_requires_b2": False,
|
||||
"date/*:header_only": False,
|
||||
"grpc/*:shared": False,
|
||||
"grpc/*:secure": True,
|
||||
"libarchive/*:shared": False,
|
||||
"libarchive/*:with_acl": False,
|
||||
"libarchive/*:with_bzip2": False,
|
||||
"libarchive/*:with_cng": False,
|
||||
"libarchive/*:with_expat": False,
|
||||
"libarchive/*:with_iconv": False,
|
||||
"libarchive/*:with_libxml2": False,
|
||||
"libarchive/*:with_lz4": True,
|
||||
"libarchive/*:with_lzma": False,
|
||||
"libarchive/*:with_lzo": False,
|
||||
"libarchive/*:with_nettle": False,
|
||||
"libarchive/*:with_openssl": False,
|
||||
"libarchive/*:with_pcreposix": False,
|
||||
"libarchive/*:with_xattr": False,
|
||||
"libarchive/*:with_zlib": False,
|
||||
"lz4/*:shared": False,
|
||||
"openssl/*:shared": False,
|
||||
"protobuf/*:shared": False,
|
||||
"protobuf/*:with_zlib": True,
|
||||
"rocksdb/*:enable_sse": False,
|
||||
"rocksdb/*:lite": False,
|
||||
"rocksdb/*:shared": False,
|
||||
"rocksdb/*:use_rtti": True,
|
||||
"rocksdb/*:with_jemalloc": False,
|
||||
"rocksdb/*:with_lz4": True,
|
||||
"rocksdb/*:with_snappy": True,
|
||||
"snappy/*:shared": False,
|
||||
"soci/*:shared": False,
|
||||
"soci/*:with_sqlite3": True,
|
||||
"soci/*:with_boost": True,
|
||||
"wasmtime/*:shared": False,
|
||||
"xxhash/*:shared": False,
|
||||
'assertions': False,
|
||||
'coverage': False,
|
||||
'fPIC': True,
|
||||
'jemalloc': False,
|
||||
'rocksdb': True,
|
||||
'shared': False,
|
||||
'static': True,
|
||||
'tests': False,
|
||||
'unity': False,
|
||||
'with_wasmedge': True,
|
||||
'tool_requires_b2': False,
|
||||
'xrpld': False,
|
||||
|
||||
'date/*:header_only': False,
|
||||
'grpc/*:shared': False,
|
||||
'grpc/*:secure': True,
|
||||
'libarchive/*:shared': False,
|
||||
'libarchive/*:with_acl': False,
|
||||
'libarchive/*:with_bzip2': False,
|
||||
'libarchive/*:with_cng': False,
|
||||
'libarchive/*:with_expat': False,
|
||||
'libarchive/*:with_iconv': False,
|
||||
'libarchive/*:with_libxml2': False,
|
||||
'libarchive/*:with_lz4': True,
|
||||
'libarchive/*:with_lzma': False,
|
||||
'libarchive/*:with_lzo': False,
|
||||
'libarchive/*:with_nettle': False,
|
||||
'libarchive/*:with_openssl': False,
|
||||
'libarchive/*:with_pcreposix': False,
|
||||
'libarchive/*:with_xattr': False,
|
||||
'libarchive/*:with_zlib': False,
|
||||
'lz4/*:shared': False,
|
||||
'openssl/*:shared': False,
|
||||
'protobuf/*:shared': False,
|
||||
'protobuf/*:with_zlib': True,
|
||||
'rocksdb/*:enable_sse': False,
|
||||
'rocksdb/*:lite': False,
|
||||
'rocksdb/*:shared': False,
|
||||
'rocksdb/*:use_rtti': True,
|
||||
'rocksdb/*:with_jemalloc': False,
|
||||
'rocksdb/*:with_lz4': True,
|
||||
'rocksdb/*:with_snappy': True,
|
||||
'snappy/*:shared': False,
|
||||
'soci/*:shared': False,
|
||||
'soci/*:with_sqlite3': True,
|
||||
'soci/*:with_boost': True,
|
||||
'xxhash/*:shared': False,
|
||||
}
|
||||
|
||||
def set_version(self):
|
||||
path = f"{self.recipe_folder}/src/libxrpl/protocol/BuildInfo.cpp"
|
||||
regex = r"versionString\s?=\s?\"(.*)\""
|
||||
with open(path, "r") as file:
|
||||
path = f'{self.recipe_folder}/src/libxrpl/protocol/BuildInfo.cpp'
|
||||
regex = r'versionString\s?=\s?\"(.*)\"'
|
||||
with open(path, 'r') as file:
|
||||
matches = (re.search(regex, line) for line in file)
|
||||
match = next(m for m in matches if m)
|
||||
self.version = match.group(1)
|
||||
|
||||
def build_requirements(self):
|
||||
# These provide build tools (protoc, grpc plugins) that run during build
|
||||
self.tool_requires("grpc/1.50.1")
|
||||
self.tool_requires('grpc/1.50.1')
|
||||
# Explicitly require b2 (e.g. for building from source for glibc compatibility)
|
||||
if self.options.tool_requires_b2:
|
||||
self.tool_requires("b2/5.3.2")
|
||||
self.tool_requires('b2/5.3.2')
|
||||
|
||||
def configure(self):
|
||||
if self.settings.compiler == "apple-clang":
|
||||
self.options["boost/*"].visibility = "global"
|
||||
if self.settings.compiler == 'apple-clang':
|
||||
self.options['boost/*'].visibility = 'global'
|
||||
|
||||
def requirements(self):
|
||||
# Force sqlite3 version to avoid conflicts with soci
|
||||
self.requires("sqlite3/3.47.0", override=True)
|
||||
# Force our custom snappy build for all dependencies
|
||||
self.requires("snappy/1.1.10@xahaud/stable", override=True)
|
||||
# Force boost version for all dependencies to avoid conflicts
|
||||
self.requires("boost/1.86.0", override=True)
|
||||
self.requires("lz4/1.10.0", force=True)
|
||||
self.requires('boost/1.86.0', override=True)
|
||||
self.requires('lz4/1.10.0', force=True)
|
||||
self.requires('protobuf/3.21.9', force=True)
|
||||
# Force sqlite3 version to avoid conflicts with soci
|
||||
self.requires('sqlite3/3.47.0', override=True)
|
||||
# Force our custom snappy build for all dependencies
|
||||
self.requires('snappy/1.1.10@xahaud/stable', override=True)
|
||||
|
||||
if self.options.with_wasmedge:
|
||||
self.requires("wasmedge/0.11.2@xahaud/stable")
|
||||
if self.options.xrpld:
|
||||
self.requires("wasmtime/47.0.3@xahaud/stable")
|
||||
self.requires('wasmedge/0.11.2@xahaud/stable')
|
||||
if self.options.jemalloc:
|
||||
self.requires("jemalloc/5.3.0")
|
||||
self.requires('jemalloc/5.3.0')
|
||||
if self.options.rocksdb:
|
||||
self.requires("rocksdb/6.29.5")
|
||||
self.requires('rocksdb/6.29.5')
|
||||
|
||||
exports_sources = (
|
||||
"CMakeLists.txt",
|
||||
"bin/getRippledInfo",
|
||||
"cfg/*",
|
||||
"cmake/*",
|
||||
"external/*",
|
||||
"include/*",
|
||||
"src/*",
|
||||
'CMakeLists.txt',
|
||||
'bin/getRippledInfo',
|
||||
'cfg/*',
|
||||
'cmake/*',
|
||||
'external/*',
|
||||
'include/*',
|
||||
'src/*',
|
||||
)
|
||||
|
||||
def layout(self):
|
||||
cmake_layout(self)
|
||||
# Fix this setting to follow the default introduced in Conan 1.48
|
||||
# to align with our build instructions.
|
||||
self.folders.generators = "build/generators"
|
||||
|
||||
generators = "CMakeDeps"
|
||||
self.folders.generators = 'build/generators'
|
||||
|
||||
generators = 'CMakeDeps'
|
||||
def generate(self):
|
||||
tc = CMakeToolchain(self)
|
||||
tc.variables["tests"] = self.options.tests
|
||||
tc.variables["assert"] = self.options.assertions
|
||||
tc.variables["coverage"] = self.options.coverage
|
||||
tc.variables["jemalloc"] = self.options.jemalloc
|
||||
tc.variables["rocksdb"] = self.options.rocksdb
|
||||
tc.variables["BUILD_SHARED_LIBS"] = self.options.shared
|
||||
tc.variables["static"] = self.options.static
|
||||
tc.variables["unity"] = self.options.unity
|
||||
tc.variables["xrpld"] = self.options.xrpld
|
||||
tc.variables['tests'] = self.options.tests
|
||||
tc.variables['assert'] = self.options.assertions
|
||||
tc.variables['coverage'] = self.options.coverage
|
||||
tc.variables['jemalloc'] = self.options.jemalloc
|
||||
tc.variables['rocksdb'] = self.options.rocksdb
|
||||
tc.variables['BUILD_SHARED_LIBS'] = self.options.shared
|
||||
tc.variables['static'] = self.options.static
|
||||
tc.variables['unity'] = self.options.unity
|
||||
tc.variables['xrpld'] = self.options.xrpld
|
||||
tc.generate()
|
||||
|
||||
def build(self):
|
||||
@@ -172,29 +167,29 @@ class Xrpl(ConanFile):
|
||||
cmake.install()
|
||||
|
||||
def package_info(self):
|
||||
libxrpl = self.cpp_info.components["libxrpl"]
|
||||
libxrpl = self.cpp_info.components['libxrpl']
|
||||
libxrpl.libs = [
|
||||
"xrpl",
|
||||
"xrpl.libpb",
|
||||
"ed25519",
|
||||
"secp256k1",
|
||||
'xrpl',
|
||||
'xrpl.libpb',
|
||||
'ed25519',
|
||||
'secp256k1',
|
||||
]
|
||||
# TODO: Fix the protobufs to include each other relative to
|
||||
# `include/`, not `include/ripple/proto/`.
|
||||
libxrpl.includedirs = ["include", "include/ripple/proto"]
|
||||
libxrpl.includedirs = ['include', 'include/ripple/proto']
|
||||
libxrpl.requires = [
|
||||
"boost::boost",
|
||||
"date::date",
|
||||
"grpc::grpc++",
|
||||
"libarchive::libarchive",
|
||||
"lz4::lz4",
|
||||
"nudb::nudb",
|
||||
"openssl::crypto",
|
||||
"protobuf::libprotobuf",
|
||||
"soci::soci",
|
||||
"sqlite3::sqlite",
|
||||
"xxhash::xxhash",
|
||||
"zlib::zlib",
|
||||
'boost::boost',
|
||||
'date::date',
|
||||
'grpc::grpc++',
|
||||
'libarchive::libarchive',
|
||||
'lz4::lz4',
|
||||
'nudb::nudb',
|
||||
'openssl::crypto',
|
||||
'protobuf::libprotobuf',
|
||||
'soci::soci',
|
||||
'sqlite3::sqlite',
|
||||
'xxhash::xxhash',
|
||||
'zlib::zlib',
|
||||
]
|
||||
if self.options.rocksdb:
|
||||
libxrpl.requires.append("rocksdb::librocksdb")
|
||||
libxrpl.requires.append('rocksdb::librocksdb')
|
||||
|
||||
4
docs/build/environment.md
vendored
4
docs/build/environment.md
vendored
@@ -11,11 +11,11 @@ platforms: Linux, macOS, or Windows.
|
||||
Package ecosystems vary across Linux distributions,
|
||||
so there is no one set of instructions that will work for every Linux user.
|
||||
These instructions are written for Ubuntu 22.04.
|
||||
They are largely copied from the [script][1] used to configure a Docker
|
||||
They are largely copied from the [script][1] used to configure our Docker
|
||||
container for continuous integration.
|
||||
That script handles many more responsibilities.
|
||||
These instructions are just the bare minimum to build one configuration of
|
||||
xahaud.
|
||||
rippled.
|
||||
You can check that codebase for other Linux distributions and versions.
|
||||
If you cannot find yours there,
|
||||
then we hope that these instructions can at least guide you in the right
|
||||
|
||||
177
docs/build/install.md
vendored
177
docs/build/install.md
vendored
@@ -1,30 +1,159 @@
|
||||
Comprehensive instructions for installing and running xahaud are available on the [https://Xahau.Network](https://xahau.network/docs/infrastructure/installing-xahaud) documentation website.
|
||||
This document contains instructions for installing rippled.
|
||||
The APT package manager is common on Debian-based Linux distributions like
|
||||
Ubuntu,
|
||||
while the YUM package manager is common on Red Hat-based Linux distributions
|
||||
like CentOS.
|
||||
Installing from source is an option for all platforms,
|
||||
and the only supported option for installing custom builds.
|
||||
|
||||
## Create the Runtime Environment
|
||||
xahaud can be [built from source](../../BUILD.md) or installed using the binary files available from [https://build.xahau.tech](https://build.xahau.tech/). After obtaining a working xahaud binary, users will need to provide a suitable runtime environment. The following setup can be used for Linux or Docker environments.
|
||||
|
||||
1. Create or download two configuration files: the main xahaud.cfg configuration file and a second validators-xahau.txt file defining which validators or UNL list publishers are trusted. The default location for these files in this xahaud repository is `cfg/`.
|
||||
2. Provide a directory structure that is congruent with the contents of xahaud.cfg. This will include a location for logfiles, such as `/var/log/xahaud/`, as well as database files, `/opt/xahaud/db/`. Configuration files are, by default, sourced from `/etc/xahaud/`. It is possible to provide a symbolic link, if users wish to store configuration files elsewhere.
|
||||
3. If desired, created a xahaud user and group, and change ownership of the binary and directories. Servers used for validating nodes should use the most restrictive permissions possible for `xahaud.cfg`, as the validation token is stored therein.
|
||||
4. If desired, create a systemd service file: `/etc/systemd/system/xahaud.service`, enabling xahaud to run as a daemon. Alternately, run: `/path/to/binary/xahaud --conf=/path/to/xahaud.cfg`.
|
||||
## From source
|
||||
|
||||
From a source build, you can install rippled and libxrpl using CMake's
|
||||
`--install` mode:
|
||||
|
||||
## Example systemd Service File
|
||||
```
|
||||
[Unit]
|
||||
Description=Xahaud Daemon
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/path/to/xahaud --silent --conf /path/to/xahaud.cfg
|
||||
Restart=on-failure
|
||||
User=xahaud
|
||||
Group=xahaud
|
||||
LimitNOFILE=65536
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
cmake --install . --prefix /opt/local
|
||||
```
|
||||
|
||||
After the systemd service file is installed, it must be loaded with: `systemctl daemon-reload`. xahaud can then be enabled: `systemctl enable --now xahaud`.
|
||||
The default [prefix][1] is typically `/usr/local` on Linux and macOS and
|
||||
`C:/Program Files/rippled` on Windows.
|
||||
|
||||
[1]: https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX.html
|
||||
|
||||
|
||||
## With the APT package manager
|
||||
|
||||
1. Update repositories:
|
||||
|
||||
sudo apt update -y
|
||||
|
||||
2. Install utilities:
|
||||
|
||||
sudo apt install -y apt-transport-https ca-certificates wget gnupg
|
||||
|
||||
3. Add Ripple's package-signing GPG key to your list of trusted keys:
|
||||
|
||||
sudo mkdir /usr/local/share/keyrings/
|
||||
wget -q -O - "https://repos.ripple.com/repos/api/gpg/key/public" | gpg --dearmor > ripple-key.gpg
|
||||
sudo mv ripple-key.gpg /usr/local/share/keyrings
|
||||
|
||||
|
||||
4. Check the fingerprint of the newly-added key:
|
||||
|
||||
gpg /usr/local/share/keyrings/ripple-key.gpg
|
||||
|
||||
The output should include an entry for Ripple such as the following:
|
||||
|
||||
gpg: WARNING: no command supplied. Trying to guess what you mean ...
|
||||
pub rsa3072 2019-02-14 [SC] [expires: 2026-02-17]
|
||||
C0010EC205B35A3310DC90DE395F97FFCCAFD9A2
|
||||
uid TechOps Team at Ripple <techops+rippled@ripple.com>
|
||||
sub rsa3072 2019-02-14 [E] [expires: 2026-02-17]
|
||||
|
||||
|
||||
In particular, make sure that the fingerprint matches. (In the above example, the fingerprint is on the third line, starting with `C001`.)
|
||||
|
||||
4. Add the appropriate Ripple repository for your operating system version:
|
||||
|
||||
echo "deb [signed-by=/usr/local/share/keyrings/ripple-key.gpg] https://repos.ripple.com/repos/rippled-deb focal stable" | \
|
||||
sudo tee -a /etc/apt/sources.list.d/ripple.list
|
||||
|
||||
The above example is appropriate for **Ubuntu 20.04 Focal Fossa**. For other operating systems, replace the word `focal` with one of the following:
|
||||
|
||||
- `jammy` for **Ubuntu 22.04 Jammy Jellyfish**
|
||||
- `bionic` for **Ubuntu 18.04 Bionic Beaver**
|
||||
- `bullseye` for **Debian 11 Bullseye**
|
||||
- `buster` for **Debian 10 Buster**
|
||||
|
||||
If you want access to development or pre-release versions of `rippled`, use one of the following instead of `stable`:
|
||||
|
||||
- `unstable` - Pre-release builds ([`release` branch](https://github.com/ripple/rippled/tree/release))
|
||||
- `nightly` - Experimental/development builds ([`develop` branch](https://github.com/ripple/rippled/tree/develop))
|
||||
|
||||
**Warning:** Unstable and nightly builds may be broken at any time. Do not use these builds for production servers.
|
||||
|
||||
5. Fetch the Ripple repository.
|
||||
|
||||
sudo apt -y update
|
||||
|
||||
6. Install the `rippled` software package:
|
||||
|
||||
sudo apt -y install rippled
|
||||
|
||||
7. Check the status of the `rippled` service:
|
||||
|
||||
systemctl status rippled.service
|
||||
|
||||
The `rippled` service should start automatically. If not, you can start it manually:
|
||||
|
||||
sudo systemctl start rippled.service
|
||||
|
||||
8. Optional: allow `rippled` to bind to privileged ports.
|
||||
|
||||
This allows you to serve incoming API requests on port 80 or 443. (If you want to do so, you must also update the config file's port settings.)
|
||||
|
||||
sudo setcap 'cap_net_bind_service=+ep' /opt/ripple/bin/rippled
|
||||
|
||||
|
||||
## With the YUM package manager
|
||||
|
||||
1. Install the Ripple RPM repository:
|
||||
|
||||
Choose the appropriate RPM repository for the stability of releases you want:
|
||||
|
||||
- `stable` for the latest production release (`master` branch)
|
||||
- `unstable` for pre-release builds (`release` branch)
|
||||
- `nightly` for experimental/development builds (`develop` branch)
|
||||
|
||||
*Stable*
|
||||
|
||||
cat << REPOFILE | sudo tee /etc/yum.repos.d/ripple.repo
|
||||
[ripple-stable]
|
||||
name=XRP Ledger Packages
|
||||
enabled=1
|
||||
gpgcheck=0
|
||||
repo_gpgcheck=1
|
||||
baseurl=https://repos.ripple.com/repos/rippled-rpm/stable/
|
||||
gpgkey=https://repos.ripple.com/repos/rippled-rpm/stable/repodata/repomd.xml.key
|
||||
REPOFILE
|
||||
|
||||
*Unstable*
|
||||
|
||||
cat << REPOFILE | sudo tee /etc/yum.repos.d/ripple.repo
|
||||
[ripple-unstable]
|
||||
name=XRP Ledger Packages
|
||||
enabled=1
|
||||
gpgcheck=0
|
||||
repo_gpgcheck=1
|
||||
baseurl=https://repos.ripple.com/repos/rippled-rpm/unstable/
|
||||
gpgkey=https://repos.ripple.com/repos/rippled-rpm/unstable/repodata/repomd.xml.key
|
||||
REPOFILE
|
||||
|
||||
*Nightly*
|
||||
|
||||
cat << REPOFILE | sudo tee /etc/yum.repos.d/ripple.repo
|
||||
[ripple-nightly]
|
||||
name=XRP Ledger Packages
|
||||
enabled=1
|
||||
gpgcheck=0
|
||||
repo_gpgcheck=1
|
||||
baseurl=https://repos.ripple.com/repos/rippled-rpm/nightly/
|
||||
gpgkey=https://repos.ripple.com/repos/rippled-rpm/nightly/repodata/repomd.xml.key
|
||||
REPOFILE
|
||||
|
||||
2. Fetch the latest repo updates:
|
||||
|
||||
sudo yum -y update
|
||||
|
||||
3. Install the new `rippled` package:
|
||||
|
||||
sudo yum install -y rippled
|
||||
|
||||
4. Configure the `rippled` service to start on boot:
|
||||
|
||||
sudo systemctl enable rippled.service
|
||||
|
||||
5. Start the `rippled` service:
|
||||
|
||||
sudo systemctl start rippled.service
|
||||
|
||||
48
external/quickjs-provider/README.md
vendored
48
external/quickjs-provider/README.md
vendored
@@ -1,48 +0,0 @@
|
||||
# QuickJS provider manifest
|
||||
|
||||
These files are generated or sealed together by a jshookz source checkout:
|
||||
|
||||
```sh
|
||||
# Current layout (cpp/provider, python/jshookz). Older checkouts used
|
||||
# packages/jshookz; bin/update-jshookz-snapshot accepts either CLI path.
|
||||
uv sync --project python/jshookz --locked --group dev
|
||||
python/jshookz/.venv/bin/jshookz build provider
|
||||
```
|
||||
|
||||
Update this Xahau branch from a clean, committed jshookz checkout with one
|
||||
command:
|
||||
|
||||
```sh
|
||||
bin/update-jshookz-snapshot /path/to/jshookz
|
||||
```
|
||||
|
||||
That builds and imports the sealed lock files plus the broad/exact-v1
|
||||
declarations, selected-surface manifest, and API-artifact manifest. CI checks out jshookz
|
||||
`main` and fails if `build provider` does not reproduce that lock. The
|
||||
importer then prints a self-contained `x-run-tests` command that
|
||||
regenerates the embedded Hook fixtures and verifies the cut.
|
||||
|
||||
`jshookz_provider.manifest.json` is the verified runtime-profile lock.
|
||||
`jshookz_provider.manifest.cmake` is its minimal CMake projection. Xahau checks
|
||||
the JSON hash before generating the C++ profile constants, and the runtime
|
||||
checks any supplied provider WASM against the projected size and SHA-256.
|
||||
`api-artifacts.json` closes the three tracked API artifacts; Xahau verifies its
|
||||
own digest and every named artifact before projecting their identities. These
|
||||
files add no parallel CMake lock-value fields.
|
||||
|
||||
The provider binary is not vendored in this integration slice. Tests inject
|
||||
the exact built artifact. Configure needs python3 to project these lock files.
|
||||
A daemon whose embed is empty will not start.
|
||||
|
||||
For a local producer-to-consumer build, point Xahau straight at the emitted
|
||||
bundle instead of copying it:
|
||||
|
||||
```sh
|
||||
cmake -S . -B build \
|
||||
-DXAHAU_QUICKJS_PROVIDER_BUNDLE_DIR=/path/to/jshookz/build/xahau-provider
|
||||
```
|
||||
|
||||
A build-time generator writes `QuickJSProviderValues.cpp` from those
|
||||
locks and, if present, the gitignored wasm. Configure only checks that
|
||||
the three lock files exist. Changing the bundle rebuilds that one
|
||||
translation unit; hash, Wasmtime, and optional-wasm checks run then.
|
||||
8
external/quickjs-provider/api-artifacts.json
vendored
8
external/quickjs-provider/api-artifacts.json
vendored
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"artifacts": {
|
||||
"python/jshookz/src/jshookz/types/hooks-api.d.ts": "649079b831bc68eff0f440644649a505addafb08a3f5174e4031c8de6aedffa0",
|
||||
"python/jshookz/src/jshookz/types/xahau-quickjs-v1.d.ts": "20881232f0602e35de0fcbb8b5a3c1511606392749a0f79daebb386204f4f4da",
|
||||
"python/jshookz/src/jshookz/types/xahau-quickjs-v1.surface.json": "96a9218bf38abbf1bc9f2839408700d03572e0b065d625263f70477bc32597ac"
|
||||
},
|
||||
"schema": "jshookz.api-artifacts.v1"
|
||||
}
|
||||
3209
external/quickjs-provider/hooks-api.d.ts
vendored
3209
external/quickjs-provider/hooks-api.d.ts
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,27 +0,0 @@
|
||||
# Generated by jshookz build provider; do not edit.
|
||||
set(XAHAU_QUICKJS_MANIFEST_SCHEMA "xahau.quickjs.runtime-profile-lock.v1")
|
||||
set(XAHAU_QUICKJS_MANIFEST_SHA256 "1673b27d21063957cece9095cceb7e2dbfa53b6f49a5b7f824a486d7d90b2391")
|
||||
set(XAHAU_QUICKJS_PROVIDER_FILE "jshookz_provider.wasm")
|
||||
set(XAHAU_QUICKJS_PROVIDER_SHA256 "f60ab333acb547e50d7d087960839bd11833cb133d496af98e0b72a1bb3b84df")
|
||||
set(XAHAU_QUICKJS_PROVIDER_SIZE "1116638")
|
||||
set(XAHAU_QUICKJS_PROVIDER_IMPORT_COUNT "13")
|
||||
set(XAHAU_QUICKJS_PROVIDER_EXPORT_COUNT "22")
|
||||
set(XAHAU_QUICKJS_NATIVE_ABI_FILE "jshookz_provider.native-abi.json")
|
||||
set(XAHAU_QUICKJS_NATIVE_ABI_SHA256 "328ec938dcad875f3bdf25b8d779dd77f3571589818ca9271cb98c64c7018f99")
|
||||
set(XAHAU_QUICKJS_BYTECODE_ABI_ID "75ea54f357d397c4b33899e495bb385dad975a43b1c4a7a2cead30474327d33e")
|
||||
set(XAHAU_QUICKJS_RUNTIME_PROFILE_ID "29acf12e170436e5ccadfbc118d02a60909f86a88262106652b2f71994b0ea25")
|
||||
set(XAHAU_QUICKJS_HOOK_API_VERSION "1")
|
||||
set(XAHAU_QUICKJS_WASMTIME_VERSION "47.0.3")
|
||||
set(XAHAU_QUICKJS_INITIALIZATION_FUEL "5000000")
|
||||
set(XAHAU_QUICKJS_INVOCATION_FUEL "50000000")
|
||||
set(XAHAU_QUICKJS_HOST_WORK_METER "base-plus-addressed-byte-v1")
|
||||
set(XAHAU_QUICKJS_HOST_WORK_BUDGET "1000000")
|
||||
set(XAHAU_QUICKJS_HOST_WORK_BASE_PER_CALL "1")
|
||||
set(XAHAU_QUICKJS_HOST_WORK_PER_ADDRESSED_BYTE "1")
|
||||
set(XAHAU_QUICKJS_HOST_ADAPTER_POLICY "xahau-raw-hook-host-v1")
|
||||
set(XAHAU_QUICKJS_HEAP_BYTES "16777216")
|
||||
set(XAHAU_QUICKJS_STACK_BYTES "65536")
|
||||
set(XAHAU_QUICKJS_SERIALIZED_OBJECT_MAX_BYTES "1048576")
|
||||
set(XAHAU_QUICKJS_SERIALIZED_OBJECT_MAX_FIELDS "32768")
|
||||
set(XAHAU_QUICKJS_SERIALIZED_OBJECT_MAX_SCOPES "32769")
|
||||
set(XAHAU_QUICKJS_SERIALIZED_OBJECT_MAX_DEPTH "10")
|
||||
@@ -1,854 +0,0 @@
|
||||
{
|
||||
"bytecode_abi_id": "75ea54f357d397c4b33899e495bb385dad975a43b1c4a7a2cead30474327d33e",
|
||||
"javascript_surface": {
|
||||
"declaration": "python/jshookz/src/jshookz/types/xahau-quickjs-v1.d.ts",
|
||||
"declaration_sha256": "20881232f0602e35de0fcbb8b5a3c1511606392749a0f79daebb386204f4f4da",
|
||||
"manifest": "python/jshookz/src/jshookz/types/xahau-quickjs-v1.surface.json",
|
||||
"schema": "jshookz.javascript-surface.v1",
|
||||
"sha256": "96a9218bf38abbf1bc9f2839408700d03572e0b065d625263f70477bc32597ac"
|
||||
},
|
||||
"provider": {
|
||||
"build": {
|
||||
"wasm_memory_max_bytes": 33554432,
|
||||
"wasm_stack_bytes": 131072
|
||||
},
|
||||
"exports": [
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "_initialize",
|
||||
"params": [],
|
||||
"results": []
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "free",
|
||||
"params": [
|
||||
"i32"
|
||||
],
|
||||
"results": []
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "malloc",
|
||||
"params": [
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i32"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "memory",
|
||||
"maximum_pages": 512,
|
||||
"memory64": false,
|
||||
"minimum_pages": 7,
|
||||
"name": "memory",
|
||||
"shared": false
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_cbak",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32",
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i32"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_compile",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i32"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_compile_module",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i32"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_destroy",
|
||||
"params": [],
|
||||
"results": []
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_enable_coverage",
|
||||
"params": [
|
||||
"i32"
|
||||
],
|
||||
"results": []
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_eval",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i32"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_eval_bytecode",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i32"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_eval_module",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i32"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_get_bytecode_len",
|
||||
"params": [],
|
||||
"results": [
|
||||
"i32"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_get_bytecode_ptr",
|
||||
"params": [],
|
||||
"results": [
|
||||
"i32"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_get_result_len",
|
||||
"params": [],
|
||||
"results": [
|
||||
"i32"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_get_result_ptr",
|
||||
"params": [],
|
||||
"results": [
|
||||
"i32"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_hook",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32",
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i32"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_init",
|
||||
"params": [],
|
||||
"results": []
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_set_max_stack_size",
|
||||
"params": [
|
||||
"i32"
|
||||
],
|
||||
"results": []
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_set_memory_limit",
|
||||
"params": [
|
||||
"i32"
|
||||
],
|
||||
"results": []
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_set_seed",
|
||||
"params": [
|
||||
"i32"
|
||||
],
|
||||
"results": []
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_validate_hook_module",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i32"
|
||||
]
|
||||
}
|
||||
],
|
||||
"imports": [
|
||||
{
|
||||
"module": "env",
|
||||
"name": "accept",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32",
|
||||
"i64"
|
||||
],
|
||||
"results": [
|
||||
"i64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"module": "env",
|
||||
"name": "emit",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32",
|
||||
"i32",
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"module": "env",
|
||||
"name": "etxn_reserve",
|
||||
"params": [
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"module": "env",
|
||||
"name": "hook_account",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"module": "env",
|
||||
"name": "ledger_last_hash",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"module": "env",
|
||||
"name": "ledger_last_time",
|
||||
"params": [],
|
||||
"results": [
|
||||
"i64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"module": "env",
|
||||
"name": "ledger_seq",
|
||||
"params": [],
|
||||
"results": [
|
||||
"i64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"module": "env",
|
||||
"name": "otxn_type",
|
||||
"params": [],
|
||||
"results": [
|
||||
"i64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"module": "env",
|
||||
"name": "prepare",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32",
|
||||
"i32",
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"module": "env",
|
||||
"name": "rollback",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32",
|
||||
"i64"
|
||||
],
|
||||
"results": [
|
||||
"i64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"module": "env",
|
||||
"name": "state",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32",
|
||||
"i32",
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"module": "env",
|
||||
"name": "state_set",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32",
|
||||
"i32",
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"module": "env",
|
||||
"name": "trace",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32",
|
||||
"i32",
|
||||
"i32",
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i64"
|
||||
]
|
||||
}
|
||||
],
|
||||
"sha256": "f60ab333acb547e50d7d087960839bd11833cb133d496af98e0b72a1bb3b84df",
|
||||
"size": 1116638
|
||||
},
|
||||
"runtime_profile_id": "29acf12e170436e5ccadfbc118d02a60909f86a88262106652b2f71994b0ea25",
|
||||
"schema": "xahau.quickjs.runtime-profile-lock.v1",
|
||||
"source": {
|
||||
"artifact": {
|
||||
"envelope_version": 1,
|
||||
"hook_api_version": 1,
|
||||
"kind": "quickjs-bytecode"
|
||||
},
|
||||
"bytecode_abi": {
|
||||
"entry_exports": {
|
||||
"callback": "optional-callable",
|
||||
"main": "required-callable"
|
||||
},
|
||||
"quickjs_bytecode_version": 5,
|
||||
"quickjs_version": "2025-09-13",
|
||||
"read_flags": [
|
||||
"JS_READ_OBJ_BYTECODE"
|
||||
],
|
||||
"root": "es-module",
|
||||
"write_flags": [
|
||||
"JS_WRITE_OBJ_BYTECODE"
|
||||
]
|
||||
},
|
||||
"engine": {
|
||||
"configuration": {
|
||||
"consume_fuel": true,
|
||||
"cranelift_nan_canonicalization": true,
|
||||
"wasi": false,
|
||||
"wasm_memory64": false,
|
||||
"wasm_multi_memory": false,
|
||||
"wasm_relaxed_simd": false,
|
||||
"wasm_tail_call": false,
|
||||
"wasm_threads": false
|
||||
},
|
||||
"implementation": "wasmtime-native-c-api",
|
||||
"module_lifecycle": "compile-once-fresh-store-and-instance-per-invocation",
|
||||
"version": "47.0.3"
|
||||
},
|
||||
"execution": {
|
||||
"host_adapter_policy": "xahau-raw-hook-host-v1",
|
||||
"host_work_exhaustion": "uncatchable-wasmtime-trap-to-wasm-error",
|
||||
"initialization": "finite-cold-qjs-init-budget-before-invocation-fuel-reset",
|
||||
"ordinary_host_status": "returned-as-i64-never-trapped",
|
||||
"pending_jobs_after_entry": "not-drained",
|
||||
"result_failure_policy": "rollback.onFail-preserves-coded-failure;rollback.requirePresent-requires-success-and-non-nullish-value;rollback.requireTruthy-requires-success-and-truthy-value;accept.unlessPresent-accepts-on-failure-or-nullish-value;accept.unlessTruthy-accepts-on-failure-or-falsy-value;guards-use-explicit-message-and-optional-code-default-zero",
|
||||
"sfHookInstructionCount": "initial-wasmtime-invocation-fuel-minus-remaining-fuel",
|
||||
"terminals": "record-hook-result-and-uncatchable-wasmtime-trap"
|
||||
},
|
||||
"javascript_surface": {
|
||||
"declaration": "python/jshookz/src/jshookz/types/xahau-quickjs-v1.d.ts",
|
||||
"manifest": "python/jshookz/src/jshookz/types/xahau-quickjs-v1.surface.json",
|
||||
"schema": "jshookz.javascript-surface.v1"
|
||||
},
|
||||
"limits": {
|
||||
"host_work_addressed_length_indices": {
|
||||
"accept": [
|
||||
1
|
||||
],
|
||||
"emit": [
|
||||
1,
|
||||
3
|
||||
],
|
||||
"hook_account": [
|
||||
1
|
||||
],
|
||||
"ledger_last_hash": [
|
||||
1
|
||||
],
|
||||
"prepare": [
|
||||
1,
|
||||
3
|
||||
],
|
||||
"rollback": [
|
||||
1
|
||||
],
|
||||
"state": [
|
||||
1,
|
||||
3
|
||||
],
|
||||
"state_set": [
|
||||
1,
|
||||
3
|
||||
],
|
||||
"trace": [
|
||||
1,
|
||||
3
|
||||
]
|
||||
},
|
||||
"host_work_base_per_call": 1,
|
||||
"host_work_budget": 1000000,
|
||||
"host_work_meter": "base-plus-addressed-byte-v1",
|
||||
"host_work_per_addressed_byte": 1,
|
||||
"quickjs_heap_bytes": 16777216,
|
||||
"quickjs_stack_bytes": 65536,
|
||||
"serialized_object_max_bytes": 1048576,
|
||||
"serialized_object_max_depth": 10,
|
||||
"serialized_object_max_fields": 32768,
|
||||
"serialized_object_max_scopes": 32769,
|
||||
"wasmtime_fuel_per_initialization": 5000000,
|
||||
"wasmtime_fuel_per_invocation": 50000000
|
||||
},
|
||||
"name": "xahau-quickjs-v1",
|
||||
"provider": {
|
||||
"allowed_exports": [
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "_initialize",
|
||||
"params": [],
|
||||
"results": []
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "free",
|
||||
"params": [
|
||||
"i32"
|
||||
],
|
||||
"results": []
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "malloc",
|
||||
"params": [
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i32"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "memory",
|
||||
"maximum_pages": 512,
|
||||
"memory64": false,
|
||||
"minimum_pages": 7,
|
||||
"name": "memory",
|
||||
"shared": false
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_cbak",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32",
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i32"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_compile",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i32"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_compile_module",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i32"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_destroy",
|
||||
"params": [],
|
||||
"results": []
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_enable_coverage",
|
||||
"params": [
|
||||
"i32"
|
||||
],
|
||||
"results": []
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_eval",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i32"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_eval_bytecode",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i32"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_eval_module",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i32"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_get_bytecode_len",
|
||||
"params": [],
|
||||
"results": [
|
||||
"i32"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_get_bytecode_ptr",
|
||||
"params": [],
|
||||
"results": [
|
||||
"i32"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_get_result_len",
|
||||
"params": [],
|
||||
"results": [
|
||||
"i32"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_get_result_ptr",
|
||||
"params": [],
|
||||
"results": [
|
||||
"i32"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_hook",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32",
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i32"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_init",
|
||||
"params": [],
|
||||
"results": []
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_set_max_stack_size",
|
||||
"params": [
|
||||
"i32"
|
||||
],
|
||||
"results": []
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_set_memory_limit",
|
||||
"params": [
|
||||
"i32"
|
||||
],
|
||||
"results": []
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_set_seed",
|
||||
"params": [
|
||||
"i32"
|
||||
],
|
||||
"results": []
|
||||
},
|
||||
{
|
||||
"kind": "function",
|
||||
"name": "qjs_validate_hook_module",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i32"
|
||||
]
|
||||
}
|
||||
],
|
||||
"build": {
|
||||
"c_flags": [
|
||||
"-fwrapv",
|
||||
"-funsigned-char",
|
||||
"-mllvm",
|
||||
"-wasm-enable-sjlj"
|
||||
],
|
||||
"cxx_flags": [
|
||||
"-fno-exceptions",
|
||||
"-fno-rtti",
|
||||
"-mllvm",
|
||||
"-wasm-enable-sjlj"
|
||||
],
|
||||
"optimization": "O2",
|
||||
"target": "wasm32-wasi",
|
||||
"wasi_sdk": "32",
|
||||
"wasm_memory_max_bytes": 33554432,
|
||||
"wasm_stack_bytes": 131072
|
||||
},
|
||||
"forbidden_import_modules": [
|
||||
"wasi_snapshot_preview1"
|
||||
],
|
||||
"imports": [
|
||||
{
|
||||
"module": "env",
|
||||
"name": "accept",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32",
|
||||
"i64"
|
||||
],
|
||||
"results": [
|
||||
"i64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"module": "env",
|
||||
"name": "emit",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32",
|
||||
"i32",
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"module": "env",
|
||||
"name": "etxn_reserve",
|
||||
"params": [
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"module": "env",
|
||||
"name": "hook_account",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"module": "env",
|
||||
"name": "ledger_last_hash",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"module": "env",
|
||||
"name": "ledger_last_time",
|
||||
"params": [],
|
||||
"results": [
|
||||
"i64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"module": "env",
|
||||
"name": "ledger_seq",
|
||||
"params": [],
|
||||
"results": [
|
||||
"i64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"module": "env",
|
||||
"name": "otxn_type",
|
||||
"params": [],
|
||||
"results": [
|
||||
"i64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"module": "env",
|
||||
"name": "prepare",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32",
|
||||
"i32",
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"module": "env",
|
||||
"name": "rollback",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32",
|
||||
"i64"
|
||||
],
|
||||
"results": [
|
||||
"i64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"module": "env",
|
||||
"name": "state",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32",
|
||||
"i32",
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"module": "env",
|
||||
"name": "state_set",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32",
|
||||
"i32",
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"module": "env",
|
||||
"name": "trace",
|
||||
"params": [
|
||||
"i32",
|
||||
"i32",
|
||||
"i32",
|
||||
"i32",
|
||||
"i32"
|
||||
],
|
||||
"results": [
|
||||
"i64"
|
||||
]
|
||||
}
|
||||
],
|
||||
"javascript": {
|
||||
"atomics": false,
|
||||
"date_now": "previous-ledger-close-ripple-epoch-to-unix-milliseconds",
|
||||
"dynamic_eval": "enabled-and-metered",
|
||||
"finalization_registry": false,
|
||||
"math_random": "absent-use-ledger-random-api",
|
||||
"number": "enabled",
|
||||
"promise": "required-for-module-evaluation-no-post-entry-job-drain",
|
||||
"shared_array_buffer": false,
|
||||
"timezone": "UTC",
|
||||
"weak_ref": false
|
||||
}
|
||||
},
|
||||
"schema": "xahau.quickjs.runtime-profile-source.v1"
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
{"selected":[{"amendment":null,"name":"accept","param_types":["uint32_t","uint32_t","int64_t"],"return_type":"int64_t","wasm_signature":["0x7e","0x7f","0x7f","0x7e"]},{"amendment":null,"name":"rollback","param_types":["uint32_t","uint32_t","int64_t"],"return_type":"int64_t","wasm_signature":["0x7e","0x7f","0x7f","0x7e"]},{"amendment":null,"name":"ledger_seq","param_types":[],"return_type":"int64_t","wasm_signature":["0x7e"]},{"amendment":null,"name":"ledger_last_time","param_types":[],"return_type":"int64_t","wasm_signature":["0x7e"]},{"amendment":null,"name":"ledger_last_hash","param_types":["uint32_t","uint32_t"],"return_type":"int64_t","wasm_signature":["0x7e","0x7f","0x7f"]},{"amendment":null,"name":"otxn_type","param_types":[],"return_type":"int64_t","wasm_signature":["0x7e"]},{"amendment":null,"name":"hook_account","param_types":["uint32_t","uint32_t"],"return_type":"int64_t","wasm_signature":["0x7e","0x7f","0x7f"]},{"amendment":null,"name":"trace","param_types":["uint32_t","uint32_t","uint32_t","uint32_t","uint32_t"],"return_type":"int64_t","wasm_signature":["0x7e","0x7f","0x7f","0x7f","0x7f","0x7f"]},{"amendment":null,"name":"state","param_types":["uint32_t","uint32_t","uint32_t","uint32_t"],"return_type":"int64_t","wasm_signature":["0x7e","0x7f","0x7f","0x7f","0x7f"]},{"amendment":null,"name":"state_set","param_types":["uint32_t","uint32_t","uint32_t","uint32_t"],"return_type":"int64_t","wasm_signature":["0x7e","0x7f","0x7f","0x7f","0x7f"]},{"amendment":"featureHooksUpdate2","name":"prepare","param_types":["uint32_t","uint32_t","uint32_t","uint32_t"],"return_type":"int64_t","wasm_signature":["0x7e","0x7f","0x7f","0x7f","0x7f"]},{"amendment":null,"name":"etxn_reserve","param_types":["uint32_t"],"return_type":"int64_t","wasm_signature":["0x7e","0x7f"]},{"amendment":null,"name":"emit","param_types":["uint32_t","uint32_t","uint32_t","uint32_t"],"return_type":"int64_t","wasm_signature":["0x7e","0x7f","0x7f","0x7f","0x7f"]}],"source":{"commit":"bb244ef7729503a0317bcff0f8fdaa93ca5cb7d2","macro_function_count":75,"path":"include/xrpl/hook/hook_api.macro","repository":"https://github.com/Xahau/xahaud"}}
|
||||
1760
external/quickjs-provider/xahau-quickjs-v1.d.ts
vendored
1760
external/quickjs-provider/xahau-quickjs-v1.d.ts
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,581 +0,0 @@
|
||||
{
|
||||
"byte_policies": {
|
||||
"AccountID.from": {
|
||||
"0": "bytesLike"
|
||||
},
|
||||
"AccountID.fromHex": {
|
||||
"0": "hexString"
|
||||
},
|
||||
"Hash256.from": {
|
||||
"0": "bytesLike"
|
||||
},
|
||||
"Hash256.fromHex": {
|
||||
"0": "hexString"
|
||||
},
|
||||
"STBlob.equals": {
|
||||
"0": "bytesLikeOrSTBlob"
|
||||
},
|
||||
"STBlob.from": {
|
||||
"0": "bytesLike"
|
||||
},
|
||||
"STBlob.fromHex": {
|
||||
"0": "hexString"
|
||||
},
|
||||
"accept": {
|
||||
"0": "lifecycleMessage"
|
||||
},
|
||||
"emit.prepare": {
|
||||
"0": "bytesLikeOrSTBlob"
|
||||
},
|
||||
"emit.tx": {
|
||||
"0": "bytesLikeOrSTBlob"
|
||||
},
|
||||
"rollback": {
|
||||
"0": "lifecycleMessage"
|
||||
},
|
||||
"state.get": {
|
||||
"0": "stateKeyLike"
|
||||
},
|
||||
"state.set": {
|
||||
"0": "stateKeyLike",
|
||||
"1": "stateValueLike"
|
||||
}
|
||||
},
|
||||
"declaration": {
|
||||
"path": "python/jshookz/src/jshookz/types/xahau-quickjs-v1.d.ts",
|
||||
"sha256": "20881232f0602e35de0fcbb8b5a3c1511606392749a0f79daebb386204f4f4da"
|
||||
},
|
||||
"globals": {
|
||||
"AccountID": "object",
|
||||
"Amount": "object",
|
||||
"Currency": "object",
|
||||
"Field": "object",
|
||||
"Hash": "object",
|
||||
"Hash128": "object",
|
||||
"Hash160": "object",
|
||||
"Hash192": "object",
|
||||
"Hash256": "object",
|
||||
"IOUAmount": "object",
|
||||
"Issue": "object",
|
||||
"MPTAmount": "object",
|
||||
"NativeAmount": "object",
|
||||
"Path": "object",
|
||||
"PathHop": "object",
|
||||
"PathSet": "object",
|
||||
"Result": "object",
|
||||
"STArray": "object",
|
||||
"STBlob": "object",
|
||||
"STObject": "object",
|
||||
"SerializedField": "object",
|
||||
"UInt": "object",
|
||||
"UInt16": "object",
|
||||
"UInt32": "object",
|
||||
"UInt64": "object",
|
||||
"UInt8": "object",
|
||||
"Vector256": "object",
|
||||
"VoidResult": "object",
|
||||
"XChainBridge": "object",
|
||||
"XFLDecimal": "object",
|
||||
"accept": "function",
|
||||
"emit": "object",
|
||||
"hook": "object",
|
||||
"ledger": "object",
|
||||
"otxn": "object",
|
||||
"rollback": "function",
|
||||
"state": "object",
|
||||
"trace": "function",
|
||||
"util": "object"
|
||||
},
|
||||
"namespaces": {
|
||||
"accept": {
|
||||
"unlessPresent": "function",
|
||||
"unlessTruthy": "function",
|
||||
"when": "function"
|
||||
},
|
||||
"emit": {
|
||||
"prepare": "function",
|
||||
"reserve": "function",
|
||||
"tx": "function"
|
||||
},
|
||||
"hook": {
|
||||
"account": "function"
|
||||
},
|
||||
"ledger": {
|
||||
"lastHash": "value",
|
||||
"lastTime": "value",
|
||||
"sequence": "value"
|
||||
},
|
||||
"otxn": {
|
||||
"type": "function"
|
||||
},
|
||||
"rollback": {
|
||||
"onAllFail": "function",
|
||||
"onAnyFail": "function",
|
||||
"onFail": "function",
|
||||
"requirePresent": "function",
|
||||
"requireTruthy": "function",
|
||||
"when": "function"
|
||||
},
|
||||
"state": {
|
||||
"get": "function",
|
||||
"set": "function"
|
||||
},
|
||||
"util": {
|
||||
"decodeObject": "function",
|
||||
"safeDecodeObject": "function",
|
||||
"validateObject": "function"
|
||||
}
|
||||
},
|
||||
"prototypes": {
|
||||
"AccountID": {
|
||||
"members": {
|
||||
"equals": "function",
|
||||
"isZero": "function",
|
||||
"toBytes": "function",
|
||||
"toHex": "function"
|
||||
},
|
||||
"own": [
|
||||
"equals",
|
||||
"isZero",
|
||||
"toBytes",
|
||||
"toHex"
|
||||
],
|
||||
"probe": "AccountID.from(new Uint8Array(20))"
|
||||
},
|
||||
"Amount": {
|
||||
"members": {
|
||||
"asIOU": "function",
|
||||
"asMPT": "function",
|
||||
"asNative": "function",
|
||||
"byteLength": "value",
|
||||
"compare": "function",
|
||||
"currency": "value",
|
||||
"drops": "value",
|
||||
"equals": "function",
|
||||
"isIOU": "function",
|
||||
"isMPT": "function",
|
||||
"isNative": "function",
|
||||
"issue": "value",
|
||||
"issuer": "value",
|
||||
"kind": "value",
|
||||
"mptIssuanceId": "value",
|
||||
"toBytes": "function",
|
||||
"toString": "function",
|
||||
"toXFL": "function",
|
||||
"value": "value"
|
||||
},
|
||||
"own": [
|
||||
"asIOU",
|
||||
"asMPT",
|
||||
"asNative",
|
||||
"byteLength",
|
||||
"compare",
|
||||
"currency",
|
||||
"drops",
|
||||
"equals",
|
||||
"isIOU",
|
||||
"isMPT",
|
||||
"isNative",
|
||||
"issue",
|
||||
"issuer",
|
||||
"kind",
|
||||
"mptIssuanceId",
|
||||
"toBytes",
|
||||
"toString",
|
||||
"toXFL",
|
||||
"value"
|
||||
],
|
||||
"probe": "util.decodeObject(STBlob.fromHex('61D4838D7EA4C680000000000000000000000000005553440000000000B5F762798A53D543A014CAF8B297CFF8F2F937E8')).Amount"
|
||||
},
|
||||
"Currency": {
|
||||
"members": {
|
||||
"byteLength": "value",
|
||||
"equals": "function",
|
||||
"isNative": "value",
|
||||
"toBytes": "function",
|
||||
"toHex": "function",
|
||||
"toString": "function"
|
||||
},
|
||||
"own": [
|
||||
"byteLength",
|
||||
"equals",
|
||||
"isNative",
|
||||
"toBytes",
|
||||
"toHex",
|
||||
"toString"
|
||||
],
|
||||
"probe": "util.decodeObject(new Uint8Array()).withField('BaseAsset', new Uint8Array(20)).BaseAsset"
|
||||
},
|
||||
"Hash128": {
|
||||
"members": {
|
||||
"byteLength": "value",
|
||||
"compare": "function",
|
||||
"equals": "function",
|
||||
"isZero": "function",
|
||||
"toBytes": "function",
|
||||
"toHex": "function"
|
||||
},
|
||||
"own": [
|
||||
"byteLength",
|
||||
"compare",
|
||||
"equals",
|
||||
"isZero",
|
||||
"toBytes",
|
||||
"toHex"
|
||||
],
|
||||
"probe": "util.decodeObject(new Uint8Array()).withField('EmailHash', new Uint8Array(16)).EmailHash"
|
||||
},
|
||||
"Hash160": {
|
||||
"members": {
|
||||
"byteLength": "value",
|
||||
"compare": "function",
|
||||
"equals": "function",
|
||||
"isZero": "function",
|
||||
"toBytes": "function",
|
||||
"toHex": "function"
|
||||
},
|
||||
"own": [
|
||||
"byteLength",
|
||||
"compare",
|
||||
"equals",
|
||||
"isZero",
|
||||
"toBytes",
|
||||
"toHex"
|
||||
],
|
||||
"probe": "util.decodeObject(new Uint8Array()).withField('TakerPaysCurrency', new Uint8Array(20)).TakerPaysCurrency"
|
||||
},
|
||||
"Hash192": {
|
||||
"members": {
|
||||
"byteLength": "value",
|
||||
"compare": "function",
|
||||
"equals": "function",
|
||||
"isZero": "function",
|
||||
"toBytes": "function",
|
||||
"toHex": "function"
|
||||
},
|
||||
"own": [
|
||||
"byteLength",
|
||||
"compare",
|
||||
"equals",
|
||||
"isZero",
|
||||
"toBytes",
|
||||
"toHex"
|
||||
],
|
||||
"probe": "util.decodeObject(new Uint8Array()).withField('MPTokenIssuanceID', new Uint8Array(24)).MPTokenIssuanceID"
|
||||
},
|
||||
"Hash256": {
|
||||
"members": {
|
||||
"byteLength": "value",
|
||||
"compare": "function",
|
||||
"equals": "function",
|
||||
"isZero": "function",
|
||||
"toBytes": "function",
|
||||
"toHex": "function"
|
||||
},
|
||||
"own": [
|
||||
"byteLength",
|
||||
"compare",
|
||||
"equals",
|
||||
"isZero",
|
||||
"toBytes",
|
||||
"toHex"
|
||||
],
|
||||
"probe": "Hash256.from(new Uint8Array(32))"
|
||||
},
|
||||
"Issue": {
|
||||
"members": {
|
||||
"currency": "value",
|
||||
"equals": "function",
|
||||
"issuer": "value",
|
||||
"kind": "value",
|
||||
"mptIssuanceId": "value",
|
||||
"toBytes": "function"
|
||||
},
|
||||
"own": [
|
||||
"currency",
|
||||
"equals",
|
||||
"issuer",
|
||||
"kind",
|
||||
"mptIssuanceId",
|
||||
"toBytes"
|
||||
],
|
||||
"probe": "util.decodeObject(new Uint8Array()).withField('LockingChainIssue', new Uint8Array(20)).LockingChainIssue"
|
||||
},
|
||||
"Path": {
|
||||
"members": {
|
||||
"[Symbol.iterator]": "function",
|
||||
"at": "function",
|
||||
"length": "value"
|
||||
},
|
||||
"own": [
|
||||
"[Symbol.iterator]",
|
||||
"at",
|
||||
"length"
|
||||
],
|
||||
"probe": "util.decodeObject(STBlob.fromHex('011201B5F762798A53D543A014CAF8B297CFF8F2F937E800')).Paths.at(0)"
|
||||
},
|
||||
"PathHop": {
|
||||
"members": {
|
||||
"account": "value",
|
||||
"currency": "value",
|
||||
"issuer": "value"
|
||||
},
|
||||
"own": [
|
||||
"account",
|
||||
"currency",
|
||||
"issuer"
|
||||
],
|
||||
"probe": "util.decodeObject(STBlob.fromHex('011201B5F762798A53D543A014CAF8B297CFF8F2F937E800')).Paths.at(0).at(0)"
|
||||
},
|
||||
"PathSet": {
|
||||
"members": {
|
||||
"[Symbol.iterator]": "function",
|
||||
"at": "function",
|
||||
"length": "value",
|
||||
"toBytes": "function"
|
||||
},
|
||||
"own": [
|
||||
"[Symbol.iterator]",
|
||||
"at",
|
||||
"length",
|
||||
"toBytes"
|
||||
],
|
||||
"probe": "util.decodeObject(STBlob.fromHex('011201B5F762798A53D543A014CAF8B297CFF8F2F937E800')).Paths"
|
||||
},
|
||||
"Result": {
|
||||
"frozen": true,
|
||||
"members": {
|
||||
"okMapOr": "function",
|
||||
"okOr": "function",
|
||||
"okOrHandle": "function"
|
||||
},
|
||||
"own": [
|
||||
"okMapOr",
|
||||
"okOr",
|
||||
"okOrHandle"
|
||||
],
|
||||
"probe": "UInt64.from(0n)"
|
||||
},
|
||||
"STArray": {
|
||||
"exotic": {
|
||||
"array": false,
|
||||
"enumerable": [
|
||||
"0"
|
||||
],
|
||||
"extensible": false,
|
||||
"own": [
|
||||
"0",
|
||||
"length"
|
||||
]
|
||||
},
|
||||
"members": {
|
||||
"[Symbol.iterator]": "function",
|
||||
"at": "function",
|
||||
"length": "value",
|
||||
"toJSON": "function"
|
||||
},
|
||||
"own": [
|
||||
"[Symbol.iterator]",
|
||||
"at",
|
||||
"toJSON"
|
||||
],
|
||||
"probe": "util.decodeObject(new Uint8Array([0xF9, 0xEA, 0x22, 0, 0, 0, 1, 0xE1, 0xF1])).Memos"
|
||||
},
|
||||
"STBlob": {
|
||||
"members": {
|
||||
"byteAt": "function",
|
||||
"byteLength": "value",
|
||||
"equals": "function",
|
||||
"toBytes": "function",
|
||||
"toHex": "function"
|
||||
},
|
||||
"own": [
|
||||
"byteAt",
|
||||
"byteLength",
|
||||
"equals",
|
||||
"toBytes",
|
||||
"toHex"
|
||||
],
|
||||
"probe": "STBlob.from(new Uint8Array(0))"
|
||||
},
|
||||
"STObject": {
|
||||
"exotic": {
|
||||
"array": false,
|
||||
"enumerable": [
|
||||
"Flags"
|
||||
],
|
||||
"extensible": false,
|
||||
"own": [
|
||||
"Flags"
|
||||
]
|
||||
},
|
||||
"members": {
|
||||
"fieldBytes": "function",
|
||||
"get": "function",
|
||||
"has": "function",
|
||||
"toBytes": "function",
|
||||
"toJSON": "function",
|
||||
"withField": "function",
|
||||
"withoutField": "function"
|
||||
},
|
||||
"own": [
|
||||
"fieldBytes",
|
||||
"get",
|
||||
"has",
|
||||
"toBytes",
|
||||
"toJSON",
|
||||
"withField",
|
||||
"withoutField"
|
||||
],
|
||||
"probe": "util.decodeObject(new Uint8Array([0x22, 0, 0, 0, 9]))"
|
||||
},
|
||||
"UInt": {
|
||||
"members": {
|
||||
"add": "function",
|
||||
"bits": "value",
|
||||
"byteLength": "value",
|
||||
"compare": "function",
|
||||
"equals": "function",
|
||||
"isZero": "function",
|
||||
"saturatingAdd": "function",
|
||||
"saturatingSubtract": "function",
|
||||
"subtract": "function",
|
||||
"toBigInt": "function",
|
||||
"toNumber": "function",
|
||||
"toString": "function",
|
||||
"wrappingAdd": "function",
|
||||
"wrappingMultiply": "function",
|
||||
"wrappingSubtract": "function"
|
||||
},
|
||||
"own": [
|
||||
"add",
|
||||
"bits",
|
||||
"byteLength",
|
||||
"compare",
|
||||
"equals",
|
||||
"isZero",
|
||||
"saturatingAdd",
|
||||
"saturatingSubtract",
|
||||
"subtract",
|
||||
"toBigInt",
|
||||
"toNumber",
|
||||
"toString",
|
||||
"wrappingAdd",
|
||||
"wrappingMultiply",
|
||||
"wrappingSubtract"
|
||||
],
|
||||
"probe": "UInt8.zero"
|
||||
},
|
||||
"Vector256": {
|
||||
"exotic": {
|
||||
"array": false,
|
||||
"enumerable": [
|
||||
"0"
|
||||
],
|
||||
"extensible": false,
|
||||
"own": [
|
||||
"0",
|
||||
"length"
|
||||
]
|
||||
},
|
||||
"members": {
|
||||
"[Symbol.iterator]": "function",
|
||||
"at": "function",
|
||||
"length": "value",
|
||||
"toBytes": "function"
|
||||
},
|
||||
"own": [
|
||||
"[Symbol.iterator]",
|
||||
"at",
|
||||
"toBytes"
|
||||
],
|
||||
"probe": "util.decodeObject(STBlob.fromHex('011320000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F')).Indexes"
|
||||
},
|
||||
"VoidResult": {
|
||||
"frozen": true,
|
||||
"members": {
|
||||
"moot": "function",
|
||||
"okMapOr": "function",
|
||||
"okOr": "function",
|
||||
"okOrHandle": "function"
|
||||
},
|
||||
"own": [
|
||||
"moot"
|
||||
],
|
||||
"probe": "state.set('surface-probe', new Uint8Array(0))"
|
||||
},
|
||||
"XChainBridge": {
|
||||
"members": {
|
||||
"IssuingChainDoor": "value",
|
||||
"IssuingChainIssue": "value",
|
||||
"LockingChainDoor": "value",
|
||||
"LockingChainIssue": "value",
|
||||
"equals": "function",
|
||||
"toBytes": "function"
|
||||
},
|
||||
"own": [
|
||||
"IssuingChainDoor",
|
||||
"IssuingChainIssue",
|
||||
"LockingChainDoor",
|
||||
"LockingChainIssue",
|
||||
"equals",
|
||||
"toBytes"
|
||||
],
|
||||
"probe": "util.decodeObject(STBlob.fromHex('011914B5F762798A53D543A014CAF8B297CFF8F2F937E8000000000000000000000000000000000000000014B5F762798A53D543A014CAF8B297CFF8F2F937E80000000000000000000000000000000000000000')).XChainBridge"
|
||||
},
|
||||
"XFLDecimal": {
|
||||
"members": {
|
||||
"isNegative": "function",
|
||||
"isZero": "function"
|
||||
},
|
||||
"own": [
|
||||
"isNegative",
|
||||
"isZero"
|
||||
],
|
||||
"probe": "util.decodeObject(STBlob.fromHex('61D4838D7EA4C680000000000000000000000000005553440000000000B5F762798A53D543A014CAF8B297CFF8F2F937E8')).Amount.toXFL()"
|
||||
}
|
||||
},
|
||||
"schema": "jshookz.javascript-surface.v1",
|
||||
"statics": {
|
||||
"AccountID": {
|
||||
"from": "function",
|
||||
"fromHex": "function",
|
||||
"one": "value",
|
||||
"zero": "value"
|
||||
},
|
||||
"Hash256": {
|
||||
"from": "function",
|
||||
"fromHex": "function",
|
||||
"zero": "value"
|
||||
},
|
||||
"STBlob": {
|
||||
"from": "function",
|
||||
"fromHex": "function"
|
||||
},
|
||||
"UInt16": {
|
||||
"from": "function",
|
||||
"max": "value",
|
||||
"mulDiv": "function",
|
||||
"zero": "value"
|
||||
},
|
||||
"UInt32": {
|
||||
"from": "function",
|
||||
"max": "value",
|
||||
"mulDiv": "function",
|
||||
"zero": "value"
|
||||
},
|
||||
"UInt64": {
|
||||
"from": "function",
|
||||
"max": "value",
|
||||
"mulDiv": "function",
|
||||
"mulDivXfl": "function",
|
||||
"zero": "value"
|
||||
},
|
||||
"UInt8": {
|
||||
"from": "function",
|
||||
"max": "value",
|
||||
"mulDiv": "function",
|
||||
"zero": "value"
|
||||
}
|
||||
}
|
||||
}
|
||||
27
external/wasmtime/conandata.yml
vendored
27
external/wasmtime/conandata.yml
vendored
@@ -1,27 +0,0 @@
|
||||
sources:
|
||||
47.0.3:
|
||||
Linux:
|
||||
armv8:
|
||||
sha256: c1ef99bb4ef0151282f339e22a67f8229d9ab336f9a17387e65f140b79c45be1
|
||||
url: https://github.com/bytecodealliance/wasmtime/releases/download/v47.0.3/wasmtime-v47.0.3-aarch64-linux-c-api.tar.xz
|
||||
x86_64:
|
||||
sha256: aaa3621f2a3d8393696702897f8f78a1cc504437d500701496d560125aefd732
|
||||
url: https://github.com/bytecodealliance/wasmtime/releases/download/v47.0.3/wasmtime-v47.0.3-x86_64-linux-c-api.tar.xz
|
||||
Macos:
|
||||
armv8:
|
||||
sha256: 1854c8f03a764c89afe77fa88d9092ab89a368e527cd27a12959b1d91152324e
|
||||
url: https://github.com/bytecodealliance/wasmtime/releases/download/v47.0.3/wasmtime-v47.0.3-aarch64-macos-c-api.tar.xz
|
||||
x86_64:
|
||||
sha256: 627622087b77b92c163e826ec6ebf834a70d78735828043edf7ace263f8a9e62
|
||||
url: https://github.com/bytecodealliance/wasmtime/releases/download/v47.0.3/wasmtime-v47.0.3-x86_64-macos-c-api.tar.xz
|
||||
MinGW:
|
||||
x86_64:
|
||||
sha256: 355a0c7b49b92bb011e74a4047cc1186271aeb8c8cfcc4360248caaf3c4d5f38
|
||||
url: https://github.com/bytecodealliance/wasmtime/releases/download/v47.0.3/wasmtime-v47.0.3-x86_64-mingw-c-api.zip
|
||||
Windows:
|
||||
armv8:
|
||||
sha256: 57107b14b28ac2152e903501fe1722007b90fc11ccd63ad6d62ed574c5dd90db
|
||||
url: https://github.com/bytecodealliance/wasmtime/releases/download/v47.0.3/wasmtime-v47.0.3-aarch64-windows-c-api.zip
|
||||
x86_64:
|
||||
sha256: 952dfbc864295eccc89caa92bc303686017ca4ea205a1f21878809f374bb77c5
|
||||
url: https://github.com/bytecodealliance/wasmtime/releases/download/v47.0.3/wasmtime-v47.0.3-x86_64-windows-c-api.zip
|
||||
162
external/wasmtime/conanfile.py
vendored
162
external/wasmtime/conanfile.py
vendored
@@ -1,162 +0,0 @@
|
||||
import os
|
||||
|
||||
from conan import ConanFile
|
||||
from conan.errors import ConanInvalidConfiguration
|
||||
from conan.tools.files import copy, get
|
||||
from conan.tools.microsoft import is_msvc
|
||||
|
||||
|
||||
required_conan_version = ">=2.0"
|
||||
|
||||
|
||||
class WasmtimeConan(ConanFile):
|
||||
name = "wasmtime"
|
||||
description = "Standalone WebAssembly runtime using Cranelift"
|
||||
license = "Apache-2.0 WITH LLVM-exception"
|
||||
url = "https://github.com/Xahau/xahaud"
|
||||
homepage = "https://github.com/bytecodealliance/wasmtime"
|
||||
topics = ("webassembly", "wasm")
|
||||
package_type = "library"
|
||||
settings = "os", "arch", "compiler", "build_type"
|
||||
options = {"shared": [True, False]}
|
||||
default_options = {"shared": False}
|
||||
no_copy_source = True
|
||||
|
||||
@property
|
||||
def _sources_os_key(self):
|
||||
if is_msvc(self):
|
||||
return "Windows"
|
||||
if self.settings.os == "Windows" and self.settings.compiler == "gcc":
|
||||
return "MinGW"
|
||||
return str(self.settings.os)
|
||||
|
||||
def configure(self):
|
||||
self.settings.rm_safe("compiler.libcxx")
|
||||
self.settings.rm_safe("compiler.cppstd")
|
||||
|
||||
def package_id(self):
|
||||
# Official release archives contain a prebuilt C ABI. Compiler patch
|
||||
# versions do not change the packaged bytes.
|
||||
if self.info.settings.compiler == "clang":
|
||||
self.info.settings.compiler = "gcc"
|
||||
del self.info.settings.compiler.version
|
||||
|
||||
def validate(self):
|
||||
try:
|
||||
self.conan_data["sources"][self.version][self._sources_os_key][
|
||||
str(self.settings.arch)
|
||||
]
|
||||
except KeyError as error:
|
||||
raise ConanInvalidConfiguration(
|
||||
"No official Wasmtime C-API archive for "
|
||||
f"{self.settings.os}/{self.settings.arch}"
|
||||
) from error
|
||||
|
||||
def build(self):
|
||||
get(
|
||||
self,
|
||||
**self.conan_data["sources"][self.version][self._sources_os_key][
|
||||
str(self.settings.arch)
|
||||
],
|
||||
destination=self.build_folder,
|
||||
strip_root=True,
|
||||
)
|
||||
|
||||
def package(self):
|
||||
copy(
|
||||
self,
|
||||
"*.h",
|
||||
dst=os.path.join(self.package_folder, "include"),
|
||||
src=os.path.join(self.build_folder, "include"),
|
||||
)
|
||||
copy(
|
||||
self,
|
||||
"*.hh",
|
||||
dst=os.path.join(self.package_folder, "include"),
|
||||
src=os.path.join(self.build_folder, "include"),
|
||||
)
|
||||
|
||||
source_lib = os.path.join(self.build_folder, "lib")
|
||||
package_lib = os.path.join(self.package_folder, "lib")
|
||||
package_bin = os.path.join(self.package_folder, "bin")
|
||||
if self.options.shared:
|
||||
copy(
|
||||
self,
|
||||
"wasmtime.dll.lib",
|
||||
dst=package_lib,
|
||||
src=source_lib,
|
||||
keep_path=False,
|
||||
)
|
||||
copy(
|
||||
self,
|
||||
"wasmtime.dll",
|
||||
dst=package_bin,
|
||||
src=source_lib,
|
||||
keep_path=False,
|
||||
)
|
||||
copy(
|
||||
self,
|
||||
"libwasmtime.dll.a",
|
||||
dst=package_lib,
|
||||
src=source_lib,
|
||||
keep_path=False,
|
||||
)
|
||||
copy(
|
||||
self,
|
||||
"libwasmtime.so*",
|
||||
dst=package_lib,
|
||||
src=source_lib,
|
||||
keep_path=False,
|
||||
)
|
||||
copy(
|
||||
self,
|
||||
"libwasmtime.dylib",
|
||||
dst=package_lib,
|
||||
src=source_lib,
|
||||
keep_path=False,
|
||||
)
|
||||
else:
|
||||
copy(
|
||||
self,
|
||||
"wasmtime.lib",
|
||||
dst=package_lib,
|
||||
src=source_lib,
|
||||
keep_path=False,
|
||||
)
|
||||
copy(
|
||||
self,
|
||||
"libwasmtime.a",
|
||||
dst=package_lib,
|
||||
src=source_lib,
|
||||
keep_path=False,
|
||||
)
|
||||
|
||||
copy(
|
||||
self,
|
||||
"LICENSE",
|
||||
dst=os.path.join(self.package_folder, "licenses"),
|
||||
src=self.build_folder,
|
||||
)
|
||||
|
||||
def package_info(self):
|
||||
if self.options.shared:
|
||||
self.cpp_info.libs = [
|
||||
"wasmtime.dll" if self.settings.os == "Windows" else "wasmtime"
|
||||
]
|
||||
else:
|
||||
if self.settings.os == "Windows":
|
||||
self.cpp_info.defines = ["WASM_API_EXTERN=", "WASI_API_EXTERN="]
|
||||
self.cpp_info.libs = ["wasmtime"]
|
||||
|
||||
if self.settings.os == "Windows":
|
||||
self.cpp_info.system_libs = [
|
||||
"ws2_32",
|
||||
"bcrypt",
|
||||
"advapi32",
|
||||
"userenv",
|
||||
"ntdll",
|
||||
"shell32",
|
||||
"ole32",
|
||||
]
|
||||
elif self.settings.os in ("Linux", "FreeBSD"):
|
||||
self.cpp_info.system_libs = ["pthread", "dl", "m", "rt"]
|
||||
@@ -2,9 +2,6 @@
|
||||
// Generated using generate_extern.sh
|
||||
#include <stdint.h>
|
||||
#ifndef HOOK_EXTERN
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int32_t __attribute__((noduplicate))
|
||||
_g(uint32_t guard_id, uint32_t maxiter);
|
||||
@@ -332,15 +329,5 @@ meta_slot(uint32_t slot_no);
|
||||
extern int64_t
|
||||
xpop_slot(uint32_t slot_no_tx, uint32_t slot_no_meta);
|
||||
|
||||
extern int64_t
|
||||
prepare(
|
||||
uint32_t write_ptr,
|
||||
uint32_t write_len,
|
||||
uint32_t read_ptr,
|
||||
uint32_t read_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#define HOOK_EXTERN
|
||||
#endif // HOOK_EXTERN
|
||||
|
||||
@@ -9,7 +9,7 @@ ENUM_FILE="$SCRIPT_DIR/../include/xrpl/hook/Enum.h"
|
||||
echo '// For documentation please see: https://xrpl-hooks.readme.io/reference/'
|
||||
echo '// Generated using generate_error.sh'
|
||||
echo '#ifndef HOOK_ERROR_CODES'
|
||||
sed -n '/enum class hook_return_code/,/};/p' "$ENUM_FILE" |
|
||||
sed -n '/enum hook_return_code/,/};/p' "$ENUM_FILE" |
|
||||
awk '
|
||||
function ltrim(s) { sub(/^[[:space:]]+/, "", s); return s }
|
||||
function rtrim(s) { sub(/[[:space:]]+$/, "", s); return s }
|
||||
@@ -31,7 +31,7 @@ sed -n '/enum class hook_return_code/,/};/p' "$ENUM_FILE" |
|
||||
|
||||
{
|
||||
line = $0
|
||||
if (line ~ /enum[[:space:]]+class[[:space:]]+hook_return_code/)
|
||||
if (line ~ /enum[[:space:]]+hook_return_code/)
|
||||
next
|
||||
if (line ~ /^[[:space:]]*\{/)
|
||||
next
|
||||
|
||||
@@ -11,9 +11,6 @@ APPLY_HOOK="$SCRIPT_DIR/../include/xrpl/hook/hook_api.macro"
|
||||
echo '// Generated using generate_extern.sh'
|
||||
echo '#include <stdint.h>'
|
||||
echo '#ifndef HOOK_EXTERN'
|
||||
echo '#ifdef __cplusplus'
|
||||
echo 'extern "C" {'
|
||||
echo '#endif'
|
||||
echo
|
||||
awk '
|
||||
function trim(s) {
|
||||
@@ -49,9 +46,6 @@ APPLY_HOOK="$SCRIPT_DIR/../include/xrpl/hook/hook_api.macro"
|
||||
}
|
||||
' "$APPLY_HOOK"
|
||||
|
||||
echo '#ifdef __cplusplus'
|
||||
echo '}'
|
||||
echo '#endif'
|
||||
echo '#define HOOK_EXTERN'
|
||||
echo '#endif // HOOK_EXTERN'
|
||||
} | (
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -eu
|
||||
|
||||
SCRIPT_DIR=$(dirname "$0")
|
||||
SCRIPT_DIR=$(cd "$SCRIPT_DIR" && pwd)
|
||||
|
||||
RIPPLED_ROOT="$SCRIPT_DIR/../include/xrpl"
|
||||
LEDGER_FORMATS="$RIPPLED_ROOT/protocol/LedgerFormats.h"
|
||||
|
||||
echo '// Generated using generate_lsflags.sh'
|
||||
echo ''
|
||||
echo '#ifndef HOOKLSFLAGS_INCLUDED'
|
||||
echo '#define HOOKLSFLAGS_INCLUDED 1'
|
||||
echo ''
|
||||
awk '
|
||||
function ltrim(s) { sub(/^[[:space:]]+/, "", s); return s }
|
||||
function rtrim(s) { sub(/[[:space:]]+$/, "", s); return s }
|
||||
function trim(s) { return rtrim(ltrim(s)) }
|
||||
|
||||
function flush_group() {
|
||||
if (entry_count > 0 && group != "") {
|
||||
printf "enum %s {\n", group
|
||||
for (i = 1; i <= entry_count; i++) {
|
||||
printf " %s,\n", entries[i]
|
||||
}
|
||||
printf "};\n"
|
||||
}
|
||||
delete entries
|
||||
entry_count = 0
|
||||
}
|
||||
|
||||
/enum LedgerSpecificFlags \{/ { inside = 1; next }
|
||||
inside && /^\};/ { inside = 0; flush_group(); next }
|
||||
!inside { next }
|
||||
|
||||
# Group header comments: // ltFOO or // remarks
|
||||
/^[[:space:]]*\/\/[[:space:]]*(lt[A-Z_]+|remarks)[[:space:]]*$/ {
|
||||
flush_group()
|
||||
line = $0
|
||||
sub(/.*\/\/[[:space:]]*/, "", line)
|
||||
group = trim(line)
|
||||
next
|
||||
}
|
||||
|
||||
# Skip pure comment lines (not group headers)
|
||||
/^[[:space:]]*\/\// { next }
|
||||
|
||||
# Skip blank lines
|
||||
/^[[:space:]]*$/ { next }
|
||||
|
||||
# Accumulate flag lines (handle multi-line values)
|
||||
{
|
||||
line = $0
|
||||
# Strip inline comments
|
||||
sub(/\/\/.*/, "", line)
|
||||
line = trim(line)
|
||||
if (line == "") next
|
||||
|
||||
if (pending != "") {
|
||||
pending = pending " " line
|
||||
} else {
|
||||
pending = line
|
||||
}
|
||||
|
||||
# If line ends with comma, the entry is complete
|
||||
if (pending ~ /,$/) {
|
||||
# Remove trailing comma
|
||||
sub(/,$/, "", pending)
|
||||
entries[++entry_count] = pending
|
||||
pending = ""
|
||||
}
|
||||
}
|
||||
|
||||
BEGIN {
|
||||
inside = 0
|
||||
group = ""
|
||||
pending = ""
|
||||
entry_count = 0
|
||||
}
|
||||
' "$LEDGER_FORMATS"
|
||||
echo ''
|
||||
echo '#endif // HOOKLSFLAGS_INCLUDED'
|
||||
@@ -1,25 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -eu
|
||||
|
||||
SCRIPT_DIR=$(dirname "$0")
|
||||
SCRIPT_DIR=$(cd "$SCRIPT_DIR" && pwd)
|
||||
|
||||
RIPPLED_ROOT="$SCRIPT_DIR/../include/xrpl"
|
||||
TX_FLAGS="$RIPPLED_ROOT/protocol/TxFlags.h"
|
||||
|
||||
echo '// Generated using generate_txflags.sh'
|
||||
echo '#include "ls_flags.h"'
|
||||
echo '#include <stdint.h>'
|
||||
echo ''
|
||||
cat "$TX_FLAGS" |
|
||||
awk '
|
||||
/^[[:space:]]*enum / {
|
||||
if (count > 0) print ""
|
||||
inside = 1
|
||||
count++
|
||||
}
|
||||
inside {
|
||||
print
|
||||
if (/};/) inside = 0
|
||||
}
|
||||
'
|
||||
@@ -1,203 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# build_xahau_h.sh
|
||||
# Builds genesis hook WASMs and updates xahau.h with hex arrays
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Color codes for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Script directory and path constants
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
XAHAU_H="${SCRIPT_DIR}/../../include/xrpl/hook/xahau.h"
|
||||
TEMP_DIR="${SCRIPT_DIR}/.temp"
|
||||
|
||||
# Hook file mappings (space-separated: name:file)
|
||||
HOOK_FILES=(
|
||||
"GovernanceHook:govern.wasm"
|
||||
"RewardHook:reward.wasm"
|
||||
# "MintHook:mint.wasm"
|
||||
)
|
||||
|
||||
# Cleanup function
|
||||
cleanup() {
|
||||
local exit_code=$?
|
||||
if [ ${exit_code} -eq 0 ] && [ -d "${TEMP_DIR}" ]; then
|
||||
rm -rf "${TEMP_DIR}"
|
||||
elif [ ${exit_code} -ne 0 ]; then
|
||||
echo -e "${RED}Error: Script failed with exit code ${exit_code}${NC}" >&2
|
||||
if [ -d "${TEMP_DIR}" ]; then
|
||||
echo -e "${YELLOW}Temp files preserved at: ${TEMP_DIR}${NC}" >&2
|
||||
fi
|
||||
fi
|
||||
exit ${exit_code}
|
||||
}
|
||||
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
# Tool verification
|
||||
echo -e "${BLUE}==> Checking required tools...${NC}"
|
||||
REQUIRED_TOOLS=("make" "xxd" "sed" "clang-format" "wasm-opt")
|
||||
for tool in "${REQUIRED_TOOLS[@]}"; do
|
||||
if ! command -v "${tool}" &> /dev/null; then
|
||||
echo -e "${RED}Error: Required tool '${tool}' not found${NC}" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo -e "${GREEN} ✓ ${tool}${NC}"
|
||||
done
|
||||
|
||||
# Verify wasm-opt version is exactly 100
|
||||
WASM_OPT_VERSION=$(wasm-opt --version | grep -oE '[0-9]+' | head -1)
|
||||
if [ "${WASM_OPT_VERSION}" != "100" ]; then
|
||||
echo -e "${RED}Error: wasm-opt version must be 100, but found ${WASM_OPT_VERSION}${NC}" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo -e "${GREEN} ✓ wasm-opt version 100${NC}"
|
||||
|
||||
# Verify xahau.h exists
|
||||
if [ ! -f "${XAHAU_H}" ]; then
|
||||
echo -e "${RED}Error: xahau.h not found at ${XAHAU_H}${NC}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create temp directory
|
||||
mkdir -p "${TEMP_DIR}"
|
||||
|
||||
# Build all WASM files
|
||||
echo -e "${BLUE}==> Building WASM files with 'make all'...${NC}"
|
||||
cd "${SCRIPT_DIR}"
|
||||
make all
|
||||
echo -e "${GREEN} Build completed successfully${NC}"
|
||||
|
||||
# Function to convert WASM to hex array
|
||||
wasm_to_hex_array() {
|
||||
local wasm_file="$1"
|
||||
local indent=" "
|
||||
|
||||
if [ ! -f "${wasm_file}" ]; then
|
||||
echo -e "${RED}Error: WASM file not found: ${wasm_file}${NC}" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Convert to hex with xxd, format with sed
|
||||
xxd -p -u -c 10 "${wasm_file}" | \
|
||||
sed 's/../0x&U,/g' | \
|
||||
sed "s/^/${indent}/g" | \
|
||||
sed '$ s/,$//'
|
||||
}
|
||||
|
||||
# Function to update hook array in xahau.h
|
||||
update_hook_array() {
|
||||
local hook_name="$1"
|
||||
local hex_array="$2"
|
||||
local temp_file="${TEMP_DIR}/xahau.h.tmp"
|
||||
|
||||
echo -e "${BLUE}==> Updating ${hook_name}...${NC}"
|
||||
|
||||
# Check if hook already exists
|
||||
if grep -q "static const std::vector<uint8_t> ${hook_name} = {" "${XAHAU_H}"; then
|
||||
echo -e "${YELLOW} Replacing existing ${hook_name}${NC}"
|
||||
|
||||
# Use awk to replace the array content
|
||||
awk -v hook="${hook_name}" -v hex="${hex_array}" '
|
||||
BEGIN { in_array=0 }
|
||||
{
|
||||
if ($0 ~ "static const std::vector<uint8_t> " hook " = {") {
|
||||
print $0
|
||||
print hex
|
||||
in_array=1
|
||||
next
|
||||
}
|
||||
if (in_array && $0 ~ /};/) {
|
||||
print "};"
|
||||
in_array=0
|
||||
next
|
||||
}
|
||||
if (!in_array) {
|
||||
print $0
|
||||
}
|
||||
}
|
||||
' "${XAHAU_H}" > "${temp_file}"
|
||||
|
||||
mv "${temp_file}" "${XAHAU_H}"
|
||||
else
|
||||
echo -e "${YELLOW} Adding new ${hook_name}${NC}"
|
||||
|
||||
# Find the position before #endif and add the new hook
|
||||
awk -v hook="${hook_name}" -v hex="${hex_array}" '
|
||||
{
|
||||
if ($0 ~ /#endif.*XAHAU_GENESIS_HOOKS/) {
|
||||
print ""
|
||||
print "static const std::vector<uint8_t> " hook " = {"
|
||||
print hex
|
||||
print "};"
|
||||
print ""
|
||||
print $0
|
||||
} else {
|
||||
print $0
|
||||
}
|
||||
}
|
||||
' "${XAHAU_H}" > "${temp_file}"
|
||||
|
||||
mv "${temp_file}" "${XAHAU_H}"
|
||||
fi
|
||||
|
||||
echo -e "${GREEN} ✓ ${hook_name} updated${NC}"
|
||||
}
|
||||
|
||||
# Process each hook
|
||||
for hook_entry in "${HOOK_FILES[@]}"; do
|
||||
hook_name="${hook_entry%%:*}"
|
||||
wasm_file="${SCRIPT_DIR}/${hook_entry##*:}"
|
||||
|
||||
echo -e "${BLUE}==> Converting ${wasm_file} to hex array...${NC}"
|
||||
hex_array=$(wasm_to_hex_array "${wasm_file}")
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}Error: Failed to convert ${wasm_file}${NC}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN} Conversion successful ($(echo "${hex_array}" | wc -l) lines)${NC}"
|
||||
|
||||
update_hook_array "${hook_name}" "${hex_array}"
|
||||
done
|
||||
|
||||
# Format with clang-format
|
||||
echo -e "${BLUE}==> Formatting with clang-format...${NC}"
|
||||
cp "${XAHAU_H}" "${TEMP_DIR}/xahau.h.before_format"
|
||||
clang-format -i "${XAHAU_H}"
|
||||
echo -e "${GREEN} Formatting completed${NC}"
|
||||
|
||||
# Verification
|
||||
echo -e "${BLUE}==> Verifying changes...${NC}"
|
||||
for hook_entry in "${HOOK_FILES[@]}"; do
|
||||
hook_name="${hook_entry%%:*}"
|
||||
if grep -q "static const std::vector<uint8_t> ${hook_name} = {" "${XAHAU_H}"; then
|
||||
echo -e "${GREEN} ✓ ${hook_name} found in xahau.h${NC}"
|
||||
else
|
||||
echo -e "${RED} ✗ ${hook_name} NOT found in xahau.h${NC}" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# Show summary
|
||||
echo ""
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo -e "${GREEN}Successfully updated xahau.h${NC}"
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo -e "Updated hooks:"
|
||||
for hook_entry in "${HOOK_FILES[@]}"; do
|
||||
hook_name="${hook_entry%%:*}"
|
||||
wasm_file="${SCRIPT_DIR}/${hook_entry##*:}"
|
||||
size=$(wc -c < "${wasm_file}" | tr -d ' ')
|
||||
echo -e " - ${hook_name}: ${size} bytes"
|
||||
done
|
||||
echo ""
|
||||
echo -e "File location: ${XAHAU_H}"
|
||||
echo ""
|
||||
@@ -1,46 +0,0 @@
|
||||
// For documentation please see: https://xrpl-hooks.readme.io/reference/
|
||||
// Generated using generate_error.sh
|
||||
#ifndef HOOK_ERROR_CODES
|
||||
#define SUCCESS 0
|
||||
#define OUT_OF_BOUNDS -1
|
||||
#define INTERNAL_ERROR -2
|
||||
#define TOO_BIG -3
|
||||
#define TOO_SMALL -4
|
||||
#define DOESNT_EXIST -5
|
||||
#define NO_FREE_SLOTS -6
|
||||
#define INVALID_ARGUMENT -7
|
||||
#define ALREADY_SET -8
|
||||
#define PREREQUISITE_NOT_MET -9
|
||||
#define FEE_TOO_LARGE -10
|
||||
#define EMISSION_FAILURE -11
|
||||
#define TOO_MANY_NONCES -12
|
||||
#define TOO_MANY_EMITTED_TXN -13
|
||||
#define NOT_IMPLEMENTED -14
|
||||
#define INVALID_ACCOUNT -15
|
||||
#define GUARD_VIOLATION -16
|
||||
#define INVALID_FIELD -17
|
||||
#define PARSE_ERROR -18
|
||||
#define RC_ROLLBACK -19
|
||||
#define RC_ACCEPT -20
|
||||
#define NO_SUCH_KEYLET -21
|
||||
#define NOT_AN_ARRAY -22
|
||||
#define NOT_AN_OBJECT -23
|
||||
#define INVALID_FLOAT -10024
|
||||
#define DIVISION_BY_ZERO -25
|
||||
#define MANTISSA_OVERSIZED -26
|
||||
#define MANTISSA_UNDERSIZED -27
|
||||
#define EXPONENT_OVERSIZED -28
|
||||
#define EXPONENT_UNDERSIZED -29
|
||||
#define OVERFLOW -30
|
||||
#define NOT_IOU_AMOUNT -31
|
||||
#define NOT_AN_AMOUNT -32
|
||||
#define CANT_RETURN_NEGATIVE -33
|
||||
#define NOT_AUTHORIZED -34
|
||||
#define PREVIOUS_FAILURE_PREVENTS_RETRY -35
|
||||
#define TOO_MANY_PARAMS -36
|
||||
#define INVALID_TXN -37
|
||||
#define RESERVE_INSUFFICIENT -38
|
||||
#define COMPLEX_NOT_SUPPORTED -39
|
||||
#define DOES_NOT_MATCH -40
|
||||
#define HOOK_ERROR_CODES
|
||||
#endif //HOOK_ERROR_CODES
|
||||
@@ -1,352 +0,0 @@
|
||||
// For documentation please see: https://xrpl-hooks.readme.io/reference/
|
||||
// Generated using generate_extern.sh
|
||||
#include <stdint.h>
|
||||
#ifndef HOOK_EXTERN
|
||||
|
||||
extern int32_t __attribute__((noduplicate))
|
||||
_g(uint32_t guard_id, uint32_t maxiter);
|
||||
|
||||
extern int64_t
|
||||
accept(uint32_t read_ptr, uint32_t read_len, int64_t error_code);
|
||||
|
||||
extern int64_t
|
||||
emit(
|
||||
uint32_t write_ptr,
|
||||
uint32_t write_len,
|
||||
uint32_t read_ptr,
|
||||
uint32_t read_len);
|
||||
|
||||
extern int64_t
|
||||
etxn_burden(void);
|
||||
|
||||
extern int64_t
|
||||
etxn_details(uint32_t write_ptr, uint32_t write_len);
|
||||
|
||||
extern int64_t
|
||||
etxn_fee_base(uint32_t read_ptr, uint32_t read_len);
|
||||
|
||||
extern int64_t
|
||||
etxn_generation(void);
|
||||
|
||||
extern int64_t
|
||||
etxn_nonce(uint32_t write_ptr, uint32_t write_len);
|
||||
|
||||
extern int64_t
|
||||
etxn_reserve(uint32_t count);
|
||||
|
||||
extern int64_t
|
||||
fee_base(void);
|
||||
|
||||
extern int64_t
|
||||
float_compare(int64_t float1, int64_t float2, uint32_t mode);
|
||||
|
||||
extern int64_t
|
||||
float_divide(int64_t float1, int64_t float2);
|
||||
|
||||
extern int64_t
|
||||
float_exponent(int64_t float1);
|
||||
|
||||
extern int64_t
|
||||
float_exponent_set(int64_t float1, int32_t exponent);
|
||||
|
||||
extern int64_t
|
||||
float_int(int64_t float1, uint32_t decimal_places, uint32_t abs);
|
||||
|
||||
extern int64_t
|
||||
float_invert(int64_t float1);
|
||||
|
||||
extern int64_t
|
||||
float_log(int64_t float1);
|
||||
|
||||
extern int64_t
|
||||
float_mantissa(int64_t float1);
|
||||
|
||||
extern int64_t
|
||||
float_mantissa_set(int64_t float1, int64_t mantissa);
|
||||
|
||||
extern int64_t
|
||||
float_mulratio(
|
||||
int64_t float1,
|
||||
uint32_t round_up,
|
||||
uint32_t numerator,
|
||||
uint32_t denominator);
|
||||
|
||||
extern int64_t
|
||||
float_multiply(int64_t float1, int64_t float2);
|
||||
|
||||
extern int64_t
|
||||
float_negate(int64_t float1);
|
||||
|
||||
extern int64_t
|
||||
float_one(void);
|
||||
|
||||
extern int64_t
|
||||
float_root(int64_t float1, uint32_t n);
|
||||
|
||||
extern int64_t
|
||||
float_set(int32_t exponent, int64_t mantissa);
|
||||
|
||||
extern int64_t
|
||||
float_sign(int64_t float1);
|
||||
|
||||
extern int64_t
|
||||
float_sign_set(int64_t float1, uint32_t negative);
|
||||
|
||||
extern int64_t
|
||||
float_sto(
|
||||
uint32_t write_ptr,
|
||||
uint32_t write_len,
|
||||
uint32_t cread_ptr,
|
||||
uint32_t cread_len,
|
||||
uint32_t iread_ptr,
|
||||
uint32_t iread_len,
|
||||
int64_t float1,
|
||||
uint32_t field_code);
|
||||
|
||||
extern int64_t
|
||||
float_sto_set(uint32_t read_ptr, uint32_t read_len);
|
||||
|
||||
extern int64_t
|
||||
float_sum(int64_t float1, int64_t float2);
|
||||
|
||||
extern int64_t
|
||||
hook_account(uint32_t write_ptr, uint32_t write_len);
|
||||
|
||||
extern int64_t
|
||||
hook_again(void);
|
||||
|
||||
extern int64_t
|
||||
hook_hash(uint32_t write_ptr, uint32_t write_len, int32_t hook_no);
|
||||
|
||||
extern int64_t
|
||||
hook_param(
|
||||
uint32_t write_ptr,
|
||||
uint32_t write_len,
|
||||
uint32_t read_ptr,
|
||||
uint32_t read_len);
|
||||
|
||||
extern int64_t
|
||||
otxn_param(
|
||||
uint32_t write_ptr,
|
||||
uint32_t write_len,
|
||||
uint32_t read_ptr,
|
||||
uint32_t read_len);
|
||||
|
||||
extern int64_t
|
||||
hook_param_set(
|
||||
uint32_t read_ptr,
|
||||
uint32_t read_len,
|
||||
uint32_t kread_ptr,
|
||||
uint32_t kread_len,
|
||||
uint32_t hread_ptr,
|
||||
uint32_t hread_len);
|
||||
|
||||
extern int64_t
|
||||
hook_pos(void);
|
||||
|
||||
extern int64_t
|
||||
hook_skip(uint32_t read_ptr, uint32_t read_len, uint32_t flags);
|
||||
|
||||
extern int64_t
|
||||
ledger_keylet(
|
||||
uint32_t write_ptr,
|
||||
uint32_t write_len,
|
||||
uint32_t lread_ptr,
|
||||
uint32_t lread_len,
|
||||
uint32_t hread_ptr,
|
||||
uint32_t hread_len);
|
||||
|
||||
extern int64_t
|
||||
ledger_last_hash(uint32_t write_ptr, uint32_t write_len);
|
||||
|
||||
extern int64_t
|
||||
ledger_last_time(void);
|
||||
|
||||
extern int64_t
|
||||
ledger_nonce(uint32_t write_ptr, uint32_t write_len);
|
||||
|
||||
extern int64_t
|
||||
ledger_seq(void);
|
||||
|
||||
extern int64_t
|
||||
meta_slot(uint32_t slot_no);
|
||||
|
||||
extern int64_t
|
||||
otxn_burden(void);
|
||||
|
||||
extern int64_t
|
||||
otxn_field(uint32_t write_ptr, uint32_t write_len, uint32_t field_id);
|
||||
|
||||
extern int64_t
|
||||
otxn_field_txt(uint32_t write_ptr, uint32_t write_len, uint32_t field_id);
|
||||
|
||||
extern int64_t
|
||||
otxn_generation(void);
|
||||
|
||||
extern int64_t
|
||||
otxn_id(uint32_t write_ptr, uint32_t write_len, uint32_t flags);
|
||||
|
||||
extern int64_t
|
||||
otxn_slot(uint32_t slot_no);
|
||||
|
||||
extern int64_t
|
||||
otxn_type(void);
|
||||
|
||||
extern int64_t
|
||||
rollback(uint32_t read_ptr, uint32_t read_len, int64_t error_code);
|
||||
|
||||
extern int64_t
|
||||
slot(uint32_t write_ptr, uint32_t write_len, uint32_t slot);
|
||||
|
||||
extern int64_t
|
||||
slot_clear(uint32_t slot);
|
||||
|
||||
extern int64_t
|
||||
slot_count(uint32_t slot);
|
||||
|
||||
extern int64_t
|
||||
slot_float(uint32_t slot_no);
|
||||
|
||||
extern int64_t
|
||||
slot_id(uint32_t write_ptr, uint32_t write_len, uint32_t slot);
|
||||
|
||||
extern int64_t
|
||||
slot_set(uint32_t read_ptr, uint32_t read_len, uint32_t slot);
|
||||
|
||||
extern int64_t
|
||||
slot_size(uint32_t slot);
|
||||
|
||||
extern int64_t
|
||||
slot_subarray(uint32_t parent_slot, uint32_t array_id, uint32_t new_slot);
|
||||
|
||||
extern int64_t
|
||||
slot_subfield(uint32_t parent_slot, uint32_t field_id, uint32_t new_slot);
|
||||
|
||||
extern int64_t
|
||||
slot_type(uint32_t slot_no, uint32_t flags);
|
||||
|
||||
extern int64_t
|
||||
state(
|
||||
uint32_t write_ptr,
|
||||
uint32_t write_len,
|
||||
uint32_t kread_ptr,
|
||||
uint32_t kread_len);
|
||||
|
||||
extern int64_t
|
||||
state_foreign(
|
||||
uint32_t write_ptr,
|
||||
uint32_t write_len,
|
||||
uint32_t kread_ptr,
|
||||
uint32_t kread_len,
|
||||
uint32_t nread_ptr,
|
||||
uint32_t nread_len,
|
||||
uint32_t aread_ptr,
|
||||
uint32_t aread_len);
|
||||
|
||||
extern int64_t
|
||||
state_foreign_set(
|
||||
uint32_t read_ptr,
|
||||
uint32_t read_len,
|
||||
uint32_t kread_ptr,
|
||||
uint32_t kread_len,
|
||||
uint32_t nread_ptr,
|
||||
uint32_t nread_len,
|
||||
uint32_t aread_ptr,
|
||||
uint32_t aread_len);
|
||||
|
||||
extern int64_t
|
||||
state_set(
|
||||
uint32_t read_ptr,
|
||||
uint32_t read_len,
|
||||
uint32_t kread_ptr,
|
||||
uint32_t kread_len);
|
||||
|
||||
extern int64_t
|
||||
sto_emplace(
|
||||
uint32_t write_ptr,
|
||||
uint32_t write_len,
|
||||
uint32_t sread_ptr,
|
||||
uint32_t sread_len,
|
||||
uint32_t fread_ptr,
|
||||
uint32_t fread_len,
|
||||
uint32_t field_id);
|
||||
|
||||
extern int64_t
|
||||
sto_erase(
|
||||
uint32_t write_ptr,
|
||||
uint32_t write_len,
|
||||
uint32_t read_ptr,
|
||||
uint32_t read_len,
|
||||
uint32_t field_id);
|
||||
|
||||
extern int64_t
|
||||
sto_subarray(uint32_t read_ptr, uint32_t read_len, uint32_t array_id);
|
||||
|
||||
extern int64_t
|
||||
sto_subfield(uint32_t read_ptr, uint32_t read_len, uint32_t field_id);
|
||||
|
||||
extern int64_t
|
||||
sto_validate(uint32_t tread_ptr, uint32_t tread_len);
|
||||
|
||||
extern int64_t
|
||||
trace(
|
||||
uint32_t mread_ptr,
|
||||
uint32_t mread_len,
|
||||
uint32_t dread_ptr,
|
||||
uint32_t dread_len,
|
||||
uint32_t as_hex);
|
||||
|
||||
extern int64_t
|
||||
trace_float(uint32_t read_ptr, uint32_t read_len, int64_t float1);
|
||||
|
||||
extern int64_t
|
||||
trace_num(uint32_t read_ptr, uint32_t read_len, int64_t number);
|
||||
|
||||
extern int64_t
|
||||
trace_slot(uint32_t read_ptr, uint32_t read_len, uint32_t slot);
|
||||
|
||||
extern int64_t
|
||||
util_accid(
|
||||
uint32_t write_ptr,
|
||||
uint32_t write_len,
|
||||
uint32_t read_ptr,
|
||||
uint32_t read_len);
|
||||
|
||||
extern int64_t
|
||||
util_keylet(
|
||||
uint32_t write_ptr,
|
||||
uint32_t write_len,
|
||||
uint32_t keylet_type,
|
||||
uint32_t a,
|
||||
uint32_t b,
|
||||
uint32_t c,
|
||||
uint32_t d,
|
||||
uint32_t e,
|
||||
uint32_t f);
|
||||
|
||||
extern int64_t
|
||||
util_raddr(
|
||||
uint32_t write_ptr,
|
||||
uint32_t write_len,
|
||||
uint32_t read_ptr,
|
||||
uint32_t read_len);
|
||||
|
||||
extern int64_t
|
||||
util_sha512h(
|
||||
uint32_t write_ptr,
|
||||
uint32_t write_len,
|
||||
uint32_t read_ptr,
|
||||
uint32_t read_len);
|
||||
|
||||
extern int64_t
|
||||
util_verify(
|
||||
uint32_t dread_ptr,
|
||||
uint32_t dread_len,
|
||||
uint32_t sread_ptr,
|
||||
uint32_t sread_len,
|
||||
uint32_t kread_ptr,
|
||||
uint32_t kread_len);
|
||||
|
||||
extern int64_t xpop_slot(uint32_t, uint32_t);
|
||||
#define HOOK_EXTERN
|
||||
#endif // HOOK_EXTERN
|
||||
@@ -1,50 +0,0 @@
|
||||
/**
|
||||
* Hook API include file
|
||||
*
|
||||
* Note to the reader:
|
||||
* This include defines two types of things: external functions and macros
|
||||
* Functions are used sparingly because a non-inlining compiler may produce
|
||||
* undesirable output.
|
||||
*
|
||||
* Find documentation here: https://xrpl-hooks.readme.io/reference/
|
||||
*/
|
||||
|
||||
#ifndef HOOKAPI_INCLUDED
|
||||
#define HOOKAPI_INCLUDED 1
|
||||
|
||||
#define KEYLET_HOOK 1
|
||||
#define KEYLET_HOOK_STATE 2
|
||||
#define KEYLET_ACCOUNT 3
|
||||
#define KEYLET_AMENDMENTS 4
|
||||
#define KEYLET_CHILD 5
|
||||
#define KEYLET_SKIP 6
|
||||
#define KEYLET_FEES 7
|
||||
#define KEYLET_NEGATIVE_UNL 8
|
||||
#define KEYLET_LINE 9
|
||||
#define KEYLET_OFFER 10
|
||||
#define KEYLET_QUALITY 11
|
||||
#define KEYLET_EMITTED_DIR 12
|
||||
#define KEYLET_TICKET 13
|
||||
#define KEYLET_SIGNERS 14
|
||||
#define KEYLET_CHECK 15
|
||||
#define KEYLET_DEPOSIT_PREAUTH 16
|
||||
#define KEYLET_UNCHECKED 17
|
||||
#define KEYLET_OWNER_DIR 18
|
||||
#define KEYLET_PAGE 19
|
||||
#define KEYLET_ESCROW 20
|
||||
#define KEYLET_PAYCHAN 21
|
||||
#define KEYLET_EMITTED 22
|
||||
#define KEYLET_NFT_OFFER 23
|
||||
#define KEYLET_HOOK_DEFINITION 24
|
||||
|
||||
#define COMPARE_EQUAL 1U
|
||||
#define COMPARE_LESS 2U
|
||||
#define COMPARE_GREATER 4U
|
||||
|
||||
#include "error.h"
|
||||
#include "extern.h"
|
||||
#include "sfcodes.h"
|
||||
#include "macro.h"
|
||||
#include "types.h"
|
||||
|
||||
#endif
|
||||
@@ -1,671 +0,0 @@
|
||||
/**
|
||||
* These are helper macros for writing hooks, all of them are optional as is including hookmacro.h at all
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "hookapi.h"
|
||||
#include "sfcodes.h"
|
||||
|
||||
#ifndef HOOKMACROS_INCLUDED
|
||||
#define HOOKMACROS_INCLUDED 1
|
||||
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define DEBUG 0
|
||||
#else
|
||||
#define DEBUG 1
|
||||
#endif
|
||||
|
||||
#define TRACEVAR(v) if (DEBUG) trace_num((uint32_t)(#v), (uint32_t)(sizeof(#v) - 1), (int64_t)v);
|
||||
#define TRACEHEX(v) if (DEBUG) trace((uint32_t)(#v), (uint32_t)(sizeof(#v) - 1), (uint32_t)(v), (uint32_t)(sizeof(v)), 1);
|
||||
#define TRACEXFL(v) if (DEBUG) trace_float((uint32_t)(#v), (uint32_t)(sizeof(#v) - 1), (int64_t)v);
|
||||
#define TRACESTR(v) if (DEBUG) trace((uint32_t)(#v), (uint32_t)(sizeof(#v) - 1), (uint32_t)(v), sizeof(v), 0);
|
||||
|
||||
// hook developers should use this guard macro, simply GUARD(<maximum iterations>)
|
||||
#define GUARD(maxiter) _g((1ULL << 31U) + __LINE__, (maxiter)+1)
|
||||
#define GUARDM(maxiter, n) _g(( (1ULL << 31U) + (__LINE__ << 16) + n), (maxiter)+1)
|
||||
|
||||
#define SBUF(str) (uint32_t)(str), sizeof(str)
|
||||
|
||||
#define REQUIRE(cond, str)\
|
||||
{\
|
||||
if (!(cond))\
|
||||
rollback(SBUF(str), __LINE__);\
|
||||
}
|
||||
|
||||
// make a report buffer as a c-string
|
||||
// provide a name for a buffer to declare (buf)
|
||||
// provide a static string
|
||||
// provide an integer to print after the string
|
||||
#define RBUF(buf, out_len, str, num)\
|
||||
unsigned char buf[sizeof(str) + 21];\
|
||||
int out_len = 0;\
|
||||
{\
|
||||
int i = 0;\
|
||||
for (; GUARDM(sizeof(str),1),i < sizeof(str); ++i)\
|
||||
(buf)[i] = str[i];\
|
||||
if ((buf)[sizeof(str)-1] == 0) i--;\
|
||||
if ((num) < 0) (buf)[i++] = '-';\
|
||||
uint64_t unsigned_num = (uint64_t)( (num) < 0 ? (num) * -1 : (num) );\
|
||||
uint64_t j = 10000000000000000000ULL;\
|
||||
int start = 1;\
|
||||
for (; GUARDM(20,2), unsigned_num > 0 && j > 0; j /= 10)\
|
||||
{\
|
||||
unsigned char digit = ( unsigned_num / j ) % 10;\
|
||||
if (digit == 0 && start)\
|
||||
continue;\
|
||||
start = 0;\
|
||||
(buf)[i++] = '0' + digit;\
|
||||
}\
|
||||
(buf)[i] = '\0';\
|
||||
out_len = i;\
|
||||
}
|
||||
|
||||
#define RBUF2(buff, out_len, str, num, str2, num2)\
|
||||
unsigned char buff[sizeof(str) + sizeof(str2) + 42];\
|
||||
int out_len = 0;\
|
||||
{\
|
||||
unsigned char* buf = buff;\
|
||||
int i = 0;\
|
||||
for (; GUARDM(sizeof(str),1),i < sizeof(str); ++i)\
|
||||
(buf)[i] = str[i];\
|
||||
if ((buf)[sizeof(str)-1] == 0) i--;\
|
||||
if ((num) < 0) (buf)[i++] = '-';\
|
||||
uint64_t unsigned_num = (uint64_t)( (num) < 0 ? (num) * -1 : (num) );\
|
||||
uint64_t j = 10000000000000000000ULL;\
|
||||
int start = 1;\
|
||||
for (; GUARDM(20,2), unsigned_num > 0 && j > 0; j /= 10)\
|
||||
{\
|
||||
unsigned char digit = ( unsigned_num / j ) % 10;\
|
||||
if (digit == 0 && start)\
|
||||
continue;\
|
||||
start = 0;\
|
||||
(buf)[i++] = '0' + digit;\
|
||||
}\
|
||||
buf += i;\
|
||||
out_len += i;\
|
||||
i = 0;\
|
||||
for (; GUARDM(sizeof(str2),3),i < sizeof(str2); ++i)\
|
||||
(buf)[i] = str2[i];\
|
||||
if ((buf)[sizeof(str2)-1] == 0) i--;\
|
||||
if ((num2) < 0) (buf)[i++] = '-';\
|
||||
unsigned_num = (uint64_t)( (num2) < 0 ? (num2) * -1 : (num2) );\
|
||||
j = 10000000000000000000ULL;\
|
||||
start = 1;\
|
||||
for (; GUARDM(20,4), unsigned_num > 0 && j > 0; j /= 10)\
|
||||
{\
|
||||
unsigned char digit = ( unsigned_num / j ) % 10;\
|
||||
if (digit == 0 && start)\
|
||||
continue;\
|
||||
start = 0;\
|
||||
(buf)[i++] = '0' + digit;\
|
||||
}\
|
||||
(buf)[i] = '\0';\
|
||||
out_len += i;\
|
||||
}
|
||||
|
||||
#define CLEARBUF(b)\
|
||||
{\
|
||||
for (int x = 0; GUARD(sizeof(b)), x < sizeof(b); ++x)\
|
||||
b[x] = 0;\
|
||||
}
|
||||
|
||||
// returns an in64_t, negative if error, non-negative if valid drops
|
||||
#define AMOUNT_TO_DROPS(amount_buffer)\
|
||||
(((amount_buffer)[0] >> 7) ? -2 : (\
|
||||
((((uint64_t)((amount_buffer)[0])) & 0xb00111111) << 56) +\
|
||||
(((uint64_t)((amount_buffer)[1])) << 48) +\
|
||||
(((uint64_t)((amount_buffer)[2])) << 40) +\
|
||||
(((uint64_t)((amount_buffer)[3])) << 32) +\
|
||||
(((uint64_t)((amount_buffer)[4])) << 24) +\
|
||||
(((uint64_t)((amount_buffer)[5])) << 16) +\
|
||||
(((uint64_t)((amount_buffer)[6])) << 8) +\
|
||||
(((uint64_t)((amount_buffer)[7])))))
|
||||
|
||||
#define SUB_OFFSET(x) ((int32_t)(x >> 32))
|
||||
#define SUB_LENGTH(x) ((int32_t)(x & 0xFFFFFFFFULL))
|
||||
|
||||
#define BUFFER_EQUAL_20(buf1, buf2)\
|
||||
(\
|
||||
*(((uint64_t*)(buf1)) + 0) == *(((uint64_t*)(buf2)) + 0) &&\
|
||||
*(((uint64_t*)(buf1)) + 1) == *(((uint64_t*)(buf2)) + 1) &&\
|
||||
*(((uint32_t*)(buf1)) + 4) == *(((uint32_t*)(buf2)) + 4))
|
||||
|
||||
#define BUFFER_EQUAL_32(buf1, buf2)\
|
||||
(\
|
||||
*(((uint64_t*)(buf1)) + 0) == *(((uint64_t*)(buf2)) + 0) &&\
|
||||
*(((uint64_t*)(buf1)) + 1) == *(((uint64_t*)(buf2)) + 1) &&\
|
||||
*(((uint64_t*)(buf1)) + 2) == *(((uint64_t*)(buf2)) + 2) &&\
|
||||
*(((uint64_t*)(buf1)) + 3) == *(((uint64_t*)(buf2)) + 3))
|
||||
|
||||
|
||||
// when using this macro buf1len may be dynamic but buf2len must be static
|
||||
// provide n >= 1 to indicate how many times the macro will be hit on the line of code
|
||||
// e.g. if it is in a loop that loops 10 times n = 10
|
||||
|
||||
#define BUFFER_EQUAL_GUARD(output, buf1, buf1len, buf2, buf2len, n)\
|
||||
{\
|
||||
output = ((buf1len) == (buf2len) ? 1 : 0);\
|
||||
for (int x = 0; GUARDM( (buf2len) * (n), 1 ), output && x < (buf2len);\
|
||||
++x)\
|
||||
output = *(((uint8_t*)(buf1)) + x) == *(((uint8_t*)(buf2)) + x);\
|
||||
}
|
||||
|
||||
#define BUFFER_SWAP(x,y)\
|
||||
{\
|
||||
uint8_t* z = x;\
|
||||
x = y;\
|
||||
y = z;\
|
||||
}
|
||||
|
||||
#define ACCOUNT_COMPARE(compare_result, buf1, buf2)\
|
||||
{\
|
||||
compare_result = 0;\
|
||||
for (int i = 0; GUARD(20), i < 20; ++i)\
|
||||
{\
|
||||
if (buf1[i] > buf2[i])\
|
||||
{\
|
||||
compare_result = 1;\
|
||||
break;\
|
||||
}\
|
||||
else if (buf1[i] < buf2[i])\
|
||||
{\
|
||||
compare_result = -1;\
|
||||
break;\
|
||||
}\
|
||||
}\
|
||||
}
|
||||
|
||||
#define BUFFER_EQUAL_STR_GUARD(output, buf1, buf1len, str, n)\
|
||||
BUFFER_EQUAL_GUARD(output, buf1, buf1len, str, (sizeof(str)-1), n)
|
||||
|
||||
#define BUFFER_EQUAL_STR(output, buf1, buf1len, str)\
|
||||
BUFFER_EQUAL_GUARD(output, buf1, buf1len, str, (sizeof(str)-1), 1)
|
||||
|
||||
#define BUFFER_EQUAL(output, buf1, buf2, compare_len)\
|
||||
BUFFER_EQUAL_GUARD(output, buf1, compare_len, buf2, compare_len, 1)
|
||||
|
||||
#define UINT16_TO_BUF(buf_raw, i)\
|
||||
{\
|
||||
unsigned char* buf = (unsigned char*)buf_raw;\
|
||||
buf[0] = (((uint64_t)i) >> 8) & 0xFFUL;\
|
||||
buf[1] = (((uint64_t)i) >> 0) & 0xFFUL;\
|
||||
}
|
||||
|
||||
#define UINT16_FROM_BUF(buf)\
|
||||
(((uint64_t)((buf)[0]) << 8) +\
|
||||
((uint64_t)((buf)[1]) << 0))
|
||||
|
||||
#define UINT32_TO_BUF(buf_raw, i)\
|
||||
{\
|
||||
unsigned char* buf = (unsigned char*)buf_raw;\
|
||||
buf[0] = (((uint64_t)i) >> 24) & 0xFFUL;\
|
||||
buf[1] = (((uint64_t)i) >> 16) & 0xFFUL;\
|
||||
buf[2] = (((uint64_t)i) >> 8) & 0xFFUL;\
|
||||
buf[3] = (((uint64_t)i) >> 0) & 0xFFUL;\
|
||||
}
|
||||
|
||||
|
||||
#define UINT32_FROM_BUF(buf)\
|
||||
(((uint64_t)((buf)[0]) << 24) +\
|
||||
((uint64_t)((buf)[1]) << 16) +\
|
||||
((uint64_t)((buf)[2]) << 8) +\
|
||||
((uint64_t)((buf)[3]) << 0))
|
||||
|
||||
#define UINT64_TO_BUF(buf_raw, i)\
|
||||
{\
|
||||
unsigned char* buf = (unsigned char*)buf_raw;\
|
||||
buf[0] = (((uint64_t)i) >> 56) & 0xFFUL;\
|
||||
buf[1] = (((uint64_t)i) >> 48) & 0xFFUL;\
|
||||
buf[2] = (((uint64_t)i) >> 40) & 0xFFUL;\
|
||||
buf[3] = (((uint64_t)i) >> 32) & 0xFFUL;\
|
||||
buf[4] = (((uint64_t)i) >> 24) & 0xFFUL;\
|
||||
buf[5] = (((uint64_t)i) >> 16) & 0xFFUL;\
|
||||
buf[6] = (((uint64_t)i) >> 8) & 0xFFUL;\
|
||||
buf[7] = (((uint64_t)i) >> 0) & 0xFFUL;\
|
||||
}
|
||||
|
||||
|
||||
#define UINT64_FROM_BUF(buf)\
|
||||
(((uint64_t)((buf)[0]) << 56) +\
|
||||
((uint64_t)((buf)[1]) << 48) +\
|
||||
((uint64_t)((buf)[2]) << 40) +\
|
||||
((uint64_t)((buf)[3]) << 32) +\
|
||||
((uint64_t)((buf)[4]) << 24) +\
|
||||
((uint64_t)((buf)[5]) << 16) +\
|
||||
((uint64_t)((buf)[6]) << 8) +\
|
||||
((uint64_t)((buf)[7]) << 0))
|
||||
|
||||
|
||||
#define INT64_FROM_BUF(buf)\
|
||||
((((uint64_t)((buf)[0] & 0x7FU) << 56) +\
|
||||
((uint64_t)((buf)[1]) << 48) +\
|
||||
((uint64_t)((buf)[2]) << 40) +\
|
||||
((uint64_t)((buf)[3]) << 32) +\
|
||||
((uint64_t)((buf)[4]) << 24) +\
|
||||
((uint64_t)((buf)[5]) << 16) +\
|
||||
((uint64_t)((buf)[6]) << 8) +\
|
||||
((uint64_t)((buf)[7]) << 0)) * (buf[0] & 0x80U ? -1 : 1))
|
||||
|
||||
#define INT64_TO_BUF(buf_raw, i)\
|
||||
{\
|
||||
unsigned char* buf = (unsigned char*)buf_raw;\
|
||||
buf[0] = (((uint64_t)i) >> 56) & 0x7FUL;\
|
||||
buf[1] = (((uint64_t)i) >> 48) & 0xFFUL;\
|
||||
buf[2] = (((uint64_t)i) >> 40) & 0xFFUL;\
|
||||
buf[3] = (((uint64_t)i) >> 32) & 0xFFUL;\
|
||||
buf[4] = (((uint64_t)i) >> 24) & 0xFFUL;\
|
||||
buf[5] = (((uint64_t)i) >> 16) & 0xFFUL;\
|
||||
buf[6] = (((uint64_t)i) >> 8) & 0xFFUL;\
|
||||
buf[7] = (((uint64_t)i) >> 0) & 0xFFUL;\
|
||||
if (i < 0) buf[0] |= 0x80U;\
|
||||
}
|
||||
|
||||
#define ttPAYMENT 0
|
||||
#define ttESCROW_CREATE 1
|
||||
#define ttESCROW_FINISH 2
|
||||
#define ttACCOUNT_SET 3
|
||||
#define ttESCROW_CANCEL 4
|
||||
#define ttREGULAR_KEY_SET 5
|
||||
#define ttOFFER_CREATE 7
|
||||
#define ttOFFER_CANCEL 8
|
||||
#define ttTICKET_CREATE 10
|
||||
#define ttSIGNER_LIST_SET 12
|
||||
#define ttPAYCHAN_CREATE 13
|
||||
#define ttPAYCHAN_FUND 14
|
||||
#define ttPAYCHAN_CLAIM 15
|
||||
#define ttCHECK_CREATE 16
|
||||
#define ttCHECK_CASH 17
|
||||
#define ttCHECK_CANCEL 18
|
||||
#define ttDEPOSIT_PREAUTH 19
|
||||
#define ttTRUST_SET 20
|
||||
#define ttACCOUNT_DELETE 21
|
||||
#define ttHOOK_SET 22
|
||||
#define ttNFTOKEN_MINT 25
|
||||
#define ttNFTOKEN_BURN 26
|
||||
#define ttNFTOKEN_CREATE_OFFER 27
|
||||
#define ttNFTOKEN_CANCEL_OFFER 28
|
||||
#define ttNFTOKEN_ACCEPT_OFFER 29
|
||||
#define ttURITOKEN_MINT 45
|
||||
#define ttURITOKEN_BURN 46
|
||||
#define ttURITOKEN_BUY 47
|
||||
#define ttURITOKEN_CREATE_SELL_OFFER 48
|
||||
#define ttURITOKEN_CANCEL_SELL_OFFER 49
|
||||
#define ttCLAIM_REWARD 98
|
||||
#define ttINVOKE 99
|
||||
#define ttAMENDMENT 100
|
||||
#define ttFEE 101
|
||||
#define ttUNL_MODIFY 102
|
||||
#define ttEMIT_FAILURE 103
|
||||
#define tfCANONICAL 0x80000000UL
|
||||
|
||||
#define atACCOUNT 1U
|
||||
#define atOWNER 2U
|
||||
#define atDESTINATION 3U
|
||||
#define atISSUER 4U
|
||||
#define atAUTHORIZE 5U
|
||||
#define atUNAUTHORIZE 6U
|
||||
#define atTARGET 7U
|
||||
#define atREGULARKEY 8U
|
||||
#define atPSEUDOCALLBACK 9U
|
||||
|
||||
#define amAMOUNT 1U
|
||||
#define amBALANCE 2U
|
||||
#define amLIMITAMOUNT 3U
|
||||
#define amTAKERPAYS 4U
|
||||
#define amTAKERGETS 5U
|
||||
#define amLOWLIMIT 6U
|
||||
#define amHIGHLIMIT 7U
|
||||
#define amFEE 8U
|
||||
#define amSENDMAX 9U
|
||||
#define amDELIVERMIN 10U
|
||||
#define amMINIMUMOFFER 16U
|
||||
#define amRIPPLEESCROW 17U
|
||||
#define amDELIVEREDAMOUNT 18U
|
||||
|
||||
/**
|
||||
* RH NOTE -- PAY ATTENTION
|
||||
*
|
||||
* ALL 'ENCODE' MACROS INCREMENT BUF_OUT
|
||||
* THIS IS TO MAKE CHAINING EASY
|
||||
* BUF_OUT IS A SACRIFICIAL POINTER
|
||||
*
|
||||
* 'ENCODE' MACROS WITH CONSTANTS HAVE
|
||||
* ALIASING TO ASSIST YOU WITH ORDER
|
||||
* _TYPECODE_FIELDCODE_ENCODE_MACRO
|
||||
* TO PRODUCE A SERIALIZED OBJECT
|
||||
* IN CANONICAL FORMAT YOU MUST ORDER
|
||||
* FIRST BY TYPE CODE THEN BY FIELD CODE
|
||||
*
|
||||
* ALL 'PREPARE' MACROS PRESERVE POINTERS
|
||||
*
|
||||
**/
|
||||
|
||||
|
||||
#define ENCODE_TL_SIZE 49
|
||||
#define ENCODE_TL(buf_out, tlamt, amount_type)\
|
||||
{\
|
||||
uint8_t uat = amount_type; \
|
||||
buf_out[0] = 0x60U +(uat & 0x0FU ); \
|
||||
for (int i = 1; GUARDM(48, 1), i < 49; ++i)\
|
||||
buf_out[i] = tlamt[i-1];\
|
||||
buf_out += ENCODE_TL_SIZE;\
|
||||
}
|
||||
#define _06_XX_ENCODE_TL(buf_out, drops, amount_type )\
|
||||
ENCODE_TL(buf_out, drops, amount_type );
|
||||
#define ENCODE_TL_AMOUNT(buf_out, drops )\
|
||||
ENCODE_TL(buf_out, drops, amAMOUNT );
|
||||
#define _06_01_ENCODE_TL_AMOUNT(buf_out, drops )\
|
||||
ENCODE_TL_AMOUNT(buf_out, drops );
|
||||
|
||||
|
||||
// Encode drops to serialization format
|
||||
// consumes 9 bytes
|
||||
#define ENCODE_DROPS_SIZE 9
|
||||
#define ENCODE_DROPS(buf_out, drops, amount_type ) \
|
||||
{\
|
||||
uint8_t uat = amount_type; \
|
||||
uint64_t udrops = drops; \
|
||||
buf_out[0] = 0x60U +(uat & 0x0FU ); \
|
||||
buf_out[1] = 0b01000000 + (( udrops >> 56 ) & 0b00111111 ); \
|
||||
buf_out[2] = (udrops >> 48) & 0xFFU; \
|
||||
buf_out[3] = (udrops >> 40) & 0xFFU; \
|
||||
buf_out[4] = (udrops >> 32) & 0xFFU; \
|
||||
buf_out[5] = (udrops >> 24) & 0xFFU; \
|
||||
buf_out[6] = (udrops >> 16) & 0xFFU; \
|
||||
buf_out[7] = (udrops >> 8) & 0xFFU; \
|
||||
buf_out[8] = (udrops >> 0) & 0xFFU; \
|
||||
buf_out += ENCODE_DROPS_SIZE; \
|
||||
}
|
||||
|
||||
#define _06_XX_ENCODE_DROPS(buf_out, drops, amount_type )\
|
||||
ENCODE_DROPS(buf_out, drops, amount_type );
|
||||
|
||||
#define ENCODE_DROPS_AMOUNT(buf_out, drops )\
|
||||
ENCODE_DROPS(buf_out, drops, amAMOUNT );
|
||||
#define _06_01_ENCODE_DROPS_AMOUNT(buf_out, drops )\
|
||||
ENCODE_DROPS_AMOUNT(buf_out, drops );
|
||||
|
||||
#define ENCODE_DROPS_FEE(buf_out, drops )\
|
||||
ENCODE_DROPS(buf_out, drops, amFEE );
|
||||
#define _06_08_ENCODE_DROPS_FEE(buf_out, drops )\
|
||||
ENCODE_DROPS_FEE(buf_out, drops );
|
||||
|
||||
#define ENCODE_TT_SIZE 3
|
||||
#define ENCODE_TT(buf_out, tt )\
|
||||
{\
|
||||
uint8_t utt = tt;\
|
||||
buf_out[0] = 0x12U;\
|
||||
buf_out[1] =(utt >> 8 ) & 0xFFU;\
|
||||
buf_out[2] =(utt >> 0 ) & 0xFFU;\
|
||||
buf_out += ENCODE_TT_SIZE; \
|
||||
}
|
||||
#define _01_02_ENCODE_TT(buf_out, tt)\
|
||||
ENCODE_TT(buf_out, tt);
|
||||
|
||||
|
||||
#define ENCODE_ACCOUNT_SIZE 22
|
||||
#define ENCODE_ACCOUNT(buf_out, account_id, account_type)\
|
||||
{\
|
||||
uint8_t uat = account_type;\
|
||||
buf_out[0] = 0x80U + uat;\
|
||||
buf_out[1] = 0x14U;\
|
||||
*(uint64_t*)(buf_out + 2) = *(uint64_t*)(account_id + 0);\
|
||||
*(uint64_t*)(buf_out + 10) = *(uint64_t*)(account_id + 8);\
|
||||
*(uint32_t*)(buf_out + 18) = *(uint32_t*)(account_id + 16);\
|
||||
buf_out += ENCODE_ACCOUNT_SIZE;\
|
||||
}
|
||||
#define _08_XX_ENCODE_ACCOUNT(buf_out, account_id, account_type)\
|
||||
ENCODE_ACCOUNT(buf_out, account_id, account_type);
|
||||
|
||||
#define ENCODE_ACCOUNT_SRC_SIZE 22
|
||||
#define ENCODE_ACCOUNT_SRC(buf_out, account_id)\
|
||||
ENCODE_ACCOUNT(buf_out, account_id, atACCOUNT);
|
||||
#define _08_01_ENCODE_ACCOUNT_SRC(buf_out, account_id)\
|
||||
ENCODE_ACCOUNT_SRC(buf_out, account_id);
|
||||
|
||||
#define ENCODE_ACCOUNT_DST_SIZE 22
|
||||
#define ENCODE_ACCOUNT_DST(buf_out, account_id)\
|
||||
ENCODE_ACCOUNT(buf_out, account_id, atDESTINATION);
|
||||
#define _08_03_ENCODE_ACCOUNT_DST(buf_out, account_id)\
|
||||
ENCODE_ACCOUNT_DST(buf_out, account_id);
|
||||
|
||||
#define ENCODE_ACCOUNT_OWNER_SIZE 22
|
||||
#define ENCODE_ACCOUNT_OWNER(buf_out, account_id) \
|
||||
ENCODE_ACCOUNT(buf_out, account_id, atOWNER);
|
||||
#define _08_02_ENCODE_ACCOUNT_OWNER(buf_out, account_id) \
|
||||
ENCODE_ACCOUNT_OWNER(buf_out, account_id);
|
||||
|
||||
#define ENCODE_UINT32_COMMON_SIZE 5U
|
||||
#define ENCODE_UINT32_COMMON(buf_out, i, field)\
|
||||
{\
|
||||
uint32_t ui = i; \
|
||||
uint8_t uf = field; \
|
||||
buf_out[0] = 0x20U +(uf & 0x0FU); \
|
||||
buf_out[1] =(ui >> 24 ) & 0xFFU; \
|
||||
buf_out[2] =(ui >> 16 ) & 0xFFU; \
|
||||
buf_out[3] =(ui >> 8 ) & 0xFFU; \
|
||||
buf_out[4] =(ui >> 0 ) & 0xFFU; \
|
||||
buf_out += ENCODE_UINT32_COMMON_SIZE; \
|
||||
}
|
||||
#define _02_XX_ENCODE_UINT32_COMMON(buf_out, i, field)\
|
||||
ENCODE_UINT32_COMMON(buf_out, i, field)\
|
||||
|
||||
#define ENCODE_UINT32_UNCOMMON_SIZE 6U
|
||||
#define ENCODE_UINT32_UNCOMMON(buf_out, i, field)\
|
||||
{\
|
||||
uint32_t ui = i; \
|
||||
uint8_t uf = field; \
|
||||
buf_out[0] = 0x20U; \
|
||||
buf_out[1] = uf; \
|
||||
buf_out[2] =(ui >> 24 ) & 0xFFU; \
|
||||
buf_out[3] =(ui >> 16 ) & 0xFFU; \
|
||||
buf_out[4] =(ui >> 8 ) & 0xFFU; \
|
||||
buf_out[5] =(ui >> 0 ) & 0xFFU; \
|
||||
buf_out += ENCODE_UINT32_UNCOMMON_SIZE; \
|
||||
}
|
||||
#define _02_XX_ENCODE_UINT32_UNCOMMON(buf_out, i, field)\
|
||||
ENCODE_UINT32_UNCOMMON(buf_out, i, field)\
|
||||
|
||||
#define ENCODE_LLS_SIZE 6U
|
||||
#define ENCODE_LLS(buf_out, lls )\
|
||||
ENCODE_UINT32_UNCOMMON(buf_out, lls, 0x1B );
|
||||
#define _02_27_ENCODE_LLS(buf_out, lls )\
|
||||
ENCODE_LLS(buf_out, lls );
|
||||
|
||||
#define ENCODE_FLS_SIZE 6U
|
||||
#define ENCODE_FLS(buf_out, fls )\
|
||||
ENCODE_UINT32_UNCOMMON(buf_out, fls, 0x1A );
|
||||
#define _02_26_ENCODE_FLS(buf_out, fls )\
|
||||
ENCODE_FLS(buf_out, fls );
|
||||
|
||||
#define ENCODE_TAG_SRC_SIZE 5
|
||||
#define ENCODE_TAG_SRC(buf_out, tag )\
|
||||
ENCODE_UINT32_COMMON(buf_out, tag, 0x3U );
|
||||
#define _02_03_ENCODE_TAG_SRC(buf_out, tag )\
|
||||
ENCODE_TAG_SRC(buf_out, tag );
|
||||
|
||||
#define ENCODE_TAG_DST_SIZE 5
|
||||
#define ENCODE_TAG_DST(buf_out, tag )\
|
||||
ENCODE_UINT32_COMMON(buf_out, tag, 0xEU );
|
||||
#define _02_14_ENCODE_TAG_DST(buf_out, tag )\
|
||||
ENCODE_TAG_DST(buf_out, tag );
|
||||
|
||||
#define ENCODE_SEQUENCE_SIZE 5
|
||||
#define ENCODE_SEQUENCE(buf_out, sequence )\
|
||||
ENCODE_UINT32_COMMON(buf_out, sequence, 0x4U );
|
||||
#define _02_04_ENCODE_SEQUENCE(buf_out, sequence )\
|
||||
ENCODE_SEQUENCE(buf_out, sequence );
|
||||
|
||||
#define ENCODE_FLAGS_SIZE 5
|
||||
#define ENCODE_FLAGS(buf_out, tag )\
|
||||
ENCODE_UINT32_COMMON(buf_out, tag, 0x2U );
|
||||
#define _02_02_ENCODE_FLAGS(buf_out, tag )\
|
||||
ENCODE_FLAGS(buf_out, tag );
|
||||
|
||||
#define ENCODE_SIGNING_PUBKEY_SIZE 35
|
||||
#define ENCODE_SIGNING_PUBKEY(buf_out, pkey )\
|
||||
{\
|
||||
buf_out[0] = 0x73U;\
|
||||
buf_out[1] = 0x21U;\
|
||||
*(uint64_t*)(buf_out + 2) = *(uint64_t*)(pkey + 0);\
|
||||
*(uint64_t*)(buf_out + 10) = *(uint64_t*)(pkey + 8);\
|
||||
*(uint64_t*)(buf_out + 18) = *(uint64_t*)(pkey + 16);\
|
||||
*(uint64_t*)(buf_out + 26) = *(uint64_t*)(pkey + 24);\
|
||||
buf[34] = pkey[32];\
|
||||
buf_out += ENCODE_SIGNING_PUBKEY_SIZE;\
|
||||
}
|
||||
|
||||
#define _07_03_ENCODE_SIGNING_PUBKEY(buf_out, pkey )\
|
||||
ENCODE_SIGNING_PUBKEY(buf_out, pkey );
|
||||
|
||||
#define ENCODE_SIGNING_PUBKEY_NULL_SIZE 2
|
||||
#define ENCODE_SIGNING_PUBKEY_NULL(buf_out )\
|
||||
{\
|
||||
*buf_out++ = 0x73U;\
|
||||
*buf_out++ = 0x00U;\
|
||||
}
|
||||
|
||||
#define _07_03_ENCODE_SIGNING_PUBKEY_NULL(buf_out )\
|
||||
ENCODE_SIGNING_PUBKEY_NULL(buf_out );
|
||||
|
||||
|
||||
#define _0E_0E_ENCODE_HOOKOBJ(buf_out, hhash)\
|
||||
{\
|
||||
uint8_t* hook0 = (hhash);\
|
||||
*buf_out++ = 0xEEU; /* hook obj start */ \
|
||||
if (hook0 == 0) /* noop */\
|
||||
{\
|
||||
/* do nothing */ \
|
||||
}\
|
||||
else\
|
||||
{\
|
||||
*buf_out++ = 0x22U; /* flags = override */\
|
||||
*buf_out++ = 0x00U;\
|
||||
*buf_out++ = 0x00U;\
|
||||
*buf_out++ = 0x00U;\
|
||||
*buf_out++ = 0x01U;\
|
||||
if (hook0 == 0xFFFFFFFFUL) /* delete operation */ \
|
||||
{\
|
||||
*buf_out++ = 0x7BU; /* empty createcode */ \
|
||||
*buf_out++ = 0x00U;\
|
||||
}\
|
||||
else\
|
||||
{\
|
||||
*buf_out++ = 0x50U; /* HookHash */\
|
||||
*buf_out++ = 0x1FU;\
|
||||
uint64_t* d = (uint64_t*)buf_out;\
|
||||
uint64_t* s = (uint64_t*)hook0;\
|
||||
*d++ = *s++;\
|
||||
*d++ = *s++;\
|
||||
*d++ = *s++;\
|
||||
*d++ = *s++;\
|
||||
buf_out+=32;\
|
||||
}\
|
||||
}\
|
||||
*buf_out++ = 0xE1U;\
|
||||
}
|
||||
|
||||
#define PREPARE_HOOKSET(buf_out_master, maxlen, h, sizeout)\
|
||||
{\
|
||||
uint8_t* buf_out = (buf_out_master); \
|
||||
uint8_t acc[20]; \
|
||||
uint32_t cls = (uint32_t)ledger_seq(); \
|
||||
hook_account(SBUF(acc)); \
|
||||
_01_02_ENCODE_TT (buf_out, ttHOOK_SET ); \
|
||||
_02_02_ENCODE_FLAGS (buf_out, tfCANONICAL ); \
|
||||
_02_04_ENCODE_SEQUENCE (buf_out, 0 ); \
|
||||
_02_26_ENCODE_FLS (buf_out, cls + 1 ); \
|
||||
_02_27_ENCODE_LLS (buf_out, cls + 5 ); \
|
||||
uint8_t* fee_ptr = buf_out; \
|
||||
_06_08_ENCODE_DROPS_FEE (buf_out, 0 ); \
|
||||
_07_03_ENCODE_SIGNING_PUBKEY_NULL (buf_out ); \
|
||||
_08_01_ENCODE_ACCOUNT_SRC (buf_out, acc ); \
|
||||
uint32_t remaining_size = (maxlen) - (buf_out - (buf_out_master)); \
|
||||
int64_t edlen = etxn_details((uint32_t)buf_out, remaining_size); \
|
||||
buf_out += edlen; \
|
||||
*buf_out++ = 0xFBU; /* hook array start */ \
|
||||
_0E_0E_ENCODE_HOOKOBJ (buf_out, h[0]); \
|
||||
_0E_0E_ENCODE_HOOKOBJ (buf_out, h[1]); \
|
||||
_0E_0E_ENCODE_HOOKOBJ (buf_out, h[2]); \
|
||||
_0E_0E_ENCODE_HOOKOBJ (buf_out, h[3]); \
|
||||
_0E_0E_ENCODE_HOOKOBJ (buf_out, h[4]); \
|
||||
_0E_0E_ENCODE_HOOKOBJ (buf_out, h[5]); \
|
||||
_0E_0E_ENCODE_HOOKOBJ (buf_out, h[6]); \
|
||||
_0E_0E_ENCODE_HOOKOBJ (buf_out, h[7]); \
|
||||
_0E_0E_ENCODE_HOOKOBJ (buf_out, h[8]); \
|
||||
_0E_0E_ENCODE_HOOKOBJ (buf_out, h[9]); \
|
||||
*buf_out++ = 0xF1U; /* hook array end */ \
|
||||
sizeout = (buf_out - (buf_out_master)); \
|
||||
int64_t fee = etxn_fee_base(buf_out_master, sizeout); \
|
||||
_06_08_ENCODE_DROPS_FEE (fee_ptr, fee ); \
|
||||
}
|
||||
|
||||
#ifdef HAS_CALLBACK
|
||||
#define PREPARE_PAYMENT_SIMPLE_SIZE 270U
|
||||
#else
|
||||
#define PREPARE_PAYMENT_SIMPLE_SIZE 248U
|
||||
#endif
|
||||
|
||||
#define PREPARE_PAYMENT_SIMPLE(buf_out_master, drops_amount_raw, to_address, dest_tag_raw, src_tag_raw)\
|
||||
{\
|
||||
uint8_t* buf_out = buf_out_master;\
|
||||
uint8_t acc[20];\
|
||||
uint64_t drops_amount = (drops_amount_raw);\
|
||||
uint32_t dest_tag = (dest_tag_raw);\
|
||||
uint32_t src_tag = (src_tag_raw);\
|
||||
uint32_t cls = (uint32_t)ledger_seq();\
|
||||
hook_account(SBUF(acc));\
|
||||
_01_02_ENCODE_TT (buf_out, ttPAYMENT ); /* uint16 | size 3 */ \
|
||||
_02_02_ENCODE_FLAGS (buf_out, tfCANONICAL ); /* uint32 | size 5 */ \
|
||||
_02_03_ENCODE_TAG_SRC (buf_out, src_tag ); /* uint32 | size 5 */ \
|
||||
_02_04_ENCODE_SEQUENCE (buf_out, 0 ); /* uint32 | size 5 */ \
|
||||
_02_14_ENCODE_TAG_DST (buf_out, dest_tag ); /* uint32 | size 5 */ \
|
||||
_02_26_ENCODE_FLS (buf_out, cls + 1 ); /* uint32 | size 6 */ \
|
||||
_02_27_ENCODE_LLS (buf_out, cls + 5 ); /* uint32 | size 6 */ \
|
||||
_06_01_ENCODE_DROPS_AMOUNT (buf_out, drops_amount ); /* amount | size 9 */ \
|
||||
uint8_t* fee_ptr = buf_out;\
|
||||
_06_08_ENCODE_DROPS_FEE (buf_out, 0 ); /* amount | size 9 */ \
|
||||
_07_03_ENCODE_SIGNING_PUBKEY_NULL (buf_out ); /* pk | size 35 */ \
|
||||
_08_01_ENCODE_ACCOUNT_SRC (buf_out, acc ); /* account | size 22 */ \
|
||||
_08_03_ENCODE_ACCOUNT_DST (buf_out, to_address ); /* account | size 22 */ \
|
||||
int64_t edlen = etxn_details((uint32_t)buf_out, PREPARE_PAYMENT_SIMPLE_SIZE); /* emitdet | size 1?? */ \
|
||||
int64_t fee = etxn_fee_base(buf_out_master, PREPARE_PAYMENT_SIMPLE_SIZE); \
|
||||
_06_08_ENCODE_DROPS_FEE (fee_ptr, fee ); \
|
||||
}
|
||||
|
||||
#ifdef HAS_CALLBACK
|
||||
#define PREPARE_PAYMENT_SIMPLE_TRUSTLINE_SIZE 309
|
||||
#else
|
||||
#define PREPARE_PAYMENT_SIMPLE_TRUSTLINE_SIZE 287
|
||||
#endif
|
||||
#define PREPARE_PAYMENT_SIMPLE_TRUSTLINE(buf_out_master, tlamt, to_address, dest_tag_raw, src_tag_raw)\
|
||||
{\
|
||||
uint8_t* buf_out = buf_out_master;\
|
||||
uint8_t acc[20];\
|
||||
uint32_t dest_tag = (dest_tag_raw);\
|
||||
uint32_t src_tag = (src_tag_raw);\
|
||||
uint32_t cls = (uint32_t)ledger_seq();\
|
||||
hook_account(SBUF(acc));\
|
||||
_01_02_ENCODE_TT (buf_out, ttPAYMENT ); /* uint16 | size 3 */ \
|
||||
_02_02_ENCODE_FLAGS (buf_out, tfCANONICAL ); /* uint32 | size 5 */ \
|
||||
_02_03_ENCODE_TAG_SRC (buf_out, src_tag ); /* uint32 | size 5 */ \
|
||||
_02_04_ENCODE_SEQUENCE (buf_out, 0 ); /* uint32 | size 5 */ \
|
||||
_02_14_ENCODE_TAG_DST (buf_out, dest_tag ); /* uint32 | size 5 */ \
|
||||
_02_26_ENCODE_FLS (buf_out, cls + 1 ); /* uint32 | size 6 */ \
|
||||
_02_27_ENCODE_LLS (buf_out, cls + 5 ); /* uint32 | size 6 */ \
|
||||
_06_01_ENCODE_TL_AMOUNT (buf_out, tlamt ); /* amount | size 48 */ \
|
||||
uint8_t* fee_ptr = buf_out;\
|
||||
_06_08_ENCODE_DROPS_FEE (buf_out, 0 ); /* amount | size 9 */ \
|
||||
_07_03_ENCODE_SIGNING_PUBKEY_NULL (buf_out ); /* pk | size 35 */ \
|
||||
_08_01_ENCODE_ACCOUNT_SRC (buf_out, acc ); /* account | size 22 */ \
|
||||
_08_03_ENCODE_ACCOUNT_DST (buf_out, to_address ); /* account | size 22 */ \
|
||||
etxn_details((uint32_t)buf_out, PREPARE_PAYMENT_SIMPLE_TRUSTLINE_SIZE); /* emitdet | size 1?? */ \
|
||||
int64_t fee = etxn_fee_base(buf_out_master, PREPARE_PAYMENT_SIMPLE_TRUSTLINE_SIZE); \
|
||||
_06_08_ENCODE_DROPS_FEE (fee_ptr, fee ); \
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,215 +0,0 @@
|
||||
// For documentation please see: https://xrpl-hooks.readme.io/reference/
|
||||
// Generated using generate_sfcodes.sh
|
||||
#define sfCloseResolution ((16U << 16U) + 1U)
|
||||
#define sfMethod ((16U << 16U) + 2U)
|
||||
#define sfTransactionResult ((16U << 16U) + 3U)
|
||||
#define sfTickSize ((16U << 16U) + 16U)
|
||||
#define sfUNLModifyDisabling ((16U << 16U) + 17U)
|
||||
#define sfHookResult ((16U << 16U) + 18U)
|
||||
#define sfLedgerEntryType ((1U << 16U) + 1U)
|
||||
#define sfTransactionType ((1U << 16U) + 2U)
|
||||
#define sfSignerWeight ((1U << 16U) + 3U)
|
||||
#define sfTransferFee ((1U << 16U) + 4U)
|
||||
#define sfVersion ((1U << 16U) + 16U)
|
||||
#define sfHookStateChangeCount ((1U << 16U) + 17U)
|
||||
#define sfHookEmitCount ((1U << 16U) + 18U)
|
||||
#define sfHookExecutionIndex ((1U << 16U) + 19U)
|
||||
#define sfHookApiVersion ((1U << 16U) + 20U)
|
||||
#define sfNetworkID ((2U << 16U) + 1U)
|
||||
#define sfFlags ((2U << 16U) + 2U)
|
||||
#define sfSourceTag ((2U << 16U) + 3U)
|
||||
#define sfSequence ((2U << 16U) + 4U)
|
||||
#define sfPreviousTxnLgrSeq ((2U << 16U) + 5U)
|
||||
#define sfLedgerSequence ((2U << 16U) + 6U)
|
||||
#define sfCloseTime ((2U << 16U) + 7U)
|
||||
#define sfParentCloseTime ((2U << 16U) + 8U)
|
||||
#define sfSigningTime ((2U << 16U) + 9U)
|
||||
#define sfExpiration ((2U << 16U) + 10U)
|
||||
#define sfTransferRate ((2U << 16U) + 11U)
|
||||
#define sfWalletSize ((2U << 16U) + 12U)
|
||||
#define sfOwnerCount ((2U << 16U) + 13U)
|
||||
#define sfDestinationTag ((2U << 16U) + 14U)
|
||||
#define sfHighQualityIn ((2U << 16U) + 16U)
|
||||
#define sfHighQualityOut ((2U << 16U) + 17U)
|
||||
#define sfLowQualityIn ((2U << 16U) + 18U)
|
||||
#define sfLowQualityOut ((2U << 16U) + 19U)
|
||||
#define sfQualityIn ((2U << 16U) + 20U)
|
||||
#define sfQualityOut ((2U << 16U) + 21U)
|
||||
#define sfStampEscrow ((2U << 16U) + 22U)
|
||||
#define sfBondAmount ((2U << 16U) + 23U)
|
||||
#define sfLoadFee ((2U << 16U) + 24U)
|
||||
#define sfOfferSequence ((2U << 16U) + 25U)
|
||||
#define sfFirstLedgerSequence ((2U << 16U) + 26U)
|
||||
#define sfLastLedgerSequence ((2U << 16U) + 27U)
|
||||
#define sfTransactionIndex ((2U << 16U) + 28U)
|
||||
#define sfOperationLimit ((2U << 16U) + 29U)
|
||||
#define sfReferenceFeeUnits ((2U << 16U) + 30U)
|
||||
#define sfReserveBase ((2U << 16U) + 31U)
|
||||
#define sfReserveIncrement ((2U << 16U) + 32U)
|
||||
#define sfSetFlag ((2U << 16U) + 33U)
|
||||
#define sfClearFlag ((2U << 16U) + 34U)
|
||||
#define sfSignerQuorum ((2U << 16U) + 35U)
|
||||
#define sfCancelAfter ((2U << 16U) + 36U)
|
||||
#define sfFinishAfter ((2U << 16U) + 37U)
|
||||
#define sfSignerListID ((2U << 16U) + 38U)
|
||||
#define sfSettleDelay ((2U << 16U) + 39U)
|
||||
#define sfTicketCount ((2U << 16U) + 40U)
|
||||
#define sfTicketSequence ((2U << 16U) + 41U)
|
||||
#define sfNFTokenTaxon ((2U << 16U) + 42U)
|
||||
#define sfMintedNFTokens ((2U << 16U) + 43U)
|
||||
#define sfBurnedNFTokens ((2U << 16U) + 44U)
|
||||
#define sfHookStateCount ((2U << 16U) + 45U)
|
||||
#define sfEmitGeneration ((2U << 16U) + 46U)
|
||||
#define sfLockCount ((2U << 16U) + 47U)
|
||||
#define sfRewardTime ((2U << 16U) + 98U)
|
||||
#define sfRewardLgrFirst ((2U << 16U) + 99U)
|
||||
#define sfRewardLgrLast ((2U << 16U) + 100U)
|
||||
#define sfIndexNext ((3U << 16U) + 1U)
|
||||
#define sfIndexPrevious ((3U << 16U) + 2U)
|
||||
#define sfBookNode ((3U << 16U) + 3U)
|
||||
#define sfOwnerNode ((3U << 16U) + 4U)
|
||||
#define sfBaseFee ((3U << 16U) + 5U)
|
||||
#define sfExchangeRate ((3U << 16U) + 6U)
|
||||
#define sfLowNode ((3U << 16U) + 7U)
|
||||
#define sfHighNode ((3U << 16U) + 8U)
|
||||
#define sfDestinationNode ((3U << 16U) + 9U)
|
||||
#define sfCookie ((3U << 16U) + 10U)
|
||||
#define sfServerVersion ((3U << 16U) + 11U)
|
||||
#define sfNFTokenOfferNode ((3U << 16U) + 12U)
|
||||
#define sfEmitBurden ((3U << 16U) + 13U)
|
||||
#define sfHookInstructionCount ((3U << 16U) + 17U)
|
||||
#define sfHookReturnCode ((3U << 16U) + 18U)
|
||||
#define sfReferenceCount ((3U << 16U) + 19U)
|
||||
#define sfRewardAccumulator ((3U << 16U) + 100U)
|
||||
#define sfEmailHash ((4U << 16U) + 1U)
|
||||
#define sfTakerPaysCurrency ((10U << 16U) + 1U)
|
||||
#define sfTakerPaysIssuer ((10U << 16U) + 2U)
|
||||
#define sfTakerGetsCurrency ((10U << 16U) + 3U)
|
||||
#define sfTakerGetsIssuer ((10U << 16U) + 4U)
|
||||
#define sfLedgerHash ((5U << 16U) + 1U)
|
||||
#define sfParentHash ((5U << 16U) + 2U)
|
||||
#define sfTransactionHash ((5U << 16U) + 3U)
|
||||
#define sfAccountHash ((5U << 16U) + 4U)
|
||||
#define sfPreviousTxnID ((5U << 16U) + 5U)
|
||||
#define sfLedgerIndex ((5U << 16U) + 6U)
|
||||
#define sfWalletLocator ((5U << 16U) + 7U)
|
||||
#define sfRootIndex ((5U << 16U) + 8U)
|
||||
#define sfAccountTxnID ((5U << 16U) + 9U)
|
||||
#define sfNFTokenID ((5U << 16U) + 10U)
|
||||
#define sfEmitParentTxnID ((5U << 16U) + 11U)
|
||||
#define sfEmitNonce ((5U << 16U) + 12U)
|
||||
#define sfEmitHookHash ((5U << 16U) + 13U)
|
||||
#define sfBookDirectory ((5U << 16U) + 16U)
|
||||
#define sfInvoiceID ((5U << 16U) + 17U)
|
||||
#define sfNickname ((5U << 16U) + 18U)
|
||||
#define sfAmendment ((5U << 16U) + 19U)
|
||||
#define sfHookOn ((5U << 16U) + 20U)
|
||||
#define sfDigest ((5U << 16U) + 21U)
|
||||
#define sfChannel ((5U << 16U) + 22U)
|
||||
#define sfConsensusHash ((5U << 16U) + 23U)
|
||||
#define sfCheckID ((5U << 16U) + 24U)
|
||||
#define sfValidatedHash ((5U << 16U) + 25U)
|
||||
#define sfPreviousPageMin ((5U << 16U) + 26U)
|
||||
#define sfNextPageMin ((5U << 16U) + 27U)
|
||||
#define sfNFTokenBuyOffer ((5U << 16U) + 28U)
|
||||
#define sfNFTokenSellOffer ((5U << 16U) + 29U)
|
||||
#define sfHookStateKey ((5U << 16U) + 30U)
|
||||
#define sfHookHash ((5U << 16U) + 31U)
|
||||
#define sfHookNamespace ((5U << 16U) + 32U)
|
||||
#define sfHookSetTxnID ((5U << 16U) + 33U)
|
||||
#define sfOfferID ((5U << 16U) + 34U)
|
||||
#define sfEscrowID ((5U << 16U) + 35U)
|
||||
#define sfURITokenID ((5U << 16U) + 36U)
|
||||
#define sfAmount ((6U << 16U) + 1U)
|
||||
#define sfBalance ((6U << 16U) + 2U)
|
||||
#define sfLimitAmount ((6U << 16U) + 3U)
|
||||
#define sfTakerPays ((6U << 16U) + 4U)
|
||||
#define sfTakerGets ((6U << 16U) + 5U)
|
||||
#define sfLowLimit ((6U << 16U) + 6U)
|
||||
#define sfHighLimit ((6U << 16U) + 7U)
|
||||
#define sfFee ((6U << 16U) + 8U)
|
||||
#define sfSendMax ((6U << 16U) + 9U)
|
||||
#define sfDeliverMin ((6U << 16U) + 10U)
|
||||
#define sfMinimumOffer ((6U << 16U) + 16U)
|
||||
#define sfRippleEscrow ((6U << 16U) + 17U)
|
||||
#define sfDeliveredAmount ((6U << 16U) + 18U)
|
||||
#define sfNFTokenBrokerFee ((6U << 16U) + 19U)
|
||||
#define sfHookCallbackFee ((6U << 16U) + 20U)
|
||||
#define sfLockedBalance ((6U << 16U) + 21U)
|
||||
#define sfPublicKey ((7U << 16U) + 1U)
|
||||
#define sfMessageKey ((7U << 16U) + 2U)
|
||||
#define sfSigningPubKey ((7U << 16U) + 3U)
|
||||
#define sfTxnSignature ((7U << 16U) + 4U)
|
||||
#define sfURI ((7U << 16U) + 5U)
|
||||
#define sfSignature ((7U << 16U) + 6U)
|
||||
#define sfDomain ((7U << 16U) + 7U)
|
||||
#define sfFundCode ((7U << 16U) + 8U)
|
||||
#define sfRemoveCode ((7U << 16U) + 9U)
|
||||
#define sfExpireCode ((7U << 16U) + 10U)
|
||||
#define sfCreateCode ((7U << 16U) + 11U)
|
||||
#define sfMemoType ((7U << 16U) + 12U)
|
||||
#define sfMemoData ((7U << 16U) + 13U)
|
||||
#define sfMemoFormat ((7U << 16U) + 14U)
|
||||
#define sfFulfillment ((7U << 16U) + 16U)
|
||||
#define sfCondition ((7U << 16U) + 17U)
|
||||
#define sfMasterSignature ((7U << 16U) + 18U)
|
||||
#define sfUNLModifyValidator ((7U << 16U) + 19U)
|
||||
#define sfValidatorToDisable ((7U << 16U) + 20U)
|
||||
#define sfValidatorToReEnable ((7U << 16U) + 21U)
|
||||
#define sfHookStateData ((7U << 16U) + 22U)
|
||||
#define sfHookReturnString ((7U << 16U) + 23U)
|
||||
#define sfHookParameterName ((7U << 16U) + 24U)
|
||||
#define sfHookParameterValue ((7U << 16U) + 25U)
|
||||
#define sfBlob ((7U << 16U) + 26U)
|
||||
#define sfAccount ((8U << 16U) + 1U)
|
||||
#define sfOwner ((8U << 16U) + 2U)
|
||||
#define sfDestination ((8U << 16U) + 3U)
|
||||
#define sfIssuer ((8U << 16U) + 4U)
|
||||
#define sfAuthorize ((8U << 16U) + 5U)
|
||||
#define sfUnauthorize ((8U << 16U) + 6U)
|
||||
#define sfRegularKey ((8U << 16U) + 8U)
|
||||
#define sfNFTokenMinter ((8U << 16U) + 9U)
|
||||
#define sfEmitCallback ((8U << 16U) + 10U)
|
||||
#define sfHookAccount ((8U << 16U) + 16U)
|
||||
#define sfIndexes ((19U << 16U) + 1U)
|
||||
#define sfHashes ((19U << 16U) + 2U)
|
||||
#define sfAmendments ((19U << 16U) + 3U)
|
||||
#define sfNFTokenOffers ((19U << 16U) + 4U)
|
||||
#define sfHookNamespaces ((19U << 16U) + 5U)
|
||||
#define sfPaths ((18U << 16U) + 1U)
|
||||
#define sfTransactionMetaData ((14U << 16U) + 2U)
|
||||
#define sfCreatedNode ((14U << 16U) + 3U)
|
||||
#define sfDeletedNode ((14U << 16U) + 4U)
|
||||
#define sfModifiedNode ((14U << 16U) + 5U)
|
||||
#define sfPreviousFields ((14U << 16U) + 6U)
|
||||
#define sfFinalFields ((14U << 16U) + 7U)
|
||||
#define sfNewFields ((14U << 16U) + 8U)
|
||||
#define sfTemplateEntry ((14U << 16U) + 9U)
|
||||
#define sfMemo ((14U << 16U) + 10U)
|
||||
#define sfSignerEntry ((14U << 16U) + 11U)
|
||||
#define sfNFToken ((14U << 16U) + 12U)
|
||||
#define sfEmitDetails ((14U << 16U) + 13U)
|
||||
#define sfHook ((14U << 16U) + 14U)
|
||||
#define sfSigner ((14U << 16U) + 16U)
|
||||
#define sfMajority ((14U << 16U) + 18U)
|
||||
#define sfDisabledValidator ((14U << 16U) + 19U)
|
||||
#define sfEmittedTxn ((14U << 16U) + 20U)
|
||||
#define sfHookExecution ((14U << 16U) + 21U)
|
||||
#define sfHookDefinition ((14U << 16U) + 22U)
|
||||
#define sfHookParameter ((14U << 16U) + 23U)
|
||||
#define sfHookGrant ((14U << 16U) + 24U)
|
||||
#define sfSigners ((15U << 16U) + 3U)
|
||||
#define sfSignerEntries ((15U << 16U) + 4U)
|
||||
#define sfTemplate ((15U << 16U) + 5U)
|
||||
#define sfNecessary ((15U << 16U) + 6U)
|
||||
#define sfSufficient ((15U << 16U) + 7U)
|
||||
#define sfAffectedNodes ((15U << 16U) + 8U)
|
||||
#define sfMemos ((15U << 16U) + 9U)
|
||||
#define sfNFTokens ((15U << 16U) + 10U)
|
||||
#define sfHooks ((15U << 16U) + 11U)
|
||||
#define sfMajorities ((15U << 16U) + 16U)
|
||||
#define sfDisabledValidators ((15U << 16U) + 17U)
|
||||
#define sfHookExecutions ((15U << 16U) + 18U)
|
||||
#define sfHookParameters ((15U << 16U) + 19U)
|
||||
#define sfHookGrants ((15U << 16U) + 20U)
|
||||
#define sfActiveValidators ((15U << 16U) + 95U)
|
||||
@@ -1,239 +0,0 @@
|
||||
#include <stdint.h>
|
||||
|
||||
// 8 byte-int = 1 bytes
|
||||
#define SFL_CLOSERESOLUTION 1
|
||||
#define SFL_METHOD 1
|
||||
#define SFL_TRANSACTIONRESULT 1
|
||||
#define SFL_TICKSIZE 1
|
||||
#define SFL_UNLMODIFYDISABLING 1
|
||||
#define SFL_HOOKRESULT 1
|
||||
// 16 byte-int = 2 bytes
|
||||
#define SFL_LEDGERENTRYTYPE 2
|
||||
#define SFL_TRANSACTIONTYPE 2
|
||||
#define SFL_SIGNERWEIGHT 2
|
||||
#define SFL_TRANSFERFEE 2
|
||||
#define SFL_VERSION 2
|
||||
#define SFL_HOOKSTATECHANGECOUNT 2
|
||||
#define SFL_HOOKEMITCOUNT 2
|
||||
#define SFL_HOOKEXECUTIONINDEX 2
|
||||
#define SFL_HOOKAPIVERSION 2
|
||||
// 32 byte-int = 4 bytes
|
||||
#define SFL_NETWORKID 4
|
||||
#define SFL_FLAGS 4
|
||||
#define SFL_SOURCETAG 4
|
||||
#define SFL_SEQUENCE 4
|
||||
#define SFL_PREVIOUSTXNLGRSEQ 4
|
||||
#define SFL_LEDGERSEQUENCE 4
|
||||
#define SFL_CLOSETIME 4
|
||||
#define SFL_PARENTCLOSETIME 4
|
||||
#define SFL_SIGNINGTIME 4
|
||||
#define SFL_EXPIRATION 4
|
||||
#define SFL_TRANSFERRATE 4
|
||||
#define SFL_WALLETSIZE 4
|
||||
#define SFL_OWNERCOUNT 4
|
||||
#define SFL_DESTINATIONTAG 4
|
||||
#define SFL_HIGHQUALITYIN 4
|
||||
#define SFL_HIGHQUALITYOUT 4
|
||||
#define SFL_LOWQUALITYIN 4
|
||||
#define SFL_LOWQUALITYOUT 4
|
||||
#define SFL_QUALITYIN 4
|
||||
#define SFL_QUALITYOUT 4
|
||||
#define SFL_STAMPESCROW 4
|
||||
#define SFL_BONDAMOUNT 4
|
||||
#define SFL_LOADFEE 4
|
||||
#define SFL_OFFERSEQUENCE 4
|
||||
#define SFL_FIRSTLEDGERSEQUENCE 4
|
||||
#define SFL_LASTLEDGERSEQUENCE 4
|
||||
#define SFL_TRANSACTIONINDEX 4
|
||||
#define SFL_OPERATIONLIMIT 4
|
||||
#define SFL_REFERENCEFEEUNITS 4
|
||||
#define SFL_RESERVEBASE 4
|
||||
#define SFL_RESERVEINCREMENT 4
|
||||
#define SFL_SETFLAG 4
|
||||
#define SFL_CLEARFLAG 4
|
||||
#define SFL_SIGNERQUORUM 4
|
||||
#define SFL_CANCELAFTER 4
|
||||
#define SFL_FINISHAFTER 4
|
||||
#define SFL_SIGNERLISTID 4
|
||||
#define SFL_SETTLEDELAY 4
|
||||
#define SFL_TICKETCOUNT 4
|
||||
#define SFL_TICKETSEQUENCE 4
|
||||
#define SFL_NFTOKENTAXON 4
|
||||
#define SFL_MINTEDNFTOKENS 4
|
||||
#define SFL_BURNEDNFTOKENS 4
|
||||
#define SFL_HOOKSTATECOUNT 4
|
||||
#define SFL_EMITGENERATION 4
|
||||
#define SFL_LOCKCOUNT 4
|
||||
#define SFL_REWARDTIME 4
|
||||
#define SFL_REWARDLGRFIRST 4
|
||||
#define SFL_REWARDLGRLAST 4
|
||||
#define SFL_FIRSTNFTOKENSEQUENCE 4
|
||||
// 64 byte-int = 8 bytes
|
||||
#define SFL_INDEX_NEXT 8
|
||||
#define SFL_INDEX_PREVIOUS 8
|
||||
#define SFL_BOOK_NODE 8
|
||||
#define SFL_OWNER_NODE 8
|
||||
#define SFL_BASE_FEE 8
|
||||
#define SFL_EXCHANGE_RATE 8
|
||||
#define SFL_LOW_NODE 8
|
||||
#define SFL_HIGH_NODE 8
|
||||
#define SFL_DESTINATION_NODE 8
|
||||
#define SFL_COOKIE 8
|
||||
#define SFL_SERVER_VERSION 8
|
||||
#define SFL_EMIT_BURDEN 8
|
||||
#define SFL_NFTOKEN_OFFER_NODE 8
|
||||
#define SFL_HOOK_INSTRUCTION_COUNT 8
|
||||
#define SFL_HOOK_RETURN_CODE 8
|
||||
#define SFL_REFERENCE_COUNT 8
|
||||
#define SFL_REWARD_ACCUMULATOR 8
|
||||
// 128 byte-int = 4 bytes
|
||||
#define SFL_EMAIL_HASH 128
|
||||
// 160 byte-int = 4 bytes
|
||||
#define SFL_TAKER_PAYS_CURRENCY 160
|
||||
#define SFL_TAKER_PAYS_ISSUER 160
|
||||
#define SFL_TAKER_GETS_CURRENCY 160
|
||||
#define SFL_TAKER_GETS_ISSUER 160
|
||||
// 256 byte-int = ??? bytes
|
||||
#define SFL_LEDGER_HASH 256
|
||||
#define SFL_PARENT_HASH 256
|
||||
#define SFL_TRANSACTION_HASH 256
|
||||
#define SFL_ACCOUNT_HASH 256
|
||||
#define SFL_HOOK_ON 256
|
||||
#define SFL_PREVIOUS_TXN_ID 256
|
||||
#define SFL_LEDGER_INDEX 256
|
||||
#define SFL_WALLET_LOCATOR 256
|
||||
#define SFL_ROOT_INDEX 256
|
||||
#define SFL_ACCOUNT_TXN_ID 256
|
||||
#define SFL_NFTOKEN_ID 256
|
||||
#define SFL_EMIT_PARENT_TXN_ID 256
|
||||
#define SFL_EMIT_NONCE 256
|
||||
#define SFL_EMIT_HOOK_HASH 256
|
||||
// 256 byte-int = ??? bytes
|
||||
#define SFL_BOOK_DIRECTORY 256
|
||||
#define SFL_INVOICE_ID 256
|
||||
#define SFL_NICKNAME 256
|
||||
#define SFL_AMENDMENT 256
|
||||
#define SFL_DIGEST 256
|
||||
#define SFL_CHANNEL 256
|
||||
#define SFL_CONSENSUS_HASH 256
|
||||
#define SFL_CHECK_ID 256
|
||||
#define SFL_VALIDATED_HASH 256
|
||||
#define SFL_PREVIOUS_PAGE_MIN 256
|
||||
#define SFL_NEXT_PAGE_MIN 256
|
||||
#define SFL_NFTOKEN_BUY_OFFER 256
|
||||
#define SFL_NFTOKEN_SELL_OFFER 256
|
||||
#define SFL_HOOK_STATE_KEY 256
|
||||
#define SFL_HOOK_HASH 256
|
||||
#define SFL_HOOK_NAMESPACE 256
|
||||
#define SFL_HOOK_SET_TXN_ID 256
|
||||
#define SFL_OFFER_ID 256
|
||||
#define SFL_ESCROW_ID 256
|
||||
#define SFL_URITOKEN_ID 256
|
||||
// 20 bytes
|
||||
#define SFL_AMOUNT 20
|
||||
#define SFL_BALANCE 20
|
||||
#define SFL_LIMIT_AMOUNT 20
|
||||
#define SFL_TAKER_PAYS 20
|
||||
#define SFL_TAKER_GETS 20
|
||||
#define SFL_LOW_LIMIT 20
|
||||
#define SFL_HIGH_LIMIT 20
|
||||
#define SFL_FEE 20
|
||||
#define SFL_SEND_MAX 20
|
||||
#define SFL_DELIVER_MIN 20
|
||||
#define SFL_LOCKED_BALANCE 20
|
||||
// Unimplemented
|
||||
#define SFL_AMOUNT_MINIMUM_OFFER 8
|
||||
#define SFL_AMOUNT_RIPPLE_ESCROW 8
|
||||
#define SFL_AMOUNT_DELIVERED_AMOUNT 8
|
||||
#define SFL_AMOUNT_NFTOKEN_BROKER_FEE 8
|
||||
#define SFL_AMOUNT_HOOK_CALLBACK_FEE 8
|
||||
#define SFL_AMOUNT_BASE_FEE_DROPS 8
|
||||
#define SFL_AMOUNT_RESERVE_BASE_DROPS 8
|
||||
#define SFL_AMOUNT_RESERVE_INCREMENT_DROPS 8
|
||||
// Unimplemented
|
||||
#define SFL_VL_PUBLIC_KEY 64
|
||||
#define SFL_VL_MESSAGE_KEY 64
|
||||
#define SFL_VL_SIGNING_PUB_KEY 64
|
||||
// Unimplemented
|
||||
#define SFL_VL_TXN_SIGNATURE 96
|
||||
// Unimplemented
|
||||
#define SFL_VL_URI 256
|
||||
// Unimplemented
|
||||
#define SFL_VL_SIGNATURE 96
|
||||
// Unimplemented
|
||||
#define SFL_VL_DOMAIN 256
|
||||
#define SFL_VL_FUND_CODE 256
|
||||
#define SFL_VL_REMOVE_CODE 256
|
||||
#define SFL_VL_EXPIRE_CODE 256
|
||||
#define SFL_VL_CREATE_CODE 256
|
||||
#define SFL_VL_MEMO_TYPE 256
|
||||
#define SFL_VL_MEMO_DATA 256
|
||||
#define SFL_VL_MEMO_FORMAT 256
|
||||
#define SFL_VL_FULFILLMENT 256
|
||||
#define SFL_VL_CONDITION 256
|
||||
// Unimplemented
|
||||
#define SFL_VL_MASTER_SIGNATURE 96
|
||||
// Unimplemented
|
||||
#define SFL_VL_UNL_MODIFY_VALIDATOR 256
|
||||
#define SFL_VL_VALIDATOR_TO_DISABLE 256
|
||||
#define SFL_VL_VALIDATOR_TO_RE_ENABLE 256
|
||||
#define SFL_VL_HOOK_STATE_DATA 256
|
||||
#define SFL_VL_HOOK_RETURN_STRING 256
|
||||
#define SFL_VL_HOOK_PARAMETER_NAME 256
|
||||
#define SFL_VL_HOOK_PARAMETER_VALUE 256
|
||||
#define SFL_VL_BLOB 256
|
||||
// 20 bytes
|
||||
#define SFL_ACCOUNT 20
|
||||
#define SFL_OWNER 20
|
||||
#define SFL_DESTINATION 20
|
||||
#define SFL_ISSUER 20
|
||||
#define SFL_AUTHORIZE 20
|
||||
#define SFL_UNAUTHORIZE 20
|
||||
#define SFL_REGULAR_KEY 20
|
||||
#define SFL_NFTOKEN_MINTER 20
|
||||
#define SFL_EMIT_CALLBACK 20
|
||||
#define SFL_HOOK_ACCOUNT 20
|
||||
#define SFL_NFTOKEN_MINTER 20
|
||||
// Unimplemented
|
||||
#define SFL_PATHS 1
|
||||
// Unimplemented
|
||||
#define SFL_VECTOR256_INDEXES 32
|
||||
#define SFL_VECTOR256_HASHES 32
|
||||
#define SFL_VECTOR256_AMENDMENTS 32
|
||||
#define SFL_VECTOR256_NFTOKEN_OFFERS 32
|
||||
#define SFL_VECTOR256_HOOK_NAMESPACES 32
|
||||
// Unimplemented
|
||||
#define SFL_TRANSACTION_META_DATA 1
|
||||
#define SFL_CREATED_NODE 1
|
||||
#define SFL_DELETED_NODE 1
|
||||
#define SFL_MODIFIED_NODE 1
|
||||
#define SFL_PREVIOUS_FIELDS 1
|
||||
#define SFL_FINAL_FIELDS 1
|
||||
#define SFL_NEW_FIELDS 1
|
||||
#define SFL_TEMPLATE_ENTRY 1
|
||||
#define SFL_MEMO 1
|
||||
#define SFL_SIGNER_ENTRY 1
|
||||
#define SFL_NFTOKEN 1
|
||||
#define SFL_EMIT_DETAILS 1
|
||||
#define SFL_HOOK 1
|
||||
#define SFL_SIGNER 1
|
||||
#define SFL_MAJORITY 1
|
||||
#define SFL_DISABLED_VALIDATOR 1
|
||||
#define SFL_EMITTED_TXN 1
|
||||
#define SFL_HOOK_EXECUTION 1
|
||||
#define SFL_HOOK_DEFINITION 1
|
||||
#define SFL_HOOK_PARAMETER 1
|
||||
#define SFL_HOOK_GRANT 1
|
||||
#define SFL_SIGNERS 1
|
||||
#define SFL_SIGNER_ENTRIES 1
|
||||
#define SFL_TEMPLATE 1
|
||||
#define SFL_NECESSARY 1
|
||||
#define SFL_SUFFICIENT 1
|
||||
#define SFL_AFFECTED_NODES 1
|
||||
#define SFL_MEMOS 1
|
||||
#define SFL_NFTOKENS 1
|
||||
#define SFL_HOOKS 1
|
||||
#define SFL_MAJORITIES 1
|
||||
#define SFL_DISABLED_VALIDATORS 1
|
||||
#define SFL_HOOK_EXECUTIONS 1
|
||||
#define SFL_HOOK_EXECUTION 1
|
||||
@@ -1,9 +1,9 @@
|
||||
all: reward govern mint
|
||||
accept:
|
||||
wasmcc accept.c -o accept.wasm -Oz -Wl,--allow-undefined -I./headers
|
||||
wasmcc accept.c -o accept.wasm -Oz -Wl,--allow-undefined -I../
|
||||
hook-cleaner accept.wasm
|
||||
reward:
|
||||
wasmcc reward.c -o reward.wasm -Oz -Wl,--allow-undefined -I./headers
|
||||
wasmcc reward.c -o reward.wasm -Oz -Wl,--allow-undefined -I../
|
||||
wasm-opt reward.wasm -o reward.wasm \
|
||||
--shrink-level=100000000 \
|
||||
--coalesce-locals-learning \
|
||||
@@ -58,7 +58,7 @@ reward:
|
||||
hook-cleaner reward.wasm
|
||||
guard_checker reward.wasm
|
||||
govern:
|
||||
wasmcc govern.c -o govern.wasm -Oz -Wl,--allow-undefined -I./headers
|
||||
wasmcc govern.c -o govern.wasm -Oz -Wl,--allow-undefined -I../
|
||||
wasm-opt govern.wasm -o govern.wasm \
|
||||
--shrink-level=100000000 \
|
||||
--coalesce-locals-learning \
|
||||
@@ -113,7 +113,7 @@ govern:
|
||||
hook-cleaner govern.wasm
|
||||
guard_checker govern.wasm
|
||||
mint:
|
||||
wasmcc mint.c -o mint.wasm -Oz -Wl,--allow-undefined -I./headers
|
||||
wasmcc mint.c -o mint.wasm -Oz -Wl,--allow-undefined -I../
|
||||
wasm-opt mint.wasm -o mint.wasm \
|
||||
--shrink-level=100000000 \
|
||||
--coalesce-locals-learning \
|
||||
@@ -142,5 +142,5 @@ mint:
|
||||
hook-cleaner mint.wasm
|
||||
guard_checker mint.wasm
|
||||
nftoken:
|
||||
wasmcc nftoken.c -o nftoken.wasm -Oz -Wl,--allow-undefined -I./headers
|
||||
wasmcc nftoken.c -o nftoken.wasm -Oz -Wl,--allow-undefined -I../
|
||||
hook-cleaner nftoken.wasm
|
||||
|
||||
@@ -49,7 +49,4 @@
|
||||
#include "macro.h"
|
||||
#include "tts.h"
|
||||
|
||||
#include "ls_flags.h"
|
||||
#include "tx_flags.h"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
// Generated using generate_lsflags.sh
|
||||
|
||||
#ifndef HOOKLSFLAGS_INCLUDED
|
||||
#define HOOKLSFLAGS_INCLUDED 1
|
||||
|
||||
enum ltACCOUNT_ROOT {
|
||||
lsfPasswordSpent = 0x00010000,
|
||||
lsfRequireDestTag = 0x00020000,
|
||||
lsfRequireAuth = 0x00040000,
|
||||
lsfDisallowXRP = 0x00080000,
|
||||
lsfDisableMaster = 0x00100000,
|
||||
lsfNoFreeze = 0x00200000,
|
||||
lsfGlobalFreeze = 0x00400000,
|
||||
lsfDefaultRipple = 0x00800000,
|
||||
lsfDepositAuth = 0x01000000,
|
||||
lsfTshCollect = 0x02000000,
|
||||
lsfDisallowIncomingNFTokenOffer = 0x04000000,
|
||||
lsfDisallowIncomingCheck = 0x08000000,
|
||||
lsfDisallowIncomingPayChan = 0x10000000,
|
||||
lsfDisallowIncomingTrustline = 0x20000000,
|
||||
lsfURITokenIssuer = 0x40000000,
|
||||
lsfDisallowIncomingRemit = 0x80000000,
|
||||
lsfAllowTrustLineClawback = 0x00001000,
|
||||
};
|
||||
enum ltOFFER {
|
||||
lsfPassive = 0x00010000,
|
||||
lsfSell = 0x00020000,
|
||||
};
|
||||
enum ltRIPPLE_STATE {
|
||||
lsfLowReserve = 0x00010000,
|
||||
lsfHighReserve = 0x00020000,
|
||||
lsfLowAuth = 0x00040000,
|
||||
lsfHighAuth = 0x00080000,
|
||||
lsfLowNoRipple = 0x00100000,
|
||||
lsfHighNoRipple = 0x00200000,
|
||||
lsfLowFreeze = 0x00400000,
|
||||
lsfHighFreeze = 0x00800000,
|
||||
lsfLowDeepFreeze = 0x02000000,
|
||||
lsfHighDeepFreeze = 0x04000000,
|
||||
lsfAMMNode = 0x01000000,
|
||||
};
|
||||
enum ltSIGNER_LIST {
|
||||
lsfOneOwnerCount = 0x00010000,
|
||||
};
|
||||
enum ltDIR_NODE {
|
||||
lsfNFTokenBuyOffers = 0x00000001,
|
||||
lsfNFTokenSellOffers = 0x00000002,
|
||||
lsfEmittedDir = 0x00000004,
|
||||
};
|
||||
enum ltNFTOKEN_OFFER {
|
||||
lsfSellNFToken = 0x00000001,
|
||||
};
|
||||
enum ltURI_TOKEN {
|
||||
lsfBurnable = 0x00000001,
|
||||
};
|
||||
enum remarks {
|
||||
lsfImmutable = 1,
|
||||
};
|
||||
enum ltMPTOKEN_ISSUANCE {
|
||||
lsfMPTLocked = 0x00000001,
|
||||
lsfMPTCanLock = 0x00000002,
|
||||
lsfMPTRequireAuth = 0x00000004,
|
||||
lsfMPTCanEscrow = 0x00000008,
|
||||
lsfMPTCanTrade = 0x00000010,
|
||||
lsfMPTCanTransfer = 0x00000020,
|
||||
lsfMPTCanClawback = 0x00000040,
|
||||
};
|
||||
enum ltMPTOKEN {
|
||||
lsfMPTAuthorized = 0x00000002,
|
||||
};
|
||||
enum ltCREDENTIAL {
|
||||
lsfAccepted = 0x00010000,
|
||||
};
|
||||
|
||||
#endif // HOOKLSFLAGS_INCLUDED
|
||||
@@ -152,13 +152,11 @@
|
||||
#define sfEscrowID ((5U << 16U) + 35U)
|
||||
#define sfURITokenID ((5U << 16U) + 36U)
|
||||
#define sfDomainID ((5U << 16U) + 37U)
|
||||
#define sfHookOnOutgoing ((5U << 16U) + 93U)
|
||||
#define sfHookOnIncoming ((5U << 16U) + 94U)
|
||||
#define sfCron ((5U << 16U) + 95U)
|
||||
#define sfHookCanEmit ((5U << 16U) + 96U)
|
||||
#define sfEmittedTxnID ((5U << 16U) + 97U)
|
||||
#define sfGovernanceMarks ((5U << 16U) + 98U)
|
||||
#define sfGovernanceFlags ((5U << 16U) + 99U)
|
||||
#define sfGovernanceMarks ((5U << 16U) + 98U)
|
||||
#define sfEmittedTxnID ((5U << 16U) + 97U)
|
||||
#define sfHookCanEmit ((5U << 16U) + 96U)
|
||||
#define sfCron ((5U << 16U) + 95U)
|
||||
#define sfNumber ((9U << 16U) + 1U)
|
||||
#define sfAmount ((6U << 16U) + 1U)
|
||||
#define sfBalance ((6U << 16U) + 2U)
|
||||
@@ -189,7 +187,6 @@
|
||||
#define sfSignatureReward ((6U << 16U) + 29U)
|
||||
#define sfMinAccountCreateAmount ((6U << 16U) + 30U)
|
||||
#define sfLPTokenBalance ((6U << 16U) + 31U)
|
||||
#define sfTrustLineRewardAccumulator ((6U << 16U) + 99U)
|
||||
#define sfPublicKey ((7U << 16U) + 1U)
|
||||
#define sfMessageKey ((7U << 16U) + 2U)
|
||||
#define sfSigningPubKey ((7U << 16U) + 3U)
|
||||
@@ -221,7 +218,6 @@
|
||||
#define sfProvider ((7U << 16U) + 30U)
|
||||
#define sfMPTokenMetadata ((7U << 16U) + 31U)
|
||||
#define sfCredentialType ((7U << 16U) + 32U)
|
||||
#define sfHookName ((7U << 16U) + 97U)
|
||||
#define sfRemarkValue ((7U << 16U) + 98U)
|
||||
#define sfRemarkName ((7U << 16U) + 99U)
|
||||
#define sfAccount ((8U << 16U) + 1U)
|
||||
@@ -257,7 +253,6 @@
|
||||
#define sfIssuingChainIssue ((24U << 16U) + 2U)
|
||||
#define sfAsset ((24U << 16U) + 3U)
|
||||
#define sfAsset2 ((24U << 16U) + 4U)
|
||||
#define sfClaimCurrency ((24U << 16U) + 5U)
|
||||
#define sfXChainBridge ((25U << 16U) + 1U)
|
||||
#define sfTransactionMetaData ((14U << 16U) + 2U)
|
||||
#define sfCreatedNode ((14U << 16U) + 3U)
|
||||
@@ -277,6 +272,7 @@
|
||||
#define sfDisabledValidator ((14U << 16U) + 19U)
|
||||
#define sfEmittedTxn ((14U << 16U) + 20U)
|
||||
#define sfHookExecution ((14U << 16U) + 21U)
|
||||
#define sfHookDefinition ((14U << 16U) + 22U)
|
||||
#define sfHookParameter ((14U << 16U) + 23U)
|
||||
#define sfHookGrant ((14U << 16U) + 24U)
|
||||
#define sfVoteEntry ((14U << 16U) + 25U)
|
||||
@@ -295,8 +291,6 @@
|
||||
#define sfActiveValidator ((14U << 16U) + 95U)
|
||||
#define sfGenesisMint ((14U << 16U) + 96U)
|
||||
#define sfRemark ((14U << 16U) + 97U)
|
||||
#define sfHighReward ((14U << 16U) + 98U)
|
||||
#define sfLowReward ((14U << 16U) + 99U)
|
||||
#define sfSigners ((15U << 16U) + 3U)
|
||||
#define sfSignerEntries ((15U << 16U) + 4U)
|
||||
#define sfTemplate ((15U << 16U) + 5U)
|
||||
@@ -319,9 +313,9 @@
|
||||
#define sfAuthorizeCredentials ((15U << 16U) + 26U)
|
||||
#define sfUnauthorizeCredentials ((15U << 16U) + 27U)
|
||||
#define sfAcceptedCredentials ((15U << 16U) + 28U)
|
||||
#define sfAmounts ((15U << 16U) + 92U)
|
||||
#define sfHookEmissions ((15U << 16U) + 93U)
|
||||
#define sfImportVLKeys ((15U << 16U) + 94U)
|
||||
#define sfActiveValidators ((15U << 16U) + 95U)
|
||||
#define sfGenesisMints ((15U << 16U) + 96U)
|
||||
#define sfRemarks ((15U << 16U) + 97U)
|
||||
#define sfGenesisMints ((15U << 16U) + 96U)
|
||||
#define sfActiveValidators ((15U << 16U) + 95U)
|
||||
#define sfImportVLKeys ((15U << 16U) + 94U)
|
||||
#define sfHookEmissions ((15U << 16U) + 93U)
|
||||
#define sfAmounts ((15U << 16U) + 92U)
|
||||
|
||||
117
hook/tx_flags.h
117
hook/tx_flags.h
@@ -1,117 +0,0 @@
|
||||
// Generated using generate_txflags.sh
|
||||
#include "ls_flags.h"
|
||||
#include <stdint.h>
|
||||
|
||||
enum UniversalFlags : uint32_t {
|
||||
tfFullyCanonicalSig = 0x80000000,
|
||||
};
|
||||
|
||||
enum AccountSetFlags : uint32_t {
|
||||
tfRequireDestTag = 0x00010000,
|
||||
tfOptionalDestTag = 0x00020000,
|
||||
tfRequireAuth = 0x00040000,
|
||||
tfOptionalAuth = 0x00080000,
|
||||
tfDisallowXRP = 0x00100000,
|
||||
tfAllowXRP = 0x00200000,
|
||||
};
|
||||
|
||||
enum AccountFlags : uint32_t {
|
||||
asfRequireDest = 1,
|
||||
asfRequireAuth = 2,
|
||||
asfDisallowXRP = 3,
|
||||
asfDisableMaster = 4,
|
||||
asfAccountTxnID = 5,
|
||||
asfNoFreeze = 6,
|
||||
asfGlobalFreeze = 7,
|
||||
asfDefaultRipple = 8,
|
||||
asfDepositAuth = 9,
|
||||
asfAuthorizedNFTokenMinter = 10,
|
||||
asfTshCollect = 11,
|
||||
asfDisallowIncomingNFTokenOffer = 12,
|
||||
asfDisallowIncomingCheck = 13,
|
||||
asfDisallowIncomingPayChan = 14,
|
||||
asfDisallowIncomingTrustline = 15,
|
||||
asfDisallowIncomingRemit = 16,
|
||||
asfAllowTrustLineClawback = 17,
|
||||
};
|
||||
|
||||
enum OfferCreateFlags : uint32_t {
|
||||
tfPassive = 0x00010000,
|
||||
tfImmediateOrCancel = 0x00020000,
|
||||
tfFillOrKill = 0x00040000,
|
||||
tfSell = 0x00080000,
|
||||
};
|
||||
|
||||
enum PaymentFlags : uint32_t {
|
||||
tfNoRippleDirect = 0x00010000,
|
||||
tfPartialPayment = 0x00020000,
|
||||
tfLimitQuality = 0x00040000,
|
||||
};
|
||||
|
||||
enum TrustSetFlags : uint32_t {
|
||||
tfSetfAuth = 0x00010000,
|
||||
tfSetNoRipple = 0x00020000,
|
||||
tfClearNoRipple = 0x00040000,
|
||||
tfSetFreeze = 0x00100000,
|
||||
tfClearFreeze = 0x00200000,
|
||||
tfSetDeepFreeze = 0x00400000,
|
||||
tfClearDeepFreeze = 0x00800000
|
||||
};
|
||||
|
||||
enum EnableAmendmentFlags : uint32_t {
|
||||
tfGotMajority = 0x00010000,
|
||||
tfLostMajority = 0x00020000,
|
||||
tfTestSuite = 0x80000000,
|
||||
};
|
||||
|
||||
enum PaymentChannelClaimFlags : uint32_t {
|
||||
tfRenew = 0x00010000,
|
||||
tfClose = 0x00020000,
|
||||
};
|
||||
|
||||
enum NFTokenMintFlags : uint32_t {
|
||||
tfBurnable = 0x00000001,
|
||||
tfOnlyXRP = 0x00000002,
|
||||
tfTrustLine = 0x00000004,
|
||||
tfTransferable = 0x00000008,
|
||||
tfMutable = 0x00000010,
|
||||
tfStrongTSH = 0x00008000,
|
||||
};
|
||||
|
||||
enum MPTokenIssuanceCreateFlags : uint32_t {
|
||||
tfMPTCanLock = lsfMPTCanLock,
|
||||
tfMPTRequireAuth = lsfMPTRequireAuth,
|
||||
tfMPTCanEscrow = lsfMPTCanEscrow,
|
||||
tfMPTCanTrade = lsfMPTCanTrade,
|
||||
tfMPTCanTransfer = lsfMPTCanTransfer,
|
||||
tfMPTCanClawback = lsfMPTCanClawback,
|
||||
};
|
||||
|
||||
enum MPTokenAuthorizeFlags : uint32_t {
|
||||
tfMPTUnauthorize = 0x00000001,
|
||||
};
|
||||
|
||||
enum MPTokenIssuanceSetFlags : uint32_t {
|
||||
tfMPTLock = 0x00000001,
|
||||
tfMPTUnlock = 0x00000002,
|
||||
};
|
||||
|
||||
enum NFTokenCreateOfferFlags : uint32_t {
|
||||
tfSellNFToken = 0x00000001,
|
||||
};
|
||||
|
||||
enum ClaimRewardFlags : uint32_t {
|
||||
tfOptOut = 0x00000001,
|
||||
};
|
||||
|
||||
enum CronSetFlags : uint32_t {
|
||||
tfCronUnset = 0x00000001,
|
||||
};
|
||||
|
||||
enum AMMClawbackFlags : uint32_t {
|
||||
tfClawTwoAssets = 0x00000001,
|
||||
};
|
||||
|
||||
enum BridgeModifyFlags : uint32_t {
|
||||
tfClearAccountCreateAmount = 0x00010000,
|
||||
};
|
||||
@@ -138,14 +138,14 @@ public:
|
||||
template <typename U>
|
||||
requires std::convertible_to<U, T>
|
||||
constexpr Expected(U&& r)
|
||||
: Base(boost::outcome_v2::in_place_type_t<T>{}, std::forward<U>(r))
|
||||
: Base(boost::outcome_v2::success(T(std::forward<U>(r))))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
requires std::convertible_to<U, E> && (!std::is_reference_v<U>)
|
||||
constexpr Expected(Unexpected<U> e)
|
||||
: Base(boost::outcome_v2::in_place_type_t<E>{}, std::move(e.value()))
|
||||
: Base(boost::outcome_v2::failure(E(std::move(e.value()))))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include <boost/beast/core/string.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
@@ -166,8 +165,6 @@ private:
|
||||
beast::severities::Severity thresh_;
|
||||
File file_;
|
||||
bool silent_ = false;
|
||||
using Transform = std::function<std::string(std::string const&)>;
|
||||
Transform transform_;
|
||||
|
||||
public:
|
||||
Logs(beast::severities::Severity level);
|
||||
@@ -206,28 +203,6 @@ public:
|
||||
std::string const& text,
|
||||
bool console);
|
||||
|
||||
/** Rewrite test log lines. Not synchronized.
|
||||
*
|
||||
* Test-only. Installed once for the life of Logs. Empty is a null check.
|
||||
*/
|
||||
void
|
||||
setTransform(Transform fn)
|
||||
{
|
||||
transform_ = std::move(fn);
|
||||
}
|
||||
|
||||
bool
|
||||
hasTransform() const
|
||||
{
|
||||
return static_cast<bool>(transform_);
|
||||
}
|
||||
|
||||
std::string
|
||||
applyTransform(std::string const& text) const
|
||||
{
|
||||
return transform_ ? transform_(text) : text;
|
||||
}
|
||||
|
||||
std::string
|
||||
rotate();
|
||||
|
||||
|
||||
@@ -14,9 +14,7 @@
|
||||
// Override uint256, Feature and Rules for guard checker build
|
||||
#define uint256 std::string
|
||||
#define featureHooksUpdate1 "1"
|
||||
#define featureHooksUpdate2 "1"
|
||||
#define fix20250131 "1"
|
||||
#define fixGuardDepth32 "1"
|
||||
namespace hook_api {
|
||||
struct Rules
|
||||
{
|
||||
@@ -320,7 +318,7 @@ namespace compare_mode {
|
||||
enum compare_mode : uint32_t { EQUAL = 1, LESS = 2, GREATER = 4 };
|
||||
}
|
||||
|
||||
enum class hook_return_code : int64_t {
|
||||
enum hook_return_code : int64_t {
|
||||
SUCCESS =
|
||||
0, // return codes > 0 are reserved for hook apis to return "success"
|
||||
OUT_OF_BOUNDS =
|
||||
@@ -387,7 +385,7 @@ enum class hook_return_code : int64_t {
|
||||
TOO_MANY_NAMESPACES = -45
|
||||
};
|
||||
|
||||
enum class ExitType : uint8_t {
|
||||
enum ExitType : uint8_t {
|
||||
UNSET = 0,
|
||||
WASM_ERROR = 1,
|
||||
ROLLBACK = 2,
|
||||
@@ -444,7 +442,6 @@ getImportWhitelist(Rules const& rules)
|
||||
|
||||
enum GuardRulesVersion : uint64_t {
|
||||
GuardRuleFix20250131 = 0x00000001,
|
||||
GuardRuleDepth32 = 0x00000002,
|
||||
};
|
||||
|
||||
inline uint64_t
|
||||
@@ -453,8 +450,6 @@ getGuardRulesVersion(Rules const& rules)
|
||||
uint64_t version = 0;
|
||||
if (rules.enabled(fix20250131))
|
||||
version |= GuardRuleFix20250131;
|
||||
if (rules.enabled(fixGuardDepth32))
|
||||
version |= GuardRuleDepth32;
|
||||
return version;
|
||||
}
|
||||
|
||||
|
||||
@@ -204,13 +204,9 @@ struct WasmBlkInf
|
||||
}
|
||||
// compute worst case execution time
|
||||
inline uint64_t
|
||||
compute_wce(
|
||||
const WasmBlkInf* blk,
|
||||
int level,
|
||||
int max_level,
|
||||
bool* recursion_limit_reached)
|
||||
compute_wce(const WasmBlkInf* blk, int level, bool* recursion_limit_reached)
|
||||
{
|
||||
if (level > max_level)
|
||||
if (level > 16)
|
||||
{
|
||||
*recursion_limit_reached = true;
|
||||
return 0;
|
||||
@@ -237,8 +233,8 @@ compute_wce(
|
||||
|
||||
if (blk->children.size() > 0)
|
||||
for (auto const& child : blk->children)
|
||||
worst_case_execution += compute_wce(
|
||||
child, level + 1, max_level, recursion_limit_reached);
|
||||
worst_case_execution +=
|
||||
compute_wce(child, level + 1, recursion_limit_reached);
|
||||
|
||||
if (parent == 0 ||
|
||||
parent->iteration_bound ==
|
||||
@@ -792,17 +788,12 @@ check_guard(
|
||||
}
|
||||
|
||||
bool recursion_limit_reached = false;
|
||||
int max_level = 16;
|
||||
if (rulesVersion & hook_api::GuardRuleDepth32)
|
||||
max_level = 32;
|
||||
uint64_t wce =
|
||||
compute_wce(&(*root), 0, max_level, &recursion_limit_reached);
|
||||
uint64_t wce = compute_wce(&(*root), 0, &recursion_limit_reached);
|
||||
if (recursion_limit_reached)
|
||||
{
|
||||
GUARDLOG(hook::log::NESTING_LIMIT)
|
||||
<< "GuardCheck "
|
||||
<< "Maximum allowable depth of blocks reached (" << max_level
|
||||
<< " levels). Flatten "
|
||||
<< "Maximum allowable depth of blocks reached (16 levels). Flatten "
|
||||
"your loops and conditions!.\n";
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -3,297 +3,10 @@
|
||||
|
||||
#include <xrpld/app/misc/Transaction.h>
|
||||
#include <xrpl/hook/Enum.h>
|
||||
#include <cfenv>
|
||||
|
||||
namespace hook {
|
||||
|
||||
using HookReturnCode = hook_api::hook_return_code;
|
||||
|
||||
namespace hook_float {
|
||||
using enum hook_api::hook_return_code;
|
||||
|
||||
// power of 10 LUT for fast integer math
|
||||
static int64_t power_of_ten[19] = {
|
||||
1LL,
|
||||
10LL,
|
||||
100LL,
|
||||
1000LL,
|
||||
10000LL,
|
||||
100000LL,
|
||||
1000000LL,
|
||||
10000000LL,
|
||||
100000000LL,
|
||||
1000000000LL,
|
||||
10000000000LL,
|
||||
100000000000LL,
|
||||
1000000000000LL,
|
||||
10000000000000LL,
|
||||
100000000000000LL,
|
||||
1000000000000000LL, // 15
|
||||
10000000000000000LL,
|
||||
100000000000000000LL,
|
||||
1000000000000000000LL,
|
||||
};
|
||||
|
||||
using namespace hook_api;
|
||||
static int64_t const minMantissa = 1000000000000000ull;
|
||||
static int64_t const maxMantissa = 9999999999999999ull;
|
||||
static int32_t const minExponent = -96;
|
||||
static int32_t const maxExponent = 80;
|
||||
|
||||
inline Expected<int32_t, HookReturnCode>
|
||||
get_exponent(int64_t float1)
|
||||
{
|
||||
using enum hook_api::hook_return_code;
|
||||
if (float1 < 0)
|
||||
return Unexpected(INVALID_FLOAT);
|
||||
if (float1 == 0)
|
||||
return 0u;
|
||||
uint64_t float_in = (uint64_t)float1;
|
||||
float_in >>= 54U;
|
||||
float_in &= 0xFFU;
|
||||
return static_cast<int32_t>(float_in) - 97;
|
||||
}
|
||||
|
||||
inline Expected<uint64_t, HookReturnCode>
|
||||
get_mantissa(int64_t float1)
|
||||
{
|
||||
using enum hook_api::hook_return_code;
|
||||
if (float1 < 0)
|
||||
return Unexpected(INVALID_FLOAT);
|
||||
if (float1 == 0)
|
||||
return 0ULL;
|
||||
float1 -= ((((uint64_t)float1) >> 54U) << 54U);
|
||||
return float1;
|
||||
}
|
||||
|
||||
inline bool
|
||||
is_negative(int64_t float1)
|
||||
{
|
||||
return ((float1 >> 62U) & 1ULL) == 0;
|
||||
}
|
||||
|
||||
inline int64_t
|
||||
invert_sign(int64_t float1)
|
||||
{
|
||||
int64_t r = (int64_t)(((uint64_t)float1) ^ (1ULL << 62U));
|
||||
return r;
|
||||
}
|
||||
|
||||
inline int64_t
|
||||
set_sign(int64_t float1, bool set_negative)
|
||||
{
|
||||
bool neg = is_negative(float1);
|
||||
if ((neg && set_negative) || (!neg && !set_negative))
|
||||
return float1;
|
||||
|
||||
return invert_sign(float1);
|
||||
}
|
||||
|
||||
inline Expected<uint64_t, HookReturnCode>
|
||||
set_mantissa(int64_t float1, uint64_t mantissa)
|
||||
{
|
||||
using enum hook_api::hook_return_code;
|
||||
if (mantissa > maxMantissa)
|
||||
return Unexpected(MANTISSA_OVERSIZED);
|
||||
if (mantissa < minMantissa)
|
||||
return Unexpected(MANTISSA_UNDERSIZED);
|
||||
return float1 - get_mantissa(float1).value() + mantissa;
|
||||
}
|
||||
|
||||
inline Expected<uint64_t, HookReturnCode>
|
||||
set_exponent(int64_t float1, int32_t exponent)
|
||||
{
|
||||
using enum hook_api::hook_return_code;
|
||||
if (exponent > maxExponent)
|
||||
return Unexpected(EXPONENT_OVERSIZED);
|
||||
if (exponent < minExponent)
|
||||
return Unexpected(EXPONENT_UNDERSIZED);
|
||||
|
||||
uint64_t exp = (exponent + 97);
|
||||
exp <<= 54U;
|
||||
float1 &= ~(0xFFLL << 54);
|
||||
float1 += (int64_t)exp;
|
||||
return float1;
|
||||
}
|
||||
|
||||
inline Expected<uint64_t, HookReturnCode>
|
||||
make_float(ripple::IOUAmount& amt)
|
||||
{
|
||||
using enum hook_api::hook_return_code;
|
||||
int64_t man_out = amt.mantissa();
|
||||
int64_t float_out = 0;
|
||||
bool neg = man_out < 0;
|
||||
if (neg)
|
||||
man_out *= -1;
|
||||
|
||||
float_out = set_sign(float_out, neg);
|
||||
auto const mantissa = set_mantissa(float_out, (uint64_t)man_out);
|
||||
if (!mantissa)
|
||||
// TODO: This change requires the amendment.
|
||||
// return Unexpected(mantissa.error());
|
||||
float_out = (int64_t)mantissa.error();
|
||||
else
|
||||
float_out = mantissa.value();
|
||||
auto const exponent = set_exponent(float_out, amt.exponent());
|
||||
if (!exponent)
|
||||
return Unexpected(exponent.error());
|
||||
float_out = exponent.value();
|
||||
return float_out;
|
||||
}
|
||||
|
||||
inline Expected<uint64_t, HookReturnCode>
|
||||
make_float(uint64_t mantissa, int32_t exponent, bool neg)
|
||||
{
|
||||
using enum hook_api::hook_return_code;
|
||||
if (mantissa == 0)
|
||||
return 0ULL;
|
||||
if (mantissa > maxMantissa)
|
||||
return Unexpected(MANTISSA_OVERSIZED);
|
||||
if (mantissa < minMantissa)
|
||||
return Unexpected(MANTISSA_UNDERSIZED);
|
||||
if (exponent > maxExponent)
|
||||
return Unexpected(EXPONENT_OVERSIZED);
|
||||
if (exponent < minExponent)
|
||||
return Unexpected(EXPONENT_UNDERSIZED);
|
||||
int64_t out = 0;
|
||||
|
||||
auto const m = set_mantissa(out, mantissa);
|
||||
if (!m)
|
||||
return Unexpected(m.error()); // LCOV_EXCL_LINE
|
||||
out = m.value();
|
||||
|
||||
auto const e = set_exponent(out, exponent);
|
||||
if (!e)
|
||||
return Unexpected(e.error()); // LCOV_EXCL_LINE
|
||||
out = e.value();
|
||||
|
||||
out = set_sign(out, neg);
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function normalizes the mantissa and exponent passed, if it can.
|
||||
* It returns the XFL and mutates the supplied manitssa and exponent.
|
||||
* If a negative mantissa is provided then the returned XFL has the negative
|
||||
* flag set. If there is an overflow error return XFL_OVERFLOW. On underflow
|
||||
* returns canonical 0
|
||||
*/
|
||||
template <typename T>
|
||||
inline Expected<uint64_t, HookReturnCode>
|
||||
normalize_xfl(T& man, int32_t& exp, bool neg = false)
|
||||
{
|
||||
if (man == 0)
|
||||
return 0ULL;
|
||||
|
||||
if (man == std::numeric_limits<int64_t>::min())
|
||||
man++;
|
||||
|
||||
constexpr bool sman = std::is_same<T, int64_t>::value;
|
||||
static_assert(sman || std::is_same<T, uint64_t>());
|
||||
|
||||
if constexpr (sman)
|
||||
{
|
||||
if (man < 0)
|
||||
{
|
||||
man *= -1LL;
|
||||
neg = true;
|
||||
}
|
||||
}
|
||||
|
||||
// mantissa order
|
||||
std::feclearexcept(FE_ALL_EXCEPT);
|
||||
int32_t mo = log10(man);
|
||||
// defensively ensure log10 produces a sane result; we'll borrow the
|
||||
// overflow error code if it didn't
|
||||
if (std::fetestexcept(FE_INVALID))
|
||||
return Unexpected(XFL_OVERFLOW); // LCOV_EXCL_LINE
|
||||
|
||||
int32_t adjust = 15 - mo;
|
||||
|
||||
if (adjust > 0)
|
||||
{
|
||||
// defensive check
|
||||
if (adjust > 18)
|
||||
return 0ULL; // LCOV_EXCL_LINE
|
||||
man *= power_of_ten[adjust];
|
||||
exp -= adjust;
|
||||
}
|
||||
else if (adjust < 0)
|
||||
{
|
||||
// defensive check
|
||||
if (-adjust > 18)
|
||||
return Unexpected(XFL_OVERFLOW); // LCOV_EXCL_LINE
|
||||
man /= power_of_ten[-adjust];
|
||||
exp -= adjust;
|
||||
}
|
||||
|
||||
if (man == 0)
|
||||
{
|
||||
exp = 0;
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
// even after adjustment the mantissa can be outside the range by one place
|
||||
// improving the math above would probably alleviate the need for these
|
||||
// branches
|
||||
if (man < minMantissa)
|
||||
{
|
||||
if (man == minMantissa - 1LL)
|
||||
man += 1LL;
|
||||
else
|
||||
{
|
||||
man *= 10LL;
|
||||
exp--;
|
||||
}
|
||||
}
|
||||
|
||||
if (man > maxMantissa)
|
||||
{
|
||||
if (man == maxMantissa + 1LL)
|
||||
man -= 1LL;
|
||||
else
|
||||
{
|
||||
man /= 10LL;
|
||||
exp++;
|
||||
}
|
||||
}
|
||||
|
||||
if (exp < minExponent)
|
||||
{
|
||||
man = 0;
|
||||
exp = 0;
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (man == 0)
|
||||
{
|
||||
exp = 0;
|
||||
return 0ULL;
|
||||
}
|
||||
|
||||
if (exp > maxExponent)
|
||||
return Unexpected(XFL_OVERFLOW);
|
||||
|
||||
auto const ret = make_float((uint64_t)man, exp, neg);
|
||||
if constexpr (sman)
|
||||
{
|
||||
if (neg)
|
||||
man *= -1LL;
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
return Unexpected(ret.error());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const int64_t float_one_internal =
|
||||
make_float(1000000000000000ull, -15, false).value();
|
||||
|
||||
} // namespace hook_float
|
||||
|
||||
using namespace ripple;
|
||||
using HookReturnCode = hook_api::hook_return_code;
|
||||
|
||||
using Bytes = std::vector<std::uint8_t>;
|
||||
|
||||
@@ -345,9 +58,6 @@ public:
|
||||
// sto_erase(): same as sto_emplace with field_object = nullopt
|
||||
|
||||
/// etxn APIs
|
||||
Expected<Bytes, HookReturnCode>
|
||||
prepare(Slice const& txBlob) const;
|
||||
|
||||
Expected<std::shared_ptr<Transaction>, HookReturnCode>
|
||||
emit(Slice const& txBlob) const;
|
||||
|
||||
@@ -457,7 +167,7 @@ public:
|
||||
Expected<ripple::uint256, HookReturnCode>
|
||||
hook_hash(int32_t hook_no) const;
|
||||
|
||||
Expected<uint64_t, HookReturnCode>
|
||||
Expected<int64_t, HookReturnCode>
|
||||
hook_again() const;
|
||||
|
||||
Expected<Blob, HookReturnCode>
|
||||
@@ -607,7 +317,7 @@ private:
|
||||
bool modified) const;
|
||||
|
||||
// these are only used by get_stobject_length below
|
||||
enum class STOParseErrorCode {
|
||||
enum parse_error {
|
||||
pe_unexpected_end = -1,
|
||||
pe_unknown_type_early = -2, // detected early
|
||||
pe_unknown_type_late = -3, // end of function
|
||||
@@ -616,8 +326,8 @@ private:
|
||||
};
|
||||
|
||||
inline Expected<
|
||||
uint32_t,
|
||||
STOParseErrorCode>
|
||||
int32_t,
|
||||
parse_error>
|
||||
get_stobject_length(
|
||||
unsigned char* start, // in - begin iterator
|
||||
unsigned char* maxptr, // in - end iterator
|
||||
@@ -1,102 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
Canonical Hook artifact classification and QuickJS deployment envelope.
|
||||
|
||||
Legacy C Hooks remain raw WebAssembly. QuickJS bytecode is never deployed
|
||||
raw: it is carried in a fixed-width, big-endian XQJS envelope whose exact
|
||||
bytes participate in HookHash.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef XRPL_HOOK_HOOKARTIFACT_H_INCLUDED
|
||||
#define XRPL_HOOK_HOOKARTIFACT_H_INCLUDED
|
||||
|
||||
#include <xrpl/basics/Expected.h>
|
||||
#include <xrpl/basics/Slice.h>
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <string_view>
|
||||
|
||||
namespace hook::artifact {
|
||||
|
||||
inline constexpr std::size_t identitySize = 32;
|
||||
inline constexpr std::size_t quickJSHeaderSize = 80;
|
||||
inline constexpr std::size_t maxCreateCodeSize = 65'535;
|
||||
inline constexpr std::array<std::uint8_t, 4> quickJSMagic = {
|
||||
'X',
|
||||
'Q',
|
||||
'J',
|
||||
'S'};
|
||||
inline constexpr std::uint8_t quickJSEnvelopeVersion = 1;
|
||||
inline constexpr std::uint8_t quickJSBytecodeKind = 1;
|
||||
|
||||
using Identity = std::array<std::uint8_t, identitySize>;
|
||||
|
||||
enum class Kind : std::uint8_t {
|
||||
legacyWasm,
|
||||
quickJSBytecode,
|
||||
};
|
||||
|
||||
enum class Error : std::uint8_t {
|
||||
tooLarge,
|
||||
tooShort,
|
||||
unknownMagic,
|
||||
truncatedQuickJSHeader,
|
||||
unsupportedEnvelopeVersion,
|
||||
unsupportedArtifactKind,
|
||||
nonCanonicalHeaderSize,
|
||||
nonZeroReserved,
|
||||
emptyPayload,
|
||||
lengthMismatch,
|
||||
zeroBytecodeABI,
|
||||
zeroRuntimeProfile,
|
||||
};
|
||||
|
||||
struct View
|
||||
{
|
||||
Kind kind;
|
||||
std::uint16_t hookApiVersion;
|
||||
Identity bytecodeABI;
|
||||
Identity runtimeProfile;
|
||||
ripple::Slice payload;
|
||||
};
|
||||
|
||||
/** Parse either a legacy raw-Wasm Hook or a canonical QuickJS artifact.
|
||||
|
||||
The returned slices retain no ownership and must not outlive `code`.
|
||||
*/
|
||||
ripple::Expected<View, Error>
|
||||
parse(ripple::Slice code) noexcept;
|
||||
|
||||
std::string_view
|
||||
toString(Error error) noexcept;
|
||||
|
||||
extern Identity const quickJSBytecodeABI;
|
||||
extern Identity const quickJSRuntimeProfile;
|
||||
extern Identity const quickJSProviderSHA256;
|
||||
extern std::size_t const quickJSProviderSize;
|
||||
extern std::uint16_t const quickJSHookApiVersion;
|
||||
extern std::uint64_t const quickJSInitializationFuel;
|
||||
extern std::uint64_t const quickJSInvocationFuel;
|
||||
extern std::string_view const quickJSHostWorkMeter;
|
||||
extern std::uint64_t const quickJSHostWorkBudget;
|
||||
extern std::uint64_t const quickJSHostWorkBasePerCall;
|
||||
extern std::uint64_t const quickJSHostWorkPerAddressedByte;
|
||||
extern std::string_view const quickJSHostAdapterPolicy;
|
||||
extern std::uint32_t const quickJSHeapBytes;
|
||||
extern std::uint32_t const quickJSStackBytes;
|
||||
extern std::uint32_t const quickJSSerializedObjectMaxBytes;
|
||||
extern std::uint32_t const quickJSSerializedObjectMaxFields;
|
||||
extern std::uint32_t const quickJSSerializedObjectMaxScopes;
|
||||
extern std::uint32_t const quickJSSerializedObjectMaxDepth;
|
||||
extern std::uint32_t const quickJSProviderMemoryMinimumPages;
|
||||
extern std::uint32_t const quickJSProviderMemoryMaximumPages;
|
||||
extern std::uint32_t const quickJSProviderWasmStackBytes;
|
||||
|
||||
bool
|
||||
isCurrentQuickJS(View const& artifact) noexcept;
|
||||
|
||||
} // namespace hook::artifact
|
||||
|
||||
#endif // XRPL_HOOK_HOOKARTIFACT_H_INCLUDED
|
||||
@@ -89,7 +89,73 @@
|
||||
|
||||
#define WASM_VAL_TYPE(T, b) CAT2(TYP_, T)
|
||||
|
||||
#define UNSIGNED_TYPE(T) std::make_unsigned_t<T>
|
||||
#define DECLARE_HOOK_FUNCTION(R, F, ...) \
|
||||
R F(hook::HookContext& hookCtx, \
|
||||
WasmEdge_CallingFrameContext const& frameCtx __VA_OPT__( \
|
||||
COMMA __VA_ARGS__)); \
|
||||
extern WasmEdge_Result WasmFunction##F( \
|
||||
void* data_ptr, \
|
||||
const WasmEdge_CallingFrameContext* frameCtx, \
|
||||
const WasmEdge_Value* in, \
|
||||
WasmEdge_Value* out); \
|
||||
extern WasmEdge_ValType WasmFunctionParams##F[]; \
|
||||
extern WasmEdge_ValType WasmFunctionResult##F[]; \
|
||||
extern WasmEdge_FunctionTypeContext* WasmFunctionType##F; \
|
||||
extern WasmEdge_String WasmFunctionName##F;
|
||||
|
||||
#define DEFINE_HOOK_FUNCTION(R, F, ...) \
|
||||
WasmEdge_Result hook_api::WasmFunction##F( \
|
||||
void* data_ptr, \
|
||||
const WasmEdge_CallingFrameContext* frameCtx, \
|
||||
const WasmEdge_Value* in, \
|
||||
WasmEdge_Value* out) \
|
||||
{ \
|
||||
__VA_OPT__(int _stack = 0;) \
|
||||
__VA_OPT__(FOR_VARS(VAR_ASSIGN, 2, __VA_ARGS__);) \
|
||||
hook::HookContext* hookCtx = \
|
||||
reinterpret_cast<hook::HookContext*>(data_ptr); \
|
||||
R return_code = hook_api::F( \
|
||||
*hookCtx, \
|
||||
*const_cast<WasmEdge_CallingFrameContext*>(frameCtx) \
|
||||
__VA_OPT__(COMMA STRIP_TYPES(__VA_ARGS__))); \
|
||||
if (return_code == RC_ROLLBACK || return_code == RC_ACCEPT) \
|
||||
return WasmEdge_Result_Terminate; \
|
||||
out[0] = RET_ASSIGN(R, return_code); \
|
||||
return WasmEdge_Result_Success; \
|
||||
}; \
|
||||
WasmEdge_ValType hook_api::WasmFunctionParams##F[] = { \
|
||||
__VA_OPT__(FOR_VARS(WASM_VAL_TYPE, 0, __VA_ARGS__))}; \
|
||||
WasmEdge_ValType hook_api::WasmFunctionResult##F[1] = { \
|
||||
WASM_VAL_TYPE(R, dummy)}; \
|
||||
WasmEdge_FunctionTypeContext* hook_api::WasmFunctionType##F = \
|
||||
WasmEdge_FunctionTypeCreate( \
|
||||
WasmFunctionParams##F, \
|
||||
VA_NARGS(NULL __VA_OPT__(, __VA_ARGS__)), \
|
||||
WasmFunctionResult##F, \
|
||||
1); \
|
||||
WasmEdge_String hook_api::WasmFunctionName##F = \
|
||||
WasmEdge_StringCreateByCString(#F); \
|
||||
R hook_api::F( \
|
||||
hook::HookContext& hookCtx, \
|
||||
WasmEdge_CallingFrameContext const& frameCtx __VA_OPT__( \
|
||||
COMMA __VA_ARGS__))
|
||||
|
||||
#define HOOK_SETUP() \
|
||||
try \
|
||||
{ \
|
||||
[[maybe_unused]] ApplyContext& applyCtx = hookCtx.applyCtx; \
|
||||
[[maybe_unused]] auto& view = applyCtx.view(); \
|
||||
[[maybe_unused]] auto j = applyCtx.app.journal("View"); \
|
||||
[[maybe_unused]] WasmEdge_MemoryInstanceContext* memoryCtx = \
|
||||
WasmEdge_CallingFrameGetMemoryInstance(&frameCtx, 0); \
|
||||
[[maybe_unused]] unsigned char* memory = \
|
||||
WasmEdge_MemoryInstanceGetPointer(memoryCtx, 0, 0); \
|
||||
[[maybe_unused]] const uint64_t memory_length = \
|
||||
WasmEdge_MemoryInstanceGetPageSize(memoryCtx) * \
|
||||
WasmEdge_kPageSize; \
|
||||
[[maybe_unused]] auto& api = hookCtx.api(); \
|
||||
if (!memoryCtx || !memory || !memory_length) \
|
||||
return INTERNAL_ERROR;
|
||||
|
||||
#define HOOK_TEARDOWN() \
|
||||
} \
|
||||
@@ -101,6 +167,54 @@
|
||||
return INTERNAL_ERROR; \
|
||||
}
|
||||
|
||||
#define WRITE_WASM_MEMORY( \
|
||||
bytes_written, \
|
||||
guest_dst_ptr, \
|
||||
guest_dst_len, \
|
||||
host_src_ptr, \
|
||||
host_src_len, \
|
||||
host_memory_ptr, \
|
||||
guest_memory_length) \
|
||||
{ \
|
||||
int64_t bytes_to_write = std::min( \
|
||||
static_cast<int64_t>(host_src_len), \
|
||||
static_cast<int64_t>(guest_dst_len)); \
|
||||
if (guest_dst_ptr + bytes_to_write > guest_memory_length) \
|
||||
{ \
|
||||
JLOG(j.warn()) << "HookError[" << HC_ACC() << "]: " << __func__ \
|
||||
<< " tried to retreive blob of " << host_src_len \
|
||||
<< " bytes past end of wasm memory"; \
|
||||
return OUT_OF_BOUNDS; \
|
||||
} \
|
||||
if (!WasmEdge_ResultOK(WasmEdge_MemoryInstanceSetData( \
|
||||
memoryCtx, \
|
||||
reinterpret_cast<const uint8_t*>(host_src_ptr), \
|
||||
guest_dst_ptr, \
|
||||
bytes_to_write))) \
|
||||
return INTERNAL_ERROR; \
|
||||
bytes_written += bytes_to_write; \
|
||||
}
|
||||
|
||||
#define WRITE_WASM_MEMORY_AND_RETURN( \
|
||||
guest_dst_ptr, \
|
||||
guest_dst_len, \
|
||||
host_src_ptr, \
|
||||
host_src_len, \
|
||||
host_memory_ptr, \
|
||||
guest_memory_length) \
|
||||
{ \
|
||||
int64_t bytes_written = 0; \
|
||||
WRITE_WASM_MEMORY( \
|
||||
bytes_written, \
|
||||
guest_dst_ptr, \
|
||||
guest_dst_len, \
|
||||
host_src_ptr, \
|
||||
host_src_len, \
|
||||
host_memory_ptr, \
|
||||
guest_memory_length); \
|
||||
return bytes_written; \
|
||||
}
|
||||
|
||||
// ptr = pointer inside the wasm memory space
|
||||
#define NOT_IN_BOUNDS(ptr, len, memory_length) \
|
||||
((static_cast<uint64_t>(ptr) >= static_cast<uint64_t>(memory_length)) || \
|
||||
@@ -158,7 +272,7 @@
|
||||
data_ptr < (data_ptr_in)) \
|
||||
return INTERNAL_ERROR; \
|
||||
if (data_len == 0) \
|
||||
return 0ULL; \
|
||||
return 0; \
|
||||
if ((write_ptr_in) == 0) \
|
||||
return data_as_int64(data_ptr, data_len); \
|
||||
if (data_len > (write_len_in)) \
|
||||
|
||||
@@ -367,8 +367,3 @@ HOOK_API_DEFINITION(
|
||||
HOOK_API_DEFINITION(
|
||||
int64_t, xpop_slot, (uint32_t, uint32_t),
|
||||
featureHooksUpdate1)
|
||||
|
||||
// int64_t prepare(uint32_t write_ptr, uint32_t write_len, uint32_t read_ptr, uint32_t read_len);
|
||||
HOOK_API_DEFINITION(
|
||||
int64_t, prepare, (uint32_t, uint32_t, uint32_t, uint32_t),
|
||||
featureHooksUpdate2)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -33,39 +33,35 @@
|
||||
*
|
||||
* Steps required to add new features to the code:
|
||||
*
|
||||
* 1) Add the appropriate XRPL_FEATURE or XRPL_FIX macro definition for the
|
||||
* feature to features.macro with the feature's name, `Supported::no`, and
|
||||
* `VoteBehavior::DefaultNo`.
|
||||
*
|
||||
* 2) Use the generated variable name as the parameter to `view.rules.enabled()`
|
||||
* to control flow into new code that this feature limits. (featureName or
|
||||
* fixName)
|
||||
*
|
||||
* 3) If the feature development is COMPLETE, and the feature is ready to be
|
||||
* SUPPORTED, change the macro parameter in features.macro to Supported::yes.
|
||||
*
|
||||
* 4) In general, any newly supported amendments (`Supported::yes`) should have
|
||||
* a `VoteBehavior::DefaultNo` indefinitely so that external governance can
|
||||
* make the decision on when to activate it. High priority bug fixes can be
|
||||
* an exception to this rule. In such cases, ensure the fix has been
|
||||
* clearly communicated to the community using appropriate channels,
|
||||
* then change the macro parameter in features.macro to
|
||||
* `VoteBehavior::DefaultYes`. The communication process is beyond
|
||||
* the scope of these instructions.
|
||||
*
|
||||
* 1) In this file, increment `numFeatures` and add a uint256 declaration
|
||||
* for the feature at the bottom
|
||||
* 2) Add a uint256 definition for the feature to the corresponding source
|
||||
* file (Feature.cpp). Use `registerFeature` to create the feature with
|
||||
* the feature's name, `Supported::no`, and `VoteBehavior::DefaultNo`. This
|
||||
* should be the only place the feature's name appears in code as a string.
|
||||
* 3) Use the uint256 as the parameter to `view.rules.enabled()` to
|
||||
* control flow into new code that this feature limits.
|
||||
* 4) If the feature development is COMPLETE, and the feature is ready to be
|
||||
* SUPPORTED, change the `registerFeature` parameter to Supported::yes.
|
||||
* 5) When the feature is ready to be ENABLED, change the `registerFeature`
|
||||
* parameter to `VoteBehavior::DefaultYes`.
|
||||
* In general, any newly supported amendments (`Supported::yes`) should have
|
||||
* a `VoteBehavior::DefaultNo` for at least one full release cycle. High
|
||||
* priority bug fixes can be an exception to this rule of thumb.
|
||||
*
|
||||
* When a feature has been enabled for several years, the conditional code
|
||||
* may be removed, and the feature "retired". To retire a feature:
|
||||
*
|
||||
* 1) MOVE the macro definition in features.macro to the "retired features"
|
||||
* section at the end of the file, and change the macro to XRPL_RETIRE.
|
||||
*
|
||||
* 1) Remove the uint256 declaration from this file.
|
||||
* 2) MOVE the uint256 definition in Feature.cpp to the "retired features"
|
||||
* section at the end of the file.
|
||||
* 3) CHANGE the name of the variable to start with "retired".
|
||||
* 4) CHANGE the parameters of the `registerFeature` call to `Supported::yes`
|
||||
* and `VoteBehavior::DefaultNo`.
|
||||
* The feature must remain registered and supported indefinitely because it
|
||||
* may exist in the Amendments object on ledger. There is no need to vote
|
||||
* for it because there's nothing to vote for. If the feature definition is
|
||||
* removed completely from the code, any instances running that code will get
|
||||
* amendment blocked. Removing the feature from the ledger is beyond the scope
|
||||
* of these instructions.
|
||||
* still exists in the ledger, but there is no need to vote for it because
|
||||
* there's nothing to vote for. If it is removed completely from the code, any
|
||||
* instances running that code will get amendment blocked. Removing the
|
||||
* feature from the ledger is beyond the scope of these instructions.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -80,32 +76,11 @@ allAmendments();
|
||||
|
||||
namespace detail {
|
||||
|
||||
#pragma push_macro("XRPL_FEATURE")
|
||||
#undef XRPL_FEATURE
|
||||
#pragma push_macro("XRPL_FIX")
|
||||
#undef XRPL_FIX
|
||||
#pragma push_macro("XRPL_RETIRE")
|
||||
#undef XRPL_RETIRE
|
||||
|
||||
#define XRPL_FEATURE(name, supported, vote) +1
|
||||
#define XRPL_FIX(name, supported, vote) +1
|
||||
#define XRPL_RETIRE(name) +1
|
||||
|
||||
// This value SHOULD be equal to the number of amendments registered in
|
||||
// Feature.cpp. Because it's only used to reserve storage, and determine how
|
||||
// large to make the FeatureBitset, it MAY be larger. It MUST NOT be less than
|
||||
// the actual number of amendments. A LogicError on startup will verify this.
|
||||
static constexpr std::size_t numFeatures =
|
||||
(0 +
|
||||
#include <xrpl/protocol/detail/features.macro>
|
||||
);
|
||||
|
||||
#undef XRPL_RETIRE
|
||||
#pragma pop_macro("XRPL_RETIRE")
|
||||
#undef XRPL_FIX
|
||||
#pragma pop_macro("XRPL_FIX")
|
||||
#undef XRPL_FEATURE
|
||||
#pragma pop_macro("XRPL_FEATURE")
|
||||
static constexpr std::size_t numFeatures = 111;
|
||||
|
||||
/** Amendments that this server supports and the default voting behavior.
|
||||
Whether they are enabled depends on the Rules defined in the validated
|
||||
@@ -345,17 +320,12 @@ foreachFeature(FeatureBitset bs, F&& f)
|
||||
#undef XRPL_FEATURE
|
||||
#pragma push_macro("XRPL_FIX")
|
||||
#undef XRPL_FIX
|
||||
#pragma push_macro("XRPL_RETIRE")
|
||||
#undef XRPL_RETIRE
|
||||
|
||||
#define XRPL_FEATURE(name, supported, vote) extern uint256 const feature##name;
|
||||
#define XRPL_FIX(name, supported, vote) extern uint256 const fix##name;
|
||||
#define XRPL_RETIRE(name)
|
||||
|
||||
#include <xrpl/protocol/detail/features.macro>
|
||||
|
||||
#undef XRPL_RETIRE
|
||||
#pragma pop_macro("XRPL_RETIRE")
|
||||
#undef XRPL_FIX
|
||||
#pragma pop_macro("XRPL_FIX")
|
||||
#undef XRPL_FEATURE
|
||||
|
||||
@@ -97,12 +97,6 @@ public:
|
||||
|
||||
static IOUAmount
|
||||
minPositiveAmount();
|
||||
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& os, IOUAmount const& x)
|
||||
{
|
||||
return os << to_string(x);
|
||||
}
|
||||
};
|
||||
|
||||
inline IOUAmount::IOUAmount(beast::Zero)
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
#ifndef RIPPLE_PROTOCOL_IMPORT_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_IMPORT_H_INCLUDED
|
||||
|
||||
// #include <ripple/basics/Log.h>
|
||||
#include <xrpld/app/misc/Manifest.h>
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/StringUtilities.h>
|
||||
#include <xrpl/basics/base64.h>
|
||||
#include <xrpl/json/json_reader.h>
|
||||
|
||||
@@ -147,9 +147,8 @@ enum LedgerSpecificFlags {
|
||||
0x40000000, // True, has minted tokens in the past
|
||||
lsfDisallowIncomingRemit = // True, no remits allowed to this account
|
||||
0x80000000,
|
||||
// 0x0004000 is available
|
||||
lsfAllowTrustLineClawback =
|
||||
0x00001000, // True, enable clawback
|
||||
lsfAllowTrustLineClawback =
|
||||
0x00001000, // True, enable clawback
|
||||
|
||||
// ltOFFER
|
||||
lsfPassive = 0x00010000,
|
||||
@@ -164,10 +163,10 @@ enum LedgerSpecificFlags {
|
||||
lsfHighNoRipple = 0x00200000,
|
||||
lsfLowFreeze = 0x00400000, // True, low side has set freeze flag
|
||||
lsfHighFreeze = 0x00800000, // True, high side has set freeze flag
|
||||
lsfAMMNode = 0x01000000, // True, trust line to AMM. Used by client
|
||||
// apps to identify payments via AMM.
|
||||
lsfLowDeepFreeze = 0x02000000, // True, low side has set deep freeze flag
|
||||
lsfHighDeepFreeze = 0x04000000, // True, high side has set deep freeze flag
|
||||
lsfAMMNode = 0x01000000, // True, trust line to AMM. Used by client
|
||||
// apps to identify payments via AMM.
|
||||
|
||||
// ltSIGNER_LIST
|
||||
lsfOneOwnerCount = 0x00010000, // True, uses only one OwnerCount
|
||||
|
||||
@@ -28,9 +28,6 @@
|
||||
|
||||
namespace ripple {
|
||||
|
||||
bool
|
||||
isFeatureEnabled(uint256 const& feature);
|
||||
|
||||
class DigestAwareReadView;
|
||||
|
||||
/** Rules controlling protocol behavior. */
|
||||
|
||||
@@ -137,7 +137,6 @@ enum TEMcodes : TERUnderlyingType {
|
||||
temXCHAIN_BRIDGE_NONDOOR_OWNER,
|
||||
temXCHAIN_BRIDGE_BAD_MIN_ACCOUNT_CREATE_AMOUNT,
|
||||
temXCHAIN_BRIDGE_BAD_REWARD_AMOUNT,
|
||||
temXCHAIN_TOO_MANY_ATTESTATIONS, // RESERVED - not used
|
||||
|
||||
temHOOK_DATA_TOO_LARGE,
|
||||
temEMPTY_DID,
|
||||
|
||||
@@ -125,14 +125,14 @@ enum TrustSetFlags : uint32_t {
|
||||
tfSetFreeze = 0x00100000,
|
||||
tfClearFreeze = 0x00200000,
|
||||
tfSetDeepFreeze = 0x00400000,
|
||||
tfClearDeepFreeze = 0x00800000
|
||||
tfClearDeepFreeze = 0x00800000,
|
||||
};
|
||||
constexpr std::uint32_t tfTrustSetMask =
|
||||
~(tfUniversal | tfSetfAuth | tfSetNoRipple | tfClearNoRipple | tfSetFreeze |
|
||||
tfClearFreeze | tfSetDeepFreeze | tfClearDeepFreeze);
|
||||
|
||||
// EnableAmendment flags:
|
||||
enum EnableAmendmentFlags : uint32_t {
|
||||
enum EnableAmendmentFlags : std::uint32_t {
|
||||
tfGotMajority = 0x00010000,
|
||||
tfLostMajority = 0x00020000,
|
||||
tfTestSuite = 0x80000000,
|
||||
|
||||
@@ -23,24 +23,12 @@
|
||||
#if !defined(XRPL_FIX)
|
||||
#error "undefined macro: XRPL_FIX"
|
||||
#endif
|
||||
#if !defined(XRPL_RETIRE)
|
||||
#error "undefined macro: XRPL_RETIRE"
|
||||
#endif
|
||||
|
||||
// clang-format off
|
||||
|
||||
// Add new amendments to the top of this list.
|
||||
// Keep it sorted in reverse chronological order.
|
||||
// If you add an amendment here, then do not forget to increment `numFeatures`
|
||||
// in include/xrpl/protocol/Feature.h.
|
||||
|
||||
XRPL_FEATURE(JSHooks, Supported::no, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (HookMap, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FIX (GuardDepth32, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(NamedHooks, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(IOURewardClaim, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (IOULockedBalanceInvariant, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (ImportIssuer, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FEATURE(HookAPISerializedType240, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(PermissionedDomains, Supported::no, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(DynamicNFT, Supported::no, VoteBehavior::DefaultNo)
|
||||
@@ -62,19 +50,17 @@ XRPL_FIX (FillOrKill, Supported::yes, VoteBehavior::DefaultYe
|
||||
XRPL_FEATURE(DID, Supported::no, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (DisallowIncomingV1, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FEATURE(XChainBridge, Supported::no, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(AMM, Supported::no, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (ReducedOffersV1, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FEATURE(HooksUpdate2, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(HookOnV2, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(AMM, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (HookAPI20251128, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FIX (CronStacking, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FEATURE(ExtendedHookState, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (InvalidTxFlags, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FEATURE(Cron, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (InvalidTxFlags, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FEATURE(IOUIssuerWeakTSH, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(DeepFreeze, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (ProvisionalDoubleThreading, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FEATURE(Clawback, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (ReducedOffersV1, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FIX (ProvisionalDoubleThreading, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FIX (RewardClaimFlags, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FEATURE(HookCanEmit, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (20250131, Supported::yes, VoteBehavior::DefaultYes)
|
||||
@@ -157,24 +143,3 @@ XRPL_FIX (NFTokenDirV1, Supported::yes, VoteBehavior::Obsolete)
|
||||
XRPL_FEATURE(NonFungibleTokensV1, Supported::yes, VoteBehavior::Obsolete)
|
||||
XRPL_FEATURE(CryptoConditionsSuite, Supported::yes, VoteBehavior::Obsolete)
|
||||
|
||||
// The following amendments have been active for at least two years. Their
|
||||
// pre-amendment code has been removed and the identifiers are deprecated.
|
||||
// All known amendments and amendments that may appear in a validated
|
||||
// ledger must be registered either here or above with the "active" amendments
|
||||
XRPL_RETIRE(MultiSign)
|
||||
XRPL_RETIRE(TrustSetAuth)
|
||||
XRPL_RETIRE(FeeEscalation)
|
||||
XRPL_RETIRE(PayChan)
|
||||
XRPL_RETIRE(CryptoConditions)
|
||||
XRPL_RETIRE(TickSize)
|
||||
XRPL_RETIRE(fix1368)
|
||||
XRPL_RETIRE(Escrow)
|
||||
XRPL_RETIRE(fix1373)
|
||||
XRPL_RETIRE(EnforceInvariants)
|
||||
XRPL_RETIRE(SortedDirectories)
|
||||
XRPL_RETIRE(fix1201)
|
||||
XRPL_RETIRE(fix1512)
|
||||
XRPL_RETIRE(fix1523)
|
||||
XRPL_RETIRE(fix1528)
|
||||
|
||||
// clang-format on
|
||||
|
||||
@@ -65,7 +65,7 @@ LEDGER_ENTRY_DUPLICATE(ltCRON, 0x0041, Cron, cron, ({
|
||||
{sfRepeatCount, soeREQUIRED},
|
||||
{sfOwnerNode, soeREQUIRED},
|
||||
{sfPreviousTxnID, soeREQUIRED},
|
||||
{sfPreviousTxnLgrSeq, soeREQUIRED},
|
||||
{sfPreviousTxnLgrSeq, soeREQUIRED}
|
||||
}))
|
||||
|
||||
/** A ledger object which describes a check.
|
||||
@@ -93,9 +93,7 @@ LEDGER_ENTRY(ltCHECK, 0x0043, Check, check, ({
|
||||
*/
|
||||
LEDGER_ENTRY(ltHOOK_DEFINITION, 'D', HookDefinition, hook_definition, ({
|
||||
{sfHookHash, soeREQUIRED},
|
||||
{sfHookOn, soeOPTIONAL},
|
||||
{sfHookOnIncoming, soeOPTIONAL},
|
||||
{sfHookOnOutgoing, soeOPTIONAL},
|
||||
{sfHookOn, soeREQUIRED},
|
||||
{sfHookCanEmit, soeOPTIONAL},
|
||||
{sfHookNamespace, soeREQUIRED},
|
||||
{sfHookParameters, soeREQUIRED},
|
||||
@@ -132,8 +130,6 @@ LEDGER_ENTRY(ltHOOK, 'H', Hook, hook, ({
|
||||
|
||||
/** The ledger object which records the last (and largest) sequence for a validator list key
|
||||
* as used in the Import amendment
|
||||
|
||||
\sa keylet::import_vlseq
|
||||
*/
|
||||
LEDGER_ENTRY(ltIMPORT_VLSEQ, 0x0049, ImportVLSequence, import_vlseq, ({
|
||||
{sfPublicKey, soeREQUIRED},
|
||||
@@ -396,8 +392,6 @@ LEDGER_ENTRY(ltRIPPLE_STATE, 0x0072, RippleState, state, ({
|
||||
{sfHighQualityOut, soeOPTIONAL},
|
||||
{sfLockedBalance, soeOPTIONAL},
|
||||
{sfLockCount, soeOPTIONAL},
|
||||
{sfHighReward, soeOPTIONAL},
|
||||
{sfLowReward, soeOPTIONAL},
|
||||
}))
|
||||
|
||||
/** The ledger object which lists the network's fee settings.
|
||||
|
||||
@@ -210,13 +210,11 @@ TYPED_SFIELD(sfOfferID, UINT256, 34)
|
||||
TYPED_SFIELD(sfEscrowID, UINT256, 35)
|
||||
TYPED_SFIELD(sfURITokenID, UINT256, 36)
|
||||
TYPED_SFIELD(sfDomainID, UINT256, 37)
|
||||
TYPED_SFIELD(sfHookOnOutgoing, UINT256, 93)
|
||||
TYPED_SFIELD(sfHookOnIncoming, UINT256, 94)
|
||||
TYPED_SFIELD(sfCron, UINT256, 95)
|
||||
TYPED_SFIELD(sfHookCanEmit, UINT256, 96)
|
||||
TYPED_SFIELD(sfEmittedTxnID, UINT256, 97)
|
||||
TYPED_SFIELD(sfGovernanceMarks, UINT256, 98)
|
||||
TYPED_SFIELD(sfGovernanceFlags, UINT256, 99)
|
||||
TYPED_SFIELD(sfGovernanceMarks, UINT256, 98)
|
||||
TYPED_SFIELD(sfEmittedTxnID, UINT256, 97)
|
||||
TYPED_SFIELD(sfHookCanEmit, UINT256, 96)
|
||||
TYPED_SFIELD(sfCron, UINT256, 95)
|
||||
|
||||
// number (common)
|
||||
TYPED_SFIELD(sfNumber, NUMBER, 1)
|
||||
@@ -257,7 +255,6 @@ TYPED_SFIELD(sfPrice, AMOUNT, 28)
|
||||
TYPED_SFIELD(sfSignatureReward, AMOUNT, 29)
|
||||
TYPED_SFIELD(sfMinAccountCreateAmount, AMOUNT, 30)
|
||||
TYPED_SFIELD(sfLPTokenBalance, AMOUNT, 31)
|
||||
TYPED_SFIELD(sfTrustLineRewardAccumulator,AMOUNT, 99)
|
||||
|
||||
// variable length (common)
|
||||
TYPED_SFIELD(sfPublicKey, VL, 1)
|
||||
@@ -293,7 +290,6 @@ TYPED_SFIELD(sfAssetClass, VL, 29)
|
||||
TYPED_SFIELD(sfProvider, VL, 30)
|
||||
TYPED_SFIELD(sfMPTokenMetadata, VL, 31)
|
||||
TYPED_SFIELD(sfCredentialType, VL, 32)
|
||||
TYPED_SFIELD(sfHookName, VL, 97)
|
||||
TYPED_SFIELD(sfRemarkValue, VL, 98)
|
||||
TYPED_SFIELD(sfRemarkName, VL, 99)
|
||||
|
||||
@@ -342,7 +338,6 @@ TYPED_SFIELD(sfLockingChainIssue, ISSUE, 1)
|
||||
TYPED_SFIELD(sfIssuingChainIssue, ISSUE, 2)
|
||||
TYPED_SFIELD(sfAsset, ISSUE, 3)
|
||||
TYPED_SFIELD(sfAsset2, ISSUE, 4)
|
||||
TYPED_SFIELD(sfClaimCurrency, ISSUE, 5)
|
||||
|
||||
// bridge
|
||||
TYPED_SFIELD(sfXChainBridge, XCHAIN_BRIDGE, 1)
|
||||
@@ -370,7 +365,7 @@ UNTYPED_SFIELD(sfMajority, OBJECT, 18)
|
||||
UNTYPED_SFIELD(sfDisabledValidator, OBJECT, 19)
|
||||
UNTYPED_SFIELD(sfEmittedTxn, OBJECT, 20)
|
||||
UNTYPED_SFIELD(sfHookExecution, OBJECT, 21)
|
||||
// 22 unused
|
||||
UNTYPED_SFIELD(sfHookDefinition, OBJECT, 22)
|
||||
UNTYPED_SFIELD(sfHookParameter, OBJECT, 23)
|
||||
UNTYPED_SFIELD(sfHookGrant, OBJECT, 24)
|
||||
UNTYPED_SFIELD(sfVoteEntry, OBJECT, 25)
|
||||
@@ -389,8 +384,6 @@ UNTYPED_SFIELD(sfImportVLKey, OBJECT, 94)
|
||||
UNTYPED_SFIELD(sfActiveValidator, OBJECT, 95)
|
||||
UNTYPED_SFIELD(sfGenesisMint, OBJECT, 96)
|
||||
UNTYPED_SFIELD(sfRemark, OBJECT, 97)
|
||||
UNTYPED_SFIELD(sfHighReward, OBJECT, 98)
|
||||
UNTYPED_SFIELD(sfLowReward, OBJECT, 99)
|
||||
|
||||
// array of objects (common)
|
||||
// ARRAY/1 is reserved for end of array
|
||||
@@ -421,9 +414,9 @@ UNTYPED_SFIELD(sfAuthAccounts, ARRAY, 25)
|
||||
UNTYPED_SFIELD(sfAuthorizeCredentials, ARRAY, 26)
|
||||
UNTYPED_SFIELD(sfUnauthorizeCredentials, ARRAY, 27)
|
||||
UNTYPED_SFIELD(sfAcceptedCredentials, ARRAY, 28)
|
||||
UNTYPED_SFIELD(sfAmounts, ARRAY, 92)
|
||||
UNTYPED_SFIELD(sfHookEmissions, ARRAY, 93)
|
||||
UNTYPED_SFIELD(sfImportVLKeys, ARRAY, 94)
|
||||
UNTYPED_SFIELD(sfActiveValidators, ARRAY, 95)
|
||||
UNTYPED_SFIELD(sfGenesisMints, ARRAY, 96)
|
||||
UNTYPED_SFIELD(sfRemarks, ARRAY, 97)
|
||||
UNTYPED_SFIELD(sfGenesisMints, ARRAY, 96)
|
||||
UNTYPED_SFIELD(sfActiveValidators, ARRAY, 95)
|
||||
UNTYPED_SFIELD(sfImportVLKeys, ARRAY, 94)
|
||||
UNTYPED_SFIELD(sfHookEmissions, ARRAY, 93)
|
||||
UNTYPED_SFIELD(sfAmounts, ARRAY, 92)
|
||||
|
||||
@@ -513,6 +513,7 @@ TRANSACTION(ttCRON_SET, 93, CronSet, ({
|
||||
{sfStartTime, soeOPTIONAL},
|
||||
}))
|
||||
|
||||
|
||||
/* A note attaching transactor that allows the owner or issuer (on a object by object basis) to attach remarks */
|
||||
TRANSACTION(ttREMARKS_SET, 94, SetRemarks, ({
|
||||
{sfObjectID, soeREQUIRED},
|
||||
@@ -550,7 +551,6 @@ TRANSACTION(ttIMPORT, 97, Import, ({
|
||||
* from a specified hook */
|
||||
TRANSACTION(ttCLAIM_REWARD, 98, ClaimReward, ({
|
||||
{sfIssuer, soeOPTIONAL},
|
||||
{sfClaimCurrency, soeOPTIONAL},
|
||||
}))
|
||||
|
||||
/** This transaction invokes a hook, providing arbitrary data. Essentially as a 0 drop payment. **/
|
||||
|
||||
@@ -76,11 +76,8 @@ JSS(Holder); // field.
|
||||
JSS(HookApiVersion); // field
|
||||
JSS(HookCanEmit); // field
|
||||
JSS(HookHash); // field
|
||||
JSS(HookName); // field
|
||||
JSS(HookNamespace); // field
|
||||
JSS(HookOn); // field
|
||||
JSS(HookOnIncoming); // field
|
||||
JSS(HookOnOutgoing); // field
|
||||
JSS(Hooks); // field
|
||||
JSS(HookGrants); // field
|
||||
JSS(HookParameters); // field
|
||||
@@ -98,7 +95,6 @@ JSS(Invalid); //
|
||||
JSS(Issuer); // in: Credential transactions
|
||||
JSS(InvoiceID); // field
|
||||
JSS(LastLedgerSequence); // in: TransactionSign; field
|
||||
JSS(FirstLedgerSequence); // in: TransactionSign; field
|
||||
JSS(LastUpdateTime); // field.
|
||||
JSS(LimitAmount); // field.
|
||||
JSS(NetworkID); // field.
|
||||
@@ -123,7 +119,6 @@ JSS(Signer); // field.
|
||||
JSS(Signers); // field.
|
||||
JSS(HookStateData); // field.
|
||||
JSS(HookStateKey); // field.
|
||||
JSS(EmitDetails); // field.
|
||||
JSS(SigningPubKey); // field.
|
||||
JSS(Subject); // in: Credential transactions
|
||||
JSS(TakerGets); // field.
|
||||
|
||||
@@ -11,11 +11,11 @@ echo "START BUILDING (HOST)"
|
||||
echo "Cleaning previously built binary"
|
||||
rm -f release-build/xahaud
|
||||
|
||||
BUILD_CORES=$(echo "scale=0 ; $(nproc) / 1.337" | bc)
|
||||
BUILD_CORES=$(echo "scale=0 ; `nproc` / 1.337" | bc)
|
||||
|
||||
if [[ "$GITHUB_REPOSITORY" == "" ]]; then
|
||||
#Default
|
||||
BUILD_CORES=${BUILD_CORES:-8}
|
||||
BUILD_CORES=${BUILD_CORES:-8}
|
||||
fi
|
||||
|
||||
# Ensure still works outside of GH Actions by setting these to /dev/null
|
||||
@@ -31,19 +31,21 @@ echo "-- GITHUB_SHA: $GITHUB_SHA"
|
||||
echo "-- GITHUB_RUN_NUMBER: $GITHUB_RUN_NUMBER"
|
||||
echo "-- CONTAINER_NAME: $CONTAINER_NAME"
|
||||
|
||||
which docker 2>/dev/null 2>/dev/null
|
||||
if [ "$?" -eq "1" ]; then
|
||||
which docker 2> /dev/null 2> /dev/null
|
||||
if [ "$?" -eq "1" ]
|
||||
then
|
||||
echo 'Docker not found. Install it first.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
stat .git 2>/dev/null 2>/dev/null
|
||||
if [ "$?" -eq "1" ]; then
|
||||
stat .git 2> /dev/null 2> /dev/null
|
||||
if [ "$?" -eq "1" ]
|
||||
then
|
||||
echo 'Run this inside the source directory. (.git dir not found).'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
STATIC_CONTAINER=$(docker ps -a | grep $CONTAINER_NAME | wc -l)
|
||||
STATIC_CONTAINER=$(docker ps -a | grep $CONTAINER_NAME |wc -l)
|
||||
|
||||
CACHE_VOLUME_NAME="xahau-release-builder-cache"
|
||||
|
||||
@@ -55,14 +57,13 @@ if false; then
|
||||
docker stop $CONTAINER_NAME
|
||||
else
|
||||
echo "No static container, build on temp container"
|
||||
rm -rf release-build
|
||||
mkdir -p release-build
|
||||
rm -rf release-build;
|
||||
mkdir -p release-build;
|
||||
|
||||
docker volume create $CACHE_VOLUME_NAME
|
||||
|
||||
# Create inline Dockerfile with environment setup for build-full.sh
|
||||
DOCKERFILE_CONTENT=$(
|
||||
cat <<'DOCKERFILE_EOF'
|
||||
DOCKERFILE_CONTENT=$(cat <<'DOCKERFILE_EOF'
|
||||
FROM ghcr.io/phusion/holy-build-box:4.0.1-amd64
|
||||
|
||||
ARG BUILD_CORES=8
|
||||
@@ -128,9 +129,6 @@ ENV CMAKE_EXE_LINKER_FLAGS="-static-libstdc++"
|
||||
ENV LLVM_DIR=/usr/lib64/llvm14/lib/cmake/llvm
|
||||
ENV WasmEdge_LIB=/usr/local/lib64/libwasmedge.a
|
||||
|
||||
ENV CC='ccache gcc'
|
||||
ENV CXX='ccache g++'
|
||||
|
||||
# Install LLD
|
||||
RUN /hbb_exe/activate-exec bash -c "source /opt/rh/gcc-toolset-11/enable && \
|
||||
cd /tmp && \
|
||||
@@ -195,7 +193,6 @@ ENV PATH=/usr/local/bin:$PATH
|
||||
RUN /hbb_exe/activate-exec bash -c "ccache -M 100G && \
|
||||
ccache -o cache_dir=/cache/ccache && \
|
||||
ccache -o compiler_check=content && \
|
||||
ccache -o direct_mode=true && \
|
||||
mkdir -p ~/.conan2 /cache/conan2 /cache/conan2_download /cache/conan2_sources && \
|
||||
echo 'core.cache:storage_path=/cache/conan2' > ~/.conan2/global.conf && \
|
||||
echo 'core.download:download_cache=/cache/conan2_download' >> ~/.conan2/global.conf && \
|
||||
@@ -217,7 +214,7 @@ RUN /hbb_exe/activate-exec bash -c "ccache -M 100G && \
|
||||
ln -s ../../bin/ccache /usr/lib64/ccache/c++"
|
||||
|
||||
DOCKERFILE_EOF
|
||||
)
|
||||
)
|
||||
|
||||
# Build custom Docker image
|
||||
IMAGE_NAME="xahaud-builder:latest"
|
||||
@@ -227,14 +224,14 @@ DOCKERFILE_EOF
|
||||
if [[ "$GITHUB_REPOSITORY" == "" ]]; then
|
||||
# Non GH, local building
|
||||
echo "Non-GH runner, local building, temp container"
|
||||
docker run -i --user 0:$(id -g) --rm -v /data/builds:/data/builds -v $(pwd):/io -v "$CACHE_VOLUME_NAME":/cache --network host "$IMAGE_NAME" /hbb_exe/activate-exec bash -c "source /opt/rh/gcc-toolset-11/enable && bash -x /io/build-full.sh '$GITHUB_REPOSITORY' '$GITHUB_SHA' '$BUILD_CORES' '$GITHUB_RUN_NUMBER'"
|
||||
docker run -i --user 0:$(id -g) --rm -v /data/builds:/data/builds -v `pwd`:/io -v "$CACHE_VOLUME_NAME":/cache --network host "$IMAGE_NAME" /hbb_exe/activate-exec bash -c "source /opt/rh/gcc-toolset-11/enable && bash -x /io/build-full.sh '$GITHUB_REPOSITORY' '$GITHUB_SHA' '$BUILD_CORES' '$GITHUB_RUN_NUMBER'"
|
||||
else
|
||||
# GH Action, runner
|
||||
echo "GH Action, runner, clean & re-create create persistent container"
|
||||
docker rm -f $CONTAINER_NAME
|
||||
echo "echo 'Stopping container: $CONTAINER_NAME'" >>"$JOB_CLEANUP_SCRIPT"
|
||||
echo "docker stop --time=15 \"$CONTAINER_NAME\" || echo 'Failed to stop container or container not running'" >>"$JOB_CLEANUP_SCRIPT"
|
||||
docker run -di --user 0:$(id -g) --name $CONTAINER_NAME -v /data/builds:/data/builds -v $(pwd):/io -v "$CACHE_VOLUME_NAME":/cache --network host "$IMAGE_NAME" /hbb_exe/activate-exec bash
|
||||
echo "echo 'Stopping container: $CONTAINER_NAME'" >> "$JOB_CLEANUP_SCRIPT"
|
||||
echo "docker stop --time=15 \"$CONTAINER_NAME\" || echo 'Failed to stop container or container not running'" >> "$JOB_CLEANUP_SCRIPT"
|
||||
docker run -di --user 0:$(id -g) --name $CONTAINER_NAME -v /data/builds:/data/builds -v `pwd`:/io -v "$CACHE_VOLUME_NAME":/cache --network host "$IMAGE_NAME" /hbb_exe/activate-exec bash
|
||||
docker exec -i $CONTAINER_NAME /hbb_exe/activate-exec bash -c "source /opt/rh/gcc-toolset-11/enable && bash -x /io/build-full.sh '$GITHUB_REPOSITORY' '$GITHUB_SHA' '$BUILD_CORES' '$GITHUB_RUN_NUMBER'"
|
||||
docker stop $CONTAINER_NAME
|
||||
fi
|
||||
|
||||
@@ -22,11 +22,11 @@
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/chrono.h>
|
||||
#include <xrpl/basics/contract.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#ifdef BEAST_ENHANCED_LOGGING
|
||||
#include <xrpl/beast/utility/EnhancedLogging.h>
|
||||
#include <date/tz.h>
|
||||
#endif
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
@@ -66,7 +66,7 @@ invalidAMMAsset(
|
||||
Issue const& issue,
|
||||
std::optional<std::pair<Issue, Issue>> const& pair)
|
||||
{
|
||||
if (isBadCurrency(issue.currency))
|
||||
if (badCurrency() == issue.currency)
|
||||
return temBAD_CURRENCY;
|
||||
if (isXRP(issue) && issue.account.isNonZero())
|
||||
return temBAD_ISSUER;
|
||||
|
||||
@@ -250,9 +250,12 @@ FeatureCollections::registerFeature(
|
||||
Feature const* i = getByName(name);
|
||||
if (!i)
|
||||
{
|
||||
// If this check fails, and you just added a feature, increase the
|
||||
// numFeatures value in Feature.h
|
||||
check(
|
||||
features.size() < detail::numFeatures,
|
||||
"More features defined than allocated.");
|
||||
"More features defined than allocated. Adjust numFeatures in "
|
||||
"Feature.h.");
|
||||
|
||||
auto const f = sha512Half(Slice(name.data(), name.size()));
|
||||
|
||||
@@ -421,26 +424,45 @@ featureToName(uint256 const& f)
|
||||
#undef XRPL_FEATURE
|
||||
#pragma push_macro("XRPL_FIX")
|
||||
#undef XRPL_FIX
|
||||
#pragma push_macro("XRPL_RETIRE")
|
||||
#undef XRPL_RETIRE
|
||||
|
||||
#define XRPL_FEATURE(name, supported, vote) \
|
||||
uint256 const feature##name = registerFeature(#name, supported, vote);
|
||||
#define XRPL_FIX(name, supported, vote) \
|
||||
uint256 const fix##name = registerFeature("fix" #name, supported, vote);
|
||||
#define XRPL_RETIRE(name) \
|
||||
[[deprecated("The referenced amendment has been retired"), maybe_unused]] \
|
||||
uint256 const retired##name = retireFeature(#name);
|
||||
|
||||
#include <xrpl/protocol/detail/features.macro>
|
||||
|
||||
#undef XRPL_RETIRE
|
||||
#pragma pop_macro("XRPL_RETIRE")
|
||||
#undef XRPL_FIX
|
||||
#pragma pop_macro("XRPL_FIX")
|
||||
#undef XRPL_FEATURE
|
||||
#pragma pop_macro("XRPL_FEATURE")
|
||||
|
||||
// clang-format off
|
||||
|
||||
// The following amendments have been active for at least two years. Their
|
||||
// pre-amendment code has been removed and the identifiers are deprecated.
|
||||
// All known amendments and amendments that may appear in a validated
|
||||
// ledger must be registered either here or above with the "active" amendments
|
||||
[[deprecated("The referenced amendment has been retired"), maybe_unused]]
|
||||
uint256 const
|
||||
retiredMultiSign = retireFeature("MultiSign"),
|
||||
retiredTrustSetAuth = retireFeature("TrustSetAuth"),
|
||||
retiredFeeEscalation = retireFeature("FeeEscalation"),
|
||||
retiredPayChan = retireFeature("PayChan"),
|
||||
retiredCryptoConditions = retireFeature("CryptoConditions"),
|
||||
retiredTickSize = retireFeature("TickSize"),
|
||||
retiredFix1368 = retireFeature("fix1368"),
|
||||
retiredEscrow = retireFeature("Escrow"),
|
||||
retiredFix1373 = retireFeature("fix1373"),
|
||||
retiredEnforceInvariants = retireFeature("EnforceInvariants"),
|
||||
retiredSortedDirectories = retireFeature("SortedDirectories"),
|
||||
retiredFix1201 = retireFeature("fix1201"),
|
||||
retiredFix1512 = retireFeature("fix1512"),
|
||||
retiredFix1523 = retireFeature("fix1523"),
|
||||
retiredFix1528 = retireFeature("fix1528");
|
||||
|
||||
// clang-format on
|
||||
|
||||
// All of the features should now be registered, since variables in a cpp file
|
||||
// are initialized from top to bottom.
|
||||
//
|
||||
|
||||
@@ -31,8 +31,6 @@
|
||||
|
||||
namespace ripple {
|
||||
|
||||
#define LEDGER_NAMESPACE2(value1, value2) (uint16_t(value1) << 8) | value2
|
||||
|
||||
/** Type-specific prefix for calculating ledger indices.
|
||||
|
||||
The identifier for a given object within the ledger is calculated based
|
||||
@@ -82,14 +80,14 @@ enum class LedgerNameSpace : std::uint16_t {
|
||||
UNL_REPORT = 'R',
|
||||
CRON = 'L',
|
||||
AMM = 'A',
|
||||
BRIDGE = LEDGER_NAMESPACE2(0x01, 'H'),
|
||||
BRIDGE = 'H',
|
||||
XCHAIN_CLAIM_ID = 'Q',
|
||||
XCHAIN_CREATE_ACCOUNT_CLAIM_ID = 'K',
|
||||
DID = LEDGER_NAMESPACE2(0x01, 'I'),
|
||||
ORACLE = LEDGER_NAMESPACE2(0x01, 'R'),
|
||||
DID = 'I',
|
||||
ORACLE = 'R',
|
||||
MPTOKEN_ISSUANCE = '~',
|
||||
MPTOKEN = 't',
|
||||
CREDENTIAL = LEDGER_NAMESPACE2(0x01, 'D'),
|
||||
CREDENTIAL = 'D',
|
||||
PERMISSIONED_DOMAIN = 'm',
|
||||
|
||||
// No longer used or supported. Left here to reserve the space
|
||||
|
||||
@@ -87,6 +87,17 @@ InnerObjectFormats::InnerObjectFormats()
|
||||
{sfEmittedTxnID, soeREQUIRED},
|
||||
{sfEmitNonce, soeOPTIONAL}});
|
||||
|
||||
add(sfHookDefinition.jsonName,
|
||||
sfHookDefinition.getCode(),
|
||||
{{sfCreateCode, soeREQUIRED},
|
||||
{sfHookNamespace, soeREQUIRED},
|
||||
{sfHookParameters, soeREQUIRED},
|
||||
{sfHookOn, soeREQUIRED},
|
||||
{sfHookCanEmit, soeOPTIONAL},
|
||||
{sfHookApiVersion, soeREQUIRED},
|
||||
{sfFlags, soeREQUIRED},
|
||||
{sfFee, soeREQUIRED}});
|
||||
|
||||
add(sfHook.jsonName,
|
||||
sfHook.getCode(),
|
||||
{{sfHookHash, soeOPTIONAL},
|
||||
@@ -95,11 +106,8 @@ InnerObjectFormats::InnerObjectFormats()
|
||||
{sfHookNamespace, soeOPTIONAL},
|
||||
{sfHookParameters, soeOPTIONAL},
|
||||
{sfHookOn, soeOPTIONAL},
|
||||
{sfHookOnIncoming, soeOPTIONAL},
|
||||
{sfHookOnOutgoing, soeOPTIONAL},
|
||||
{sfHookCanEmit, soeOPTIONAL},
|
||||
{sfHookApiVersion, soeOPTIONAL},
|
||||
{sfHookName, soeOPTIONAL},
|
||||
{sfFlags, soeOPTIONAL}});
|
||||
|
||||
add(sfHookGrant.jsonName,
|
||||
@@ -254,24 +262,6 @@ InnerObjectFormats::InnerObjectFormats()
|
||||
{sfIssuer, soeREQUIRED},
|
||||
{sfCredentialType, soeREQUIRED},
|
||||
});
|
||||
|
||||
add(sfHighReward.jsonName,
|
||||
sfHighReward.getCode(),
|
||||
{
|
||||
{sfRewardLgrFirst, soeREQUIRED},
|
||||
{sfRewardLgrLast, soeREQUIRED},
|
||||
{sfRewardTime, soeREQUIRED},
|
||||
{sfTrustLineRewardAccumulator, soeREQUIRED},
|
||||
});
|
||||
|
||||
add(sfLowReward.jsonName,
|
||||
sfLowReward.getCode(),
|
||||
{
|
||||
{sfRewardLgrFirst, soeREQUIRED},
|
||||
{sfRewardLgrLast, soeREQUIRED},
|
||||
{sfRewardTime, soeREQUIRED},
|
||||
{sfTrustLineRewardAccumulator, soeREQUIRED},
|
||||
});
|
||||
}
|
||||
|
||||
InnerObjectFormats const&
|
||||
|
||||
@@ -111,7 +111,7 @@ issueFromJson(Json::Value const& v)
|
||||
}
|
||||
|
||||
auto const currency = to_currency(curStr.asString());
|
||||
if (isBadCurrency(currency) || currency == noCurrency())
|
||||
if (currency == badCurrency() || currency == noCurrency())
|
||||
{
|
||||
Throw<Json::error>("issueFromJson currency must be a valid currency");
|
||||
}
|
||||
|
||||
@@ -153,12 +153,4 @@ Rules::operator!=(Rules const& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
bool
|
||||
isFeatureEnabled(uint256 const& feature)
|
||||
{
|
||||
auto const& rules = getCurrentTransactionRules();
|
||||
return rules && rules->enabled(feature);
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
@@ -103,7 +103,7 @@ currencyFromJson(SField const& name, Json::Value const& v)
|
||||
}
|
||||
|
||||
auto const currency = to_currency(v.asString());
|
||||
if (isBadCurrency(currency) || currency == noCurrency())
|
||||
if (currency == badCurrency() || currency == noCurrency())
|
||||
{
|
||||
Throw<std::runtime_error>(
|
||||
"currencyFromJson currency must be a valid currency");
|
||||
|
||||
@@ -48,7 +48,6 @@ TxFormats::TxFormats()
|
||||
{sfFirstLedgerSequence, soeOPTIONAL},
|
||||
{sfNetworkID, soeOPTIONAL},
|
||||
{sfHookParameters, soeOPTIONAL},
|
||||
{sfHookName, soeOPTIONAL},
|
||||
};
|
||||
|
||||
#pragma push_macro("UNWRAP")
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user