Compare commits

..

10 Commits

Author SHA1 Message Date
Pratik Mankawde
a6b0671f21 cleanup one more include
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-22 14:07:06 +00:00
Pratik Mankawde
9d08722cd0 minor change
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-22 12:43:18 +00:00
Pratik Mankawde
6e17998acb ordering changes
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-22 12:15:18 +00:00
Pratik Mankawde
72ad34d214 more changes
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-22 11:46:20 +00:00
Pratik Mankawde
c9dd2d73e2 Merge remote-tracking branch 'origin/develop' into pratik/Move-includes-to-cpp-files 2026-01-22 11:05:03 +00:00
Pratik Mankawde
63d91b24b9 first itr
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-22 11:03:40 +00:00
David Fuelling
211054baff docs: Update Ripple Bug Bounty public key (#6258)
The Ripple Bug Bounty program recently changed the public keys that security researchers can use to encrypt vulnerabilities and messages for submission to the program. This information was updated on https://ripple.com/legal/bug-bounty/ and this PR updates the `SECURITY.md` to align.
2026-01-21 19:55:56 -05:00
Bart
4fd4e93b3e ci: Add missing commit hash to Conan recipe version (#6256)
During several iterations of development of https://github.com/XRPLF/rippled/pull/6235, the commit hash was supposed to be moved into the `run:` statement, but it slipped through the cracks and did not get added. This change adds the commit hash as suffix to the Conan recipe version.
2026-01-21 19:17:05 -05:00
Ayaz Salikhov
4cd6cc3e01 fix: Include <functional> header in Number.h (#6254)
The `Number.h` header file now has `std::reference_wrapper` from `<functional>`, but the include is missing, causing downstream build problems. This change adds the header.
2026-01-21 18:52:22 -05:00
Bart
a37c556079 ci: Upload Conan recipe for merges into develop and commits to release (#6235)
This change uploads the `libxrpl` library as a Conan recipe to our remote when (i) merging into the `develop` branch, (ii) committing to a PR that targets a `release*` branch, and (iii) a versioned tag is applied. Clio is only notified in the second case. The user and channel are no longer used when uploading the recipe.

Specific changes are:
* A `generate-version` action is added, which extracts the build version from `BuildInfo.cpp` and appends the short 7-character commit hash to it for merges into the `develop` branch and for commits to a PR that targets a `release*` branch. When a tag is applied, however, the tag itself is used as the version. This functionality has been turned into a separate action as we will use the same versioning logic for creating .rpm and .deb packages, as well as Docker images.
* An `upload-recipe` action is added, which calls the `generate-version` action and further handles the uploading of the recipe to Conan.
* This action is called by both the `on-pr` and `on-trigger` workflows, and a new `on-tag` workflow.

The reason for this change is that we have downstream uses for the `libxrpl` library, but currently only upload the recipe to check for compatibility with Clio when making commits to a PR that targets the release branch.
2026-01-21 17:31:44 -05:00
156 changed files with 364 additions and 19281 deletions

View File

@@ -268,7 +268,6 @@ words:
- venv
- vfalco
- vinnie
- wasmi
- wextra
- wptr
- writeme

6
.github/CODEOWNERS vendored
View File

@@ -1,2 +1,8 @@
# Allow anyone to review any change by default.
*
# Require the rpc-reviewers team to review changes to the rpc code.
include/xrpl/protocol/ @xrplf/rpc-reviewers
src/libxrpl/protocol/ @xrplf/rpc-reviewers
src/xrpld/rpc/ @xrplf/rpc-reviewers
src/xrpld/app/misc/ @xrplf/rpc-reviewers

View File

@@ -0,0 +1,42 @@
name: Generate build version number
description: "Generate build version number."
outputs:
version:
description: "The generated build version number."
value: ${{ steps.version.outputs.version }}
runs:
using: composite
steps:
# When a tag is pushed, the version is used as-is.
- name: Generate version for tag event
if: ${{ github.event_name == 'tag' }}
shell: bash
env:
VERSION: ${{ github.ref_name }}
run: echo "VERSION=${VERSION}" >> "${GITHUB_ENV}"
# When a tag is not pushed, then the version is extracted from the
# BuildInfo.cpp file and the shortened commit hash appended to it.
- name: Generate version for non-tag event
if: ${{ github.event_name != 'tag' }}
shell: bash
run: |
echo 'Extracting version from BuildInfo.cpp.'
VERSION="$(cat src/libxrpl/protocol/BuildInfo.cpp | grep "versionString =" | awk -F '"' '{print $2}')"
if [[ -z "${VERSION}" ]]; then
echo 'Unable to extract version from BuildInfo.cpp.'
exit 1
fi
echo 'Appending shortened commit hash to version.'
SHA='${{ github.sha }}'
VERSION="${VERSION}-${SHA:0:7}"
echo "VERSION=${VERSION}" >> "${GITHUB_ENV}"
- name: Output version
id: version
shell: bash
run: echo "version=${VERSION}" >> "${GITHUB_OUTPUT}"

View File

@@ -2,11 +2,11 @@ name: Setup Conan
description: "Set up Conan configuration, profile, and remote."
inputs:
conan_remote_name:
remote_name:
description: "The name of the Conan remote to use."
required: false
default: xrplf
conan_remote_url:
remote_url:
description: "The URL of the Conan endpoint to use."
required: false
default: https://conan.ripplex.io
@@ -36,11 +36,11 @@ runs:
- name: Set up Conan remote
shell: bash
env:
CONAN_REMOTE_NAME: ${{ inputs.conan_remote_name }}
CONAN_REMOTE_URL: ${{ inputs.conan_remote_url }}
REMOTE_NAME: ${{ inputs.remote_name }}
REMOTE_URL: ${{ inputs.remote_url }}
run: |
echo "Adding Conan remote '${CONAN_REMOTE_NAME}' at '${CONAN_REMOTE_URL}'."
conan remote add --index 0 --force "${CONAN_REMOTE_NAME}" "${CONAN_REMOTE_URL}"
echo "Adding Conan remote '${REMOTE_NAME}' at '${REMOTE_URL}'."
conan remote add --index 0 --force "${REMOTE_NAME}" "${REMOTE_URL}"
echo 'Listing Conan remotes.'
conan remote list

View File

@@ -19,6 +19,7 @@ libxrpl.protocol > xrpl.json
libxrpl.protocol > xrpl.protocol
libxrpl.resource > xrpl.basics
libxrpl.resource > xrpl.json
libxrpl.resource > xrpl.protocol
libxrpl.resource > xrpl.resource
libxrpl.server > xrpl.basics
libxrpl.server > xrpl.json

View File

@@ -1,7 +1,8 @@
# This workflow runs all workflows to check, build and test the project on
# various Linux flavors, as well as on MacOS and Windows, on every push to a
# user branch. However, it will not run if the pull request is a draft unless it
# has the 'DraftRunCI' label.
# has the 'DraftRunCI' label. For commits to PRs that target a release branch,
# it also uploads the libxrpl recipe to the Conan remote.
name: PR
on:
@@ -53,7 +54,6 @@ jobs:
.github/scripts/rename/**
.github/workflows/reusable-check-levelization.yml
.github/workflows/reusable-check-rename.yml
.github/workflows/reusable-notify-clio.yml
.github/workflows/on-pr.yml
# Keep the paths below in sync with those in `on-trigger.yml`.
@@ -66,6 +66,7 @@ jobs:
.github/workflows/reusable-build-test.yml
.github/workflows/reusable-strategy-matrix.yml
.github/workflows/reusable-test.yml
.github/workflows/reusable-upload-recipe.yml
.codecov.yml
cmake/**
conan/**
@@ -121,22 +122,42 @@ jobs:
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
notify-clio:
upload-recipe:
needs:
- should-run
- build-test
if: ${{ needs.should-run.outputs.go == 'true' && startsWith(github.ref, 'refs/heads/release') }}
uses: ./.github/workflows/reusable-notify-clio.yml
# Only run when committing to a PR that targets a release branch in the
# XRPLF repository.
if: ${{ github.repository_owner == 'XRPLF' && needs.should-run.outputs.go == 'true' && startsWith(github.ref, 'refs/heads/release') }}
uses: ./.github/workflows/reusable-upload-recipe.yml
secrets:
clio_notify_token: ${{ secrets.CLIO_NOTIFY_TOKEN }}
conan_remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }}
conan_remote_password: ${{ secrets.CONAN_REMOTE_PASSWORD }}
remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }}
remote_password: ${{ secrets.CONAN_REMOTE_PASSWORD }}
notify-clio:
needs: upload-recipe
runs-on: ubuntu-latest
steps:
# Notify the Clio repository about the newly proposed release version, so
# it can be checked for compatibility before the release is actually made.
- name: Notify Clio
env:
GH_TOKEN: ${{ secrets.CLIO_NOTIFY_TOKEN }}
PR_URL: ${{ github.event.pull_request.html_url }}
run: |
gh api --method POST -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" \
/repos/xrplf/clio/dispatches -f "event_type=check_libxrpl" \
-F "client_payload[ref]=${{ needs.upload-recipe.outputs.recipe_ref }}" \
-F "client_payload[pr_url]=${PR_URL}"
passed:
if: failure() || cancelled()
needs:
- build-test
- check-levelization
- check-rename
- build-test
- upload-recipe
- notify-clio
runs-on: ubuntu-latest
steps:
- name: Fail

25
.github/workflows/on-tag.yml vendored Normal file
View File

@@ -0,0 +1,25 @@
# This workflow uploads the libxrpl recipe to the Conan remote when a versioned
# tag is pushed.
name: Tag
on:
push:
tags:
- "v*"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash
jobs:
upload-recipe:
# Only run when a tag is pushed to the XRPLF repository.
if: ${{ github.repository_owner == 'XRPLF' }}
uses: ./.github/workflows/reusable-upload-recipe.yml
secrets:
remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }}
remote_password: ${{ secrets.CONAN_REMOTE_PASSWORD }}

View File

@@ -1,8 +1,7 @@
# This workflow runs all workflows to build and test the code on various Linux
# flavors, as well as on MacOS and Windows, on a scheduled basis, on merge into
# the 'develop' or 'release*' branches, or when requested manually. Upon
# successful completion, it also uploads the built libxrpl package to the Conan
# remote.
# the 'develop' or 'release*' branches, or when requested manually. Upon pushes
# to the develop branch it also uploads the libxrpl recipe to the Conan remote.
name: Trigger
on:
@@ -24,6 +23,7 @@ on:
- ".github/workflows/reusable-build-test.yml"
- ".github/workflows/reusable-strategy-matrix.yml"
- ".github/workflows/reusable-test.yml"
- ".github/workflows/reusable-upload-recipe.yml"
- ".codecov.yml"
- "cmake/**"
- "conan/**"
@@ -76,3 +76,12 @@ jobs:
strategy_matrix: ${{ github.event_name == 'schedule' && 'all' || 'minimal' }}
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
upload-recipe:
needs: build-test
# Only run when pushing to the develop branch in the XRPLF repository.
if: ${{ github.repository_owner == 'XRPLF' && github.event_name == 'push' && github.ref == 'refs/heads/develop' }}
uses: ./.github/workflows/reusable-upload-recipe.yml
secrets:
remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }}
remote_password: ${{ secrets.CONAN_REMOTE_PASSWORD }}

View File

@@ -1,91 +0,0 @@
# This workflow exports the built libxrpl package to the Conan remote on a
# a channel named after the pull request, and notifies the Clio repository about
# the new version so it can check for compatibility.
name: Notify Clio
# This workflow can only be triggered by other workflows.
on:
workflow_call:
inputs:
conan_remote_name:
description: "The name of the Conan remote to use."
required: false
type: string
default: xrplf
conan_remote_url:
description: "The URL of the Conan endpoint to use."
required: false
type: string
default: https://conan.ripplex.io
secrets:
clio_notify_token:
description: "The GitHub token to notify Clio about new versions."
required: true
conan_remote_username:
description: "The username for logging into the Conan remote."
required: true
conan_remote_password:
description: "The password for logging into the Conan remote."
required: true
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-clio
cancel-in-progress: true
defaults:
run:
shell: bash
jobs:
upload:
if: ${{ github.event.pull_request.head.repo.full_name == github.repository }}
runs-on: ubuntu-latest
container: ghcr.io/xrplf/ci/ubuntu-noble:gcc-13-sha-5dd7158
steps:
- name: Checkout repository
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Generate outputs
id: generate
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
echo 'Generating user and channel.'
echo "user=clio" >> "${GITHUB_OUTPUT}"
echo "channel=pr_${PR_NUMBER}" >> "${GITHUB_OUTPUT}"
echo 'Extracting version.'
echo "version=$(cat src/libxrpl/protocol/BuildInfo.cpp | grep "versionString =" | awk -F '"' '{print $2}')" >> "${GITHUB_OUTPUT}"
- name: Calculate conan reference
id: conan_ref
run: |
echo "conan_ref=${{ steps.generate.outputs.version }}@${{ steps.generate.outputs.user }}/${{ steps.generate.outputs.channel }}" >> "${GITHUB_OUTPUT}"
- name: Set up Conan
uses: ./.github/actions/setup-conan
with:
conan_remote_name: ${{ inputs.conan_remote_name }}
conan_remote_url: ${{ inputs.conan_remote_url }}
- name: Log into Conan remote
env:
CONAN_REMOTE_NAME: ${{ inputs.conan_remote_name }}
run: conan remote login "${CONAN_REMOTE_NAME}" "${{ secrets.conan_remote_username }}" --password "${{ secrets.conan_remote_password }}"
- name: Upload package
env:
CONAN_REMOTE_NAME: ${{ inputs.conan_remote_name }}
run: |
conan export --user=${{ steps.generate.outputs.user }} --channel=${{ steps.generate.outputs.channel }} .
conan upload --confirm --check --remote="${CONAN_REMOTE_NAME}" xrpl/${{ steps.conan_ref.outputs.conan_ref }}
outputs:
conan_ref: ${{ steps.conan_ref.outputs.conan_ref }}
notify:
needs: upload
runs-on: ubuntu-latest
steps:
- name: Notify Clio
env:
GH_TOKEN: ${{ secrets.clio_notify_token }}
PR_URL: ${{ github.event.pull_request.html_url }}
run: |
gh api --method POST -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" \
/repos/xrplf/clio/dispatches -f "event_type=check_libxrpl" \
-F "client_payload[conan_ref]=${{ needs.upload.outputs.conan_ref }}" \
-F "client_payload[pr_url]=${PR_URL}"

View File

@@ -0,0 +1,78 @@
# This workflow exports the built libxrpl package to the Conan remote.
name: Upload Conan recipe
# This workflow can only be triggered by other workflows.
on:
workflow_call:
inputs:
remote_name:
description: "The name of the Conan remote to use."
required: false
type: string
default: xrplf
remote_url:
description: "The URL of the Conan endpoint to use."
required: false
type: string
default: https://conan.ripplex.io
secrets:
remote_username:
description: "The username for logging into the Conan remote."
required: true
remote_password:
description: "The password for logging into the Conan remote."
required: true
outputs:
recipe_ref:
description: "The Conan recipe reference ('name/version') that was uploaded."
value: ${{ jobs.upload.outputs.ref }}
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-upload-recipe
cancel-in-progress: true
defaults:
run:
shell: bash
jobs:
upload:
runs-on: ubuntu-latest
container: ghcr.io/xrplf/ci/ubuntu-noble:gcc-13-sha-5dd7158
steps:
- name: Checkout repository
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Generate build version number
id: version
uses: ./.github/actions/generate-version
- name: Determine recipe reference
id: ref
run: echo "ref=xrpl/${{ steps.version.outputs.version }}" >> "${GITHUB_OUTPUT}"
- name: Set up Conan
uses: ./.github/actions/setup-conan
with:
remote_name: ${{ inputs.remote_name }}
remote_url: ${{ inputs.remote_url }}
- name: Log into Conan remote
env:
REMOTE_NAME: ${{ inputs.remote_name }}
REMOTE_USERNAME: ${{ inputs.remote_username }}
REMOTE_PASSWORD: ${{ inputs.remote_password }}
run: conan remote login "${REMOTE_NAME}" "${REMOTE_USERNAME}" --password "${REMOTE_PASSWORD}"
- name: Upload Conan recipe
env:
RECIPE_REF: ${{ steps.ref.outputs.ref }}
REMOTE_NAME: ${{ inputs.remote_name }}
run: |
conan export .
conan upload --confirm --check --remote="${REMOTE_NAME}" ${RECIPE_REF}
outputs:
ref: ${{ steps.ref.outputs.ref }}

View File

@@ -86,8 +86,8 @@ jobs:
- name: Setup Conan
uses: ./.github/actions/setup-conan
with:
conan_remote_name: ${{ env.CONAN_REMOTE_NAME }}
conan_remote_url: ${{ env.CONAN_REMOTE_URL }}
remote_name: ${{ env.CONAN_REMOTE_NAME }}
remote_url: ${{ env.CONAN_REMOTE_URL }}
- name: Build dependencies
uses: ./.github/actions/build-deps

View File

@@ -103,7 +103,6 @@ find_package(OpenSSL REQUIRED)
find_package(secp256k1 REQUIRED)
find_package(SOCI REQUIRED)
find_package(SQLite3 REQUIRED)
find_package(wasmi REQUIRED)
find_package(xxHash REQUIRED)
target_link_libraries(xrpl_libs INTERFACE

View File

@@ -78,72 +78,61 @@ To report a qualifying bug, please send a detailed report to:
| Email Address | bugs@ripple.com |
| :-----------: | :-------------------------------------------------- |
| Short Key ID | `0xC57929BE` |
| Long Key ID | `0xCD49A0AFC57929BE` |
| Fingerprint | `24E6 3B02 37E0 FA9C 5E96 8974 CD49 A0AF C579 29BE` |
| Short Key ID | `0xA9F514E0` |
| Long Key ID | `0xD900855AA9F514E0` |
| Fingerprint | `B72C 0654 2F2A E250 2763 A268 D900 855A A9F5 14E0` |
The full PGP key for this address, which is also available on several key servers (e.g. on [keyserver.ubuntu.com](https://keyserver.ubuntu.com)), is:
```
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
7Tz8SQkuxltX/yBXMV3Ddy0t6nWV2SZEfuxJAQI=
=spg4
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
=nGuD
-----END PGP PUBLIC KEY BLOCK-----
```

View File

@@ -63,7 +63,6 @@ target_link_libraries(xrpl.imports.main
Xrpl::opts
Xrpl::syslibs
secp256k1::secp256k1
wasmi::wasmi
xrpl.libpb
xxHash::xxhash
$<$<BOOL:${voidstar}>:antithesis-sdk-cpp>

View File

@@ -3,7 +3,6 @@
"requires": [
"zlib/1.3.1#b8bc2603263cf7eccbd6e17e66b0ed76%1765850150.075",
"xxhash/0.8.3#681d36a0a6111fc56e5e45ea182c19cc%1765850149.987",
"wasmi/1.0.6#407c9db14601a8af1c7dd3b388f3e4cd%1768164779.349",
"sqlite3/3.49.1#8631739a4c9b93bd3d6b753bac548a63%1765850149.926",
"soci/4.0.3#a9f8d773cd33e356b5879a4b0564f287%1765850149.46",
"snappy/1.1.10#968fef506ff261592ec30c574d4a7809%1765850147.878",

View File

@@ -35,7 +35,6 @@ class Xrpl(ConanFile):
"openssl/3.5.4",
"secp256k1/0.7.0",
"soci/4.0.3",
"wasmi/1.0.6",
"zlib/1.3.1",
]
@@ -217,7 +216,6 @@ class Xrpl(ConanFile):
"soci::soci",
"secp256k1::secp256k1",
"sqlite3::sqlite",
"wasmi::wasmi",
"xxhash::xxhash",
"zlib::zlib",
]

View File

@@ -4,6 +4,7 @@
#include <xrpl/beast/utility/instrumentation.h>
#include <cstdint>
#include <functional>
#include <limits>
#include <optional>
#include <ostream>
@@ -750,10 +751,6 @@ abs(Number x) noexcept
Number
power(Number const& f, unsigned n);
// logarithm with base 10
Number
lg(Number const& value);
// Returns f^(1/d)
// Uses NewtonRaphson iterations until the result stops changing
// to find the root of the polynomial g(x) = x^d - f

View File

@@ -3,16 +3,19 @@
#include <xrpl/basics/CountedObject.h>
#include <xrpl/core/ClosureCounter.h>
#include <xrpl/core/LoadMonitor.h>
#include <functional>
#include <memory>
namespace xrpl {
class LoadEvent;
class LoadMonitor;
// Note that this queue should only be used for CPU-bound jobs
// It is primarily intended for signature checking
enum JobType {
enum JobType : int {
// Special type indicating an invalid job - will go away soon.
jtINVALID = -1,

View File

@@ -5,6 +5,7 @@
#include <xrpl/core/ClosureCounter.h>
#include <xrpl/core/JobTypeData.h>
#include <xrpl/core/JobTypes.h>
#include <xrpl/core/LoadEvent.h>
#include <xrpl/core/detail/Workers.h>
#include <xrpl/json/json_value.h>

View File

@@ -4,9 +4,12 @@
#include <xrpl/basics/Log.h>
#include <xrpl/beast/insight/Collector.h>
#include <xrpl/core/JobTypeInfo.h>
#include <xrpl/core/LoadMonitor.h>
namespace xrpl {
enum JobType : int;
struct JobTypeData
{
private:

View File

@@ -1,10 +1,13 @@
#ifndef XRPL_CORE_JOBTYPEINFO_H_INCLUDED
#define XRPL_CORE_JOBTYPEINFO_H_INCLUDED
#include <xrpl/core/Job.h>
#include <chrono>
#include <string>
namespace xrpl {
enum JobType : int;
/** Holds all the 'static' information about a job, which does not change */
class JobTypeInfo
{

View File

@@ -3,13 +3,14 @@
#include <xrpl/basics/UptimeClock.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/core/LoadEvent.h>
#include <chrono>
#include <mutex>
namespace xrpl {
class LoadEvent;
// Monitors load levels and response times
// VFALCO TODO Rename this. Having both LoadManager and LoadMonitor is

View File

@@ -1,9 +1,8 @@
#ifndef XRPL_CORE_PERFLOG_H
#define XRPL_CORE_PERFLOG_H
#include <xrpl/basics/BasicConfig.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/core/JobTypes.h>
#include <xrpl/json/json_value.h>
#include <boost/filesystem.hpp>
@@ -13,11 +12,14 @@
#include <memory>
#include <string>
namespace beast {
class Journal;
namespace Json {
class Value;
}
class Section;
namespace xrpl {
class Application;
namespace perf {

View File

@@ -7,11 +7,13 @@
#include <xrpl/ledger/ApplyView.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/STArray.h>
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/TER.h>
namespace xrpl {
class STArray;
class STTx;
namespace credentials {
// These function will be used by the code that use DepositPreauth / Credentials

View File

@@ -1,7 +1,6 @@
#ifndef XRPL_LEDGER_PAYMENTSANDBOX_H_INCLUDED
#define XRPL_LEDGER_PAYMENTSANDBOX_H_INCLUDED
#include <xrpl/ledger/RawView.h>
#include <xrpl/ledger/Sandbox.h>
#include <xrpl/ledger/detail/ApplyViewBase.h>
#include <xrpl/protocol/AccountID.h>
@@ -10,6 +9,9 @@
namespace xrpl {
// Forward declarations
class RawView;
namespace detail {
// VFALCO TODO Inline this implementation

View File

@@ -12,14 +12,17 @@
#include <xrpl/protocol/Rules.h>
#include <xrpl/protocol/STAmount.h>
#include <xrpl/protocol/STLedgerEntry.h>
#include <xrpl/protocol/STTx.h>
#include <cstdint>
#include <memory>
#include <optional>
#include <unordered_set>
namespace xrpl {
class STTx;
class STObject;
//------------------------------------------------------------------------------
/** A view into a ledger.

View File

@@ -6,7 +6,6 @@
#include <xrpl/protocol/Keylet.h>
#include <xrpl/protocol/LedgerFormats.h>
#include <xrpl/protocol/Protocol.h>
#include <xrpl/protocol/PublicKey.h>
#include <xrpl/protocol/STXChainBridge.h>
#include <xrpl/protocol/Serializer.h>
#include <xrpl/protocol/UintTypes.h>

View File

@@ -2,13 +2,14 @@
#define XRPL_PROTOCOL_NFTSYNTHETICSERIALIZER_H_INCLUDED
#include <xrpl/json/json_forwards.h>
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/TxMeta.h>
#include <memory>
namespace xrpl {
class STTx;
class TxMeta;
namespace RPC {
/**

View File

@@ -3,8 +3,6 @@
#include <xrpl/basics/base_uint.h>
#include <xrpl/json/json_forwards.h>
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/TxMeta.h>
#include <memory>
#include <optional>
@@ -12,6 +10,9 @@
namespace xrpl {
class STTx;
class TxMeta;
/**
Add a `nftoken_ids` field to the `meta` output parameter.
The field is only added to successful NFTokenMint, NFTokenAcceptOffer,

View File

@@ -3,14 +3,15 @@
#include <xrpl/basics/base_uint.h>
#include <xrpl/json/json_forwards.h>
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/TxMeta.h>
#include <memory>
#include <optional>
namespace xrpl {
class STTx;
class TxMeta;
/**
Add an `offer_id` field to the `meta` output parameter.
The field is only added to successful NFTokenCreateOffer transactions.

View File

@@ -1,15 +1,17 @@
#ifndef XRPL_PROTOCOL_PERMISSION_H_INCLUDED
#define XRPL_PROTOCOL_PERMISSION_H_INCLUDED
#include <xrpl/protocol/Rules.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/TxFormats.h>
#include <optional>
#include <string>
#include <unordered_map>
namespace xrpl {
class Rules;
enum TxType : std::uint16_t;
/**
* We have both transaction type permissions and granular type permissions.
* Since we will reuse the TransactionFormats to parse the Transaction

View File

@@ -252,13 +252,6 @@ std::uint8_t constexpr vaultMaximumIOUScale = 18;
* another vault; counted from 0 */
std::uint8_t constexpr maxAssetCheckDepth = 5;
/** The maximum length of a Data field in Escrow object that can be updated by
* Wasm code */
std::size_t constexpr maxWasmDataLength = 4 * 1024;
/** The maximum length of a parameters passed from Wasm code*/
std::size_t constexpr maxWasmParamLength = 1024;
/** A ledger index. */
using LedgerIndex = std::uint32_t;

View File

@@ -11,7 +11,6 @@
#include <xrpl/protocol/MPTAmount.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STBase.h>
#include <xrpl/protocol/Serializer.h>
#include <xrpl/protocol/XRPAmount.h>
#include <xrpl/protocol/json_get_or_throw.h>

View File

@@ -5,7 +5,6 @@
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/Serializer.h>
#include <ostream>
#include <string>
#include <type_traits>
#include <typeinfo>

View File

@@ -5,8 +5,6 @@
#include <xrpl/json/json_value.h>
#include <optional>
#include <ostream>
#include <string>
#include <unordered_map>
namespace xrpl {
@@ -122,8 +120,6 @@ enum TEMcodes : TERUnderlyingType {
temARRAY_TOO_LARGE,
temBAD_TRANSFER_FEE,
temINVALID_INNER_BATCH,
temBAD_WASM,
};
//------------------------------------------------------------------------------

View File

@@ -38,13 +38,16 @@ enum TxType : std::uint16_t
{
#pragma push_macro("TRANSACTION")
#pragma push_macro("TRANSACTION_INCLUDE")
#undef TRANSACTION
#undef TRANSACTION_INCLUDE
#define TRANSACTION(tag, value, ...) tag = value,
#include <xrpl/protocol/detail/transactions.macro>
#undef TRANSACTION
#pragma pop_macro("TRANSACTION_INCLUDE")
#pragma pop_macro("TRANSACTION")
/** This transaction type is deprecated; it is retained for historical purposes. */

View File

@@ -578,7 +578,7 @@ LEDGER_ENTRY(ltLOAN, 0x0089, Loan, loan, ({
// The unrounded true total value of the loan.
//
// - TrueTotalPrincipalOutstanding can be computed using the algorithm
// in the xrpl::detail::loanPrincipalFromPeriodicPayment function.
// in the ripple::detail::loanPrincipalFromPeriodicPayment function.
//
// - TrueTotalInterestOutstanding = TrueTotalLoanValue -
// TrueTotalPrincipalOutstanding

View File

@@ -2,11 +2,13 @@
#define XRPL_RESOURCE_CONSUMER_H_INCLUDED
#include <xrpl/basics/Log.h>
#include <xrpl/protocol/PublicKey.h>
#include <xrpl/resource/Charge.h>
#include <xrpl/resource/Disposition.h>
namespace xrpl {
class PublicKey;
namespace Resource {
struct Entry;

View File

@@ -5,6 +5,7 @@
#include <xrpl/beast/clock/abstract_clock.h>
#include <xrpl/beast/core/List.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/PublicKey.h>
#include <xrpl/resource/detail/Key.h>
#include <xrpl/resource/detail/Tuning.h>

View File

@@ -984,48 +984,6 @@ power(Number const& f, unsigned n)
return r;
}
// Continued fraction approximation of ln(x)
static Number
ln(Number const& x, unsigned iterations = 50)
{
if (x <= 0)
throw std::runtime_error("Not positive value");
Number const z = (x - 1) / (x + 1);
Number const zz = z * z;
Number denom = Number(1, -10);
// Construct the fraction from the bottom up
for (int i = iterations; i > 0; --i)
{
Number k(2 * i - 1);
denom = k - (i * i * zz / denom);
}
auto const r = 2 * z / denom;
return r;
}
Number
lg(Number const& x)
{
static Number const ln10 = ln(Number(10));
if (x <= Number(10))
{
auto const r = ln(x) / ln10;
return r;
}
// ln(x) = ln(normX * 10^norm) = ln(normX) + norm * ln(10)
int diffExp = 15 + x.exponent();
Number const normalX = x / Number(1, diffExp); // (1 <= normalX < 10)
auto const lnX = ln(normalX) + diffExp * ln10;
auto const r = lnX / ln10;
return r;
}
// Returns f^(1/d)
// Uses NewtonRaphson iterations until the result stops changing
// to find the non-negative root of the polynomial g(x) = x^d - f

View File

@@ -1,5 +1,7 @@
#include <xrpl/beast/core/CurrentThreadName.h>
#include <xrpl/core/Job.h>
#include <xrpl/core/LoadEvent.h>
#include <xrpl/core/LoadMonitor.h>
namespace xrpl {

View File

@@ -1,5 +1,6 @@
#include <xrpl/basics/contract.h>
#include <xrpl/core/JobQueue.h>
#include <xrpl/core/LoadEvent.h>
#include <xrpl/core/PerfLog.h>
#include <mutex>

View File

@@ -1,5 +1,6 @@
#include <xrpl/basics/Log.h>
#include <xrpl/basics/UptimeClock.h>
#include <xrpl/core/LoadEvent.h>
#include <xrpl/core/LoadMonitor.h>
namespace xrpl {

View File

@@ -1,6 +1,7 @@
#include <xrpl/basics/contract.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/ledger/ApplyView.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Protocol.h>
#include <limits>

View File

@@ -1,5 +1,7 @@
#include <xrpl/ledger/CredentialHelpers.h>
#include <xrpl/ledger/View.h>
#include <xrpl/protocol/STArray.h>
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/digest.h>

View File

@@ -1,5 +1,6 @@
#include <xrpl/basics/contract.h>
#include <xrpl/ledger/OpenView.h>
#include <xrpl/protocol/STTx.h>
namespace xrpl {

View File

@@ -1,5 +1,6 @@
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/ledger/PaymentSandbox.h>
#include <xrpl/ledger/RawView.h>
#include <xrpl/ledger/View.h>
#include <xrpl/protocol/SField.h>

View File

@@ -2,6 +2,7 @@
#include <xrpl/basics/Log.h>
#include <xrpl/basics/chrono.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/ledger/ApplyView.h>
#include <xrpl/ledger/CredentialHelpers.h>
#include <xrpl/ledger/Credit.h>
#include <xrpl/ledger/ReadView.h>

View File

@@ -1,7 +1,9 @@
#include <xrpl/basics/chrono.h>
#include <xrpl/beast/core/CurrentThreadName.h>
#include <xrpl/json/json_value.h>
#include <xrpl/nodestore/Backend.h>
#include <xrpl/nodestore/Database.h>
#include <xrpl/nodestore/Scheduler.h>
#include <xrpl/protocol/HashPrefix.h>
#include <xrpl/protocol/jss.h>

View File

@@ -1,6 +1,8 @@
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Permissions.h>
#include <xrpl/protocol/Rules.h>
#include <xrpl/protocol/TxFormats.h>
#include <xrpl/protocol/jss.h>
namespace xrpl {

View File

@@ -1,9 +1,11 @@
#include <xrpl/json/json_value.h>
#include <xrpl/protocol/TER.h>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <optional>
#include <ostream>
#include <string>
#include <unordered_map>
#include <utility>
@@ -200,7 +202,6 @@ transResults()
MAKE_ERROR(temARRAY_TOO_LARGE, "Malformed: Array is too large."),
MAKE_ERROR(temBAD_TRANSFER_FEE, "Malformed: Transfer fee is outside valid range."),
MAKE_ERROR(temINVALID_INNER_BATCH, "Malformed: Invalid inner batch transaction."),
MAKE_ERROR(temBAD_WASM, "Malformed: Provided WASM code is invalid."),
MAKE_ERROR(terRETRY, "Retry transaction."),
MAKE_ERROR(terFUNDS_SPENT, "DEPRECATED."),

View File

@@ -1,6 +1,7 @@
#include <xrpl/basics/Log.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/PublicKey.h>
#include <xrpl/resource/Charge.h>
#include <xrpl/resource/Consumer.h>
#include <xrpl/resource/Disposition.h>

View File

@@ -1,9 +1,13 @@
#include <xrpl/basics/TaggedCache.ipp>
#include <xrpl/basics/contract.h>
#include <xrpl/shamap/Family.h>
#include <xrpl/shamap/SHAMap.h>
#include <xrpl/shamap/SHAMapAccountStateLeafNode.h>
#include <xrpl/shamap/SHAMapInnerNode.h>
#include <xrpl/shamap/SHAMapLeafNode.h>
#include <xrpl/shamap/SHAMapNodeID.h>
#include <xrpl/shamap/SHAMapSyncFilter.h>
#include <xrpl/shamap/SHAMapTreeNode.h>
#include <xrpl/shamap/SHAMapTxLeafNode.h>
#include <xrpl/shamap/SHAMapTxPlusMetaLeafNode.h>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,995 +0,0 @@
#ifdef _DEBUG
// #define DEBUG_OUTPUT 1
#endif
#include <test/app/TestHostFunctions.h>
#include <xrpld/app/wasm/HostFuncWrapper.h>
#if (defined(__clang_major__) && __clang_major__ < 15)
#include <experimental/source_location>
using source_location = std::experimental::source_location;
#else
#include <source_location>
using std::source_location;
#endif
namespace xrpl {
namespace test {
bool
testGetDataIncrement();
using Add_proto = int32_t(int32_t, int32_t);
static wasm_trap_t*
Add(void* env, wasm_val_vec_t const* params, wasm_val_vec_t* results)
{
int32_t Val1 = params->data[0].of.i32;
int32_t Val2 = params->data[1].of.i32;
// printf("Host function \"Add\": %d + %d\n", Val1, Val2);
results->data[0] = WASM_I32_VAL(Val1 + Val2);
return nullptr;
}
std::optional<int32_t>
runFinishFunction(std::string const& code)
{
auto& engine = WasmEngine::instance();
auto const ws = boost::algorithm::unhex(code);
Bytes const wasm(ws.begin(), ws.end());
auto const re = engine.run(wasm, "finish");
if (re.has_value())
{
return std::optional<int32_t>(re->result);
}
else
{
return std::nullopt;
}
}
struct Wasm_test : public beast::unit_test::suite
{
void
checkResult(
Expected<WasmResult<int32_t>, TER> re,
int32_t expectedResult,
int64_t expectedCost,
source_location const location = source_location::current())
{
auto const lineStr = " (" + std::to_string(location.line()) + ")";
if (BEAST_EXPECTS(re.has_value(), transToken(re.error()) + lineStr))
{
BEAST_EXPECTS(
re->result == expectedResult,
std::to_string(re->result) + lineStr);
BEAST_EXPECTS(
re->cost == expectedCost, std::to_string(re->cost) + lineStr);
}
}
void
testGetDataHelperFunctions()
{
testcase("getData helper functions");
BEAST_EXPECT(testGetDataIncrement());
}
void
testWasmLib()
{
testcase("wasmtime lib test");
// clang-format off
/* The WASM module buffer. */
Bytes const wasm = {/* WASM header */
0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00, 0x00,
/* Type section */
0x01, 0x07, 0x01,
/* function type {i32, i32} -> {i32} */
0x60, 0x02, 0x7F, 0x7F, 0x01, 0x7F,
/* Import section */
0x02, 0x13, 0x01,
/* module name: "extern" */
0x06, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6E,
/* extern name: "func-add" */
0x08, 0x66, 0x75, 0x6E, 0x63, 0x2D, 0x61, 0x64, 0x64,
/* import desc: func 0 */
0x00, 0x00,
/* Function section */
0x03, 0x02, 0x01, 0x00,
/* Export section */
0x07, 0x0A, 0x01,
/* export name: "addTwo" */
0x06, 0x61, 0x64, 0x64, 0x54, 0x77, 0x6F,
/* export desc: func 0 */
0x00, 0x01,
/* Code section */
0x0A, 0x0A, 0x01,
/* code body */
0x08, 0x00, 0x20, 0x00, 0x20, 0x01, 0x10, 0x00, 0x0B};
// clang-format on
auto& vm = WasmEngine::instance();
std::shared_ptr<ImportVec> imports(std::make_shared<ImportVec>());
WasmImpFunc<Add_proto>(
*imports, "func-add", reinterpret_cast<void*>(&Add));
auto re = vm.run(wasm, "addTwo", wasmParams(1234, 5678), imports);
// if (res) printf("invokeAdd get the result: %d\n", res.value());
checkResult(re, 6'912, 59);
}
void
testBadWasm()
{
testcase("bad wasm test");
using namespace test::jtx;
Env env{*this};
std::shared_ptr<HostFunctions> hfs(new HostFunctions(env.journal));
{
auto wasmHex = "00000000";
auto wasmStr = boost::algorithm::unhex(std::string(wasmHex));
std::vector<uint8_t> wasm(wasmStr.begin(), wasmStr.end());
std::string funcName("mock_escrow");
auto re = runEscrowWasm(wasm, hfs, funcName, {}, 15);
BEAST_EXPECT(!re);
}
{
auto wasmHex = "00112233445566778899AA";
auto wasmStr = boost::algorithm::unhex(std::string(wasmHex));
std::vector<uint8_t> wasm(wasmStr.begin(), wasmStr.end());
std::string funcName("mock_escrow");
auto const re = preflightEscrowWasm(wasm, hfs, funcName);
BEAST_EXPECT(!isTesSuccess(re));
}
{
// FinishFunction wrong function name
// pub fn bad() -> bool {
// unsafe { host_lib::getLedgerSqn() >= 5 }
// }
auto const badWasmHex =
"0061736d010000000105016000017f02190108686f73745f6c69620c6765"
"744c656467657253716e00000302010005030100100611027f00418080c0"
"000b7f00418080c0000b072b04066d656d6f727902000362616400010a5f"
"5f646174615f656e6403000b5f5f686561705f6261736503010a09010700"
"100041044a0b004d0970726f64756365727302086c616e67756167650104"
"52757374000c70726f6365737365642d6279010572757374631d312e3835"
"2e31202834656231363132353020323032352d30332d31352900490f7461"
"726765745f6665617475726573042b0f6d757461626c652d676c6f62616c"
"732b087369676e2d6578742b0f7265666572656e63652d74797065732b0a"
"6d756c746976616c7565";
auto wasmStr = boost::algorithm::unhex(std::string(badWasmHex));
std::vector<uint8_t> wasm(wasmStr.begin(), wasmStr.end());
auto const re =
preflightEscrowWasm(wasm, hfs, ESCROW_FUNCTION_NAME);
BEAST_EXPECT(!isTesSuccess(re));
}
}
void
testWasmLedgerSqn()
{
testcase("Wasm get ledger sequence");
auto wasmStr = boost::algorithm::unhex(ledgerSqnWasmHex);
Bytes wasm(wasmStr.begin(), wasmStr.end());
using namespace test::jtx;
Env env{*this};
std::shared_ptr<HostFunctions> hfs(new TestLedgerDataProvider(env));
auto imports = std::make_shared<ImportVec>();
WASM_IMPORT_FUNC2(
*imports, getLedgerSqn, "get_ledger_sqn", hfs.get(), 33);
auto& engine = WasmEngine::instance();
auto re = engine.run(
wasm,
ESCROW_FUNCTION_NAME,
{},
imports,
hfs,
1'000'000,
env.journal);
checkResult(re, 0, 151);
env.close();
env.close();
// empty module - run the same instance
re = engine.run(
{}, ESCROW_FUNCTION_NAME, {}, imports, hfs, 1'000'000, env.journal);
checkResult(re, 5, 190);
}
void
testWasmFib()
{
testcase("Wasm fibo");
auto const ws = boost::algorithm::unhex(fibWasmHex);
Bytes const wasm(ws.begin(), ws.end());
auto& engine = WasmEngine::instance();
auto const re = engine.run(wasm, "fib", wasmParams(10));
checkResult(re, 55, 1'137);
}
void
testWasmSha()
{
testcase("Wasm sha");
auto const ws = boost::algorithm::unhex(sha512PureWasmHex);
Bytes const wasm(ws.begin(), ws.end());
auto& engine = WasmEngine::instance();
auto const re =
engine.run(wasm, "sha512_process", wasmParams(sha512PureWasmHex));
checkResult(re, 34'432, 151'155);
}
void
testWasmB58()
{
testcase("Wasm base58");
auto const ws = boost::algorithm::unhex(b58WasmHex);
Bytes const wasm(ws.begin(), ws.end());
auto& engine = WasmEngine::instance();
Bytes outb;
outb.resize(1024);
auto const minsz = std::min(
static_cast<std::uint32_t>(512),
static_cast<std::uint32_t>(b58WasmHex.size()));
auto const s = std::string_view(b58WasmHex.c_str(), minsz);
auto const re = engine.run(wasm, "b58enco", wasmParams(outb, s));
checkResult(re, 700, 2'886'069);
}
void
testHFCost()
{
testcase("wasm test host functions cost");
using namespace test::jtx;
Env env(*this);
{
std::string const wasmHex = allHostFunctionsWasmHex;
std::string const wasmStr = boost::algorithm::unhex(wasmHex);
std::vector<uint8_t> const wasm(wasmStr.begin(), wasmStr.end());
auto& engine = WasmEngine::instance();
std::shared_ptr<HostFunctions> hfs(new TestHostFunctions(env, 0));
auto imp = createWasmImport(*hfs);
for (auto& i : *imp)
i.second.gas = 0;
auto re = engine.run(
wasm,
ESCROW_FUNCTION_NAME,
{},
imp,
hfs,
1'000'000,
env.journal);
checkResult(re, 1, 25'503);
env.close();
}
env.close();
env.close();
env.close();
env.close();
env.close();
{
std::string const wasmHex = allHostFunctionsWasmHex;
std::string const wasmStr = boost::algorithm::unhex(wasmHex);
std::vector<uint8_t> const wasm(wasmStr.begin(), wasmStr.end());
auto& engine = WasmEngine::instance();
std::shared_ptr<HostFunctions> hfs(new TestHostFunctions(env, 0));
auto const imp = createWasmImport(*hfs);
auto re = engine.run(
wasm,
ESCROW_FUNCTION_NAME,
{},
imp,
hfs,
1'000'000,
env.journal);
checkResult(re, 1, 64'763);
env.close();
}
// not enough gas
{
std::string const wasmHex = allHostFunctionsWasmHex;
std::string const wasmStr = boost::algorithm::unhex(wasmHex);
std::vector<uint8_t> const wasm(wasmStr.begin(), wasmStr.end());
auto& engine = WasmEngine::instance();
std::shared_ptr<HostFunctions> hfs(new TestHostFunctions(env, 0));
auto const imp = createWasmImport(*hfs);
auto re = engine.run(
wasm, ESCROW_FUNCTION_NAME, {}, imp, hfs, 200, env.journal);
if (BEAST_EXPECT(!re))
{
BEAST_EXPECTS(
re.error() == tecFAILED_PROCESSING,
std::to_string(TERtoInt(re.error())));
}
env.close();
}
}
void
testEscrowWasmDN()
{
testcase("escrow wasm devnet test");
std::string const wasmStr =
boost::algorithm::unhex(allHostFunctionsWasmHex);
std::vector<uint8_t> wasm(wasmStr.begin(), wasmStr.end());
using namespace test::jtx;
Env env{*this};
{
std::shared_ptr<HostFunctions> hfs(new TestHostFunctions(env, 0));
auto re =
runEscrowWasm(wasm, hfs, ESCROW_FUNCTION_NAME, {}, 100'000);
checkResult(re, 1, 64'763);
}
{
// max<int64_t>() gas
std::shared_ptr<HostFunctions> hfs(new TestHostFunctions(env, 0));
auto re = runEscrowWasm(wasm, hfs, ESCROW_FUNCTION_NAME, {}, -1);
checkResult(re, 1, 64'763);
}
{ // fail because trying to access nonexistent field
struct BadTestHostFunctions : public TestHostFunctions
{
explicit BadTestHostFunctions(Env& env) : TestHostFunctions(env)
{
}
Expected<Bytes, HostFunctionError>
getTxField(SField const& fname) override
{
return Unexpected(HostFunctionError::FIELD_NOT_FOUND);
}
};
std::shared_ptr<HostFunctions> hfs(new BadTestHostFunctions(env));
auto re =
runEscrowWasm(wasm, hfs, ESCROW_FUNCTION_NAME, {}, 100'000);
checkResult(re, -201, 28'148);
}
{ // fail because trying to allocate more than MAX_PAGES memory
struct BadTestHostFunctions : public TestHostFunctions
{
explicit BadTestHostFunctions(Env& env) : TestHostFunctions(env)
{
}
Expected<Bytes, HostFunctionError>
getTxField(SField const& fname) override
{
return Bytes((128 + 1) * 64 * 1024, 1);
}
};
std::shared_ptr<HostFunctions> hfs(new BadTestHostFunctions(env));
auto re =
runEscrowWasm(wasm, hfs, ESCROW_FUNCTION_NAME, {}, 100'000);
checkResult(re, -201, 28'148);
}
{ // fail because recursion too deep
auto const wasmStr = boost::algorithm::unhex(deepRecursionHex);
std::vector<uint8_t> wasm(wasmStr.begin(), wasmStr.end());
std::shared_ptr<TestHostFunctionsSink> hfs(
new TestHostFunctionsSink(env));
std::string funcName("finish");
auto re = runEscrowWasm(wasm, hfs, funcName, {}, 1'000'000'000);
BEAST_EXPECT(!re && re.error());
// std::cout << "bad case (deep recursion) result " << re.error()
// << std::endl;
auto const& sink = hfs->getSink();
auto countSubstr = [](std::string const& str,
std::string const& substr) {
std::size_t pos = 0;
int occurrences = 0;
while ((pos = str.find(substr, pos)) != std::string::npos)
{
occurrences++;
pos += substr.length();
}
return occurrences;
};
auto const s = sink.messages().str();
BEAST_EXPECT(
countSubstr(s, "WASMI Error: failure to call func") == 1);
BEAST_EXPECT(countSubstr(s, "exception: <finish> failure") > 0);
}
{ // infinite loop
auto const wasmStr = boost::algorithm::unhex(infiniteLoopWasmHex);
Bytes wasm(wasmStr.begin(), wasmStr.end());
std::string const funcName("loop");
std::shared_ptr<HostFunctions> hfs(new TestHostFunctions(env, 0));
// infinite loop should be caught and fail
auto const re = runEscrowWasm(wasm, hfs, funcName, {}, 1'000'000);
if (BEAST_EXPECT(!re.has_value()))
{
BEAST_EXPECT(re.error() == tecFAILED_PROCESSING);
}
}
{
// expected import not provided
auto wasmStr = boost::algorithm::unhex(ledgerSqnWasmHex);
Bytes wasm(wasmStr.begin(), wasmStr.end());
std::shared_ptr<HostFunctions> hfs(new TestLedgerDataProvider(env));
std::shared_ptr<ImportVec> imports(std::make_shared<ImportVec>());
WASM_IMPORT_FUNC2(
*imports, getLedgerSqn, "get_ledger_sqn2", hfs.get());
auto& engine = WasmEngine::instance();
auto re = engine.run(
wasm,
ESCROW_FUNCTION_NAME,
{},
imports,
hfs,
1'000'000,
env.journal);
BEAST_EXPECT(!re);
}
{
// bad import format
auto wasmStr = boost::algorithm::unhex(ledgerSqnWasmHex);
Bytes wasm(wasmStr.begin(), wasmStr.end());
std::shared_ptr<HostFunctions> hfs(new TestLedgerDataProvider(env));
std::shared_ptr<ImportVec> imports(std::make_shared<ImportVec>());
WASM_IMPORT_FUNC2(
*imports, getLedgerSqn, "get_ledger_sqn", hfs.get());
(*imports)[0].first = nullptr;
auto& engine = WasmEngine::instance();
auto re = engine.run(
wasm,
ESCROW_FUNCTION_NAME,
{},
imports,
hfs,
1'000'000,
env.journal);
BEAST_EXPECT(!re);
}
{
// bad function name
auto wasmStr = boost::algorithm::unhex(ledgerSqnWasmHex);
Bytes wasm(wasmStr.begin(), wasmStr.end());
std::shared_ptr<HostFunctions> hfs(new TestLedgerDataProvider(env));
std::shared_ptr<ImportVec> imports(std::make_shared<ImportVec>());
WASM_IMPORT_FUNC2(
*imports, getLedgerSqn, "get_ledger_sqn", hfs.get());
auto& engine = WasmEngine::instance();
auto re = engine.run(
wasm, "func1", {}, imports, hfs, 1'000'000, env.journal);
BEAST_EXPECT(!re);
}
}
void
testFloat()
{
testcase("float point");
std::string const funcName("finish");
using namespace test::jtx;
Env env(*this);
{
std::string const wasmHex = floatTestsWasmHex;
std::string const wasmStr = boost::algorithm::unhex(wasmHex);
std::vector<uint8_t> const wasm(wasmStr.begin(), wasmStr.end());
std::shared_ptr<HostFunctions> hfs(new TestHostFunctions(env, 0));
auto re = runEscrowWasm(wasm, hfs, funcName, {}, 200'000);
checkResult(re, 1, 110'699);
env.close();
}
{
std::string const wasmHex = float0Hex;
std::string const wasmStr = boost::algorithm::unhex(wasmHex);
std::vector<uint8_t> const wasm(wasmStr.begin(), wasmStr.end());
std::shared_ptr<HostFunctions> hfs(new TestHostFunctions(env, 0));
auto re = runEscrowWasm(wasm, hfs, funcName, {}, 100'000);
checkResult(re, 1, 4'259);
env.close();
}
}
void
perfTest()
{
testcase("Perf test host functions");
using namespace jtx;
using namespace std::chrono;
// std::string const funcName("test");
auto const& wasmHex = hfPerfTest;
std::string const wasmStr = boost::algorithm::unhex(wasmHex);
std::vector<uint8_t> const wasm(wasmStr.begin(), wasmStr.end());
// std::string const credType = "abcde";
// std::string const credType2 = "fghijk";
// std::string const credType3 = "0123456";
// char const uri[] = "uri";
Account const alan{"alan"};
Account const bob{"bob"};
Account const issuer{"issuer"};
{
Env env(*this);
// Env env(*this, envconfig(), {}, nullptr,
// beast::severities::kTrace);
env.fund(XRP(5000), alan, bob, issuer);
env.close();
// // create escrow
// auto const seq = env.seq(alan);
// auto const k = keylet::escrow(alan, seq);
// // auto const allowance = 3'600;
// auto escrowCreate = escrow::create(alan, bob, XRP(1000));
// XRPAmount txnFees = env.current()->fees().base + 1000;
// env(escrowCreate,
// escrow::finish_function(wasmHex),
// escrow::finish_time(env.now() + 11s),
// escrow::cancel_time(env.now() + 100s),
// escrow::data("1000000000"), // 1000 XRP in drops
// memodata("memo1234567"),
// memodata("2memo1234567"),
// fee(txnFees));
// // create depositPreauth
// auto const k = keylet::depositPreauth(
// bob,
// {{issuer.id(), makeSlice(credType)},
// {issuer.id(), makeSlice(credType2)},
// {issuer.id(), makeSlice(credType3)}});
// env(deposit::authCredentials(
// bob,
// {{issuer, credType},
// {issuer, credType2},
// {issuer, credType3}}));
// create nft
[[maybe_unused]] uint256 const nft0{
token::getNextID(env, alan, 0u)};
env(token::mint(alan, 0u));
auto const k = keylet::nftoffer(alan, 0);
[[maybe_unused]] uint256 const nft1{
token::getNextID(env, alan, 0u)};
env(token::mint(alan, 0u),
token::uri(
"https://github.com/XRPLF/XRPL-Standards/discussions/"
"279?id=github.com/XRPLF/XRPL-Standards/discussions/"
"279&ut=github.com/XRPLF/XRPL-Standards/discussions/"
"279&sid=github.com/XRPLF/XRPL-Standards/discussions/"
"279&aot=github.com/XRPLF/XRPL-Standards/disc"));
[[maybe_unused]] uint256 const nft2{
token::getNextID(env, alan, 0u)};
env(token::mint(alan, 0u));
env.close();
std::shared_ptr<HostFunctions> hfs(
new PerfHostFunctions(env, k, env.tx()));
auto re = runEscrowWasm(wasm, hfs, ESCROW_FUNCTION_NAME);
if (BEAST_EXPECT(re.has_value()))
{
BEAST_EXPECT(re->result);
std::cout << "Res: " << re->result << " cost: " << re->cost
<< std::endl;
}
// env(escrow::finish(alan, alan, seq),
// escrow::comp_allowance(allowance),
// fee(txnFees),
// ter(tesSUCCESS));
env.close();
}
}
void
testCodecovWasm()
{
testcase("Codecov wasm test");
using namespace test::jtx;
Env env{*this};
auto const wasmStr = boost::algorithm::unhex(codecovTestsWasmHex);
Bytes const wasm(wasmStr.begin(), wasmStr.end());
std::shared_ptr<HostFunctions> hfs(new TestHostFunctions(env, 0));
auto const allowance = 187'131;
auto re = runEscrowWasm(wasm, hfs, ESCROW_FUNCTION_NAME, {}, allowance);
checkResult(re, 1, allowance);
}
void
testDisabledFloat()
{
testcase("disabled float");
using namespace test::jtx;
Env env{*this};
auto const wasmStr = boost::algorithm::unhex(disabledFloatHex);
Bytes wasm(wasmStr.begin(), wasmStr.end());
std::string const funcName("finish");
std::shared_ptr<HostFunctions> hfs(new TestHostFunctions(env, 0));
{
// f32 set constant, opcode disabled exception
auto const re = runEscrowWasm(wasm, hfs, funcName, {}, 1'000'000);
if (BEAST_EXPECT(!re.has_value()))
{
BEAST_EXPECT(re.error() == tecFAILED_PROCESSING);
}
}
{
// f32 add, can't create module exception
wasm[0x117] = 0x92;
auto const re = runEscrowWasm(wasm, hfs, funcName, {}, 1'000'000);
if (BEAST_EXPECT(!re.has_value()))
{
BEAST_EXPECT(re.error() == tecFAILED_PROCESSING);
}
}
}
void
testWasmMemory()
{
testcase("Wasm additional memory limit tests");
BEAST_EXPECT(runFinishFunction(memoryPointerAtLimitHex).value() == 1);
BEAST_EXPECT(
runFinishFunction(memoryPointerOverLimitHex).has_value() == false);
BEAST_EXPECT(
runFinishFunction(memoryOffsetOverLimitHex).has_value() == false);
BEAST_EXPECT(
runFinishFunction(memoryEndOfWordOverLimitHex).has_value() ==
false);
BEAST_EXPECT(runFinishFunction(memoryGrow0To1PageHex).value() == 1);
BEAST_EXPECT(runFinishFunction(memoryGrow1To0PageHex).value() == -1);
BEAST_EXPECT(runFinishFunction(memoryLastByteOf8MBHex).value() == 1);
BEAST_EXPECT(
runFinishFunction(memoryGrow1MoreThan8MBHex).value() == -1);
BEAST_EXPECT(runFinishFunction(memoryGrow0MoreThan8MBHex).value() == 1);
BEAST_EXPECT(
runFinishFunction(memoryInit1MoreThan8MBHex).has_value() == false);
BEAST_EXPECT(
runFinishFunction(memoryNegativeAddressHex).has_value() == false);
}
void
testWasmTable()
{
testcase("Wasm table limit tests");
BEAST_EXPECT(runFinishFunction(table64ElementsHex).value() == 1);
BEAST_EXPECT(
runFinishFunction(table65ElementsHex).has_value() == false);
BEAST_EXPECT(runFinishFunction(table2TablesHex).has_value() == false);
BEAST_EXPECT(runFinishFunction(table0ElementsHex).value() == 1);
BEAST_EXPECT(runFinishFunction(tableUintMaxHex).has_value() == false);
}
void
testWasmProposal()
{
testcase("Wasm disabled proposal tests");
BEAST_EXPECT(
runFinishFunction(proposalMutableGlobalHex).has_value() == false);
BEAST_EXPECT(
runFinishFunction(proposalGcStructNewHex).has_value() == false);
BEAST_EXPECT(
runFinishFunction(proposalMultiValueHex).has_value() == false);
BEAST_EXPECT(
runFinishFunction(proposalSignExtHex).has_value() == false);
BEAST_EXPECT(
runFinishFunction(proposalFloatToIntHex).has_value() == false);
BEAST_EXPECT(
runFinishFunction(proposalBulkMemoryHex).has_value() == false);
BEAST_EXPECT(
runFinishFunction(proposalRefTypesHex).has_value() == false);
BEAST_EXPECT(
runFinishFunction(proposalTailCallHex).has_value() == false);
BEAST_EXPECT(
runFinishFunction(proposalExtendedConstHex).has_value() == false);
BEAST_EXPECT(
runFinishFunction(proposalMultiMemoryHex).has_value() == false);
BEAST_EXPECT(
runFinishFunction(proposalCustomPageSizesHex).has_value() == false);
BEAST_EXPECT(
runFinishFunction(proposalMemory64Hex).has_value() == false);
BEAST_EXPECT(
runFinishFunction(proposalWideArithmeticHex).has_value() == false);
}
void
testWasmTrap()
{
testcase("Wasm trap tests");
BEAST_EXPECT(runFinishFunction(trapDivideBy0Hex).has_value() == false);
BEAST_EXPECT(
runFinishFunction(trapIntOverflowHex).has_value() == false);
BEAST_EXPECT(
runFinishFunction(trapUnreachableHex).has_value() == false);
BEAST_EXPECT(runFinishFunction(trapNullCallHex).has_value() == false);
BEAST_EXPECT(
runFinishFunction(trapFuncSigMismatchHex).has_value() == false);
}
void
testWasmWasi()
{
testcase("Wasm Wasi tests");
BEAST_EXPECT(runFinishFunction(wasiGetTimeHex).has_value() == false);
BEAST_EXPECT(runFinishFunction(wasiPrintHex).has_value() == false);
}
void
testWasmSectionCorruption()
{
testcase("Wasm Section Corruption tests");
BEAST_EXPECT(runFinishFunction(badMagicNumberHex).has_value() == false);
BEAST_EXPECT(
runFinishFunction(badVersionNumberHex).has_value() == false);
BEAST_EXPECT(runFinishFunction(lyingHeaderHex).has_value() == false);
BEAST_EXPECT(
runFinishFunction(neverEndingNumberHex).has_value() == false);
BEAST_EXPECT(runFinishFunction(vectorLieHex).has_value() == false);
BEAST_EXPECT(
runFinishFunction(sectionOrderingHex).has_value() == false);
BEAST_EXPECT(runFinishFunction(ghostPayloadHex).has_value() == false);
BEAST_EXPECT(
runFinishFunction(junkAfterSectionHex).has_value() == false);
BEAST_EXPECT(
runFinishFunction(invalidSectionIdHex).has_value() == false);
BEAST_EXPECT(
runFinishFunction(localVariableBombHex).has_value() == false);
}
void
testStartFunctionLoop()
{
testcase("infinite loop in start function");
using namespace test::jtx;
Env env(*this);
auto wasmStr = boost::algorithm::unhex(startLoopHex);
Bytes wasm(wasmStr.begin(), wasmStr.end());
std::shared_ptr<HostFunctions> hfs(new TestLedgerDataProvider(env));
std::shared_ptr<ImportVec> imports(std::make_shared<ImportVec>());
auto& engine = WasmEngine::instance();
auto checkRes =
engine.check(wasm, "finish", {}, imports, hfs, env.journal);
BEAST_EXPECTS(
checkRes == tesSUCCESS, std::to_string(TERtoInt(checkRes)));
auto re = engine.run(
wasm,
ESCROW_FUNCTION_NAME,
{},
imports,
hfs,
1'000'000,
env.journal);
BEAST_EXPECTS(
re.error() == tecFAILED_PROCESSING,
std::to_string(TERtoInt(re.error())));
}
void
testBadAlloc()
{
testcase("Wasm Bad Alloc");
// bad_alloc.c
auto wasmStr = boost::algorithm::unhex(badAllocHex);
Bytes wasm(wasmStr.begin(), wasmStr.end());
using namespace test::jtx;
Env env{*this};
std::shared_ptr<HostFunctions> hfs(new TestLedgerDataProvider(env));
// std::shared_ptr<ImportVec> imports(std::make_shared<ImportVec>());
uint8_t buf1[8] = {7, 8, 9, 10, 11, 12, 13, 14};
{ // forged "allocate" return valid address
std::vector<WasmParam> params = {
{.type = WT_U8V,
.of = {.u8v = {.d = buf1, .sz = sizeof(buf1)}}}};
auto& engine = WasmEngine::instance();
auto re = engine.run(
wasm, "test", params, {}, hfs, 1'000'000, env.journal);
if (BEAST_EXPECT(re))
{
BEAST_EXPECTS(re->result == 7, std::to_string(re->result));
BEAST_EXPECTS(re->cost == 430, std::to_string(re->cost));
}
}
{ // return 0 whithout calling wasm
std::vector<WasmParam> params = {
{.type = WT_U8V, .of = {.u8v = {.d = buf1, .sz = 0}}}};
auto& engine = WasmEngine::instance();
auto re = engine.run(
wasm, "test", params, {}, hfs, 1'000'000, env.journal);
BEAST_EXPECT(!re) &&
BEAST_EXPECT(re.error() == tecFAILED_PROCESSING);
}
{ // forged "allocate" return 8Mb (which is more than memory limit)
std::vector<WasmParam> params = {
{.type = WT_U8V, .of = {.u8v = {.d = buf1, .sz = 1}}}};
auto& engine = WasmEngine::instance();
auto re = engine.run(
wasm, "test", params, {}, hfs, 1'000'000, env.journal);
BEAST_EXPECT(!re) &&
BEAST_EXPECT(re.error() == tecFAILED_PROCESSING);
}
{ // forged "allocate" return 0
std::vector<WasmParam> params = {
{.type = WT_U8V, .of = {.u8v = {.d = buf1, .sz = 2}}}};
auto& engine = WasmEngine::instance();
auto re = engine.run(
wasm, "test", params, {}, hfs, 1'000'000, env.journal);
BEAST_EXPECT(!re) &&
BEAST_EXPECT(re.error() == tecFAILED_PROCESSING);
}
{ // forged "allocate" return -1
std::vector<WasmParam> params = {
{.type = WT_U8V, .of = {.u8v = {.d = buf1, .sz = 3}}}};
auto& engine = WasmEngine::instance();
auto re = engine.run(
wasm, "test", params, {}, hfs, 1'000'000, env.journal);
BEAST_EXPECT(!re) &&
BEAST_EXPECT(re.error() == tecFAILED_PROCESSING);
}
env.close();
}
void
testBadAlign()
{
testcase("Wasm Bad Align");
// bad_align.c
auto wasmStr = boost::algorithm::unhex(badAlignHex);
Bytes wasm(wasmStr.begin(), wasmStr.end());
using namespace test::jtx;
Env env{*this};
std::shared_ptr<HostFunctions> hfs(new TestHostFunctions(env, 0));
auto imports = createWasmImport(*hfs);
{ // Calls float_from_uint with bad aligment.
// Can be checked through codecov
auto& engine = WasmEngine::instance();
auto re = engine.run(
wasm, "test", {}, imports, hfs, 1'000'000, env.journal);
BEAST_EXPECT(re && re->result == 0xbab88d46);
}
env.close();
}
void
run() override
{
using namespace test::jtx;
testGetDataHelperFunctions();
testWasmLib();
testBadWasm();
testWasmLedgerSqn();
testWasmFib();
testWasmSha();
testWasmB58();
testHFCost();
testEscrowWasmDN();
testFloat();
testCodecovWasm();
testDisabledFloat();
testWasmMemory();
testWasmTable();
testWasmProposal();
testWasmTrap();
testWasmWasi();
testWasmSectionCorruption();
testStartFunctionLoop();
testBadAlloc();
testBadAlign();
// perfTest();
}
};
BEAST_DEFINE_TESTSUITE(Wasm, app, xrpl);
} // namespace test
} // namespace xrpl

View File

@@ -1,3 +0,0 @@
**/target
**/debug
*.wasm

View File

@@ -1,171 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "all_host_functions"
version = "0.1.0"
dependencies = [
"xrpl-wasm-stdlib",
]
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]]
name = "bs58"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4"
dependencies = [
"tinyvec",
]
[[package]]
name = "cfg-if"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "cpufeatures"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
dependencies = [
"libc",
]
[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
]
[[package]]
name = "generic-array"
version = "0.14.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "libc"
version = "0.2.177"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
[[package]]
name = "proc-macro2"
version = "1.0.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1"
dependencies = [
"proc-macro2",
]
[[package]]
name = "sha2"
version = "0.10.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "syn"
version = "2.0.108"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "tinyvec"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa"
dependencies = [
"tinyvec_macros",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "typenum"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
[[package]]
name = "unicode-ident"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "xrpl-address-macro"
version = "0.7.1"
source = "git+https://github.com/ripple/xrpl-wasm-stdlib.git#d27d3e0b4abf3c0215aade729d89053805efe48e"
dependencies = [
"bs58",
"quote",
"sha2",
"syn",
]
[[package]]
name = "xrpl-wasm-stdlib"
version = "0.7.1"
source = "git+https://github.com/ripple/xrpl-wasm-stdlib.git#d27d3e0b4abf3c0215aade729d89053805efe48e"
dependencies = [
"xrpl-address-macro",
]

View File

@@ -1,21 +0,0 @@
[package]
name = "all_host_functions"
version = "0.1.0"
edition = "2024"
# This empty workspace definition keeps this project independent of the parent workspace
[workspace]
[lib]
crate-type = ["cdylib"]
[dependencies]
xrpl-std = { git = "https://github.com/ripple/xrpl-wasm-stdlib.git", package = "xrpl-wasm-stdlib" }
[profile.dev]
panic = "abort"
[profile.release]
panic = "abort"
opt-level = "z"
lto = true

View File

@@ -1,772 +0,0 @@
#![cfg_attr(target_arch = "wasm32", no_std)]
#[cfg(not(target_arch = "wasm32"))]
extern crate std;
//
// Host Functions Test
// Tests 26 host functions (across 7 categories)
//
// With craft you can run this test with:
// craft test --project host_functions_test --test-case host_functions_test
//
// Amount Format Update:
// - XRP amounts now return as 8-byte serialized rippled objects
// - IOU and MPT amounts return in variable-length serialized format
// - Format details: https://xrpl.org/docs/references/protocol/binary-format#amount-fields
//
// Error Code Ranges:
// -100 to -199: Ledger Header Functions (3 functions)
// -200 to -299: Transaction Data Functions (5 functions)
// -300 to -399: Current Ledger Object Functions (4 functions)
// -400 to -499: Any Ledger Object Functions (5 functions)
// -500 to -599: Keylet Generation Functions (4 functions)
// -600 to -699: Utility Functions (4 functions)
// -700 to -799: Data Update Functions (1 function)
//
use xrpl_std::core::current_tx::escrow_finish::EscrowFinish;
use xrpl_std::core::current_tx::traits::TransactionCommonFields;
use xrpl_std::host;
use xrpl_std::host::trace::{trace, trace_account_buf, trace_data, trace_num, DataRepr};
use xrpl_std::sfield;
#[unsafe(no_mangle)]
pub extern "C" fn finish() -> i32 {
let _ = trace("=== HOST FUNCTIONS TEST ===");
let _ = trace("Testing 26 host functions");
// Category 1: Ledger Header Data Functions (3 functions)
// Error range: -100 to -199
match test_ledger_header_functions() {
0 => (),
err => return err,
}
// Category 2: Transaction Data Functions (5 functions)
// Error range: -200 to -299
match test_transaction_data_functions() {
0 => (),
err => return err,
}
// Category 3: Current Ledger Object Functions (4 functions)
// Error range: -300 to -399
match test_current_ledger_object_functions() {
0 => (),
err => return err,
}
// Category 4: Any Ledger Object Functions (5 functions)
// Error range: -400 to -499
match test_any_ledger_object_functions() {
0 => (),
err => return err,
}
// Category 5: Keylet Generation Functions (4 functions)
// Error range: -500 to -599
match test_keylet_generation_functions() {
0 => (),
err => return err,
}
// Category 6: Utility Functions (4 functions)
// Error range: -600 to -699
match test_utility_functions() {
0 => (),
err => return err,
}
// Category 7: Data Update Functions (1 function)
// Error range: -700 to -799
match test_data_update_functions() {
0 => (),
err => return err,
}
let _ = trace("SUCCESS: All host function tests passed!");
1 // Success return code for WASM finish function
}
/// Test Category 1: Ledger Header Data Functions (3 functions)
/// - get_ledger_sqn() - Get ledger sequence number
/// - get_parent_ledger_time() - Get parent ledger timestamp
/// - get_parent_ledger_hash() - Get parent ledger hash
fn test_ledger_header_functions() -> i32 {
let _ = trace("--- Category 1: Ledger Header Functions ---");
// Test 1.1: get_ledger_sqn() - should return current ledger sequence number
let sqn_result = unsafe { host::get_ledger_sqn() };
if sqn_result <= 0 {
let _ = trace_num("ERROR: get_ledger_sqn failed:", sqn_result as i64);
return -101; // Ledger sequence number test failed
}
let _ = trace_num("Ledger sequence number:", sqn_result as i64);
// Test 1.2: get_parent_ledger_time() - should return parent ledger timestamp
let time_result = unsafe { host::get_parent_ledger_time() };
if time_result <= 0 {
let _ = trace_num("ERROR: get_parent_ledger_time failed:", time_result as i64);
return -102; // Parent ledger time test failed
}
let _ = trace_num("Parent ledger time:", time_result as i64);
// Test 1.3: get_parent_ledger_hash() - should return parent ledger hash (32 bytes)
let mut hash_buffer = [0u8; 32];
let hash_result =
unsafe { host::get_parent_ledger_hash(hash_buffer.as_mut_ptr(), hash_buffer.len()) };
if hash_result != 32 {
let _ = trace_num(
"ERROR: get_parent_ledger_hash wrong length:",
hash_result as i64,
);
return -103; // Parent ledger hash test failed - should be exactly 32 bytes
}
let _ = trace_data("Parent ledger hash:", &hash_buffer, DataRepr::AsHex);
let _ = trace("SUCCESS: Ledger header functions");
0
}
/// Test Category 2: Transaction Data Functions (5 functions)
/// Tests all functions for accessing current transaction data
fn test_transaction_data_functions() -> i32 {
let _ = trace("--- Category 2: Transaction Data Functions ---");
// Test 2.1: get_tx_field() - Basic transaction field access
// Test with Account field (required, 20 bytes)
let mut account_buffer = [0u8; 20];
let account_len = unsafe {
host::get_tx_field(
sfield::Account,
account_buffer.as_mut_ptr(),
account_buffer.len(),
)
};
if account_len != 20 {
let _ = trace_num(
"ERROR: get_tx_field(Account) wrong length:",
account_len as i64,
);
return -201; // Basic transaction field test failed
}
let _ = trace_account_buf("Transaction Account:", &account_buffer);
// Test with Fee field (XRP amount - 8 bytes in new serialized format)
// New format: XRP amounts are always 8 bytes (positive: value | cPositive flag, negative: just value)
let mut fee_buffer = [0u8; 8];
let fee_len =
unsafe { host::get_tx_field(sfield::Fee, fee_buffer.as_mut_ptr(), fee_buffer.len()) };
if fee_len != 8 {
let _ = trace_num(
"ERROR: get_tx_field(Fee) wrong length (expected 8 bytes for XRP):",
fee_len as i64,
);
return -202; // Fee field test failed - XRP amounts should be exactly 8 bytes
}
let _ = trace_num("Transaction Fee length:", fee_len as i64);
let _ = trace_data(
"Transaction Fee (serialized XRP amount):",
&fee_buffer,
DataRepr::AsHex,
);
// Test with Sequence field (required, 4 bytes uint32)
let mut seq_buffer = [0u8; 4];
let seq_len =
unsafe { host::get_tx_field(sfield::Sequence, seq_buffer.as_mut_ptr(), seq_buffer.len()) };
if seq_len != 4 {
let _ = trace_num(
"ERROR: get_tx_field(Sequence) wrong length:",
seq_len as i64,
);
return -203; // Sequence field test failed
}
let _ = trace_data("Transaction Sequence:", &seq_buffer, DataRepr::AsHex);
// NOTE: get_tx_field2() through get_tx_field6() have been deprecated.
// Use get_tx_field() with appropriate parameters for all transaction field access.
// Test 2.2: get_tx_nested_field() - Nested field access with locator
let locator = [0x01, 0x00]; // Simple locator for first element
let mut nested_buffer = [0u8; 32];
let nested_result = unsafe {
host::get_tx_nested_field(
locator.as_ptr(),
locator.len(),
nested_buffer.as_mut_ptr(),
nested_buffer.len(),
)
};
if nested_result < 0 {
let _ = trace_num(
"INFO: get_tx_nested_field not applicable:",
nested_result as i64,
);
// Expected - locator may not match transaction structure
} else {
let _ = trace_num("Nested field length:", nested_result as i64);
let _ = trace_data(
"Nested field:",
&nested_buffer[..nested_result as usize],
DataRepr::AsHex,
);
}
// Test 2.3: get_tx_array_len() - Get array length
let signers_len = unsafe { host::get_tx_array_len(sfield::Signers) };
let _ = trace_num("Signers array length:", signers_len as i64);
let memos_len = unsafe { host::get_tx_array_len(sfield::Memos) };
let _ = trace_num("Memos array length:", memos_len as i64);
// Test 2.4: get_tx_nested_array_len() - Get nested array length with locator
let nested_array_len =
unsafe { host::get_tx_nested_array_len(locator.as_ptr(), locator.len()) };
if nested_array_len < 0 {
let _ = trace_num(
"INFO: get_tx_nested_array_len not applicable:",
nested_array_len as i64,
);
} else {
let _ = trace_num("Nested array length:", nested_array_len as i64);
}
let _ = trace("SUCCESS: Transaction data functions");
0
}
/// Test Category 3: Current Ledger Object Functions (4 functions)
/// Tests functions that access the current ledger object being processed
fn test_current_ledger_object_functions() -> i32 {
let _ = trace("--- Category 3: Current Ledger Object Functions ---");
// Test 3.1: get_current_ledger_obj_field() - Access field from current ledger object
// Test with Balance field (XRP amount - 8 bytes in new serialized format)
let mut balance_buffer = [0u8; 8];
let balance_result = unsafe {
host::get_current_ledger_obj_field(
sfield::Balance,
balance_buffer.as_mut_ptr(),
balance_buffer.len(),
)
};
if balance_result <= 0 {
let _ = trace_num(
"INFO: get_current_ledger_obj_field(Balance) failed (may be expected):",
balance_result as i64,
);
// This might fail if current ledger object doesn't have balance field
} else if balance_result == 8 {
let _ = trace_num(
"Current object balance length (XRP amount):",
balance_result as i64,
);
let _ = trace_data(
"Current object balance (serialized XRP amount):",
&balance_buffer,
DataRepr::AsHex,
);
} else {
let _ = trace_num(
"Current object balance length (non-XRP amount):",
balance_result as i64,
);
let _ = trace_data(
"Current object balance:",
&balance_buffer[..balance_result as usize],
DataRepr::AsHex,
);
}
// Test with Account field
let mut current_account_buffer = [0u8; 20];
let current_account_result = unsafe {
host::get_current_ledger_obj_field(
sfield::Account,
current_account_buffer.as_mut_ptr(),
current_account_buffer.len(),
)
};
if current_account_result <= 0 {
let _ = trace_num(
"INFO: get_current_ledger_obj_field(Account) failed:",
current_account_result as i64,
);
} else {
let _ = trace_account_buf("Current ledger object account:", &current_account_buffer);
}
// Test 3.2: get_current_ledger_obj_nested_field() - Nested field access
let locator = [0x01, 0x00]; // Simple locator
let mut current_nested_buffer = [0u8; 32];
let current_nested_result = unsafe {
host::get_current_ledger_obj_nested_field(
locator.as_ptr(),
locator.len(),
current_nested_buffer.as_mut_ptr(),
current_nested_buffer.len(),
)
};
if current_nested_result < 0 {
let _ = trace_num(
"INFO: get_current_ledger_obj_nested_field not applicable:",
current_nested_result as i64,
);
} else {
let _ = trace_num("Current nested field length:", current_nested_result as i64);
let _ = trace_data(
"Current nested field:",
&current_nested_buffer[..current_nested_result as usize],
DataRepr::AsHex,
);
}
// Test 3.3: get_current_ledger_obj_array_len() - Array length in current object
let current_array_len = unsafe { host::get_current_ledger_obj_array_len(sfield::Signers) };
let _ = trace_num(
"Current object Signers array length:",
current_array_len as i64,
);
// Test 3.4: get_current_ledger_obj_nested_array_len() - Nested array length
let current_nested_array_len =
unsafe { host::get_current_ledger_obj_nested_array_len(locator.as_ptr(), locator.len()) };
if current_nested_array_len < 0 {
let _ = trace_num(
"INFO: get_current_ledger_obj_nested_array_len not applicable:",
current_nested_array_len as i64,
);
} else {
let _ = trace_num(
"Current nested array length:",
current_nested_array_len as i64,
);
}
let _ = trace("SUCCESS: Current ledger object functions");
0
}
/// Test Category 4: Any Ledger Object Functions (5 functions)
/// Tests functions that work with cached ledger objects
fn test_any_ledger_object_functions() -> i32 {
let _ = trace("--- Category 4: Any Ledger Object Functions ---");
// First we need to cache a ledger object to test the other functions
// Get the account from transaction and generate its keylet
let escrow_finish = EscrowFinish;
let account_id = escrow_finish.get_account().unwrap();
// Test 4.1: cache_ledger_obj() - Cache a ledger object
let mut keylet_buffer = [0u8; 32];
let keylet_result = unsafe {
host::account_keylet(
account_id.0.as_ptr(),
account_id.0.len(),
keylet_buffer.as_mut_ptr(),
keylet_buffer.len(),
)
};
if keylet_result != 32 {
let _ = trace_num(
"ERROR: account_keylet failed for caching test:",
keylet_result as i64,
);
return -401; // Keylet generation failed for caching test
}
let cache_result =
unsafe { host::cache_ledger_obj(keylet_buffer.as_ptr(), keylet_result as usize, 0) };
if cache_result <= 0 {
let _ = trace_num(
"INFO: cache_ledger_obj failed (expected with test fixtures):",
cache_result as i64,
);
// Test fixtures may not contain the account object - this is expected
// We'll test the interface but expect failures
// Test 4.2-4.5 with invalid slot (should fail gracefully)
let mut test_buffer = [0u8; 32];
// Test get_ledger_obj_field with invalid slot
let field_result = unsafe {
host::get_ledger_obj_field(
1,
sfield::Balance,
test_buffer.as_mut_ptr(),
test_buffer.len(),
)
};
if field_result < 0 {
let _ = trace_num(
"INFO: get_ledger_obj_field failed as expected (no cached object):",
field_result as i64,
);
}
// Test get_ledger_obj_nested_field with invalid slot
let locator = [0x01, 0x00];
let nested_result = unsafe {
host::get_ledger_obj_nested_field(
1,
locator.as_ptr(),
locator.len(),
test_buffer.as_mut_ptr(),
test_buffer.len(),
)
};
if nested_result < 0 {
let _ = trace_num(
"INFO: get_ledger_obj_nested_field failed as expected:",
nested_result as i64,
);
}
// Test get_ledger_obj_array_len with invalid slot
let array_result = unsafe { host::get_ledger_obj_array_len(1, sfield::Signers) };
if array_result < 0 {
let _ = trace_num(
"INFO: get_ledger_obj_array_len failed as expected:",
array_result as i64,
);
}
// Test get_ledger_obj_nested_array_len with invalid slot
let nested_array_result =
unsafe { host::get_ledger_obj_nested_array_len(1, locator.as_ptr(), locator.len()) };
if nested_array_result < 0 {
let _ = trace_num(
"INFO: get_ledger_obj_nested_array_len failed as expected:",
nested_array_result as i64,
);
}
let _ = trace("SUCCESS: Any ledger object functions (interface tested)");
return 0;
}
// If we successfully cached an object, test the access functions
let slot = cache_result;
let _ = trace_num("Successfully cached object in slot:", slot as i64);
// Test 4.2: get_ledger_obj_field() - Access field from cached object
let mut cached_balance_buffer = [0u8; 8];
let cached_balance_result = unsafe {
host::get_ledger_obj_field(
slot,
sfield::Balance,
cached_balance_buffer.as_mut_ptr(),
cached_balance_buffer.len(),
)
};
if cached_balance_result <= 0 {
let _ = trace_num(
"INFO: get_ledger_obj_field(Balance) failed:",
cached_balance_result as i64,
);
} else if cached_balance_result == 8 {
let _ = trace_num(
"Cached object balance length (XRP amount):",
cached_balance_result as i64,
);
let _ = trace_data(
"Cached object balance (serialized XRP amount):",
&cached_balance_buffer,
DataRepr::AsHex,
);
} else {
let _ = trace_num(
"Cached object balance length (non-XRP amount):",
cached_balance_result as i64,
);
let _ = trace_data(
"Cached object balance:",
&cached_balance_buffer[..cached_balance_result as usize],
DataRepr::AsHex,
);
}
// Test 4.3: get_ledger_obj_nested_field() - Nested field from cached object
let locator = [0x01, 0x00];
let mut cached_nested_buffer = [0u8; 32];
let cached_nested_result = unsafe {
host::get_ledger_obj_nested_field(
slot,
locator.as_ptr(),
locator.len(),
cached_nested_buffer.as_mut_ptr(),
cached_nested_buffer.len(),
)
};
if cached_nested_result < 0 {
let _ = trace_num(
"INFO: get_ledger_obj_nested_field not applicable:",
cached_nested_result as i64,
);
} else {
let _ = trace_num("Cached nested field length:", cached_nested_result as i64);
let _ = trace_data(
"Cached nested field:",
&cached_nested_buffer[..cached_nested_result as usize],
DataRepr::AsHex,
);
}
// Test 4.4: get_ledger_obj_array_len() - Array length from cached object
let cached_array_len = unsafe { host::get_ledger_obj_array_len(slot, sfield::Signers) };
let _ = trace_num(
"Cached object Signers array length:",
cached_array_len as i64,
);
// Test 4.5: get_ledger_obj_nested_array_len() - Nested array length from cached object
let cached_nested_array_len =
unsafe { host::get_ledger_obj_nested_array_len(slot, locator.as_ptr(), locator.len()) };
if cached_nested_array_len < 0 {
let _ = trace_num(
"INFO: get_ledger_obj_nested_array_len not applicable:",
cached_nested_array_len as i64,
);
} else {
let _ = trace_num(
"Cached nested array length:",
cached_nested_array_len as i64,
);
}
let _ = trace("SUCCESS: Any ledger object functions");
0
}
/// Test Category 5: Keylet Generation Functions (4 functions)
/// Tests keylet generation functions for different ledger entry types
fn test_keylet_generation_functions() -> i32 {
let _ = trace("--- Category 5: Keylet Generation Functions ---");
let escrow_finish = EscrowFinish;
let account_id = escrow_finish.get_account().unwrap();
// Test 5.1: account_keylet() - Generate keylet for account
let mut account_keylet_buffer = [0u8; 32];
let account_keylet_result = unsafe {
host::account_keylet(
account_id.0.as_ptr(),
account_id.0.len(),
account_keylet_buffer.as_mut_ptr(),
account_keylet_buffer.len(),
)
};
if account_keylet_result != 32 {
let _ = trace_num(
"ERROR: account_keylet failed:",
account_keylet_result as i64,
);
return -501; // Account keylet generation failed
}
let _ = trace_data("Account keylet:", &account_keylet_buffer, DataRepr::AsHex);
// Test 5.2: credential_keylet() - Generate keylet for credential
let mut credential_keylet_buffer = [0u8; 32];
let credential_keylet_result = unsafe {
host::credential_keylet(
account_id.0.as_ptr(), // Subject
account_id.0.len(),
account_id.0.as_ptr(), // Issuer - same account for test
account_id.0.len(),
b"TestType".as_ptr(), // Credential type
9usize, // Length of "TestType"
credential_keylet_buffer.as_mut_ptr(),
credential_keylet_buffer.len(),
)
};
if credential_keylet_result <= 0 {
let _ = trace_num(
"INFO: credential_keylet failed (expected - interface issue):",
credential_keylet_result as i64,
);
// This is expected to fail due to unusual parameter types
} else {
let _ = trace_data(
"Credential keylet:",
&credential_keylet_buffer[..credential_keylet_result as usize],
DataRepr::AsHex,
);
}
// Test 5.3: escrow_keylet() - Generate keylet for escrow
let mut escrow_keylet_buffer = [0u8; 32];
let escrow_keylet_result = unsafe {
host::escrow_keylet(
account_id.0.as_ptr(),
account_id.0.len(),
1000, // Sequence number
escrow_keylet_buffer.as_mut_ptr(),
escrow_keylet_buffer.len(),
)
};
if escrow_keylet_result != 32 {
let _ = trace_num("ERROR: escrow_keylet failed:", escrow_keylet_result as i64);
return -503; // Escrow keylet generation failed
}
let _ = trace_data("Escrow keylet:", &escrow_keylet_buffer, DataRepr::AsHex);
// Test 5.4: oracle_keylet() - Generate keylet for oracle
let mut oracle_keylet_buffer = [0u8; 32];
let oracle_keylet_result = unsafe {
host::oracle_keylet(
account_id.0.as_ptr(),
account_id.0.len(),
42, // Document ID
oracle_keylet_buffer.as_mut_ptr(),
oracle_keylet_buffer.len(),
)
};
if oracle_keylet_result != 32 {
let _ = trace_num("ERROR: oracle_keylet failed:", oracle_keylet_result as i64);
return -504; // Oracle keylet generation failed
}
let _ = trace_data("Oracle keylet:", &oracle_keylet_buffer, DataRepr::AsHex);
let _ = trace("SUCCESS: Keylet generation functions");
0
}
/// Test Category 6: Utility Functions (4 functions)
/// Tests utility functions for hashing, NFT access, and tracing
fn test_utility_functions() -> i32 {
let _ = trace("--- Category 6: Utility Functions ---");
// Test 6.1: compute_sha512_half() - SHA512 hash computation (first 32 bytes)
let test_data = b"Hello, XRPL WASM world!";
let mut hash_output = [0u8; 32];
let hash_result = unsafe {
host::compute_sha512_half(
test_data.as_ptr(),
test_data.len(),
hash_output.as_mut_ptr(),
hash_output.len(),
)
};
if hash_result != 32 {
let _ = trace_num("ERROR: compute_sha512_half failed:", hash_result as i64);
return -601; // SHA512 half computation failed
}
let _ = trace_data("Input data:", test_data, DataRepr::AsHex);
let _ = trace_data("SHA512 half hash:", &hash_output, DataRepr::AsHex);
// Test 6.2: get_nft() - NFT data retrieval
let escrow_finish = EscrowFinish;
let account_id = escrow_finish.get_account().unwrap();
let nft_id = [0u8; 32]; // Dummy NFT ID for testing
let mut nft_buffer = [0u8; 256];
let nft_result = unsafe {
host::get_nft(
account_id.0.as_ptr(),
account_id.0.len(),
nft_id.as_ptr(),
nft_id.len(),
nft_buffer.as_mut_ptr(),
nft_buffer.len(),
)
};
if nft_result <= 0 {
let _ = trace_num(
"INFO: get_nft failed (expected - no such NFT):",
nft_result as i64,
);
// This is expected - test account likely doesn't own the dummy NFT
} else {
let _ = trace_num("NFT data length:", nft_result as i64);
let _ = trace_data(
"NFT data:",
&nft_buffer[..nft_result as usize],
DataRepr::AsHex,
);
}
// Test 6.3: trace() - Debug logging with data
let trace_message = b"Test trace message";
let trace_data_payload = b"payload";
let trace_result = unsafe {
host::trace(
trace_message.as_ptr(),
trace_message.len(),
trace_data_payload.as_ptr(),
trace_data_payload.len(),
1, // as_hex = true
)
};
if trace_result < 0 {
let _ = trace_num("ERROR: trace() failed:", trace_result as i64);
return -603; // Trace function failed
}
let _ = trace_num("Trace function bytes written:", trace_result as i64);
// Test 6.4: trace_num() - Debug logging with number
let test_number = 42i64;
let trace_num_result = trace_num("Test number trace", test_number);
use xrpl_std::host::Result;
match trace_num_result {
Result::Ok(_) => {
let _ = trace_num("Trace_num function succeeded", 0);
}
Result::Err(_) => {
let _ = trace_num("ERROR: trace_num() failed:", -604);
return -604; // Trace number function failed
}
}
let _ = trace("SUCCESS: Utility functions");
0
}
/// Test Category 7: Data Update Functions (1 function)
/// Tests the function for modifying the current ledger entry
fn test_data_update_functions() -> i32 {
let _ = trace("--- Category 7: Data Update Functions ---");
// Test 7.1: update_data() - Update current ledger entry data
let update_payload = b"Updated ledger entry data from WASM test";
let update_result = unsafe { host::update_data(update_payload.as_ptr(), update_payload.len()) };
if update_result != update_payload.len() as i32 {
let _ = trace_num("ERROR: update_data failed:", update_result as i64);
return -701; // Data update failed
}
let _ = trace_data(
"Successfully updated ledger entry with:",
update_payload,
DataRepr::AsHex,
);
let _ = trace("SUCCESS: Data update functions");
0
}

View File

@@ -1,171 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "all_keylets"
version = "0.0.1"
dependencies = [
"xrpl-wasm-stdlib",
]
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]]
name = "bs58"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4"
dependencies = [
"tinyvec",
]
[[package]]
name = "cfg-if"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "cpufeatures"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
dependencies = [
"libc",
]
[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
]
[[package]]
name = "generic-array"
version = "0.14.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "libc"
version = "0.2.177"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
[[package]]
name = "proc-macro2"
version = "1.0.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1"
dependencies = [
"proc-macro2",
]
[[package]]
name = "sha2"
version = "0.10.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "syn"
version = "2.0.108"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "tinyvec"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa"
dependencies = [
"tinyvec_macros",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "typenum"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
[[package]]
name = "unicode-ident"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "xrpl-address-macro"
version = "0.7.1"
source = "git+https://github.com/ripple/xrpl-wasm-stdlib.git#d27d3e0b4abf3c0215aade729d89053805efe48e"
dependencies = [
"bs58",
"quote",
"sha2",
"syn",
]
[[package]]
name = "xrpl-wasm-stdlib"
version = "0.7.1"
source = "git+https://github.com/ripple/xrpl-wasm-stdlib.git#d27d3e0b4abf3c0215aade729d89053805efe48e"
dependencies = [
"xrpl-address-macro",
]

View File

@@ -1,21 +0,0 @@
[package]
edition = "2024"
name = "all_keylets"
version = "0.0.1"
# This empty workspace definition keeps this project independent of the parent workspace
[workspace]
[lib]
crate-type = ["cdylib"]
[profile.release]
lto = true
opt-level = 's'
panic = "abort"
[dependencies]
xrpl-std = { git = "https://github.com/ripple/xrpl-wasm-stdlib.git", package = "xrpl-wasm-stdlib" }
[profile.dev]
panic = "abort"

View File

@@ -1,181 +0,0 @@
#![cfg_attr(target_arch = "wasm32", no_std)]
#[cfg(not(target_arch = "wasm32"))]
extern crate std;
use crate::host::{Error, Result, Result::Err, Result::Ok};
use xrpl_std::core::ledger_objects::current_escrow::get_current_escrow;
use xrpl_std::core::ledger_objects::current_escrow::CurrentEscrow;
use xrpl_std::core::ledger_objects::ledger_object;
use xrpl_std::core::ledger_objects::traits::CurrentEscrowFields;
use xrpl_std::core::types::account_id::AccountID;
use xrpl_std::core::types::currency::Currency;
use xrpl_std::core::types::issue::{IouIssue, Issue, XrpIssue};
use xrpl_std::core::types::keylets;
use xrpl_std::core::types::mpt_id::MptId;
use xrpl_std::core::types::uint::Hash256;
use xrpl_std::host;
use xrpl_std::host::trace::{trace, trace_account, trace_data, trace_num, DataRepr};
use xrpl_std::sfield;
#[unsafe(no_mangle)]
pub fn object_exists(
keylet_result: Result<keylets::KeyletBytes>,
keylet_type: &str,
field: i32,
) -> Result<bool> {
match keylet_result {
Ok(keylet) => {
let _ = trace_data(keylet_type, &keylet, DataRepr::AsHex);
let slot = unsafe { host::cache_ledger_obj(keylet.as_ptr(), keylet.len(), 0) };
if slot <= 0 {
let _ = trace_num("Error: ", slot.into());
return Err(Error::from_code(slot));
}
if field == 0 {
let new_field = sfield::PreviousTxnID;
let _ = trace_num("Getting field: ", new_field.into());
match ledger_object::get_field::<Hash256>(slot, new_field) {
Ok(data) => {
let _ = trace_data("Field data: ", &data.0, DataRepr::AsHex);
}
Err(result_code) => {
let _ = trace_num("Error getting field: ", result_code.into());
return Err(result_code);
}
}
} else {
let _ = trace_num("Getting field: ", field.into());
match ledger_object::get_field::<AccountID>(slot, field) {
Ok(data) => {
let _ = trace_data("Field data: ", &data.0, DataRepr::AsHex);
}
Err(result_code) => {
let _ = trace_num("Error getting field: ", result_code.into());
return Err(result_code);
}
}
}
Ok(true)
}
Err(error) => {
let _ = trace_num("Error getting keylet: ", error.into());
Err(error)
}
}
}
#[unsafe(no_mangle)]
pub extern "C" fn finish() -> i32 {
let _ = trace("$$$$$ STARTING WASM EXECUTION $$$$$");
let escrow: CurrentEscrow = get_current_escrow();
let account = escrow.get_account().unwrap_or_panic();
let _ = trace_account("Account:", &account);
let destination = escrow.get_destination().unwrap_or_panic();
let _ = trace_account("Destination:", &destination);
let mut seq = 5;
macro_rules! check_object_exists {
($keylet:expr, $type:expr, $field:expr) => {
match object_exists($keylet, $type, $field) {
Ok(_exists) => {
// false isn't returned
let _ = trace(concat!(
$type,
" object exists, proceeding with escrow finish."
));
}
Err(error) => {
let _ = trace_num("Current seq value:", seq.try_into().unwrap());
return error.code();
}
}
};
}
let account_keylet = keylets::account_keylet(&account);
check_object_exists!(account_keylet, "Account", sfield::Account);
let currency_code: &[u8; 3] = b"USD";
let currency: Currency = Currency::from(*currency_code);
let line_keylet = keylets::line_keylet(&account, &destination, &currency);
check_object_exists!(line_keylet, "Trustline", sfield::Generic);
seq += 1;
let asset1 = Issue::XRP(XrpIssue {});
let asset2 = Issue::IOU(IouIssue::new(destination, currency));
check_object_exists!(
keylets::amm_keylet(&asset1, &asset2),
"AMM",
sfield::Account
);
let check_keylet = keylets::check_keylet(&account, seq);
check_object_exists!(check_keylet, "Check", sfield::Account);
seq += 1;
let cred_type: &[u8] = b"termsandconditions";
let credential_keylet = keylets::credential_keylet(&account, &account, cred_type);
check_object_exists!(credential_keylet, "Credential", sfield::Subject);
seq += 1;
let delegate_keylet = keylets::delegate_keylet(&account, &destination);
check_object_exists!(delegate_keylet, "Delegate", sfield::Account);
seq += 1;
let deposit_preauth_keylet = keylets::deposit_preauth_keylet(&account, &destination);
check_object_exists!(deposit_preauth_keylet, "DepositPreauth", sfield::Account);
seq += 1;
let did_keylet = keylets::did_keylet(&account);
check_object_exists!(did_keylet, "DID", sfield::Account);
seq += 1;
let escrow_keylet = keylets::escrow_keylet(&account, seq);
check_object_exists!(escrow_keylet, "Escrow", sfield::Account);
seq += 1;
let mpt_issuance_keylet = keylets::mpt_issuance_keylet(&account, seq);
let mpt_id = MptId::new(seq.try_into().unwrap(), account);
check_object_exists!(mpt_issuance_keylet, "MPTIssuance", sfield::Issuer);
seq += 1;
let mptoken_keylet = keylets::mptoken_keylet(&mpt_id, &destination);
check_object_exists!(mptoken_keylet, "MPToken", sfield::Account);
let nft_offer_keylet = keylets::nft_offer_keylet(&destination, 6);
check_object_exists!(nft_offer_keylet, "NFTokenOffer", sfield::Owner);
let offer_keylet = keylets::offer_keylet(&account, seq);
check_object_exists!(offer_keylet, "Offer", sfield::Account);
seq += 1;
let paychan_keylet = keylets::paychan_keylet(&account, &destination, seq);
check_object_exists!(paychan_keylet, "PayChannel", sfield::Account);
seq += 1;
let pd_keylet = keylets::permissioned_domain_keylet(&account, seq);
check_object_exists!(pd_keylet, "PermissionedDomain", sfield::Owner);
seq += 1;
let signers_keylet = keylets::signers_keylet(&account);
check_object_exists!(signers_keylet, "SignerList", sfield::Generic);
seq += 1;
seq += 1; // ticket sequence number is one greater
let ticket_keylet = keylets::ticket_keylet(&account, seq);
check_object_exists!(ticket_keylet, "Ticket", sfield::Account);
seq += 1;
let vault_keylet = keylets::vault_keylet(&account, seq);
check_object_exists!(vault_keylet, "Vault", sfield::Account);
// seq += 1;
1 // All keylets exist, finish the escrow.
}

View File

@@ -1,73 +0,0 @@
#include <stdint.h>
static char const b58digits_ordered[] =
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
uint8_t e_data[32 * 1024];
void*
allocate(int sz)
{
static int idx = 0;
if (idx >= 32)
return 0;
if (sz > 1024)
return 0;
return &e_data[idx++ << 10];
}
void
deallocate(void* p)
{
}
extern int32_t
b58enco(char* b58, int32_t b58sz, void const* data, int32_t binsz)
{
uint8_t const* bin = data;
int32_t carry;
int32_t i, j, high, zcount = 0;
int32_t size;
while (zcount < binsz && !bin[zcount])
++zcount;
size = (binsz - zcount) * 138 / 100 + 1;
uint8_t* buf = allocate(size);
if (!buf)
return 0;
// memset(buf, 0, size);
for (i = 0; i < size; ++i)
buf[i] = 0;
for (i = zcount, high = size - 1; i < binsz; ++i, high = j)
{
for (carry = bin[i], j = size - 1; (j > high) || carry; --j)
{
carry += 256 * buf[j];
buf[j] = carry % 58;
carry /= 58;
if (!j)
break;
}
}
for (j = 0; j < size && !buf[j]; ++j)
;
if (b58sz <= zcount + size - j)
return 0;
if (zcount)
{
// memset(b58, '1', zcount);
for (i = 0; i < zcount; ++i)
b58[i] = '1';
}
for (i = zcount; j < size; ++i, ++j)
b58[i] = b58digits_ordered[buf[j]];
b58[i] = '\0';
return i + 1;
}

View File

@@ -1,23 +0,0 @@
#include <stdint.h>
int32_t
float_from_uint(uint8_t const*, int32_t, uint8_t*, int32_t, int32_t);
int32_t
get_tx_nested_field(uint8_t const*, int32_t, uint8_t*, int32_t);
uint8_t e_data[32 * 1024];
int32_t
test()
{
e_data[1] = 0xFF;
e_data[2] = 0xFF;
e_data[3] = 0xFF;
e_data[4] = 0xFF;
e_data[5] = 0xFF;
e_data[6] = 0xFF;
e_data[7] = 0xFF;
e_data[8] = 0xFF;
float_from_uint(&e_data[1], 8, &e_data[35], 12, 0);
return *((int32_t*)(&e_data[36]));
}

View File

@@ -1,27 +0,0 @@
#include <stdint.h>
char buf[1024];
void*
allocate(int sz)
{
if (!sz)
return 0;
if (sz == 1)
return ((void*)(8 * 1024 * 1024));
if (sz == 2)
return 0;
if (sz == 3)
return ((void*)(0xFFFFFFFF));
return &buf[sz];
}
int32_t
test(char* p, int32_t sz)
{
if (!sz)
return 0;
return p[0];
}

View File

@@ -1,171 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]]
name = "bs58"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4"
dependencies = [
"tinyvec",
]
[[package]]
name = "cfg-if"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "codecov_tests"
version = "0.0.1"
dependencies = [
"xrpl-wasm-stdlib",
]
[[package]]
name = "cpufeatures"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
dependencies = [
"libc",
]
[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
]
[[package]]
name = "generic-array"
version = "0.14.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "libc"
version = "0.2.177"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
[[package]]
name = "proc-macro2"
version = "1.0.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1"
dependencies = [
"proc-macro2",
]
[[package]]
name = "sha2"
version = "0.10.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "syn"
version = "2.0.108"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "tinyvec"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa"
dependencies = [
"tinyvec_macros",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "typenum"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
[[package]]
name = "unicode-ident"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "xrpl-address-macro"
version = "0.7.1"
source = "git+https://github.com/ripple/xrpl-wasm-stdlib.git#d27d3e0b4abf3c0215aade729d89053805efe48e"
dependencies = [
"bs58",
"quote",
"sha2",
"syn",
]
[[package]]
name = "xrpl-wasm-stdlib"
version = "0.7.1"
source = "git+https://github.com/ripple/xrpl-wasm-stdlib.git#d27d3e0b4abf3c0215aade729d89053805efe48e"
dependencies = [
"xrpl-address-macro",
]

View File

@@ -1,18 +0,0 @@
[package]
edition = "2024"
name = "codecov_tests"
version = "0.0.1"
# This empty workspace definition keeps this project independent of the parent workspace
[workspace]
[lib]
crate-type = ["cdylib"]
[profile.release]
lto = true
opt-level = 's'
panic = "abort"
[dependencies]
xrpl-std = { git = "https://github.com/ripple/xrpl-wasm-stdlib.git", package = "xrpl-wasm-stdlib" }

View File

@@ -1,47 +0,0 @@
//TODO add docs after discussing the interface
//Note that Craft currently does not honor the rounding modes
#[allow(unused)]
pub const FLOAT_ROUNDING_MODES_TO_NEAREST: i32 = 0;
#[allow(unused)]
pub const FLOAT_ROUNDING_MODES_TOWARDS_ZERO: i32 = 1;
#[allow(unused)]
pub const FLOAT_ROUNDING_MODES_DOWNWARD: i32 = 2;
#[allow(unused)]
pub const FLOAT_ROUNDING_MODES_UPWARD: i32 = 3;
// pub enum RippledRoundingModes{
// ToNearest = 0,
// TowardsZero = 1,
// DOWNWARD = 2,
// UPWARD = 3
// }
#[allow(unused)]
#[link(wasm_import_module = "host_lib")]
unsafe extern "C" {
pub fn get_parent_ledger_hash(out_buff_ptr: i32, out_buff_len: i32) -> i32;
pub fn cache_ledger_obj(keylet_ptr: i32, keylet_len: i32, cache_num: i32) -> i32;
pub fn get_tx_nested_array_len(locator_ptr: i32, locator_len: i32) -> i32;
pub fn account_keylet(
account_ptr: i32,
account_len: i32,
out_buff_ptr: *mut u8,
out_buff_len: usize,
) -> i32;
pub fn line_keylet(
account1_ptr: *const u8,
account1_len: usize,
account2_ptr: *const u8,
account2_len: usize,
currency_ptr: i32,
currency_len: i32,
out_buff_ptr: *mut u8,
out_buff_len: usize,
) -> i32;
pub fn trace_num(msg_read_ptr: i32, msg_read_len: i32, number: i64) -> i32;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,134 +0,0 @@
import os
import sys
import subprocess
import re
OPT = "-Oz"
def update_fixture(project_name, wasm):
fixture_name = (
re.sub(r"_([a-z])", lambda m: m.group(1).upper(), project_name) + "WasmHex"
)
print(f"Updating fixture: {fixture_name}")
cpp_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "fixtures.cpp"))
h_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "fixtures.h"))
with open(cpp_path, "r", encoding="utf8") as f:
cpp_content = f.read()
pattern = rf'extern std::string const {fixture_name} =[ \n]+"[^;]*;'
if re.search(pattern, cpp_content, flags=re.MULTILINE):
updated_cpp_content = re.sub(
pattern,
f'extern std::string const {fixture_name} = "{wasm}";',
cpp_content,
flags=re.MULTILINE,
)
else:
with open(h_path, "r", encoding="utf8") as f:
h_content = f.read()
updated_h_content = (
h_content.rstrip() + f"\n\n extern std::string const {fixture_name};\n"
)
with open(h_path, "w", encoding="utf8") as f:
f.write(updated_h_content)
updated_cpp_content = (
cpp_content.rstrip()
+ f'\n\nextern std::string const {fixture_name} = "{wasm}";\n'
)
with open(cpp_path, "w", encoding="utf8") as f:
f.write(updated_cpp_content)
def process_rust(project_name):
project_path = os.path.abspath(
os.path.join(os.path.dirname(__file__), project_name)
)
wasm_location = f"target/wasm32v1-none/release/{project_name}.wasm"
build_cmd = (
f"(cd {project_path} "
f"&& cargo build --target wasm32v1-none --release "
f"&& wasm-opt {wasm_location} {OPT} -o {wasm_location}"
")"
)
try:
result = subprocess.run(
build_cmd, shell=True, check=True, capture_output=True, text=True
)
print(f"stdout: {result.stdout}")
if result.stderr:
print(f"stderr: {result.stderr}")
print(f"WASM file for {project_name} has been built and optimized.")
except subprocess.CalledProcessError as e:
print(f"exec error: {e}")
sys.exit(1)
src_path = os.path.abspath(
os.path.join(
os.path.dirname(__file__),
f"{project_name}/target/wasm32v1-none/release/{project_name}.wasm",
)
)
with open(src_path, "rb") as f:
data = f.read()
wasm = data.hex()
update_fixture(project_name, wasm)
def process_c(project_name):
project_path = os.path.abspath(
os.path.join(os.path.dirname(__file__), f"{project_name}.c")
)
wasm_path = os.path.abspath(
os.path.join(os.path.dirname(__file__), f"{project_name}.wasm")
)
build_cmd = (
f"$CC --sysroot=$SYSROOT "
f"-O3 -ffast-math --target=wasm32 -fno-exceptions -fno-threadsafe-statics -fvisibility=default -Wl,--export-all -Wl,--no-entry -Wl,--allow-undefined -DNDEBUG --no-standard-libraries -fno-builtin-memset "
f"-o {wasm_path} {project_path}"
f"&& wasm-opt {wasm_path} {OPT} -o {wasm_path}"
)
try:
result = subprocess.run(
build_cmd, shell=True, check=True, capture_output=True, text=True
)
print(f"stdout: {result.stdout}")
if result.stderr:
print(f"stderr: {result.stderr}")
print(
f"WASM file for {project_name} has been built with WASI support using clang."
)
except subprocess.CalledProcessError as e:
print(f"exec error: {e}")
sys.exit(1)
with open(wasm_path, "rb") as f:
data = f.read()
wasm = data.hex()
update_fixture(project_name, wasm)
if __name__ == "__main__":
if len(sys.argv) > 2:
print("Usage: python copyFixtures.py [<project_name>]")
sys.exit(1)
if len(sys.argv) == 2:
if os.path.isdir(os.path.join(os.path.dirname(__file__), sys.argv[1])):
process_rust(sys.argv[1])
else:
process_c(sys.argv[1])
print("Fixture has been processed.")
else:
dirs = [
d
for d in os.listdir(os.path.dirname(__file__))
if os.path.isdir(os.path.join(os.path.dirname(__file__), d))
]
c_files = [f for f in os.listdir(os.path.dirname(__file__)) if f.endswith(".c")]
for d in dirs:
process_rust(d)
for c in c_files:
process_c(c[:-2])
print("All fixtures have been processed.")

View File

@@ -1,34 +0,0 @@
(module
(type (;0;) (func))
(type (;1;) (func (result i32)))
(func (;0;) (type 0))
(func (;1;) (type 1) (result i32)
f32.const -2048
f32.const 2050
f32.sub
drop
i32.const 1)
(memory (;0;) 2)
(global (;0;) i32 (i32.const 1024))
(global (;1;) i32 (i32.const 1024))
(global (;2;) i32 (i32.const 2048))
(global (;3;) i32 (i32.const 2048))
(global (;4;) i32 (i32.const 67584))
(global (;5;) i32 (i32.const 1024))
(global (;6;) i32 (i32.const 67584))
(global (;7;) i32 (i32.const 131072))
(global (;8;) i32 (i32.const 0))
(global (;9;) i32 (i32.const 1))
(export "memory" (memory 0))
(export "__wasm_call_ctors" (func 0))
(export "finish" (func 1))
(export "buf" (global 0))
(export "__dso_handle" (global 1))
(export "__data_end" (global 2))
(export "__stack_low" (global 3))
(export "__stack_high" (global 4))
(export "__global_base" (global 5))
(export "__heap_base" (global 6))
(export "__heap_end" (global 7))
(export "__memory_base" (global 8))
(export "__table_base" (global 9)))

View File

@@ -1,12 +0,0 @@
// typedef long long mint;
typedef int mint;
mint
fib(mint n)
{
if (!n)
return 0;
if (n <= 2)
return 1;
return fib(n - 1) + fib(n - 2);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,87 +0,0 @@
#pragma once
// TODO: consider moving these to separate files (and figure out the build)
#include <string>
extern std::string const ledgerSqnWasmHex;
extern std::string const allHostFunctionsWasmHex;
extern std::string const deepRecursionHex;
extern std::string const fibWasmHex;
extern std::string const b58WasmHex;
extern std::string const sha512PureWasmHex;
extern std::string const hfPerfTest;
extern std::string const allKeyletsWasmHex;
extern std::string const codecovTestsWasmHex;
extern std::string const floatTestsWasmHex;
extern std::string const float0Hex;
extern std::string const disabledFloatHex;
extern std::string const memoryPointerAtLimitHex;
extern std::string const memoryPointerOverLimitHex;
extern std::string const memoryOffsetOverLimitHex;
extern std::string const memoryEndOfWordOverLimitHex;
extern std::string const memoryGrow0To1PageHex;
extern std::string const memoryGrow1To0PageHex;
extern std::string const memoryLastByteOf8MBHex;
extern std::string const memoryGrow1MoreThan8MBHex;
extern std::string const memoryGrow0MoreThan8MBHex;
extern std::string const memoryInit1MoreThan8MBHex;
extern std::string const memoryNegativeAddressHex;
extern std::string const table64ElementsHex;
extern std::string const table65ElementsHex;
extern std::string const table2TablesHex;
extern std::string const table0ElementsHex;
extern std::string const tableUintMaxHex;
extern std::string const proposalMutableGlobalHex;
extern std::string const proposalGcStructNewHex;
extern std::string const proposalMultiValueHex;
extern std::string const proposalSignExtHex;
extern std::string const proposalFloatToIntHex;
extern std::string const proposalBulkMemoryHex;
extern std::string const proposalRefTypesHex;
extern std::string const proposalTailCallHex;
extern std::string const proposalExtendedConstHex;
extern std::string const proposalMultiMemoryHex;
extern std::string const proposalCustomPageSizesHex;
extern std::string const proposalMemory64Hex;
extern std::string const proposalWideArithmeticHex;
extern std::string const trapDivideBy0Hex;
extern std::string const trapIntOverflowHex;
extern std::string const trapUnreachableHex;
extern std::string const trapNullCallHex;
extern std::string const trapFuncSigMismatchHex;
extern std::string const wasiGetTimeHex;
extern std::string const wasiPrintHex;
extern std::string const badMagicNumberHex;
extern std::string const badVersionNumberHex;
extern std::string const lyingHeaderHex;
extern std::string const neverEndingNumberHex;
extern std::string const vectorLieHex;
extern std::string const sectionOrderingHex;
extern std::string const ghostPayloadHex;
extern std::string const junkAfterSectionHex;
extern std::string const invalidSectionIdHex;
extern std::string const localVariableBombHex;
extern std::string const infiniteLoopWasmHex;
extern std::string const startLoopHex;
extern std::string const badAllocHex;
extern std::string const badAlignHex;

View File

@@ -1,171 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]]
name = "bs58"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4"
dependencies = [
"tinyvec",
]
[[package]]
name = "cfg-if"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "cpufeatures"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
dependencies = [
"libc",
]
[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
]
[[package]]
name = "float_tests"
version = "0.0.1"
dependencies = [
"xrpl-wasm-stdlib",
]
[[package]]
name = "generic-array"
version = "0.14.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "libc"
version = "0.2.177"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
[[package]]
name = "proc-macro2"
version = "1.0.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1"
dependencies = [
"proc-macro2",
]
[[package]]
name = "sha2"
version = "0.10.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "syn"
version = "2.0.108"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "tinyvec"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa"
dependencies = [
"tinyvec_macros",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "typenum"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
[[package]]
name = "unicode-ident"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "xrpl-address-macro"
version = "0.7.1"
source = "git+https://github.com/ripple/xrpl-wasm-stdlib.git#d27d3e0b4abf3c0215aade729d89053805efe48e"
dependencies = [
"bs58",
"quote",
"sha2",
"syn",
]
[[package]]
name = "xrpl-wasm-stdlib"
version = "0.7.1"
source = "git+https://github.com/ripple/xrpl-wasm-stdlib.git#d27d3e0b4abf3c0215aade729d89053805efe48e"
dependencies = [
"xrpl-address-macro",
]

View File

@@ -1,21 +0,0 @@
[package]
name = "float_tests"
version = "0.0.1"
edition = "2024"
# This empty workspace definition keeps this project independent of the parent workspace
[workspace]
[lib]
crate-type = ["cdylib"]
[profile.release]
lto = true
opt-level = 's'
panic = "abort"
[dependencies]
xrpl-std = { git = "https://github.com/ripple/xrpl-wasm-stdlib.git", package = "xrpl-wasm-stdlib" }
[profile.dev]
panic = "abort"

View File

@@ -1,461 +0,0 @@
#![allow(unused_imports)]
#![allow(unused_variables)]
#![cfg_attr(target_arch = "wasm32", no_std)]
#[cfg(not(target_arch = "wasm32"))]
extern crate std;
use xrpl_std::core::locator::Locator;
use xrpl_std::core::types::opaque_float::{FLOAT_NEGATIVE_ONE, FLOAT_ONE};
use xrpl_std::decode_hex_32;
use xrpl_std::host::trace::DataRepr::AsHex;
use xrpl_std::host::trace::{trace, trace_data, trace_float, trace_num, DataRepr};
use xrpl_std::host::{
cache_ledger_obj, float_add, float_compare, float_divide, float_from_int, float_from_uint,
float_log, float_multiply, float_pow, float_root, float_set, float_subtract,
get_ledger_obj_array_len, get_ledger_obj_field, get_ledger_obj_nested_field,
trace_opaque_float, FLOAT_ROUNDING_MODES_TO_NEAREST,
};
use xrpl_std::sfield;
use xrpl_std::sfield::{
Account, AccountTxnID, Balance, Domain, EmailHash, Flags, LedgerEntryType, MessageKey,
OwnerCount, PreviousTxnID, PreviousTxnLgrSeq, RegularKey, Sequence, TicketCount, TransferRate,
};
fn test_float_from_wasm() {
let _ = trace("\n$$$ test_float_from_wasm $$$");
let mut f: [u8; 8] = [0u8; 8];
if 8 == unsafe { float_from_int(12300, f.as_mut_ptr(), 8, FLOAT_ROUNDING_MODES_TO_NEAREST) } {
let _ = trace_float(" float from i64 12300:", &f);
let _ = trace_data(" float from i64 12300 as HEX:", &f, AsHex);
} else {
let _ = trace(" float from i64 12300: failed");
}
let u64_value: u64 = 12300;
if 8 == unsafe {
float_from_uint(
&u64_value as *const u64 as *const u8,
8,
f.as_mut_ptr(),
8,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
} {
let _ = trace_float(" float from u64 12300:", &f);
} else {
let _ = trace(" float from u64 12300: failed");
}
if 8 == unsafe { float_set(2, 123, f.as_mut_ptr(), 8, FLOAT_ROUNDING_MODES_TO_NEAREST) } {
let _ = trace_float(" float from exp 2, mantissa 123:", &f);
} else {
let _ = trace(" float from exp 2, mantissa 3: failed");
}
let _ = trace_float(" float from const 1:", &FLOAT_ONE);
let _ = trace_float(" float from const -1:", &FLOAT_NEGATIVE_ONE);
}
fn test_float_compare() {
let _ = trace("\n$$$ test_float_compare $$$");
let mut f1: [u8; 8] = [0u8; 8];
if 8 != unsafe { float_from_int(1, f1.as_mut_ptr(), 8, FLOAT_ROUNDING_MODES_TO_NEAREST) } {
let _ = trace(" float from 1: failed");
} else {
let _ = trace_float(" float from 1:", &f1);
}
if 0 == unsafe { float_compare(f1.as_ptr(), 8, FLOAT_ONE.as_ptr(), 8) } {
let _ = trace(" float from 1 == FLOAT_ONE");
} else {
let _ = trace(" float from 1 != FLOAT_ONE");
}
if 1 == unsafe { float_compare(f1.as_ptr(), 8, FLOAT_NEGATIVE_ONE.as_ptr(), 8) } {
let _ = trace(" float from 1 > FLOAT_NEGATIVE_ONE");
} else {
let _ = trace(" float from 1 !> FLOAT_NEGATIVE_ONE");
}
if 2 == unsafe { float_compare(FLOAT_NEGATIVE_ONE.as_ptr(), 8, f1.as_ptr(), 8) } {
let _ = trace(" FLOAT_NEGATIVE_ONE < float from 1");
} else {
let _ = trace(" FLOAT_NEGATIVE_ONE !< float from 1");
}
}
fn test_float_add_subtract() {
let _ = trace("\n$$$ test_float_add_subtract $$$");
let mut f_compute: [u8; 8] = FLOAT_ONE;
for i in 0..9 {
unsafe {
float_add(
f_compute.as_ptr(),
8,
FLOAT_ONE.as_ptr(),
8,
f_compute.as_mut_ptr(),
8,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
// let _ = trace_float(" float:", &f_compute);
}
let mut f10: [u8; 8] = [0u8; 8];
if 8 != unsafe { float_from_int(10, f10.as_mut_ptr(), 8, FLOAT_ROUNDING_MODES_TO_NEAREST) } {
// let _ = trace(" float from 10: failed");
}
if 0 == unsafe { float_compare(f10.as_ptr(), 8, f_compute.as_ptr(), 8) } {
let _ = trace(" repeated add: good");
} else {
let _ = trace(" repeated add: bad");
}
for i in 0..11 {
unsafe {
float_subtract(
f_compute.as_ptr(),
8,
FLOAT_ONE.as_ptr(),
8,
f_compute.as_mut_ptr(),
8,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
}
if 0 == unsafe { float_compare(f_compute.as_ptr(), 8, FLOAT_NEGATIVE_ONE.as_ptr(), 8) } {
let _ = trace(" repeated subtract: good");
} else {
let _ = trace(" repeated subtract: bad");
}
}
fn test_float_multiply_divide() {
let _ = trace("\n$$$ test_float_multiply_divide $$$");
let mut f10: [u8; 8] = [0u8; 8];
unsafe { float_from_int(10, f10.as_mut_ptr(), 8, FLOAT_ROUNDING_MODES_TO_NEAREST) };
let mut f_compute: [u8; 8] = FLOAT_ONE;
for i in 0..6 {
unsafe {
float_multiply(
f_compute.as_ptr(),
8,
f10.as_ptr(),
8,
f_compute.as_mut_ptr(),
8,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
// let _ = trace_float(" float:", &f_compute);
}
let mut f1000000: [u8; 8] = [0u8; 8];
unsafe {
float_from_int(
1000000,
f1000000.as_mut_ptr(),
8,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
if 0 == unsafe { float_compare(f1000000.as_ptr(), 8, f_compute.as_ptr(), 8) } {
let _ = trace(" repeated multiply: good");
} else {
let _ = trace(" repeated multiply: bad");
}
for i in 0..7 {
unsafe {
float_divide(
f_compute.as_ptr(),
8,
f10.as_ptr(),
8,
f_compute.as_mut_ptr(),
8,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
}
let mut f01: [u8; 8] = [0u8; 8];
unsafe { float_set(-1, 1, f01.as_mut_ptr(), 8, FLOAT_ROUNDING_MODES_TO_NEAREST) };
if 0 == unsafe { float_compare(f_compute.as_ptr(), 8, f01.as_ptr(), 8) } {
let _ = trace(" repeated divide: good");
} else {
let _ = trace(" repeated divide: bad");
}
}
fn test_float_pow() {
let _ = trace("\n$$$ test_float_pow $$$");
let mut f_compute: [u8; 8] = [0u8; 8];
unsafe {
float_pow(
FLOAT_ONE.as_ptr(),
8,
3,
f_compute.as_mut_ptr(),
8,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
let _ = trace_float(" float cube of 1:", &f_compute);
unsafe {
float_pow(
FLOAT_NEGATIVE_ONE.as_ptr(),
8,
6,
f_compute.as_mut_ptr(),
8,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
let _ = trace_float(" float 6th power of -1:", &f_compute);
let mut f9: [u8; 8] = [0u8; 8];
unsafe { float_from_int(9, f9.as_mut_ptr(), 8, FLOAT_ROUNDING_MODES_TO_NEAREST) };
unsafe {
float_pow(
f9.as_ptr(),
8,
2,
f_compute.as_mut_ptr(),
8,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
let _ = trace_float(" float square of 9:", &f_compute);
unsafe {
float_pow(
f9.as_ptr(),
8,
0,
f_compute.as_mut_ptr(),
8,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
let _ = trace_float(" float 0th power of 9:", &f_compute);
let mut f0: [u8; 8] = [0u8; 8];
unsafe { float_from_int(0, f0.as_mut_ptr(), 8, FLOAT_ROUNDING_MODES_TO_NEAREST) };
unsafe {
float_pow(
f0.as_ptr(),
8,
2,
f_compute.as_mut_ptr(),
8,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
let _ = trace_float(" float square of 0:", &f_compute);
let r = unsafe {
float_pow(
f0.as_ptr(),
8,
0,
f_compute.as_mut_ptr(),
8,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
let _ = trace_num(
" float 0th power of 0 (expecting INVALID_PARAMS error):",
r as i64,
);
}
fn test_float_root() {
let _ = trace("\n$$$ test_float_root $$$");
let mut f9: [u8; 8] = [0u8; 8];
unsafe { float_from_int(9, f9.as_mut_ptr(), 8, FLOAT_ROUNDING_MODES_TO_NEAREST) };
let mut f_compute: [u8; 8] = [0u8; 8];
unsafe {
float_root(
f9.as_ptr(),
8,
2,
f_compute.as_mut_ptr(),
8,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
let _ = trace_float(" float sqrt of 9:", &f_compute);
unsafe {
float_root(
f9.as_ptr(),
8,
3,
f_compute.as_mut_ptr(),
8,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
let _ = trace_float(" float cbrt of 9:", &f_compute);
let mut f1000000: [u8; 8] = [0u8; 8];
unsafe {
float_from_int(
1000000,
f1000000.as_mut_ptr(),
8,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
unsafe {
float_root(
f1000000.as_ptr(),
8,
3,
f_compute.as_mut_ptr(),
8,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
let _ = trace_float(" float cbrt of 1000000:", &f_compute);
unsafe {
float_root(
f1000000.as_ptr(),
8,
6,
f_compute.as_mut_ptr(),
8,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
let _ = trace_float(" float 6th root of 1000000:", &f_compute);
}
fn test_float_log() {
let _ = trace("\n$$$ test_float_log $$$");
let mut f1000000: [u8; 8] = [0u8; 8];
unsafe {
float_from_int(
1000000,
f1000000.as_mut_ptr(),
8,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
let mut f_compute: [u8; 8] = [0u8; 8];
unsafe {
float_log(
f1000000.as_ptr(),
8,
f_compute.as_mut_ptr(),
8,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
let _ = trace_float(" log_10 of 1000000:", &f_compute);
}
fn test_float_negate() {
let _ = trace("\n$$$ test_float_negate $$$");
let mut f_compute: [u8; 8] = [0u8; 8];
unsafe {
float_multiply(
FLOAT_ONE.as_ptr(),
8,
FLOAT_NEGATIVE_ONE.as_ptr(),
8,
f_compute.as_mut_ptr(),
8,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
// let _ = trace_float(" float:", &f_compute);
if 0 == unsafe { float_compare(FLOAT_NEGATIVE_ONE.as_ptr(), 8, f_compute.as_ptr(), 8) } {
let _ = trace(" negate const 1: good");
} else {
let _ = trace(" negate const 1: bad");
}
unsafe {
float_multiply(
FLOAT_NEGATIVE_ONE.as_ptr(),
8,
FLOAT_NEGATIVE_ONE.as_ptr(),
8,
f_compute.as_mut_ptr(),
8,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
// let _ = trace_float(" float:", &f_compute);
if 0 == unsafe { float_compare(FLOAT_ONE.as_ptr(), 8, f_compute.as_ptr(), 8) } {
let _ = trace(" negate const -1: good");
} else {
let _ = trace(" negate const -1: bad");
}
}
fn test_float_invert() {
let _ = trace("\n$$$ test_float_invert $$$");
let mut f_compute: [u8; 8] = [0u8; 8];
let mut f10: [u8; 8] = [0u8; 8];
unsafe { float_from_int(10, f10.as_mut_ptr(), 8, FLOAT_ROUNDING_MODES_TO_NEAREST) };
unsafe {
float_divide(
FLOAT_ONE.as_ptr(),
8,
f10.as_ptr(),
8,
f_compute.as_mut_ptr(),
8,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
let _ = trace_float(" invert a float from 10:", &f_compute);
unsafe {
float_divide(
FLOAT_ONE.as_ptr(),
8,
f_compute.as_ptr(),
8,
f_compute.as_mut_ptr(),
8,
FLOAT_ROUNDING_MODES_TO_NEAREST,
)
};
let _ = trace_float(" invert again:", &f_compute);
// if f10's value is 7, then invert twice won't match the original value
if 0 == unsafe { float_compare(f10.as_ptr(), 8, f_compute.as_ptr(), 8) } {
let _ = trace(" invert twice: good");
} else {
let _ = trace(" invert twice: bad");
}
}
#[unsafe(no_mangle)]
pub extern "C" fn finish() -> i32 {
test_float_from_wasm();
test_float_compare();
test_float_add_subtract();
test_float_multiply_divide();
test_float_pow();
test_float_root();
test_float_log();
test_float_negate();
test_float_invert();
1
}

View File

@@ -1,8 +0,0 @@
int
loop()
{
int volatile x = 0;
while (1)
x++;
return x;
}

View File

@@ -1,27 +0,0 @@
#include <stdint.h>
int32_t
get_ledger_sqn();
// int32_t trace(uint8_t const*, int32_t, uint8_t const*, int32_t, int32_t);
// int32_t trace_num(uint8_t const*, int32_t, int64_t);
// uint8_t buf[1024];
// char const test_res[] = "sqn: ";
// char const test_name[] = "TEST get_ledger_sqn";
int
finish()
{
// trace((uint8_t const *)test_name, sizeof(test_name) - 1, 0, 0, 0);
// memset(buf, 0, sizeof(buf));
// for(int i = 0; i < sizeof(buf); ++i) buf[i] = 0;
int x = get_ledger_sqn();
// if (x >= 0)
// x = *((int32_t*)buf);
// trace_num((uint8_t const *)test`_res, sizeof(test_res) - 1, x);
return x < 0 ? x : (x >= 5 ? x : 0);
}

View File

@@ -1,145 +0,0 @@
#include <stdint.h>
#include <stdlib.h>
static uint64_t const K512[] = {
0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f,
0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019,
0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242,
0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3,
0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 0x2de92c6f592b0275,
0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f,
0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc,
0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6,
0x92722c851482353b, 0xa2bfe8a14cf10364, 0xa81a664bbc423001,
0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99,
0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb,
0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc,
0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915,
0xc67178f2e372532b, 0xca273eceea26619c, 0xd186b8c721c0c207,
0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba,
0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
0x5fcb6fab3ad6faec, 0x6c44198c4a475817};
#define ROTATE(x, y) (((x) >> (y)) | ((x) << (64 - (y))))
#define Sigma0(x) (ROTATE((x), 28) ^ ROTATE((x), 34) ^ ROTATE((x), 39))
#define Sigma1(x) (ROTATE((x), 14) ^ ROTATE((x), 18) ^ ROTATE((x), 41))
#define sigma0(x) (ROTATE((x), 1) ^ ROTATE((x), 8) ^ ((x) >> 7))
#define sigma1(x) (ROTATE((x), 19) ^ ROTATE((x), 61) ^ ((x) >> 6))
#define Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z)))
#define Maj(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
static inline uint64_t
B2U64(uint8_t val, uint8_t sh)
{
return ((uint64_t)val) << sh;
}
void*
allocate(int sz)
{
return malloc(sz);
}
void
deallocate(void* p)
{
free(p);
}
uint8_t e_data[32 * 1024];
uint8_t*
sha512_process(uint8_t const* data, int32_t length)
{
static uint64_t state[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint64_t a, b, c, d, e, f, g, h, s0, s1, T1, T2;
uint64_t X[16];
uint64_t blocks = length / 128;
while (blocks--)
{
a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];
f = state[5];
g = state[6];
h = state[7];
unsigned i;
for (i = 0; i < 16; i++)
{
X[i] = B2U64(data[0], 56) | B2U64(data[1], 48) |
B2U64(data[2], 40) | B2U64(data[3], 32) | B2U64(data[4], 24) |
B2U64(data[5], 16) | B2U64(data[6], 8) | B2U64(data[7], 0);
data += 8;
T1 = h;
T1 += Sigma1(e);
T1 += Ch(e, f, g);
T1 += K512[i];
T1 += X[i];
T2 = Sigma0(a);
T2 += Maj(a, b, c);
h = g;
g = f;
f = e;
e = d + T1;
d = c;
c = b;
b = a;
a = T1 + T2;
}
for (i = 16; i < 80; i++)
{
s0 = X[(i + 1) & 0x0f];
s0 = sigma0(s0);
s1 = X[(i + 14) & 0x0f];
s1 = sigma1(s1);
T1 = X[i & 0xf] += s0 + s1 + X[(i + 9) & 0xf];
T1 += h + Sigma1(e) + Ch(e, f, g) + K512[i];
T2 = Sigma0(a) + Maj(a, b, c);
h = g;
g = f;
f = e;
e = d + T1;
d = c;
c = b;
b = a;
a = T1 + T2;
}
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;
state[5] += f;
state[6] += g;
state[7] += h;
}
return (uint8_t*)(state);
}
// int main ()
//{
// return 0;
// }

View File

@@ -1,13 +0,0 @@
(module
;; Define a memory with 1 initial page.
;; CRITICAL: We explicitly set the page size to 1 kilobyte.
;; Standard Wasm implies (pagesize 65536).
(memory 1 (pagesize 1024))
(func $finish (result i32)
;; If this module instantiates, the runtime accepted the custom page size.
i32.const 1
)
(export "finish" (func $finish))
)

View File

@@ -1,29 +0,0 @@
(module
;; Define a Mutable Global Variable to act as our counter.
;; We initialize it to 1,000,000.
(global $counter (mut i32) (i32.const 1000000))
(func $finish (result i32)
;; 1. Check if counter == 0 (Base Case)
global.get $counter
i32.eqz
if
;; If counter is 0, we are done. Return 1.
i32.const 1
return
end
;; 2. Decrement the Global Counter
global.get $counter
i32.const 1
i32.sub
global.set $counter
;; 3. Recursive Step: Call SELF
;; This puts an i32 (1) on the stack when it returns.
call $finish
)
;; Export the only function we have
(export "finish" (func $finish))
)

View File

@@ -1,21 +0,0 @@
(module
;; Define a 64-bit memory (index type i64)
;; Start with 1 page.
(memory i64 1)
(func $finish (result i32)
;; 1. Perform a store using a 64-bit address.
;; Even if the value is small (0), the type MUST be i64.
i64.const 0 ;; Address (64-bit)
i32.const 42 ;; Value (32-bit)
i32.store8 ;; Opcode doesn't change, but validation rules do.
;; 2. check memory size
;; memory.size now returns an i64.
memory.size
i64.const 1
i64.eq ;; Returns i32 (1 if true)
)
(export "finish" (func $finish))
)

View File

@@ -1,28 +0,0 @@
(module
;; 1. Define Memory: 1 Page = 64KB = 65,536 bytes
(memory 1)
;; Export memory so the host can inspect it if needed
(export "memory" (memory 0))
(func $test_straddle (result i32)
;; Push the address onto the stack.
;; 65534 is valid, but it is only 2 bytes away from the end.
i32.const 65534
;; Attempt to load an i32 (4 bytes) from that address.
;; This requires bytes 65534, 65535, 65536, and 65537.
;; Since 65536 is the first invalid byte, this MUST trap.
i32.load
;; Clean up the stack.
;; The load pushed a value, but we don't care what it is.
drop
;; Return 1 to signal "I survived the memory access"
i32.const 1
)
;; Export the function so you can call it from your host (JS, Python, etc.)
(export "finish" (func $test_straddle))
)

View File

@@ -1,29 +0,0 @@
(module
;; Start at your limit: 128 pages (8MB)
(memory 128)
(export "memory" (memory 0))
(func $try_grow_beyond_limit (result i32)
;; Attempt to grow by 0 page
i32.const 0
memory.grow
;; memory.grow returns:
;; -1 if the growth failed (Correct behavior for your limit)
;; 128 (old size) if growth succeeded (Means limit was bypassed)
;; Check if result == -1
i32.const -1
i32.eq
if
;; Growth FAILED (Host blocked it). Return -1.
i32.const -1
return
end
;; Growth SUCCEEDED (Host allowed it). Return 1.
i32.const 1
)
(export "finish" (func $try_grow_beyond_limit))
)

View File

@@ -1,26 +0,0 @@
(module
;; 1. Define Memory: Start with 0 pages
(memory 0)
;; Export memory to host
(export "memory" (memory 0))
(func $grow_from_zero (result i32)
;; We have 0 pages. We want to add 1 page.
;; Push delta (1) onto stack.
i32.const 1
;; Grow the memory.
;; If successful: memory becomes 64KB, returns old size (0).
;; If failed: memory stays 0, returns -1.
memory.grow
;; Drop the return value of memory.grow
drop
;; Return 1 (as requested)
i32.const 1
)
(export "finish" (func $grow_from_zero))
)

View File

@@ -1,29 +0,0 @@
(module
;; Start at your limit: 128 pages (8MB)
(memory 128)
(export "memory" (memory 0))
(func $try_grow_beyond_limit (result i32)
;; Attempt to grow by 1 page
i32.const 1
memory.grow
;; memory.grow returns:
;; -1 if the growth failed (Correct behavior for your limit)
;; 128 (old size) if growth succeeded (Means limit was bypassed)
;; Check if result == -1
i32.const -1
i32.eq
if
;; Growth FAILED (Host blocked it). Return -1.
i32.const -1
return
end
;; Growth SUCCEEDED (Host allowed it). Return 1.
i32.const 1
)
(export "finish" (func $try_grow_beyond_limit))
)

View File

@@ -1,33 +0,0 @@
(module
;; 1. Define Memory: Start with 1 page (64KB)
(memory 1)
;; Export memory to host
(export "memory" (memory 0))
(func $grow_negative (result i32)
;; The user pushed -1. In Wasm, this is interpreted as unsigned MAX_UINT32.
;; This is requesting to add 4,294,967,295 pages (approx 256 TB).
;; A secure runtime MUST fail this request (return -1) without crashing.
i32.const -1
;; Grow the memory.
;; Returns: old_size if success, -1 if failure.
memory.grow
;; Check if result == -1 (Failure)
i32.const -1
i32.eq
if
;; If memory.grow returned -1, we return -1 to signal "Correctly failed".
i32.const -1
return
end
;; If we are here, memory.grow somehow SUCCEEDED (Vulnerability).
;; We return 1 to signal "Unexpected Success".
i32.const 1
)
(export "finish" (func $grow_negative))
)

View File

@@ -1,27 +0,0 @@
(module
;; Define memory: 129 pages (> 8MB limit) min, 129 pages max
(memory 129 129)
;; Export memory so host can verify size
(export "memory" (memory 0))
;; access last byte of 8MB limit
(func $access_last_byte (result i32)
;; Math: 128 pages * 64,536 bytes/page = 8,388,608 bytes
;; Valid indices: 0 to 8,388,607
;; Push the address of the LAST valid byte
i32.const 8388607
;; Load byte from that address
i32.load8_u
;; Drop the value (we don't care what it is, just that we could read it)
drop
;; Return 1 to indicate success
i32.const 1
)
(export "finish" (func $access_last_byte))
)

View File

@@ -1,26 +0,0 @@
(module
;; Define memory: 128 pages (8MB) min, 128 pages max
(memory 128 128)
;; Export memory so host can verify size
(export "memory" (memory 0))
(func $access_last_byte (result i32)
;; Math: 128 pages * 64,536 bytes/page = 8,388,608 bytes
;; Valid indices: 0 to 8,388,607
;; Push the address of the LAST valid byte
i32.const 8388607
;; Load byte from that address
i32.load8_u
;; Drop the value (we don't care what it is, just that we could read it)
drop
;; Return 1 to indicate success
i32.const 1
)
(export "finish" (func $access_last_byte))
)

View File

@@ -1,23 +0,0 @@
(module
;; Define memory: 128 pages (8MB) min, 128 pages max
(memory 128 128)
;; Export memory so host can verify size
(export "memory" (memory 0))
(func $access_last_byte (result i32)
;; Push a negative address
i32.const -1
;; Load byte from that address
i32.load8_u
;; Drop the value
drop
;; Return 1 to indicate success
i32.const 1
)
(export "finish" (func $access_last_byte))
)

View File

@@ -1,27 +0,0 @@
(module
;; 1. Define Memory: 1 Page = 64KB
(memory 1)
(export "memory" (memory 0))
(func $test_offset_overflow (result i32)
;; 1. Push the base address onto the stack.
;; We use '0', which is the safest, most valid address possible.
i32.const 0
;; 2. Attempt to load using a static offset.
;; syntax: i32.load offset=N align=N
;; We set the offset to 65536 (the size of the memory).
;; The effective address becomes 0 + 65536 = 65536.
i32.load offset=65536
;; Clean up the stack.
;; The load pushed a value, but we don't care what it is.
drop
;; Return 1 to signal "I survived the memory access"
i32.const 1
)
(export "finish" (func $test_offset_overflow))
)

View File

@@ -1,22 +0,0 @@
(module
;; Define 1 page of memory (64KB = 65,536 bytes)
(memory 1)
(func $read_edge (result i32)
;; Push the index of the LAST valid byte
i32.const 65535
;; Load 1 byte (unsigned)
i32.load8_u
;; Clean up the stack.
;; The load pushed a value, but we don't care what it is.
drop
;; Return 1 to signal "I survived the memory access"
i32.const 1
)
;; Export as "finish" as requested
(export "finish" (func $read_edge))
)

View File

@@ -1,23 +0,0 @@
(module
;; Define 1 page of memory (64KB = 65,536 bytes)
(memory 1)
(func $read_overflow (result i32)
;; Push the index of the FIRST invalid byte
;; Memory is 0..65535, so 65536 is out of bounds.
i32.const 65536
;; Load 1 byte (unsigned)
i32.load8_u
;; Clean up the stack.
;; The load pushed a value, but we don't care what it is.
drop
;; Return 1 to signal "I survived the memory access"
i32.const 1
)
;; Export as "finish" as requested
(export "finish" (func $read_overflow))
)

View File

@@ -1,16 +0,0 @@
(module
;; Memory 0: Index 0 (Empty)
(memory 0)
;; Memory 1: Index 1 (Size 1 page)
;; If multi-memory is disabled, this line causes a validation error (max 1 memory).
(memory 1)
(func $finish (result i32)
;; Query size of Memory Index 1.
;; Should return 1 (success).
memory.size 1
)
(export "finish" (func $finish))
)

View File

@@ -1,25 +0,0 @@
(module
;; Define 1 page of memory
(memory 1)
(export "memory" (memory 0))
(func $test_bulk_ops (result i32)
;; Setup: Write value 42 at index 0 so we have something to copy
(i32.store8 (i32.const 0) (i32.const 42))
;; Test memory.copy (Opcode 0xFC 0x0A)
;; Copy 1 byte from offset 0 to offset 100
(memory.copy
(i32.const 100) ;; Destination Offset
(i32.const 0) ;; Source Offset
(i32.const 1) ;; Size (bytes)
)
;; Verify: Read byte at offset 100. Should be 42.
(i32.load8_u (i32.const 100))
(i32.const 42)
i32.eq
)
(export "finish" (func $test_bulk_ops))
)

View File

@@ -1,15 +0,0 @@
(module
;; 1. Define a global using an EXTENDED constant expression.
;; MVP only allows (i32.const X).
;; This proposal allows (i32.add (i32.const X) (i32.const Y)).
(global $g i32 (i32.add (i32.const 10) (i32.const 32)))
(func $finish (result i32)
;; 2. verify the global equals 42
global.get $g
i32.const 42
i32.eq
)
(export "finish" (func $finish))
)

View File

@@ -1,18 +0,0 @@
(module
(func $test_saturation (result i32)
;; 1. Push a float that is too big for a 32-bit integer
;; 1e10 (10 billion) > 2.14 billion (Max i32)
f32.const 1.0e10
;; 2. Attempt saturating conversion (Opcode 0xFC 0x00)
;; If supported: Clamps to MAX_I32.
;; If disabled: Validation error (unknown instruction).
i32.trunc_sat_f32_s
;; 3. Check if result is MAX_I32 (2147483647)
i32.const 2147483647
i32.eq
)
(export "finish" (func $test_saturation))
)

View File

@@ -1,12 +0,0 @@
;; generated by wasm-tools print gc_test.wasm that has the following hex
;; 0061736d01000000010b026000017f5f027f017f0103020100070a010666696e69736800000a0a010800fb01011a41010b
(module
(type (;0;) (func (result i32)))
(type (;1;) (struct (field (mut i32)) (field (mut i32))))
(export "finish" (func 0))
(func (;0;) (type 0) (result i32)
struct.new_default 1
drop
i32.const 1
)
)

Some files were not shown because too many files have changed in this diff Show More