Compare commits

..

4 Commits

Author SHA1 Message Date
Bart
0944823ffe Remove all-caps unity references 2026-01-30 08:08:03 -05:00
Bart
5de758d246 Add rename script change 2026-01-30 09:32:03 +00:00
Bart
573c7311d7 Merge branch 'develop' into bthomee/unity 2026-01-30 09:27:01 +00:00
Bart
75da9bec06 refactor: Remove unity builds 2026-01-30 08:20:14 +00:00
14 changed files with 32 additions and 263 deletions

View File

@@ -51,22 +51,20 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
# Only generate a subset of configurations in PRs.
if not all:
# Debian:
# - Bookworm using GCC 13: Release and Unity on linux/amd64, set
# the reference fee to 500.
# - Bookworm using GCC 15: Debug and no Unity on linux/amd64, enable
# code coverage (which will be done below).
# - Bookworm using Clang 16: Debug and no Unity on linux/arm64,
# enable voidstar.
# - Bookworm using Clang 17: Release and no Unity on linux/amd64,
# set the reference fee to 1000.
# - Bookworm using Clang 20: Debug and Unity on linux/amd64.
# - Bookworm using GCC 13: Release on linux/amd64, set the reference
# fee to 500.
# - Bookworm using GCC 15: Debug on linux/amd64, enable code
# coverage (which will be done below).
# - Bookworm using Clang 16: Debug on linux/arm64, enable voidstar.
# - Bookworm using Clang 17: Release on linux/amd64, set the
# reference fee to 1000.
# - Bookworm using Clang 20: Debug on linux/amd64.
if os["distro_name"] == "debian":
skip = True
if os["distro_version"] == "bookworm":
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-13"
and build_type == "Release"
and "-Dunity=ON" in cmake_args
and architecture["platform"] == "linux/amd64"
):
cmake_args = f"-DUNIT_TEST_REFERENCE_FEE=500 {cmake_args}"
@@ -74,14 +72,12 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-15"
and build_type == "Debug"
and "-Dunity=OFF" in cmake_args
and architecture["platform"] == "linux/amd64"
):
skip = False
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-16"
and build_type == "Debug"
and "-Dunity=OFF" in cmake_args
and architecture["platform"] == "linux/arm64"
):
cmake_args = f"-Dvoidstar=ON {cmake_args}"
@@ -89,7 +85,6 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-17"
and build_type == "Release"
and "-Dunity=ON" in cmake_args
and architecture["platform"] == "linux/amd64"
):
cmake_args = f"-DUNIT_TEST_REFERENCE_FEE=1000 {cmake_args}"
@@ -97,7 +92,6 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-20"
and build_type == "Debug"
and "-Dunity=ON" in cmake_args
and architecture["platform"] == "linux/amd64"
):
skip = False
@@ -105,15 +99,14 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
continue
# RHEL:
# - 9 using GCC 12: Debug and Unity on linux/amd64.
# - 10 using Clang: Release and no Unity on linux/amd64.
# - 9 using GCC 12: Debug on linux/amd64.
# - 10 using Clang: Release on linux/amd64.
if os["distro_name"] == "rhel":
skip = True
if os["distro_version"] == "9":
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-12"
and build_type == "Debug"
and "-Dunity=ON" in cmake_args
and architecture["platform"] == "linux/amd64"
):
skip = False
@@ -121,7 +114,6 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-any"
and build_type == "Release"
and "-Dunity=OFF" in cmake_args
and architecture["platform"] == "linux/amd64"
):
skip = False
@@ -129,17 +121,16 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
continue
# Ubuntu:
# - Jammy using GCC 12: Debug and no Unity on linux/arm64.
# - Noble using GCC 14: Release and Unity on linux/amd64.
# - Noble using Clang 18: Debug and no Unity on linux/amd64.
# - Noble using Clang 19: Release and Unity on linux/arm64.
# - Jammy using GCC 12: Debug on linux/arm64.
# - Noble using GCC 14: Release on linux/amd64.
# - Noble using Clang 18: Debug on linux/amd64.
# - Noble using Clang 19: Release on linux/arm64.
if os["distro_name"] == "ubuntu":
skip = True
if os["distro_version"] == "jammy":
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-12"
and build_type == "Debug"
and "-Dunity=OFF" in cmake_args
and architecture["platform"] == "linux/arm64"
):
skip = False
@@ -147,21 +138,18 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-14"
and build_type == "Release"
and "-Dunity=ON" in cmake_args
and architecture["platform"] == "linux/amd64"
):
skip = False
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-18"
and build_type == "Debug"
and "-Dunity=OFF" in cmake_args
and architecture["platform"] == "linux/amd64"
):
skip = False
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-19"
and build_type == "Release"
and "-Dunity=ON" in cmake_args
and architecture["platform"] == "linux/arm64"
):
skip = False
@@ -169,20 +157,16 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
continue
# MacOS:
# - Debug and no Unity on macos/arm64.
# - Debug on macos/arm64.
if os["distro_name"] == "macos" and not (
build_type == "Debug"
and "-Dunity=OFF" in cmake_args
and architecture["platform"] == "macos/arm64"
build_type == "Debug" and architecture["platform"] == "macos/arm64"
):
continue
# Windows:
# - Release and Unity on windows/amd64.
# - Release on windows/amd64.
if os["distro_name"] == "windows" and not (
build_type == "Release"
and "-Dunity=ON" in cmake_args
and architecture["platform"] == "windows/amd64"
build_type == "Release" and architecture["platform"] == "windows/amd64"
):
continue
@@ -209,18 +193,17 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
):
continue
# Enable code coverage for Debian Bookworm using GCC 15 in Debug and no
# Unity on linux/amd64
# Enable code coverage for Debian Bookworm using GCC 15 in Debug on
# linux/amd64
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-15"
and build_type == "Debug"
and "-Dunity=OFF" in cmake_args
and architecture["platform"] == "linux/amd64"
):
cmake_args = f"-Dcoverage=ON -Dcoverage_format=xml -DCODE_COVERAGE_VERBOSE=ON -DCMAKE_C_FLAGS=-O0 -DCMAKE_CXX_FLAGS=-O0 {cmake_args}"
# Generate a unique name for the configuration, e.g. macos-arm64-debug
# or debian-bookworm-gcc-12-amd64-release-unity.
# or debian-bookworm-gcc-12-amd64-release.
config_name = os["distro_name"]
if (n := os["distro_version"]) != "":
config_name += f"-{n}"
@@ -234,8 +217,6 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
config_name += f"-{build_type.lower()}"
if "-Dcoverage=ON" in cmake_args:
config_name += "-coverage"
if "-Dunity=ON" in cmake_args:
config_name += "-unity"
# Add the configuration to the list, with the most unique fields first,
# so that they are easier to identify in the GitHub Actions UI, as long

View File

@@ -208,5 +208,5 @@
}
],
"build_type": ["Debug", "Release"],
"cmake_args": ["-Dunity=OFF", "-Dunity=ON"]
"cmake_args": [""]
}

View File

@@ -15,8 +15,5 @@
}
],
"build_type": ["Debug", "Release"],
"cmake_args": [
"-Dunity=OFF -DCMAKE_POLICY_VERSION_MINIMUM=3.5",
"-Dunity=ON -DCMAKE_POLICY_VERSION_MINIMUM=3.5"
]
"cmake_args": ["-DCMAKE_POLICY_VERSION_MINIMUM=3.5"]
}

View File

@@ -15,5 +15,5 @@
}
],
"build_type": ["Debug", "Release"],
"cmake_args": ["-Dunity=OFF", "-Dunity=ON"]
"cmake_args": [""]
}

View File

@@ -545,16 +545,10 @@ See [Sanitizers docs](./docs/build/sanitizers.md) for more details.
| `assert` | OFF | Enable assertions. |
| `coverage` | OFF | Prepare the coverage report. |
| `tests` | OFF | Build tests. |
| `unity` | OFF | Configure a unity build. |
| `xrpld` | OFF | Build the xrpld application, and not just the libxrpl library. |
| `werr` | OFF | Treat compilation warnings as errors |
| `wextra` | OFF | Enable additional compilation warnings |
[Unity builds][5] may be faster for the first build
(at the cost of much more memory) since they concatenate sources into fewer
translation units. Non-unity builds may be faster for incremental builds,
and can be helpful for detecting `#include` omissions.
## Troubleshooting
### Conan
@@ -621,7 +615,6 @@ If you want to experiment with a new package, follow these steps:
[1]: https://github.com/conan-io/conan-center-index/issues/13168
[2]: https://en.cppreference.com/w/cpp/compiler_support/20
[3]: https://docs.conan.io/en/latest/getting_started.html
[5]: https://en.wikipedia.org/wiki/Unity_build
[6]: https://github.com/boostorg/beast/issues/2648
[7]: https://github.com/boostorg/beast/issues/2661
[gcovr]: https://gcovr.com/en/stable/getting-started.html

View File

@@ -9,8 +9,5 @@ function (xrpl_add_test name)
isolate_headers(${target} "${CMAKE_SOURCE_DIR}" "${CMAKE_SOURCE_DIR}/tests/${name}" PRIVATE)
# Make sure the test isn't optimized away in unity builds
set_target_properties(${target} PROPERTIES UNITY_BUILD_MODE GROUP UNITY_BUILD_BATCH_SIZE 0) # Adjust as needed
add_test(NAME ${target} COMMAND ${target})
endfunction ()

View File

@@ -4,12 +4,7 @@
include(target_protobuf_sources)
# Protocol buffers cannot participate in a unity build,
# because all the generated sources
# define a bunch of `static const` variables with the same names,
# so we just build them as a separate library.
add_library(xrpl.libpb)
set_target_properties(xrpl.libpb PROPERTIES UNITY_BUILD OFF)
target_protobuf_sources(xrpl.libpb xrpl/proto LANGUAGE cpp IMPORT_DIRS include/xrpl/proto
PROTOS include/xrpl/proto/xrpl.proto)
@@ -160,12 +155,4 @@ if (xrpld)
# antithesis_instrumentation.h, which is not exported as INTERFACE
target_include_directories(xrpld PRIVATE ${CMAKE_SOURCE_DIR}/external/antithesis-sdk)
endif ()
# any files that don't play well with unity should be added here
if (tests)
set_source_files_properties(
# these two seem to produce conflicts in beast teardown template methods
src/test/rpc/ValidatorRPC_test.cpp src/test/ledger/Invariants_test.cpp PROPERTIES SKIP_UNITY_BUILD_INCLUSION
TRUE)
endif ()
endif ()

View File

@@ -30,14 +30,6 @@ if (tests)
endif ()
endif ()
option(unity "Creates a build using UNITY support in cmake." OFF)
if (unity)
if (NOT is_ci)
set(CMAKE_UNITY_BUILD_BATCH_SIZE 15 CACHE STRING "")
endif ()
set(CMAKE_UNITY_BUILD ON CACHE BOOL "Do a unity build")
endif ()
if (is_clang AND is_linux)
option(voidstar "Enable Antithesis instrumentation." OFF)
endif ()

View File

@@ -23,7 +23,6 @@ class Xrpl(ConanFile):
"shared": [True, False],
"static": [True, False],
"tests": [True, False],
"unity": [True, False],
"xrpld": [True, False],
}
@@ -55,7 +54,6 @@ class Xrpl(ConanFile):
"shared": False,
"static": True,
"tests": False,
"unity": False,
"xrpld": False,
"date/*:header_only": True,
"ed25519/*:shared": False,
@@ -168,7 +166,6 @@ class Xrpl(ConanFile):
tc.variables["rocksdb"] = self.options.rocksdb
tc.variables["BUILD_SHARED_LIBS"] = self.options.shared
tc.variables["static"] = self.options.static
tc.variables["unity"] = self.options.unity
tc.variables["xrpld"] = self.options.xrpld
tc.generate()

View File

@@ -1,5 +1,5 @@
#ifndef XRPL_UNITY_ROCKSDB_H_INCLUDED
#define XRPL_UNITY_ROCKSDB_H_INCLUDED
#ifndef XRPL_BASICS_ROCKSDB_H_INCLUDED
#define XRPL_BASICS_ROCKSDB_H_INCLUDED
#if XRPL_ROCKSDB_AVAILABLE
// #include <rocksdb2/port/port_posix.h>

View File

@@ -16,7 +16,6 @@
// Add new amendments to the top of this list.
// Keep it sorted in reverse chronological order.
XRPL_FIX (DisallowIncomingV1_1, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (BatchInnerSigs, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(LendingProtocol, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(PermissionDelegationV1_1, Supported::no, VoteBehavior::DefaultNo)

View File

@@ -85,7 +85,8 @@ registerSSLCerts(boost::asio::ssl::context& ctx, boost::system::error_code& ec,
// There is a very unpleasant interaction between <wincrypt> and
// openssl x509 types (namely the former has macros that stomp
// on the latter), these undefs allow this TU to be safely used in
// unity builds without messing up subsequent TUs.
// unity builds without messing up subsequent TUs. Although we
// no longer use unity builds, leaving the undefs here does no harm.
#if BOOST_OS_WINDOWS
#undef X509_NAME
#undef X509_EXTENSIONS

View File

@@ -4173,170 +4173,6 @@ public:
env.require(balance(bob, gwUSD(10)));
}
void
testDisallowIncomingTrustline(FeatureBitset features)
{
testcase("DisallowIncomingTrustline in OfferCreate");
// Test that asfDisallowIncomingTrustline flag prevents offer crossing
// when the taker doesn't have a trustline.
//
// 1. alice creates a trustline and sells USD/gw tokens.
//
// 2. gw sets asfDisallowIncomingTrustline flag.
//
// 3. An account without a trustline tries to create an offer for USD/gw.
// Without amendment: succeeds and crosses alice's offer (backward compatible).
// With amendment: fails with tecNO_LINE (new behavior).
//
// 4. An account WITH an existing trustline can create an offer.
// The offer succeeds and crosses alice's offer.
//
// Note: The DisallowIncomingTrustline flag also prevents NEW trustlines
// from being created via TrustSet (enforced by fixDisallowIncomingV1).
// So accounts must create trustlines BEFORE the issuer sets the flag.
using namespace jtx;
// Test without fixDisallowIncomingV1_1 amendment
{
Env env{*this, features - fixDisallowIncomingV1_1};
auto const gw = Account("gw");
auto const alice = Account("alice");
auto const bob = Account("bob");
auto const gwUSD = gw["USD"];
env.fund(XRP(400000), gw, alice, bob);
env.close();
// Alice creates trustline and gets some USD
env(trust(alice, gwUSD(100)));
env.close();
env(pay(gw, alice, gwUSD(50)));
env.close();
// Alice creates sell offer
env(offer(alice, XRP(4000), gwUSD(40)));
env.close();
env.require(offers(alice, 1));
// GW sets DisallowIncomingTrustline flag
env(fset(gw, asfDisallowIncomingTrustline));
env.close();
// Without the amendment, bob can still create offer without trustline
// and the offer should cross (old behavior)
env(offer(bob, gwUSD(40), XRP(4000)));
env.close();
// Offer should have crossed
env.require(offers(alice, 0));
env.require(offers(bob, 0));
env.require(balance(bob, gwUSD(40)));
}
// Test with fixDisallowIncomingV1_1 amendment
{
Env env{*this, features};
auto const gw = Account("gw");
auto const alice = Account("alice");
auto const bob = Account("bob");
auto const carol = Account("carol");
auto const dan = Account("dan");
auto const gwUSD = gw["USD"];
env.fund(XRP(400000), gw, alice, bob, carol, dan);
env.close();
// Alice creates trustline and gets some USD
env(trust(alice, gwUSD(100)));
env.close();
env(pay(gw, alice, gwUSD(50)));
env.close();
// Bob and carol create trustlines BEFORE the flag is set
env(trust(bob, gwUSD(100)));
env.close();
env(trust(carol, gwUSD(100)));
env.close();
// Alice creates sell offer
env(offer(alice, XRP(4000), gwUSD(40)));
env.close();
env.require(offers(alice, 1));
env.require(balance(alice, gwUSD(50)));
// GW sets DisallowIncomingTrustline flag
env(fset(gw, asfDisallowIncomingTrustline));
env.close();
// Dan tries to create offer without trustline - should fail
env(offer(dan, gwUSD(40), XRP(4000)), ter(tecNO_LINE));
env.close();
// Alice's offer should still exist
env.require(offers(alice, 1));
env.require(balance(alice, gwUSD(50)));
// Dan shouldn't have any offers or balance
env.require(offers(dan, 0));
env.require(balance(dan, gwUSD(none)));
// Bob already has trustline, so his offer should succeed and cross
env(offer(bob, gwUSD(40), XRP(4000)));
env.close();
// Offer should have crossed
env.require(offers(alice, 0));
env.require(offers(bob, 0));
env.require(balance(alice, gwUSD(10)));
env.require(balance(bob, gwUSD(40)));
// Test scenario where carol already has a trustline (created before flag was set)
// Carol should be able to create offer since trustline already exists
env(pay(gw, alice, gwUSD(50)));
env.close();
env(offer(alice, XRP(1000), gwUSD(10)));
env.close();
env.require(offers(alice, 1));
env(offer(carol, gwUSD(10), XRP(1000)));
env.close();
// Offer should have crossed
env.require(offers(alice, 0));
env.require(offers(carol, 0));
env.require(balance(alice, gwUSD(50)));
env.require(balance(carol, gwUSD(10)));
// Test that gw can clear the flag
env(fclear(gw, asfDisallowIncomingTrustline));
env.close();
// Create new account eve without trustline
auto const eve = Account("eve");
env.fund(XRP(400000), eve);
env.close();
// Bob creates another sell offer
env(pay(gw, bob, gwUSD(50)));
env.close();
env(offer(bob, XRP(5000), gwUSD(50)));
env.close();
env.require(offers(bob, 1));
// Eve should now be able to create offer without trustline (flag is cleared)
env(offer(eve, gwUSD(50), XRP(5000)));
env.close();
// Offer should have crossed
env.require(offers(bob, 0));
env.require(offers(eve, 0));
env.require(balance(eve, gwUSD(50)));
}
}
void
testRCSmoketest(FeatureBitset features)
{
@@ -5173,7 +5009,6 @@ public:
testSelfPayUnlimitedFunds(features);
testRequireAuth(features);
testMissingAuth(features);
testDisallowIncomingTrustline(features);
testRCSmoketest(features);
testSelfAuth(features);
testDeletedOfferIssuer(features);

View File

@@ -216,22 +216,10 @@ CreateOffer::checkAcceptAsset(
// An account can always accept its own issuance.
return tesSUCCESS;
// Read the trustline once for multiple flag checks to optimize performance
auto const trustLine = view.read(keylet::line(id, issue.account, issue.currency));
// Check if the issuer has lsfDisallowIncomingTrustline set
// If so, the account must already have a trustline to receive tokens
if (view.rules().enabled(fixDisallowIncomingV1_1) && ((*issuerAccount)[sfFlags] & lsfDisallowIncomingTrustline))
{
if (!trustLine)
{
JLOG(j.debug()) << "delay: can't receive IOUs from issuer with DisallowIncomingTrustline set.";
return (flags & tapRETRY) ? TER{terNO_LINE} : TER{tecNO_LINE};
}
}
if ((*issuerAccount)[sfFlags] & lsfRequireAuth)
{
auto const trustLine = view.read(keylet::line(id, issue.account, issue.currency));
if (!trustLine)
{
return (flags & tapRETRY) ? TER{terNO_LINE} : TER{tecNO_LINE};
@@ -260,6 +248,8 @@ CreateOffer::checkAcceptAsset(
return tesSUCCESS;
}
auto const trustLine = view.read(keylet::line(id, issue.account, issue.currency));
if (!trustLine)
{
return tesSUCCESS;