diff --git a/.claude/skills/index.md b/.claude/skills/index.md new file mode 100644 index 0000000000..6a87e1740d --- /dev/null +++ b/.claude/skills/index.md @@ -0,0 +1,99 @@ +# xrpld Codebase Skills Index + +## Description +This is the top-level guide for all best-practices skills in this repository. Use this to understand the codebase organization and find the right skill for any task. + +## When to Use Skills +Reference a skill whenever you are: +- **Writing new code** in a module - check the skill first for established patterns +- **Modifying existing code** - verify your changes follow module conventions +- **Adding a new transaction type** - see `libxrpl/tx/transactors.md` for the full template +- **Debugging** - skills list key files and common pitfalls per module +- **Reviewing code** - skills document what "correct" looks like for each module + +## Codebase Architecture + +The codebase is split into two main areas: + +### `src/libxrpl/` — The Library (skills in `.claude/skills/libxrpl/`) +Reusable library code: data types, serialization, cryptography, ledger state, transaction processing, and storage. This is the **protocol layer**. + +| Module | Responsibility | +|--------|---------------| +| `basics` | Foundational types: Buffer, Slice, base_uint, Number, logging, error contracts | +| `beast` | Support layer: Journal logging, test framework, instrumentation, IP types | +| `conditions` | Crypto-conditions (RFC): fulfillment validation, DER encoding | +| `core` | Job queue, load monitoring, hash-based message dedup | +| `crypto` | CSPRNG, secure erasure, RFC1751 encoding | +| `json` | Json::Value, parsing, serialization, StaticString optimization | +| `ledger` | ReadView/ApplyView, state tables, payment sandbox, credit ops | +| `net` | HTTP/HTTPS client, SSL certs, async I/O | +| `nodestore` | Persistent node storage: RocksDB, NuDB, Memory backends | +| `protocol` | STObject hierarchy, SField, Serializer, TER codes, Features, Keylets | +| `proto` | Protocol Buffer generated headers (gRPC API definitions) | +| `rdb` | SOCI database wrapper, checkpointing | +| `resource` | Rate limiting, endpoint tracking, abuse prevention | +| `server` | Port config, SSL/TLS, WebSocket, admin networks | +| `shamap` | SHA-256 Merkle radix tree (16-way branching, COW) | +| `tx` | Transaction pipeline: Transactor base, preflight/preclaim/doApply | + +### `src/xrpld/` — The Server Application (skills in `.claude/skills/xrpld/`) +The running rippled server: application lifecycle, consensus, networking, RPC, and peer management. This is the **application layer**. + +| Module | Responsibility | +|--------|---------------| +| `app` | Application singleton, ledger management, consensus adapters, services | +| `app/main` | Application initialization and lifecycle | +| `app/ledger` | Ledger storage, retrieval, immutable state management | +| `app/consensus` | RCL consensus adapters (bridges generic algorithm to rippled) | +| `app/misc` | Fee voting, amendments, SHAMapStore, TxQ, validators, NetworkOPs | +| `app/paths` | Payment path finding algorithm, trust line caching | +| `app/rdb` | Application-level database operations | +| `app/tx` | Application-level transaction handling | +| `consensus` | Generic consensus algorithm (CRTP-based, app-independent) | +| `core` | Configuration (Config.h), time keeping, network ID | +| `overlay` | P2P networking: peer connections, protocol buffers, clustering | +| `peerfinder` | Network discovery: bootcache, livecache, slot management | +| `perflog` | Performance logging and instrumentation | +| `rpc` | RPC handler dispatch, coroutine suspension, 40+ command handlers | +| `shamap` | Application-level SHAMap operations (NodeFamily) | + +### `include/xrpl/` — Header Files +Headers live in `include/xrpl/` and mirror the `src/libxrpl/` structure. Each skill already references its corresponding headers in the "Key Files" section. + +## Cross-Cutting Conventions + +### Error Handling +- **Transaction errors**: Return `TER` enum (tesSUCCESS, tecFROZEN, temBAD_AMOUNT, etc.) +- **Logic errors**: `Throw()`, `LogicError()`, `XRPL_ASSERT()` +- **I/O errors**: `Status` enum or `boost::system::error_code` +- **RPC errors**: Inject via `context.params` + +### Assertions +```cpp +XRPL_ASSERT(condition, "ClassName::method : description"); // Debug only +XRPL_VERIFY(condition, "ClassName::method : description"); // Always enabled +``` + +### Logging +```cpp +JLOG(j_.warn()) << "Message"; // Always wrap in JLOG macro +``` + +### Memory Management +- `IntrusiveRefCounts` + `SharedIntrusive` for shared ownership in libxrpl +- `std::shared_ptr` for shared ownership in xrpld +- `std::unique_ptr` for exclusive ownership +- `CountedObject` mixin for instance tracking + +### Feature Gating +```cpp +if (ctx.rules.enabled(featureMyFeature)) { /* new behavior */ } +``` + +### Code Organization +- Headers in `include/xrpl/`, implementations in `src/libxrpl/` or `src/xrpld/` +- `#pragma once` (never `#ifndef` guards) +- `namespace xrpl { }` for all code +- `detail/` namespace for internal helpers +- Factory functions: `make_*()` returning `unique_ptr` or `shared_ptr` diff --git a/.claude/skills/libxrpl/basics.md b/.claude/skills/libxrpl/basics.md new file mode 100644 index 0000000000..204cf6be9c --- /dev/null +++ b/.claude/skills/libxrpl/basics.md @@ -0,0 +1,79 @@ +# Basics Module Best Practices + +## Description +Use when working with foundational utilities in `src/libxrpl/basics/` or `include/xrpl/basics/`. Covers data structures, memory management, logging, numeric operations, error handling, and string utilities. + +## Responsibility +Provides fundamental building blocks for the entire codebase: memory types (Buffer, Slice, Blob), intrusive smart pointers, arbitrary-precision integers (base_uint), multi-precision decimal arithmetic (Number), logging infrastructure, exception handling contracts, and platform abstractions. + +## Key Patterns + +### Memory Types +- **Slice** - Non-owning view into contiguous bytes (like std::span) +- **Buffer** - Owning byte container (like std::vector) +- **Blob** - Alias for std::vector +- Prefer `Slice` for read-only parameters, `Buffer` for owned data + +### Intrusive Smart Pointers +```cpp +// Prefer intrusive pointers over std::shared_ptr for minimal overhead +// Object embeds its own reference count +class MyObject : public IntrusiveRefCounts { + // ... +}; +// Use SharedIntrusive when weak pointers needed +``` + +### Error Handling +```cpp +// Contract-based exceptions (logs call stack then throws) +Throw("Invalid source file"); +LogThrow("exception message"); + +// Logic errors for invariant violations +LogicError("This should never happen"); + +// Assertions (fuzzing-aware) +XRPL_ASSERT(condition, "function_name : description"); +XRPL_VERIFY(condition, "message"); // Always enabled, not just debug +``` + +### Logging +```cpp +// Use JLOG macro - short-circuits if level disabled +JLOG(debugLog().warn()) << "Message: " << value; +JLOG(j_.trace()) << "Verbose detail"; +// Never: debugLog().warn() << "msg"; // Missing JLOG wastes formatting +``` + +### Number Precision +```cpp +// Use Number for multi-precision decimal arithmetic +// Always use RAII guard for rounding mode +NumberRoundModeGuard mg(Number::towards_zero); +auto result = amount * rate; +// Guard restores previous mode on scope exit +``` + +### base_uint Template +```cpp +// Typed big-endian integers: base_uint +// Tag prevents mixing unrelated types of same width +using uint256 = base_uint<256, void>; +using AccountID = base_uint<160, detail::AccountIDTag>; +``` + +## Common Pitfalls +- Never use `std::shared_ptr` when IntrusiveRefCounts is available - it adds a separate allocation +- Never format log messages without JLOG wrapper - wastes CPU when level is disabled +- Never use raw `assert()` - use `XRPL_ASSERT` for fuzzing instrumentation support +- Never mix `Buffer` and `Slice` ownership semantics - Slice does NOT own its data + +## Key Files +- `include/xrpl/basics/IntrusiveRefCounts.h` - Atomic reference counting +- `include/xrpl/basics/IntrusivePointer.h` - Smart pointer using intrusive refs +- `include/xrpl/basics/base_uint.h` - Arbitrary-length big-endian integers +- `include/xrpl/basics/Buffer.h`, `Blob.h`, `Slice.h` - Memory types +- `include/xrpl/basics/Number.h` - Multi-precision decimal arithmetic +- `include/xrpl/basics/Log.h` - Logging infrastructure +- `include/xrpl/basics/contract.h` - Throw, LogicError, XRPL_ASSERT diff --git a/.claude/skills/libxrpl/beast.md b/.claude/skills/libxrpl/beast.md new file mode 100644 index 0000000000..31803b5ed0 --- /dev/null +++ b/.claude/skills/libxrpl/beast.md @@ -0,0 +1,62 @@ +# Beast Module Best Practices + +## Description +Use when working with the Beast support layer in `src/libxrpl/beast/` or `include/xrpl/beast/`. Covers networking types, unit testing, Journal logging, and instrumentation. + +## Responsibility +Library support layer providing network types (IP addresses, endpoints), unit testing framework, Journal/logging abstractions, instrumentation/assertion macros, and type introspection utilities. + +## Key Patterns + +### Journal Logging +```cpp +// Journal wraps a Sink pointer - copy by value is cheap +beast::Journal const j_; + +// Severity levels: kTrace, kDebug, kInfo, kWarning, kError, kFatal +JLOG(j_.warn()) << "User-facing issue"; +JLOG(j_.debug()) << "Implementation detail"; +JLOG(j_.trace()) << "Very verbose diagnostic"; +JLOG(j_.error()) << "Unexpected failure"; +``` + +### Unit Testing +```cpp +class MyTest : public beast::unit_test::suite { + void run() override { + testcase("feature description"); + BEAST_EXPECT(value == expected); // Non-fatal assertion + BEAST_REQUIRE(value == expected); // Fatal - aborts test on failure + } +}; +BEAST_DEFINE_TESTSUITE(MyTest, module, ripple); +``` + +### Instrumentation +```cpp +// Use XRPL_ASSERT for debug-only assertions (fuzzing-aware) +XRPL_ASSERT(ptr != nullptr, "MyClass::method : null pointer"); + +// Format: "ClassName::methodName : description" +// The string format is important for fuzzing instrumentation +``` + +### IP Endpoint Types +```cpp +// Use beast::IP::Endpoint for network addresses +beast::IP::Endpoint endpoint; +// Supports both IPv4 and IPv6 +// Includes port information +``` + +## Common Pitfalls +- Never use `BEAST_EXPECT` when the test cannot continue on failure - use `BEAST_REQUIRE` instead +- Never create a Journal with a dangling Sink pointer - ensure Sink outlives Journal +- Always include "ClassName::methodName" prefix in XRPL_ASSERT messages for traceability + +## Key Files +- `include/xrpl/beast/utility/Journal.h` - Log sink abstraction +- `include/xrpl/beast/unit_test/suite.h` - Test framework +- `include/xrpl/beast/utility/instrumentation.h` - XRPL_ASSERT macros +- `include/xrpl/beast/net/IPEndpoint.h` - Network endpoint types +- `include/xrpl/beast/core/SemanticVersion.h` - Version parsing diff --git a/.claude/skills/libxrpl/beast/clock.md b/.claude/skills/libxrpl/beast/clock.md new file mode 100644 index 0000000000..412fe502a3 --- /dev/null +++ b/.claude/skills/libxrpl/beast/clock.md @@ -0,0 +1,33 @@ +# Beast Clock Module Best Practices + +## Description +Use when working with clock abstractions in `src/libxrpl/beast/clock/` or `include/xrpl/beast/clock/`. Covers abstract clock interfaces and manual clock implementations for testing. + +## Responsibility +Provides clock abstractions that decouple code from system time, enabling deterministic testing with manual clocks and supporting different time granularities. + +## Key Patterns + +### Abstract Clock Interface +```cpp +// Use abstract_clock for testable time-dependent code +// Production: uses system clock +// Testing: uses manual_clock for deterministic control +``` + +### Manual Clock for Testing +```cpp +// Advance time manually in tests +manual_clock clock; +clock.advance(std::chrono::seconds(30)); +// Deterministic - no flaky tests from timing issues +``` + +## Common Pitfalls +- Never use `std::chrono::system_clock::now()` directly - inject clock dependency +- Always use manual_clock in unit tests for deterministic behavior +- Be aware of Ripple Epoch vs Unix Epoch when working with ledger timestamps + +## Key Files +- `include/xrpl/beast/clock/abstract_clock.h` - Abstract clock interface +- `include/xrpl/beast/clock/manual_clock.h` - Testable clock implementation diff --git a/.claude/skills/libxrpl/beast/core.md b/.claude/skills/libxrpl/beast/core.md new file mode 100644 index 0000000000..a47d0bbe50 --- /dev/null +++ b/.claude/skills/libxrpl/beast/core.md @@ -0,0 +1,29 @@ +# Beast Core Module Best Practices + +## Description +Use when working with core beast utilities in `src/libxrpl/beast/core/` or `include/xrpl/beast/core/`. Covers semantic versioning and core type utilities. + +## Responsibility +Provides core utilities including semantic version parsing/comparison, system abstractions, and foundational type support. + +## Key Patterns + +### Semantic Version Parsing +```cpp +// Parse version strings following semver spec +SemanticVersion version; +if (version.parse("1.2.3-beta")) { + auto major = version.majorVersion; + auto minor = version.minorVersion; + auto patch = version.patchVersion; +} +// Supports comparison operators for version ordering +``` + +## Common Pitfalls +- Always validate version strings before using - parse() returns false on invalid input +- Remember that pre-release versions have lower precedence than release versions + +## Key Files +- `include/xrpl/beast/core/SemanticVersion.h` - Version parsing and comparison +- `src/libxrpl/beast/core/SemanticVersion.cpp` - Implementation diff --git a/.claude/skills/libxrpl/beast/insight.md b/.claude/skills/libxrpl/beast/insight.md new file mode 100644 index 0000000000..eabb64f282 --- /dev/null +++ b/.claude/skills/libxrpl/beast/insight.md @@ -0,0 +1,41 @@ +# Beast Insight Module Best Practices + +## Description +Use when working with metrics and monitoring in `src/libxrpl/beast/insight/` or `include/xrpl/beast/insight/`. Covers counters, gauges, and metrics collection. + +## Responsibility +Provides metrics collection infrastructure for monitoring application performance: counters for cumulative values, gauges for point-in-time measurements, and hooks for metrics export. + +## Key Patterns + +### Metrics Types +```cpp +// Counter: Monotonically increasing value (e.g., total requests) +insight::Counter requests; +++requests; + +// Gauge: Point-in-time value (e.g., current connections) +insight::Gauge connections; +connections = currentCount; + +// Event: Timed operation tracking +insight::Event latency; +``` + +### Null Metrics +```cpp +// Use NullCollector when metrics disabled +// All operations become no-ops with zero overhead +auto collector = insight::NullCollector::New(); +``` + +## Common Pitfalls +- Use Counter for cumulative values, Gauge for current state - don't mix them +- Always use NullCollector for tests - avoids metrics overhead +- Never store raw metric values in long-lived objects - use the insight types + +## Key Files +- `include/xrpl/beast/insight/Counter.h` - Cumulative counter +- `include/xrpl/beast/insight/Gauge.h` - Point-in-time gauge +- `include/xrpl/beast/insight/Collector.h` - Metrics collector interface +- `include/xrpl/beast/insight/NullCollector.h` - No-op collector diff --git a/.claude/skills/libxrpl/beast/net.md b/.claude/skills/libxrpl/beast/net.md new file mode 100644 index 0000000000..a0ec08b337 --- /dev/null +++ b/.claude/skills/libxrpl/beast/net.md @@ -0,0 +1,46 @@ +# Beast Net Module Best Practices + +## Description +Use when working with network types in `src/libxrpl/beast/net/` or `include/xrpl/beast/net/`. Covers IP address and endpoint representations. + +## Responsibility +Provides network type abstractions for IP addresses (v4 and v6) and endpoints (address + port), with parsing utilities and comparison operators. + +## Key Patterns + +### IP Endpoint Usage +```cpp +// beast::IP::Endpoint combines address + port +beast::IP::Endpoint endpoint( + beast::IP::Address::from_string("127.0.0.1"), 51235); + +// Supports both IPv4 and IPv6 +beast::IP::Endpoint v6endpoint( + beast::IP::Address::from_string("::1"), 51235); +``` + +### Address Parsing +```cpp +// Parse from string with error handling +boost::system::error_code ec; +auto address = beast::IP::Address::from_string(input, ec); +if (ec) { /* handle invalid address */ } +``` + +### Comparison and Ordering +```cpp +// Endpoints support full comparison for use in containers +std::set endpoints; +std::map consumers; +``` + +## Common Pitfalls +- Always handle both IPv4 and IPv6 when working with endpoints +- Use error_code overload of from_string to handle invalid input gracefully +- Never assume address format - always parse and validate + +## Key Files +- `include/xrpl/beast/net/IPEndpoint.h` - Combined address + port +- `include/xrpl/beast/net/IPAddress.h` - IP address types +- `include/xrpl/beast/net/IPAddressV4.h` - IPv4 specific +- `include/xrpl/beast/net/IPAddressV6.h` - IPv6 specific diff --git a/.claude/skills/libxrpl/beast/utility.md b/.claude/skills/libxrpl/beast/utility.md new file mode 100644 index 0000000000..c7ea46f000 --- /dev/null +++ b/.claude/skills/libxrpl/beast/utility.md @@ -0,0 +1,47 @@ +# Beast Utility Module Best Practices + +## Description +Use when working with beast utility classes in `src/libxrpl/beast/utility/` or `include/xrpl/beast/utility/`. Covers Journal logging, instrumentation, and type introspection. + +## Responsibility +Provides utility classes including the Journal logging abstraction (Sink + Stream), XRPL_ASSERT/XRPL_VERIFY instrumentation macros, and type introspection helpers. + +## Key Patterns + +### Journal and Sink Architecture +```cpp +// Sink: abstract base for log message routing +class Sink { + virtual void write(beast::severities::Severity level, std::string const& text) = 0; + void console(bool output); // Enable console output +}; + +// Journal: lightweight wrapper around Sink* (copy by value) +beast::Journal j(sinkPtr); +JLOG(j.warn()) << "Message"; + +// WrappedSink: adds prefix to all messages +beast::WrappedSink wrappedSink(parentSink, "MyModule"); +``` + +### Instrumentation Macros +```cpp +// XRPL_ASSERT: Debug-only assertion (disabled in release, fuzzing-aware) +XRPL_ASSERT(condition, "ClassName::method : description"); + +// XRPL_VERIFY: Always-enabled assertion +XRPL_VERIFY(condition, "ClassName::method : description"); + +// Format convention: "ClassName::methodName : human-readable description" +``` + +## Common Pitfalls +- Always use "ClassName::methodName" prefix in assertion messages +- Journal is cheap to copy (just a pointer) - pass by value is fine +- WrappedSink must outlive any Journal created from it +- XRPL_ASSERT is no-op in release builds - don't put side effects in the condition + +## Key Files +- `include/xrpl/beast/utility/Journal.h` - Log sink abstraction and Journal +- `include/xrpl/beast/utility/instrumentation.h` - XRPL_ASSERT, XRPL_VERIFY +- `include/xrpl/beast/utility/WrappedSink.h` - Prefixed log sink diff --git a/.claude/skills/libxrpl/conditions.md b/.claude/skills/libxrpl/conditions.md new file mode 100644 index 0000000000..8b05e903bb --- /dev/null +++ b/.claude/skills/libxrpl/conditions.md @@ -0,0 +1,63 @@ +# Conditions Module Best Practices + +## Description +Use when working with crypto-conditions in `src/libxrpl/conditions/` or `include/xrpl/conditions/`. Implements the RFC crypto-conditions specification. + +## Responsibility +Implements crypto-conditions for conditional payments: condition fingerprints, fulfillment validation, multiple condition types (preimage, prefix, threshold, RSA, Ed25519), and binary DER serialization/deserialization. + +## Key Patterns + +### Fulfillment Interface +```cpp +// Abstract base for all fulfillment types +struct Fulfillment { + virtual ~Fulfillment() = default; + virtual Buffer fingerprint() const = 0; + virtual Type type() const = 0; + virtual bool validate(Slice data) const = 0; + virtual std::uint32_t cost() const = 0; + virtual Condition condition() const = 0; +}; +``` + +### Factory Pattern for Deserialization +```cpp +// Returns unique_ptr + sets error_code (non-throwing) +std::unique_ptr deserialize(Slice s, std::error_code& ec); + +// Usage: +std::error_code ec; +auto fulfillment = Fulfillment::deserialize(data, ec); +if (ec) return {}; // Early return on error +``` + +### Type-Safe Enums +```cpp +enum class Type : std::uint8_t { + preimageSha256 = 0, + prefixSha256 = 1, + thresholdSha256 = 2, + rsaSha256 = 3, + ed25519Sha256 = 4 +}; +``` + +### Size Limits +```cpp +static constexpr std::size_t maxSerializedCondition = 128; +static constexpr std::size_t maxSerializedFulfillment = 256; +// Always respect these limits when creating conditions +``` + +## Common Pitfalls +- Never throw exceptions from binary parsing - use `std::error_code` parameter pattern +- Always check `ec` after deserialization before using the result +- Respect `maxSerializedFulfillment` size limits + +## Key Files +- `include/xrpl/conditions/Condition.h` - Base condition with type/fingerprint/cost +- `include/xrpl/conditions/Fulfillment.h` - Abstract fulfillment interface +- `include/xrpl/conditions/detail/PreimageSha256.h` - Preimage implementation +- `include/xrpl/conditions/detail/utils.h` - DER encoding/decoding +- `include/xrpl/conditions/detail/error.h` - Error codes diff --git a/.claude/skills/libxrpl/core.md b/.claude/skills/libxrpl/core.md new file mode 100644 index 0000000000..91d55d143d --- /dev/null +++ b/.claude/skills/libxrpl/core.md @@ -0,0 +1,61 @@ +# Core Module Best Practices + +## Description +Use when working with job processing and routing infrastructure in `src/libxrpl/core/` or `include/xrpl/core/`. Covers job queues, load monitoring, and message deduplication. + +## Responsibility +Distributed job processing with priority levels, load monitoring for execution tracking, and hash-based message suppression/routing for peer deduplication. + +## Key Patterns + +### Job Queue Priorities +```cpp +// Job types ordered by priority (lower enum = lower priority) +enum JobType { + jtINVALID = -1, + jtPACK, // Lowest priority + jtCLIENT_WEBSOCKET, + // ... + jtVALIDATION_t, // Trusted validation (high) + jtADMIN // Admin operations (highest) +}; +// Position in enum determines scheduling priority +``` + +### HashRouter for Deduplication +```cpp +// Suppress duplicate messages from peers +std::optional> shouldRelay(uint256 const& key); +// Returns {} if already relayed, set of peers if should relay + +// Track peer that sent a message +auto result = router.addSuppressionPeer(key, peer); +``` + +### RAII Locking +```cpp +// Always use lock_guard for mutex protection +std::lock_guard lock(mutex_); +auto result = emplace(key); +result.first.addPeer(peer); +return result.second; // Return while lock is held +``` + +### Optional Return Types +```cpp +// Use std::optional for "maybe" results +std::optional> shouldRelay(uint256 const& key); +// Caller checks: if (auto peers = shouldRelay(key)) { ... } +``` + +## Common Pitfalls +- Never hold locks longer than necessary - lock_guard scope = critical section +- Never ignore job priorities when scheduling work - use appropriate JobType +- Always let HashRouter handle message deduplication rather than implementing custom logic + +## Key Files +- `include/xrpl/core/Job.h` - Job wrapper with type, index, function +- `include/xrpl/core/JobTypes.h` - Job type enumerations and metadata +- `include/xrpl/core/JobQueue.h` - Priority queue for dispatching jobs +- `include/xrpl/core/HashRouter.h` - Duplicate message suppression +- `include/xrpl/core/LoadMonitor.h` - Job execution time tracking diff --git a/.claude/skills/libxrpl/core/detail.md b/.claude/skills/libxrpl/core/detail.md new file mode 100644 index 0000000000..fa370933f4 --- /dev/null +++ b/.claude/skills/libxrpl/core/detail.md @@ -0,0 +1,32 @@ +# Core Detail Module Best Practices + +## Description +Use when working with internal core implementation details in `src/libxrpl/core/detail/`. These are private implementation helpers not intended for direct external use. + +## Responsibility +Internal implementation details for the core module, including helper functions and private data structures used by JobQueue, HashRouter, and LoadMonitor. + +## Key Patterns + +### Detail Namespace Convention +```cpp +namespace xrpl { +namespace detail { +// Internal helpers - not part of public API +// May change without notice between versions +} +} +``` + +### Encapsulation +- Code in `detail/` should only be included by its parent module +- Never include detail headers from outside the core module +- If you need functionality from detail, use the public core API instead + +## Common Pitfalls +- Never depend on detail namespace types or functions from outside the core module +- Detail implementations may change without preserving API compatibility +- Always use the public `core/` headers for stable interfaces + +## Key Files +- Files in this directory are implementation details of `include/xrpl/core/` headers diff --git a/.claude/skills/libxrpl/crypto.md b/.claude/skills/libxrpl/crypto.md new file mode 100644 index 0000000000..afbef2f40a --- /dev/null +++ b/.claude/skills/libxrpl/crypto.md @@ -0,0 +1,51 @@ +# Crypto Module Best Practices + +## Description +Use when working with cryptographic operations in `src/libxrpl/crypto/` or `include/xrpl/crypto/`. Covers CSPRNG, secure memory erasure, and RFC1751 encoding. + +## Responsibility +Low-level cryptographic operations: cryptographically secure random number generation (CSPRNG), RFC1751 word-based encoding for keys, and secure memory erasure to prevent sensitive data leakage. + +## Key Patterns + +### CSPRNG Usage +```cpp +// Thread-safe PRNG - use the global singleton +auto& prng = crypto_prng(); + +// Generate random value +auto randomValue = prng(); + +// Fill buffer with random bytes +prng(buffer.data(), buffer.size()); + +// NEVER create your own csprng_engine - use crypto_prng() +``` + +### Secure Memory Erasure +```cpp +// Use volatile memset to prevent compiler optimization +secure_erase(secretKey.data(), secretKey.size()); +// MUST be called before destroying any buffer containing secrets +``` + +### Engine Concept Conformance +```cpp +// csprng_engine meets UniformRandomNumberEngine requirements +using result_type = std::uint64_t; +static constexpr result_type min(); +static constexpr result_type max(); +// Can be used with standard distributions +``` + +## Common Pitfalls +- Never create a local `csprng_engine` instance - always use `crypto_prng()` singleton +- Never use `std::rand()` or `std::mt19937` for security-sensitive operations +- Always call `secure_erase()` on secret key material before destruction +- Never copy or move a `csprng_engine` - it's non-copyable and non-movable by design +- Be aware of OpenSSL version differences - locking behavior varies + +## Key Files +- `include/xrpl/crypto/csprng.h` - Thread-safe PRNG engine +- `include/xrpl/crypto/RFC1751.h` - Human-readable key encoding +- `include/xrpl/crypto/secure_erase.h` - Volatile memset for secrets diff --git a/.claude/skills/libxrpl/json.md b/.claude/skills/libxrpl/json.md new file mode 100644 index 0000000000..e258e93e1f --- /dev/null +++ b/.claude/skills/libxrpl/json.md @@ -0,0 +1,68 @@ +# JSON Module Best Practices + +## Description +Use when working with JSON parsing and serialization in `src/libxrpl/json/` or `include/xrpl/json/`. Covers Json::Value, readers, writers, and custom allocators. + +## Responsibility +JSON value representation (discriminated union for all JSON types), parsing text to Value objects, serialization from Value to text, and custom string allocation for memory control. + +## Key Patterns + +### Json::Value Usage +```cpp +// Discriminated union - supports all JSON types +Json::Value obj(Json::objectValue); +obj["key"] = "string_value"; +obj["count"] = 42u; +obj["flag"] = true; +obj["nested"] = Json::objectValue; + +// Array creation +Json::Value arr(Json::arrayValue); +arr.append("item"); +arr.append(123); + +// Type checking +if (obj.isObject()) { ... } +if (obj.isMember("key")) { ... } +``` + +### StaticString Optimization +```cpp +// Use StaticString for compile-time known keys to avoid allocation +static const Json::StaticString code("code"); +static const Json::StaticString message("message"); +object[code] = 1234; // No dynamic allocation for key +object[message] = "ok"; // Key stored as pointer, not copied +``` + +### Value Type Enum +```cpp +enum ValueType { + nullValue = 0, + intValue, uintValue, realValue, + stringValue, booleanValue, + arrayValue, objectValue +}; +// Check type before accessing to avoid undefined behavior +``` + +### Lazy Initialization +```cpp +// Container elements auto-created on access (like JavaScript) +Json::Value obj; +obj["newKey"]["nested"] = 1; // Creates intermediate objects automatically +// Be aware: accessing a non-existent key creates it +``` + +## Common Pitfalls +- Accessing a non-existent key via `operator[]` creates a null entry - use `isMember()` to check first if you don't want side effects +- Use `const` overload of `operator[]` to avoid auto-creation: `obj["key"]` on const ref returns null reference +- Prefer `StaticString` for frequently-used keys to avoid repeated allocations +- Never assume JSON numeric types - check `isInt()`, `isUInt()`, `isDouble()` explicitly + +## Key Files +- `include/xrpl/json/json_value.h` - Main Value class +- `include/xrpl/json/json_reader.h` - Text-to-Value parser +- `include/xrpl/json/json_writer.h` - Value-to-text serializer +- `include/xrpl/json/json_forwards.h` - Forward declarations and aliases diff --git a/.claude/skills/libxrpl/ledger.md b/.claude/skills/libxrpl/ledger.md new file mode 100644 index 0000000000..963c676084 --- /dev/null +++ b/.claude/skills/libxrpl/ledger.md @@ -0,0 +1,84 @@ +# Ledger Module Best Practices + +## Description +Use when working with ledger state management in `src/libxrpl/ledger/` or `include/xrpl/ledger/`. Covers views, state tables, payments, and credit operations. + +## Responsibility +Manages the state of the distributed ledger: abstractions for viewing, reading, and applying transactions to ledger state. Handles account ownership tracking, trust lines, payment processing, directory management, and credential verification. + +## Key Patterns + +### ReadView vs ApplyView +```cpp +// ReadView: Read-only access to ledger state +bool exists = view.exists(keylet::account(accountID)); +auto sle = view.read(keylet::account(accountID)); // Returns shared_ptr + +// ApplyView: Mutable access for transaction application +auto sle = view.peek(keylet::account(accountID)); // Returns shared_ptr +sle->setFieldAmount(sfBalance, newBalance); +view.update(sle); // Commit change +view.insert(newSle); // Create new entry +view.erase(sle); // Remove entry +``` + +### Enum-Based Control (No Boolean Blindness) +```cpp +// NEVER: bool ignoreFreeze = true; +// ALWAYS: Use named enums +enum FreezeHandling { fhIGNORE_FREEZE, fhZERO_IF_FROZEN }; +enum AuthHandling { ahIGNORE_AUTH, ahZERO_IF_UNAUTHORIZED }; + +STAmount accountHolds(ReadView const& view, AccountID const& account, + Currency const& currency, AccountID const& issuer, + FreezeHandling zeroIfFrozen, beast::Journal j); +``` + +### Asset Variant Handling +```cpp +// Use std::visit for Asset (Issue or MPTIssue) +return std::visit( + [&](auto const& issue) { + return isIndividualFrozen(view, account, issue); + }, + asset.value()); +``` + +### PaymentSandbox for Isolation +```cpp +// Test payment effects before committing +PaymentSandbox sandbox(&view); +// ... apply changes to sandbox ... +sandbox.apply(view); // Commit all changes atomically +// Or let sandbox destruct to discard +``` + +### TER Return Codes +```cpp +// Transaction results are returned as TER, not exceptions +TER result = doApply(); +if (result != tesSUCCESS) return result; +// TER categories: tes (success), tec (claimed fee), tef (failure), tel (local), tem (malformed) +``` + +### Depth Limiting +```cpp +// Recursive operations use depth parameter to prevent infinite recursion +TER checkVaultState(ReadView const& view, AccountID const& id, int depth = 0); +if (depth > maxDepth) return tecINTERNAL; +``` + +## Common Pitfalls +- Never use `read()` when you need to modify - use `peek()` instead +- Never forget to call `view.update(sle)` after modifying a peeked SLE +- Never use bare booleans for control flags - use the enum types +- Always check for frozen/unauthorized states before operating on trust lines +- Never ignore TER return values - propagate them up the call chain + +## Key Files +- `include/xrpl/ledger/View.h` - Core read/write operations (largest file) +- `include/xrpl/ledger/ReadView.h` - Read-only interface +- `include/xrpl/ledger/ApplyView.h` - Mutable interface +- `src/libxrpl/ledger/PaymentSandbox.cpp` - Isolated payment testing +- `src/libxrpl/ledger/ApplyStateTable.cpp` - State change management +- `src/libxrpl/ledger/Credit.cpp` - Trust line and IOU operations diff --git a/.claude/skills/libxrpl/net.md b/.claude/skills/libxrpl/net.md new file mode 100644 index 0000000000..a7f2555eb1 --- /dev/null +++ b/.claude/skills/libxrpl/net.md @@ -0,0 +1,58 @@ +# Net Module Best Practices + +## Description +Use when working with network communication in `src/libxrpl/net/` or `include/xrpl/net/`. Covers HTTP/HTTPS client functionality and SSL certificate management. + +## Responsibility +Provides HTTP/HTTPS client functionality for network requests, including SSL certificate registration, asynchronous request handling with boost::asio, and callback-based completion. + +## Key Patterns + +### Async HTTP with Callbacks +```cpp +// Callback returns bool indicating success/continuation +HTTPClient::get( + bSSL, io_context, + std::deque{"site1.com", "site2.com"}, // Fallback sites + 443, "/path", + maxResponseBytes, + timeout, + [](boost::system::error_code const& ec, int status, std::string const& body) -> bool { + if (ec) return false; // Stop + // Process response + return true; // Success + }, + headers, journal); +``` + +### Lifetime Management with shared_from_this +```cpp +// Async callbacks use intrusive_ptr for safe lifetime +class HTTPClientImp : public HTTPClient, + public std::enable_shared_from_this { + void startAsync() { + auto self = shared_from_this(); // Prevent premature destruction + // ... schedule async operations ... + } +}; +``` + +### Deadline Timers +```cpp +// Always set timeouts for network operations +boost::asio::basic_waitable_timer timer_; +timer_.expires_after(std::chrono::seconds(timeout)); +// Cancel pending operation on timeout +``` + +## Common Pitfalls +- Never start async operations without capturing shared_from_this - object may be destroyed before callback +- Always set deadline timers on network operations to prevent hanging connections +- Always set maximum response size limits to prevent resource exhaustion +- Never assume DNS resolution will succeed - handle resolver errors + +## Key Files +- `include/xrpl/net/HTTPClient.h` - Main HTTP client interface +- `src/libxrpl/net/HTTPClient.cpp` - Implementation with async I/O +- `src/libxrpl/net/RegisterSSLCerts.cpp` - SSL certificate registration +- `include/xrpl/net/HTTPClientSSLContext.h` - SSL context management diff --git a/.claude/skills/libxrpl/net/images.md b/.claude/skills/libxrpl/net/images.md new file mode 100644 index 0000000000..ed09fa8459 --- /dev/null +++ b/.claude/skills/libxrpl/net/images.md @@ -0,0 +1,24 @@ +# Net Images Module Best Practices + +## Description +Use when working with static image assets in `src/libxrpl/net/images/`. Contains embedded image data used by the HTTP server. + +## Responsibility +Stores static image assets (favicons, logos) as embedded byte arrays for serving via the built-in HTTP server without external file dependencies. + +## Key Patterns + +### Embedded Assets +```cpp +// Images stored as static const byte arrays +// Compiled directly into the binary - no file I/O needed at runtime +static unsigned char const favicon[] = { /* ... */ }; +``` + +## Common Pitfalls +- Keep embedded images small - they increase binary size +- Use appropriate image formats (ICO for favicons, PNG for logos) +- Update both the source image and the byte array when changing assets + +## Key Files +- `src/libxrpl/net/images/` - Static image byte arrays embedded in the binary diff --git a/.claude/skills/libxrpl/nodestore.md b/.claude/skills/libxrpl/nodestore.md new file mode 100644 index 0000000000..833dbecd51 --- /dev/null +++ b/.claude/skills/libxrpl/nodestore.md @@ -0,0 +1,68 @@ +# NodeStore Module Best Practices + +## Description +Use when working with persistent node storage in `src/libxrpl/nodestore/` or `include/xrpl/nodestore/`. Covers the storage abstraction layer, backend implementations, and caching. + +## Responsibility +Abstraction layer for persistent storage of ledger nodes (SHAMap leaves and inner nodes). Supports multiple backend implementations (RocksDB, NuDB, Memory, Null) with a plugin architecture, caching, and async operations. + +## Key Patterns + +### Abstract Factory for Backends +```cpp +// Backend is pure virtual - concrete implementations selected at runtime +class Backend { + virtual ~Backend() = default; + virtual Status fetch(void const* key, std::shared_ptr*) = 0; + virtual void store(std::shared_ptr const&) = 0; + virtual void storeBatch(Batch const& batch) = 0; +}; +// Backends: RocksDB, NuDB, Memory (testing), Null (disabled) +``` + +### Batch Operations +```cpp +// Always prefer batch operations for multiple reads/writes +virtual std::pair>, Status> + fetchBatch(std::vector const& hashes) = 0; +virtual void storeBatch(Batch const& batch) = 0; +// Significantly reduces I/O overhead vs individual operations +``` + +### Status Enum (Not Exceptions) +```cpp +enum class Status { ok, notFound, keyTooBig, /* ... */ }; +// I/O operations return Status, NOT throw exceptions +auto [objects, status] = backend->fetchBatch(hashes); +if (status != Status::ok) { /* handle */ } +``` + +### Configuration via Section +```cpp +// Backend options come from config file sections +RocksDBBackend(int keyBytes, Section const& keyValues, + Scheduler& scheduler, beast::Journal journal); +// Allows runtime tuning without recompilation +``` + +### Async Fetch with Scheduler +```cpp +// Non-blocking reads via scheduler integration +virtual void asyncFetch(uint256 const& hash, + std::function)>&& callback); +// Callback invoked on scheduler thread +``` + +## Common Pitfalls +- Never use individual fetch/store in tight loops - use batch operations +- Never throw exceptions from backend implementations - return Status enum +- Always configure appropriate cache sizes for the workload +- Never assume a fetch will succeed - always check Status +- Use Memory backend for unit tests, never RocksDB + +## Key Files +- `include/xrpl/nodestore/Database.h` - Main storage interface +- `include/xrpl/nodestore/Backend.h` - Abstract backend interface +- `include/xrpl/nodestore/Manager.h` - Backend factory +- `include/xrpl/nodestore/NodeObject.h` - Individual node wrapper +- `src/libxrpl/nodestore/BatchWriter.cpp` - Batch write optimization diff --git a/.claude/skills/libxrpl/nodestore/backend.md b/.claude/skills/libxrpl/nodestore/backend.md new file mode 100644 index 0000000000..93b34885e9 --- /dev/null +++ b/.claude/skills/libxrpl/nodestore/backend.md @@ -0,0 +1,66 @@ +# NodeStore Backend Module Best Practices + +## Description +Use when working with storage backend implementations in `src/libxrpl/nodestore/backend/`. Covers RocksDB, NuDB, Memory, and Null backend factories. + +## Responsibility +Concrete backend implementations for the NodeStore abstraction layer. Each backend provides persistent (or ephemeral) storage with different performance characteristics and use cases. + +## Key Patterns + +### Backend Factory Registration +```cpp +// Each backend is a factory that creates Backend instances +// Registered by name in the Manager +class RocksDBFactory : public Factory { + std::string getName() const override { return "RocksDB"; } + std::unique_ptr createInstance(...) override; +}; +``` + +### RocksDB Configuration +```cpp +// Extensive tuning via config Section +// Key options: +// open_files - Max open file descriptors +// filter_bits - Bloom filter bits per key (default 10) +// cache_mb - Block cache size in MB +// file_size_mb - Target SST file size +// compression - snappy (default), zlib, lz4, none +// block_size - Block size in KB (default 4) +// num_threads - Background compaction threads +``` + +### NuDB for Deterministic Storage +```cpp +// NuDB supports deterministic initialization +// Useful for reproducible test databases +// Hash-based storage with direct memory-mapped I/O +// Lower CPU overhead than RocksDB for write-heavy workloads +``` + +### Memory Backend for Testing +```cpp +// In-memory storage - fast but not persistent +// Use for unit tests only +// Thread-safe with internal mutex +``` + +### Null Backend for Disabled Storage +```cpp +// No-op backend - all operations succeed but store nothing +// Use when storage feature is disabled in config +``` + +## Common Pitfalls +- Use Memory backend for tests, never RocksDB (test isolation and speed) +- Always tune RocksDB bloom filter bits - default 10 is good for most workloads +- NuDB doesn't support range queries - only point lookups by hash +- Never use Null backend in production - data loss guaranteed +- Always configure appropriate open_files limits for the OS + +## Key Files +- `src/libxrpl/nodestore/backend/RocksDBFactory.cpp` - RocksDB backend (~12.5KB) +- `src/libxrpl/nodestore/backend/NuDBFactory.cpp` - NuDB backend (~12KB) +- `src/libxrpl/nodestore/backend/MemoryFactory.cpp` - In-memory backend (~5KB) +- `src/libxrpl/nodestore/backend/NullFactory.cpp` - No-op backend (~2KB) diff --git a/.claude/skills/libxrpl/proto.md b/.claude/skills/libxrpl/proto.md new file mode 100644 index 0000000000..ec8952ab85 --- /dev/null +++ b/.claude/skills/libxrpl/proto.md @@ -0,0 +1,35 @@ +# Proto Module Best Practices + +## Description +Use when working with Protocol Buffer definitions in `include/xrpl/proto/`. Covers gRPC API definitions and generated protobuf headers. + +## Responsibility +Contains Protocol Buffer generated headers defining the gRPC API for rippled. These define the wire format for RPC communication between clients and the server. + +## Key Patterns + +### Proto Organization +``` +include/xrpl/proto/ +└── org/xrpl/rpc/v1/ + └── *.proto generated headers +``` + +### Usage +```cpp +#include +// Use generated types for gRPC request/response +``` + +### Versioning +- API is versioned under `org/xrpl/rpc/v1/` +- New versions get a new directory (v2/, etc.) +- Never modify generated files directly - modify the .proto source + +## Common Pitfalls +- Never hand-edit generated .pb.h files - regenerate from .proto sources +- Always use the versioned path (v1/) when including proto headers +- Proto types are for serialization only - convert to native types for business logic + +## Key Files +- `include/xrpl/proto/org/xrpl/rpc/v1/` - Generated gRPC API headers diff --git a/.claude/skills/libxrpl/protocol.md b/.claude/skills/libxrpl/protocol.md new file mode 100644 index 0000000000..9d39b7144b --- /dev/null +++ b/.claude/skills/libxrpl/protocol.md @@ -0,0 +1,123 @@ +# Protocol Module Best Practices + +## Description +Use when working with serialization and data types in `src/libxrpl/protocol/` or `include/xrpl/protocol/`. Covers STObject hierarchy, SField registry, serialization, TER codes, features, and keylets. + +## Responsibility +Defines serialization formats, data types, and protocol constants. Handles conversion between C++ objects and wire format, JSON representation, and database storage. The largest module in libxrpl with 60+ files. + +## Key Patterns + +### STObject Hierarchy +```cpp +// STBase is the abstract root for all serializable types +// Concrete types: STInteger, STBlob, STAmount, STArray, STObject, STPathSet, STVector256 + +// Access fields type-safely via SField references +auto amount = obj[sfAmount]; // Returns STAmount +auto flags = obj[sfFlags]; // Returns uint32 +auto dest = obj[sfDestination]; // Returns AccountID +auto has = obj.isFieldPresent(sfMemos); // Check presence +``` + +### SField Registry +```cpp +// Fields are statically registered - never create SField at runtime +// SField carries type information and field ID +extern SField const sfAmount; // STAmount type +extern SField const sfFlags; // STInteger type +extern SField const sfDestination; // STAccount type + +// Field IDs are protocol-defined and must not change +``` + +### Serializer for Binary Format +```cpp +// Deterministic binary serialization +Serializer s; +obj.add(s); // Append binary representation +auto blob = s.peekData(); // Get bytes + +// Deserialization +SerialIter sit(blob.data(), blob.size()); +auto obj = std::make_shared(sit, sfTransaction); +``` + +### Bidirectional JSON/Binary Conversion +```cpp +// Object to JSON +Json::Value json = obj.getJson(JsonOptions::none); + +// JSON to Object +STParsedJSONObject parsed("tx_json", json); +if (parsed.object) { /* use parsed.object */ } +``` + +### TER (Transaction Error Result) Codes +```cpp +// Categories: +// tes - success (tesSUCCESS) +// tec - claimed fee, no effect (tecNO_DST, tecFROZEN, tecINSUFFICIENT_RESERVE) +// tef - failure (tefFAILURE) +// tel - local error (telNETWORK_ID_MAKES_TX_NON_CANONICAL) +// tem - malformed (temINVALID, temBAD_AMOUNT, temDISABLED) + +// Check categories: +isTesSuccess(ter) // ter == tesSUCCESS +isTecClaim(ter) // tec range +isTemMalformed(ter) // tem range +``` + +### Feature/Amendment Flags +```cpp +// Gate new behavior on amendments +if (ctx.rules.enabled(featureMyFeature)) { + // New behavior +} else { + // Legacy behavior +} +// Register features in Feature.cpp +``` + +### Keylet for Ledger Entry Keys +```cpp +// Type-safe ledger key generation +auto key = keylet::account(accountID); // Account root +auto key = keylet::line(a, b, currency); // Trust line +auto key = keylet::offer(account, seq); // Offer +auto key = keylet::nftoken(tokenID); // NFT +// Keylet carries both the key (uint256) and the expected ledger entry type +``` + +### SOTemplate for Schema Validation +```cpp +// Define expected fields for a ledger entry type +SOTemplate const ltACCOUNT_ROOT = { + {sfAccount, soeREQUIRED}, + {sfBalance, soeREQUIRED}, + {sfFlags, soeREQUIRED}, + {sfSequence, soeREQUIRED}, + {sfOwnerCount, soeDEFAULT}, + // ... +}; +``` + +## Common Pitfalls +- Never create SField instances at runtime - they are static protocol definitions +- Never modify field IDs - they are part of the binary protocol +- Always use `isFieldPresent()` before accessing optional fields +- Never ignore TER return values - they carry critical error information +- Always gate new fields/behavior on feature amendments for consensus safety +- Respect JSON parsing depth limit of 10 to prevent stack overflow +- Use `[[nodiscard]]` on functions returning TER + +## Key Files +- `include/xrpl/protocol/STObject.h` - Generic structured object container +- `include/xrpl/protocol/STAmount.h` - XRP and IOU amounts +- `include/xrpl/protocol/SField.h` - Field definitions +- `include/xrpl/protocol/TER.h` - Transaction result codes +- `include/xrpl/protocol/Feature.h` - Amendment flags +- `include/xrpl/protocol/Indexes.h` - Ledger entry key generation +- `include/xrpl/protocol/Keylet.h` - Type-safe ledger keys +- `include/xrpl/protocol/SOTemplate.h` - Object schema definitions +- `src/libxrpl/protocol/STParsedJSON.cpp` - JSON to object conversion diff --git a/.claude/skills/libxrpl/rdb.md b/.claude/skills/libxrpl/rdb.md new file mode 100644 index 0000000000..319401bd28 --- /dev/null +++ b/.claude/skills/libxrpl/rdb.md @@ -0,0 +1,60 @@ +# RDB Module Best Practices + +## Description +Use when working with relational database access in `src/libxrpl/rdb/` or `include/xrpl/rdb/`. Covers SOCI wrapper, database configuration, and checkpointing. + +## Responsibility +Provides a C++ wrapper around SOCI (SQLite/PostgreSQL abstraction) for relational data access, configuration management, blob type conversions, and periodic WAL checkpoint management. + +## Key Patterns + +### DBConfig Lazy Initialization +```cpp +// Construct config without opening connection +DBConfig config(basicConfig, "my_database"); + +// Open session later when needed +soci::session session; +config.open(session); +// Allows config parsing separate from database I/O +``` + +### Blob Conversions +```cpp +// Convert between SOCI blobs and standard types +soci::blob blob(session); +std::vector bytes; +convert(blob, bytes); // blob -> vector + +std::string str; +convert(blob, str); // blob -> string +``` + +### Checkpointer with Weak Pointer Safety +```cpp +// Checkpointer uses weak_ptr to detect session destruction +auto checkpointer = makeCheckpointer( + id, + std::weak_ptr(sessionPtr), + jobQueue, + logs); +checkpointer->schedule(); // Periodic WAL checkpoints +// If session is destroyed, checkpointer safely no-ops +``` + +### Thread-Safe Sessions +```cpp +// Each thread gets its own soci::session from the pool +// Never share a soci::session across threads +``` + +## Common Pitfalls +- Never share a soci::session across threads - each thread needs its own +- Always use `std::weak_ptr` for session references in long-lived objects (like Checkpointer) +- Be aware of SOCI include warnings - use pragma diagnostic push/pop +- Always convert blobs to standard types before processing + +## Key Files +- `include/xrpl/rdb/SociDB.h` - Main wrapper interface +- `src/libxrpl/rdb/SociDB.cpp` - Implementation +- `src/libxrpl/rdb/DatabaseCon.cpp` - Database connection setup diff --git a/.claude/skills/libxrpl/resource.md b/.claude/skills/libxrpl/resource.md new file mode 100644 index 0000000000..b2b89241e8 --- /dev/null +++ b/.claude/skills/libxrpl/resource.md @@ -0,0 +1,64 @@ +# Resource Module Best Practices + +## Description +Use when working with rate limiting and resource management in `src/libxrpl/resource/` or `include/xrpl/resource/`. Covers endpoint tracking, charge/fee management, and abuse prevention. + +## Responsibility +Tracks resource consumption by network endpoints (inbound/outbound connections) to prevent abuse and ensure fair resource allocation. Manages consumer lifecycle, charge accounting, and gossip-based reputation sharing. + +## Key Patterns + +### Manager/Impl Pattern +```cpp +// Abstract Manager interface with factory function +class Manager { virtual ~Manager() = 0; }; +std::unique_ptr make_Manager(beast::Journal journal); + +// Implementation hidden in cpp +class ManagerImp : public Manager { /* ... */ }; +``` + +### Consumer Factory +```cpp +// Different consumer types for different connection sources +Consumer newInboundEndpoint(beast::IP::Endpoint const& address); +Consumer newOutboundEndpoint(beast::IP::Endpoint const& address); +Consumer newUnlimitedEndpoint(beast::IP::Endpoint const& address); +``` + +### Background Thread Shutdown +```cpp +// Clean shutdown pattern with condition variable +~ManagerImp() { + { + std::lock_guard lock(mutex_); + stop_ = true; + cond_.notify_one(); + } + thread_.join(); // Wait for thread to finish +} +``` + +### Proxy-Aware Endpoint Detection +```cpp +// Handle forwarded-for headers safely +boost::system::error_code ec; +auto proxiedIp = boost::asio::ip::make_address(forwardedFor, ec); +if (ec) { + journal_.warn() << "Invalid IP: " << ec.message(); + return newInboundEndpoint(address); // Fallback to socket IP +} +``` + +## Common Pitfalls +- Never trust forwarded-for headers without proxy flag validation +- Always use the factory methods - never construct Consumer directly +- Always join background threads in destructor +- Use separate consumer types for different connection trust levels + +## Key Files +- `include/xrpl/resource/ResourceManager.h` - Manager interface +- `src/libxrpl/resource/ResourceManager.cpp` - Implementation +- `include/xrpl/resource/Consumer.h` - Per-endpoint tracking +- `src/libxrpl/resource/Charge.cpp` - Cost definitions +- `src/libxrpl/resource/Fees.cpp` - Fee calculations diff --git a/.claude/skills/libxrpl/server.md b/.claude/skills/libxrpl/server.md new file mode 100644 index 0000000000..9cc9fd9c59 --- /dev/null +++ b/.claude/skills/libxrpl/server.md @@ -0,0 +1,68 @@ +# Server Module Best Practices + +## Description +Use when working with server configuration in `src/libxrpl/server/` or `include/xrpl/server/`. Covers port configuration, SSL/TLS, WebSocket options, and authentication. + +## Responsibility +Manages server listening ports, WebSocket configuration, SSL/TLS setup, authentication credentials, and admin network restrictions. Handles parsing configuration into validated port structures. + +## Key Patterns + +### Dual ParsedPort/Port Pattern +```cpp +// ParsedPort: intermediate parsing result (may be incomplete) +struct ParsedPort { /* partially validated fields */ }; + +// Port: final validated configuration (ready to use) +struct Port { + std::string name; + boost::asio::ip::address ip; + std::uint16_t port = 0; + std::set protocol; + // ... +}; +``` + +### Configuration Section Parsing +```cpp +// Parse from config file section, log errors to stream +void parse_Port(ParsedPort& port, Section const& section, std::ostream& log); +// Does NOT throw - logs issues and sets defaults +``` + +### CIDR Admin Networks +```cpp +// IP-based admin access control with CIDR support +std::vector admin_nets_v4; +std::vector admin_nets_v6; +// Supports both IPv4 and IPv6 ranges +``` + +### WebSocket Options +```cpp +// Fine-grained compression control +boost::beast::websocket::permessage_deflate pmd_options; +// Queue limits prevent memory exhaustion +std::optional ws_queue_limit; +// limit=0 means unlimited (not -1) +``` + +### SSL Context Lazy Creation +```cpp +// SSL context created only when needed +std::shared_ptr context; +// Initialized when first SSL connection established +``` + +## Common Pitfalls +- Never use port-only access control - always use CIDR network restrictions for admin +- Use `iless` comparator for protocol names (case-insensitive) +- Remember that `limit=0` means unlimited, not disabled +- Always log parsing errors rather than throwing +- Separate user/admin credentials - don't reuse + +## Key Files +- `include/xrpl/server/Port.h` - Port configuration structure +- `src/libxrpl/server/Port.cpp` - Parsing and validation +- `src/libxrpl/server/JSONRPCUtil.cpp` - RPC utility functions +- `src/libxrpl/server/LoadFeeTrack.cpp` - Load and fee tracking diff --git a/.claude/skills/libxrpl/shamap.md b/.claude/skills/libxrpl/shamap.md new file mode 100644 index 0000000000..ddd029543f --- /dev/null +++ b/.claude/skills/libxrpl/shamap.md @@ -0,0 +1,83 @@ +# SHAMap Module Best Practices + +## Description +Use when working with the Merkle tree implementation in `src/libxrpl/shamap/` or `include/xrpl/shamap/`. Covers the SHA-256 based radix tree used for ledger state representation. + +## Responsibility +Implements a SHA-256 based Merkle radix tree with 16-way branching (hexadecimal). Provides efficient ledger state representation with O(log N) proof-of-inclusion, copy-on-write snapshots, synchronization, and delta calculation. + +## Key Patterns + +### State Machine Lifecycle +```cpp +enum class SHAMapState { Modifying, Immutable, Synching, Invalid }; +// Modifying: Can add/remove/modify entries +// Immutable: Snapshot - no modifications allowed +// Synching: Being synchronized from peers +// Invalid: Corrupted or destroyed +// Transitions are one-way: Modifying -> Immutable (via snapshot) +``` + +### Copy-on-Write via COWID +```cpp +std::uint32_t cowid_ = 1; +// Each snapshot gets a new COWID +// Children are only copied when modified (lazy copy) +// Immutable snapshots share nodes with the active map +auto snapshot = map.snapShot(true); // Creates immutable copy +``` + +### 16-Way Radix Branching +```cpp +static inline constexpr unsigned int branchFactor = 16; +static inline constexpr unsigned int leafDepth = 64; +// 256-bit key / 4 bits per nibble = 64 levels max +// Each inner node has up to 16 children +``` + +### Node Type Hierarchy +```cpp +// SHAMapTreeNode (base) -> SHAMapInnerNode (16 children) +// -> SHAMapLeafNode (data + key) +// Use dynamic_pointer_cast for safe downcasting +auto inner = intr_ptr::dynamic_pointer_cast(node); +if (inner) { /* process inner node */ } +``` + +### Walk-Up for Modifications (dirtyUp) +```cpp +// After modifying a leaf, propagate hash changes to root +void dirtyUp(SharedPtrNodeStack& stack, uint256 const& target, ...); +// Updates hashes from leaf -> root through the stack +``` + +### Lazy Traversal +```cpp +// Navigate to a leaf by key +SHAMapLeafNode* walkTowardsKey(uint256 const& id, + SharedPtrNodeStack* stack = nullptr); +// Returns leaf or nullptr; optionally records path for dirtyUp +``` + +### Intrusive Pointers for Nodes +```cpp +// Nodes use intrusive reference counting (not std::shared_ptr) +intr_ptr::SharedPtr root_; +// Minimal overhead - reference count embedded in node +``` + +## Common Pitfalls +- Never modify an Immutable map - check state before mutations +- Always call dirtyUp after modifying a leaf to maintain hash integrity +- Never assume node type without dynamic_pointer_cast check +- Remember that snapshots share nodes - COW means nodes are only copied on write +- Always use the provided iterators for safe traversal, not manual tree walking + +## Key Files +- `include/xrpl/shamap/SHAMap.h` - Main map implementation +- `include/xrpl/shamap/SHAMapTreeNode.h` - Base node class +- `include/xrpl/shamap/SHAMapInnerNode.h` - Interior nodes (16-way) +- `include/xrpl/shamap/SHAMapLeafNode.h` - Leaf nodes with data +- `include/xrpl/shamap/SHAMapNodeID.h` - Tree position identifier +- `src/libxrpl/shamap/SHAMapDelta.cpp` - Difference between maps +- `src/libxrpl/shamap/SHAMapSync.cpp` - Synchronization algorithm diff --git a/.claude/skills/libxrpl/tx.md b/.claude/skills/libxrpl/tx.md new file mode 100644 index 0000000000..23fa9c3bba --- /dev/null +++ b/.claude/skills/libxrpl/tx.md @@ -0,0 +1,137 @@ +# Transaction (tx) Module Best Practices + +## Description +Use when working with transaction processing in `src/libxrpl/tx/` or `include/xrpl/tx/`. Covers the Transactor base class, transaction pipeline, invariant checks, and apply context. + +## Responsibility +Implements the transaction processing pipeline: static validation (preflight), fee-claim checks (preclaim), transaction execution (doApply), and post-apply invariant verification. All transaction types derive from the Transactor base class. + +## Key Patterns + +### Transaction Pipeline (3 Phases) +```cpp +// Phase 1: Preflight - Static validation, NO ledger access +static NotTEC preflight(PreflightContext const& ctx) { + if (ctx.tx[sfAmount] <= beast::zero) + return temBAD_AMOUNT; + return tesSUCCESS; +} + +// Phase 2: Preclaim - Ledger read-only checks +static TER preclaim(PreclaimContext const& ctx) { + auto sle = ctx.view.read(keylet::account(ctx.tx[sfAccount])); + if (!sle) return tecNO_DST; + return tesSUCCESS; +} + +// Phase 3: doApply - Actual ledger mutations +TER doApply() override { + auto sle = view().peek(keylet::account(account_)); + sle->setFieldAmount(sfBalance, newBalance); + view().update(sle); + return tesSUCCESS; +} +``` + +### Transactor Base Class +```cpp +class MyTransaction : public Transactor { +public: + static constexpr ConsequencesFactoryType ConsequencesFactory{Normal}; + + explicit MyTransaction(ApplyContext& ctx) : Transactor(ctx) {} + + // Optional: Gate on amendment + static bool checkExtraFeatures(PreflightContext const& ctx); + + // Optional: Custom flag mask + static std::uint32_t getFlagsMask(PreflightContext const& ctx); + + // Required + static NotTEC preflight(PreflightContext const& ctx); + static TER preclaim(PreclaimContext const& ctx); + TER doApply() override; + + // Optional: Custom fee calculation + static XRPAmount calculateBaseFee(ReadView const& view, STTx const& tx); +}; +``` + +### Feature Gating +```cpp +static bool checkExtraFeatures(PreflightContext const& ctx) { + // Return false to disable when amendment not enabled + return ctx.rules.enabled(featureMyFeature); +} +``` + +### Flag Validation +```cpp +static std::uint32_t getFlagsMask(PreflightContext const& ctx) { + return tfMyTransactionMask; // Allowed flags +} +// Base class validates: (tx.getFlags() & ~getFlagsMask()) == 0 +``` + +### ConsequencesFactory Types +```cpp +// Normal: Standard transaction +static constexpr ConsequencesFactoryType ConsequencesFactory{Normal}; +// Blocker: Affects subsequent transactions' ability to claim fees +static constexpr ConsequencesFactoryType ConsequencesFactory{Blocker}; +// Custom: Override makeTxConsequences() static method +static constexpr ConsequencesFactoryType ConsequencesFactory{Custom}; +``` + +### TER Error Code Progression +``` +tem* (malformed): temINVALID, temBAD_AMOUNT, temDISABLED - preflight errors +tef* (failure): tefFAILURE, tefNESTED_FAILURE - infrastructure errors +tel* (local): telNETWORK_ID_MAKES_TX_NON_CANONICAL - local-only errors +tec* (claimed): tecNO_DST, tecFROZEN, tecINSUFFICIENT_RESERVE - fee claimed, no effect +tes (success): tesSUCCESS - transaction applied +``` + +### Logging Convention +```cpp +JLOG(ctx.j.warn()) << "User error message"; // User-facing issues +JLOG(ctx.j.debug()) << "Detailed diagnostic"; // Implementation details +JLOG(ctx.j.trace()) << "Very verbose info"; // Deep debugging +JLOG(ctx.j.error()) << "Unexpected failure"; // Should not happen +``` + +### View Operations in doApply +```cpp +// Read-only (returns const SLE) +auto sle = view().read(keylet::account(accountID)); + +// Mutable (returns non-const SLE) +auto sle = view().peek(keylet::account(accountID)); +sle->setFieldAmount(sfBalance, newBalance); +view().update(sle); // MUST call after modification + +// Create new entry +auto sle = std::make_shared(keylet::myEntry(id)); +sle->setFieldText(sfData, data); +view().insert(sle); + +// Remove entry +view().erase(sle); +``` + +## Common Pitfalls +- Never access ledger state in preflight - it only has PreflightContext (no view) +- Never mutate ledger state in preclaim - it has ReadView only +- Always call `view().update(sle)` after modifying a peeked SLE +- Never return `tesSUCCESS` from preclaim/preflight if validation failed +- Always gate new transaction types on feature amendments +- Use `NotTEC` return type for preflight (not TER) - prevents returning tec codes from static checks +- Never forget to register new transaction types in `transactions.macro` and `applySteps.cpp` + +## Key Files +- `include/xrpl/tx/Transactor.h` - Base class with static method signatures +- `src/libxrpl/tx/Transactor.cpp` - Base implementation (41KB) +- `src/libxrpl/tx/apply.cpp` - Transaction application entry point +- `src/libxrpl/tx/ApplyContext.cpp` - Context management +- `src/libxrpl/tx/InvariantCheck.cpp` - Post-apply invariant validation (117KB) +- `src/libxrpl/tx/applySteps.cpp` - Step-by-step dispatch diff --git a/.claude/skills/libxrpl/tx/paths.md b/.claude/skills/libxrpl/tx/paths.md new file mode 100644 index 0000000000..6aee8d2a66 --- /dev/null +++ b/.claude/skills/libxrpl/tx/paths.md @@ -0,0 +1,72 @@ +# Transaction Paths Module Best Practices + +## Description +Use when working with payment path finding and execution in `src/libxrpl/tx/paths/` or `include/xrpl/tx/paths/`. Covers the flow engine, ripple calculation, and offer stream processing. + +## Responsibility +Implements payment path finding and execution for cross-currency payments. Handles the flow engine for executing payments across multiple paths (strands), offer book management, and amount calculation. + +## Key Patterns + +### Flow Engine Entry Point +```cpp +path::RippleCalc::Output flow( + PaymentSandbox& view, + STAmount const& deliver, + AccountID const& src, + AccountID const& dst, + STPathSet const& paths, + bool defaultPaths, + bool partialPayment, + bool ownerPaysTransferFee, + OfferCrossing offerCrossing, + std::optional const& limitQuality, + std::optional const& sendMax, + std::optional const& domainID, + beast::Journal j, + path::detail::FlowDebugInfo* flowDebugInfo = nullptr); +``` + +### Strand-Based Execution +```cpp +// A "strand" is a single payment path through the DEX +// Multiple strands can be tried to find the best rate +// StrandFlow executes a single strand +// Flow tries all strands and picks the best result +``` + +### OfferStream for Order Book Processing +```cpp +// Iterates through offers in an order book +// Handles expired offers, unfunded offers, and self-crossing +// Automatically cleans up stale offers during traversal +``` + +### Quality-Based Routing +```cpp +// Quality = exchange rate between input and output +// Lower quality number = better rate +// limitQuality prevents accepting rates worse than threshold +``` + +### PaymentSandbox Isolation +```cpp +// All path calculations happen in a PaymentSandbox +// Changes are only committed if the payment succeeds +// Allows trying multiple paths without side effects +``` + +## Common Pitfalls +- Never modify the ledger directly during path calculation - use PaymentSandbox +- Always respect limitQuality to prevent unfavorable exchange rates +- Be aware that offer traversal may clean up stale offers as a side effect +- FlowDebugInfo is optional and only for debugging - never rely on it in production logic +- Path finding is computationally expensive - respect depth and complexity limits + +## Key Files +- `include/xrpl/tx/paths/Flow.h` - Main flow engine entry point +- `include/xrpl/tx/paths/RippleCalc.h` - Payment amount calculation +- `src/libxrpl/tx/paths/OfferStream.cpp` - Order book traversal (~12KB) +- `src/libxrpl/tx/paths/BookTip.cpp` - Order book tip management +- `src/libxrpl/tx/paths/detail/Steps.h` - Step-by-step calculation +- `src/libxrpl/tx/paths/detail/StrandFlow.h` - Single path execution diff --git a/.claude/skills/libxrpl/tx/transactors.md b/.claude/skills/libxrpl/tx/transactors.md new file mode 100644 index 0000000000..6a7c6c6f51 --- /dev/null +++ b/.claude/skills/libxrpl/tx/transactors.md @@ -0,0 +1,164 @@ +# Transactors Module Best Practices + +## Description +Use when adding or modifying transaction types in `src/libxrpl/tx/transactors/`. This is the guide for implementing new transactors following the established patterns. + +## Responsibility +Contains all concrete transaction type implementations. Each transactor follows the Transactor base class pattern with preflight/preclaim/doApply phases. Transaction types are organized by feature area in subdirectories. + +## Template for New Transactors + +### Header File (`include/xrpl/tx/transactors/MyTx.h`) +```cpp +#pragma once +#include + +namespace xrpl { + +class MyTransaction : public Transactor { +public: + static constexpr ConsequencesFactoryType ConsequencesFactory{Normal}; + + explicit MyTransaction(ApplyContext& ctx) : Transactor(ctx) {} + + static bool checkExtraFeatures(PreflightContext const& ctx); + static std::uint32_t getFlagsMask(PreflightContext const& ctx); + static NotTEC preflight(PreflightContext const& ctx); + static TER preclaim(PreclaimContext const& ctx); + TER doApply() override; +}; + +} +``` + +### Implementation File (`src/libxrpl/tx/transactors/MyFeature/MyTx.cpp`) +```cpp +#include +#include +#include +#include +#include + +namespace xrpl { + +bool +MyTransaction::checkExtraFeatures(PreflightContext const& ctx) +{ + return ctx.rules.enabled(featureMyFeature); +} + +std::uint32_t +MyTransaction::getFlagsMask(PreflightContext const& ctx) +{ + return tfUniversalMask; // Or custom mask +} + +NotTEC +MyTransaction::preflight(PreflightContext const& ctx) +{ + // Static validation - NO ledger access + auto const& tx = ctx.tx; + + if (tx[sfAmount] <= beast::zero) + { + JLOG(ctx.j.warn()) << "Bad amount."; + return temBAD_AMOUNT; + } + + return tesSUCCESS; +} + +TER +MyTransaction::preclaim(PreclaimContext const& ctx) +{ + // Ledger read-only checks + auto const sle = ctx.view.read( + keylet::account(ctx.tx[sfAccount])); + if (!sle) + return terNO_ACCOUNT; + + return tesSUCCESS; +} + +TER +MyTransaction::doApply() +{ + // Mutate ledger state + auto sle = view().peek(keylet::account(account_)); + if (!sle) + return tefINTERNAL; + + sle->setFieldAmount(sfBalance, newBalance); + view().update(sle); + + return tesSUCCESS; +} + +} +``` + +### Registration Checklist +1. Add transaction type to `include/xrpl/protocol/detail/transactions.macro` +2. Add dispatch case to `src/libxrpl/tx/applySteps.cpp` +3. Add feature flag to `include/xrpl/protocol/Feature.h` and `src/libxrpl/protocol/Feature.cpp` +4. Add invariant checks if needed in `src/libxrpl/tx/InvariantCheck.cpp` +5. Add to `disabledTxTypes` in Batch.cpp if not batch-compatible + +## Key Patterns Across All Transactors + +### Feature Gating +```cpp +static bool checkExtraFeatures(PreflightContext const& ctx) { + return ctx.rules.enabled(featureMyFeature); +} +``` + +### Variant-Aware Validation +```cpp +// When handling Asset (Issue or MPTIssue): +if (auto const ret = std::visit( + [&](T const&) { return preflightHelper(ctx); }, + ctx.tx[sfAmount].asset().value()); !isTesSuccess(ret)) + return ret; +``` + +### Ledger Entry CRUD in doApply +```cpp +// Create +auto sle = std::make_shared(keylet::myEntry(id)); +view().insert(sle); + +// Read (mutable) +auto sle = view().peek(keylet::myEntry(id)); + +// Update +sle->setFieldU32(sfFlags, newFlags); +view().update(sle); + +// Delete +view().erase(sle); +``` + +### Helper/Utils Files +```cpp +// Complex features use a separate Helpers/Utils file: +// AMM -> AMMHelpers.h, AMMUtils.h +// NFT -> NFTokenUtils.h +// Lending -> LendingHelpers.h +// Keep reusable logic in helpers, transaction-specific logic in transactors +``` + +## Common Pitfalls +- Never forget to register in `transactions.macro` and `applySteps.cpp` +- Never access ledger state in preflight (no view available) +- Never mutate state in preclaim (read-only view) +- Always call `view().update(sle)` after modifying a peeked entry +- Always gate on feature amendment for consensus safety +- Use `NotTEC` return type from preflight, `TER` from preclaim/doApply +- Put shared logic in a *Helpers.h file, not duplicated across transactors + +## Key Files +- `include/xrpl/tx/Transactor.h` - Base class definition +- `src/libxrpl/tx/applySteps.cpp` - Transaction type dispatch +- `include/xrpl/protocol/detail/transactions.macro` - Transaction type registry +- `src/libxrpl/tx/InvariantCheck.cpp` - Post-apply validation diff --git a/.claude/skills/libxrpl/tx/transactors/AMM.md b/.claude/skills/libxrpl/tx/transactors/AMM.md new file mode 100644 index 0000000000..04fa906ee6 --- /dev/null +++ b/.claude/skills/libxrpl/tx/transactors/AMM.md @@ -0,0 +1,68 @@ +# AMM (Automated Market Maker) Transactors Best Practices + +## Description +Use when working with AMM transaction types in `src/libxrpl/tx/transactors/AMM/`. Covers pool creation, deposits, withdrawals, voting, bidding, deletion, and clawback. + +## Responsibility +Implements decentralized trading pools with liquidity provider (LP) tokens. Allows users to create AMM pools, deposit/withdraw liquidity, vote on trading fees, bid on auction slots, and manage pool lifecycle. + +## Key Patterns + +### AMM Transaction Types +- **AMMCreate** - Create a new AMM pool with two assets +- **AMMDeposit** - Add liquidity to a pool, receive LP tokens +- **AMMWithdraw** - Remove liquidity, burn LP tokens +- **AMMVote** - Vote on trading fee percentage +- **AMMBid** - Bid on the auction slot for discounted trading +- **AMMDelete** - Remove an empty AMM pool +- **AMMClawback** - Issuer clawback of assets from AMM + +### Precision Arithmetic +```cpp +// AMM calculations require controlled rounding +// ALWAYS use NumberRoundModeGuard for rounding control +NumberRoundModeGuard mg(Number::towards_zero); +auto lpTokens = ammLPTokens(amount1, amount2, lptIssue); + +// Or explicit mode changes with RAII save +{ + saveNumberRoundMode _{Number::getround()}; + Number::setround(Number::upward); + auto value = calculation; +} +``` + +### Helper Functions (AMMHelpers.h) +```cpp +ammLPTokens() // Calculate LP tokens from pool reserves +lpTokensOut() // LP tokens from deposit +ammAssetIn() / ammAssetOut() // Calculate swap amounts +withinRelativeDistance() // Quality tolerance checks +changeSpotPriceQuality() // Quote generation algorithm +// Quadratic equation solving for pricing +``` + +### Feature Gates +```cpp +// Multiple amendment versions +ammEnabled(ctx.rules) // Base AMM feature +fixAMMv1_1 // First fix amendment +fixAMMv1_3 // Third fix amendment +// Always check which amendments are active +``` + +## Common Pitfalls +- Never perform AMM math without setting the rounding mode first +- Always use `NumberRoundModeGuard` (RAII) - never manually set/restore rounding +- Be aware that AMM calculations involve quadratic equations - precision matters +- AMMClawback has different authorization requirements than regular clawback +- Check `withinRelativeDistance` for quality tolerance rather than exact equality + +## Key Files +- `src/libxrpl/tx/transactors/AMM/AMMCreate.cpp` - Pool creation +- `src/libxrpl/tx/transactors/AMM/AMMDeposit.cpp` - Liquidity deposit (~887 lines) +- `src/libxrpl/tx/transactors/AMM/AMMWithdraw.cpp` - Liquidity withdrawal (~911 lines) +- `src/libxrpl/tx/transactors/AMM/AMMVote.cpp` - Fee voting +- `src/libxrpl/tx/transactors/AMM/AMMBid.cpp` - Auction slot bidding +- `include/xrpl/tx/transactors/AMM/AMMHelpers.h` - Shared math utilities +- `include/xrpl/tx/transactors/AMM/AMMUtils.h` - AMM state utilities diff --git a/.claude/skills/libxrpl/tx/transactors/Check.md b/.claude/skills/libxrpl/tx/transactors/Check.md new file mode 100644 index 0000000000..35f84de0fd --- /dev/null +++ b/.claude/skills/libxrpl/tx/transactors/Check.md @@ -0,0 +1,44 @@ +# Check Transactors Best Practices + +## Description +Use when working with Check transaction types in `src/libxrpl/tx/transactors/Check/`. Covers check creation, cashing, and cancellation. + +## Responsibility +Implements a check-like payment mechanism (delayed payment authorization). A sender creates a check, the recipient cashes it, and either party can cancel it (with expiration support). + +## Key Patterns + +### Check Lifecycle +```cpp +// 1. CreateCheck - Sender authorizes payment +// Validates: destination exists, amount valid, expiration future +// Creates: Check ledger entry with sender, destination, amount + +// 2. CashCheck - Recipient claims payment +// Validates: caller is destination, check not expired +// Executes: transfers funds from sender to destination + +// 3. CancelCheck - Either party cancels +// Validates: caller is sender or destination, or check expired +// Removes: Check ledger entry +``` + +### Error Codes +```cpp +tecNO_DST // Destination account doesn't exist +temREDUNDANT // Check to self +temBAD_AMOUNT // Invalid amount +temBAD_EXPIRATION // Expiration in the past +tecEXPIRED // Check has expired (for CashCheck) +``` + +## Common Pitfalls +- Checks can be cancelled by either sender or destination +- Expired checks can be cancelled by anyone +- CashCheck must handle both exact amount and "deliver minimum" modes +- Always validate expiration against the parent ledger close time + +## Key Files +- `src/libxrpl/tx/transactors/Check/CreateCheck.cpp` - Check creation +- `src/libxrpl/tx/transactors/Check/CashCheck.cpp` - Check fulfillment (~440 lines) +- `src/libxrpl/tx/transactors/Check/CancelCheck.cpp` - Check cancellation diff --git a/.claude/skills/libxrpl/tx/transactors/Delegate.md b/.claude/skills/libxrpl/tx/transactors/Delegate.md new file mode 100644 index 0000000000..cf38fac24a --- /dev/null +++ b/.claude/skills/libxrpl/tx/transactors/Delegate.md @@ -0,0 +1,43 @@ +# Delegate Transactors Best Practices + +## Description +Use when working with delegation transaction types in `src/libxrpl/tx/transactors/Delegate/`. Covers delegate set and utilities. + +## Responsibility +Manages transaction signing delegation, allowing accounts to authorize other accounts to sign transactions on their behalf without exposing the master key. + +## Key Patterns + +### Delegate Operations +```cpp +// DelegateSet - Create or modify a delegation +// Validates: delegate account exists, permissions valid +// Creates/Updates: Delegate ledger entry + +// DelegateUtils - Shared utilities +// deleteDelegate() - Public cleanup interface, used by DeleteAccount +``` + +### Feature Gates +```cpp +// fixDelegateV1_1 - Added data existence checks +if (ctx.rules.enabled(fixDelegateV1_1)) { + // Perform additional validation +} +``` + +### Integration with DeleteAccount +```cpp +// DelegateUtils::deleteDelegate() is called by DeleteAccount +// for cleanup when an account is being deleted +// Must handle all delegation-related ledger entries +``` + +## Common Pitfalls +- Always check feature gate `fixDelegateV1_1` for data existence validation +- Delegate cleanup must be thorough - used by DeleteAccount +- Never allow self-delegation + +## Key Files +- `src/libxrpl/tx/transactors/Delegate/DelegateSet.cpp` - Delegation management +- `include/xrpl/tx/transactors/Delegate/DelegateUtils.h` - Shared utilities diff --git a/.claude/skills/libxrpl/tx/transactors/Lending.md b/.claude/skills/libxrpl/tx/transactors/Lending.md new file mode 100644 index 0000000000..5690116e0a --- /dev/null +++ b/.claude/skills/libxrpl/tx/transactors/Lending.md @@ -0,0 +1,69 @@ +# Lending Transactors Best Practices + +## Description +Use when working with lending protocol transaction types in `src/libxrpl/tx/transactors/Lending/`. Covers loan management, broker operations, and payment calculation. + +## Responsibility +Implements a complex loan protocol with amortization schedules, interest calculation, broker management, and collateral handling. The largest transactor feature area by code volume. + +## Key Patterns + +### Loan Lifecycle +```cpp +// LoanSet - Create or configure a loan +// LoanPay - Make loan payments (principal + interest) +// LoanManage - Manage loan state transitions +// LoanDelete - Remove a completed/cancelled loan +``` + +### Broker Operations +```cpp +// LoanBrokerSet - Create/configure a broker +// LoanBrokerDelete - Remove a broker +// LoanBrokerCoverDeposit - Deposit collateral +// LoanBrokerCoverWithdraw - Withdraw collateral +// LoanBrokerCoverClawback - Clawback broker assets +``` + +### Payment Calculation (LendingHelpers.h) +```cpp +struct LoanPaymentParts { + Number principalPaid; // Reduces loan balance + Number interestPaid; // Goes to Vault + Number valueChange; // Loan value adjustment + Number feePaid; // Goes to Broker +}; + +// Key helper functions: +checkLendingProtocolDependencies() // Validate feature gates +loanPeriodicRate() // Interest with secondsInYear +roundPeriodicPayment() // Consistent rounding +``` + +### Feature Gate +```cpp +// All lending operations gated on single feature +ctx.rules.enabled(featureLendingProtocol) +``` + +### Batch Transaction Restriction +```cpp +// Lending transactions are DISABLED in batch transactions +// Listed in Batch::disabledTxTypes +// Cannot be included in atomic batch operations +``` + +## Common Pitfalls +- Lending is disabled in Batch transactions - do not try to batch lending ops +- Payment calculations require precise rounding - use LendingHelpers functions +- Always validate lending protocol dependencies before operations +- Interest calculation uses `secondsInYear` constant - be aware of leap year handling +- LendingHelpers.h is ~1800 lines - the most complex helper file in the codebase + +## Key Files +- `src/libxrpl/tx/transactors/Lending/LoanSet.cpp` - Loan configuration (~585 lines) +- `src/libxrpl/tx/transactors/Lending/LoanPay.cpp` - Payment processing (~548 lines) +- `src/libxrpl/tx/transactors/Lending/LoanManage.cpp` - State management +- `src/libxrpl/tx/transactors/Lending/LoanDelete.cpp` - Loan removal +- `src/libxrpl/tx/transactors/Lending/LoanBrokerSet.cpp` - Broker setup +- `include/xrpl/tx/transactors/Lending/LendingHelpers.h` - Shared calculations (~1799 lines) diff --git a/.claude/skills/libxrpl/tx/transactors/MPT.md b/.claude/skills/libxrpl/tx/transactors/MPT.md new file mode 100644 index 0000000000..3be02dcea6 --- /dev/null +++ b/.claude/skills/libxrpl/tx/transactors/MPT.md @@ -0,0 +1,53 @@ +# MPT (Multi-Purpose Token) Transactors Best Practices + +## Description +Use when working with MPT transaction types in `src/libxrpl/tx/transactors/MPT/`. Covers token issuance creation, configuration, destruction, and authorization. + +## Responsibility +Implements Multi-Purpose Token (MPT) operations - a fungible token system simpler than full IOU trust lines. Handles token issuance lifecycle and holder authorization. + +## Key Patterns + +### MPT Transaction Types +```cpp +// MPTokenIssuanceCreate - Create a new token issuance +// MPTokenIssuanceSet - Modify issuance settings +// MPTokenIssuanceDestroy - Destroy an issuance (if no holders) +// MPTokenAuthorize - Authorize/deauthorize a holder +``` + +### MPT vs IOU Trust Lines +```cpp +// MPT is simpler than IOU trust lines: +// - No rippling mechanics +// - No transfer fees between holders (only issuer) +// - Simpler authorization model +// - Uses MPTIssue instead of Issue +// - Uses MPTAmount instead of IOUAmount +``` + +### Feature Gate +```cpp +ctx.rules.enabled(featureMPTokensV1) +``` + +### Asset Variant Handling +```cpp +// MPTIssue is part of the Asset variant (Issue | MPTIssue) +// Use std::visit when handling Asset generically: +std::visit([&](auto const& issue) { + // Works for both Issue and MPTIssue +}, asset.value()); +``` + +## Common Pitfalls +- MPT issuances cannot be destroyed if any holders exist +- Authorization is per-holder, not per-token +- Don't confuse MPTIssue with Issue - they have different keylet types +- Always check `featureMPTokensV1` before MPT operations + +## Key Files +- `src/libxrpl/tx/transactors/MPT/MPTokenIssuanceCreate.cpp` - Create issuance +- `src/libxrpl/tx/transactors/MPT/MPTokenIssuanceSet.cpp` - Modify settings +- `src/libxrpl/tx/transactors/MPT/MPTokenIssuanceDestroy.cpp` - Destroy issuance +- `src/libxrpl/tx/transactors/MPT/MPTokenAuthorize.cpp` - Holder authorization diff --git a/.claude/skills/libxrpl/tx/transactors/NFT.md b/.claude/skills/libxrpl/tx/transactors/NFT.md new file mode 100644 index 0000000000..87dfae77f9 --- /dev/null +++ b/.claude/skills/libxrpl/tx/transactors/NFT.md @@ -0,0 +1,76 @@ +# NFT (Non-Fungible Token) Transactors Best Practices + +## Description +Use when working with NFT transaction types in `src/libxrpl/tx/transactors/NFT/`. Covers minting, burning, offer management, and token modification. + +## Responsibility +Implements NFT creation, trading, and lifecycle management. Handles token minting, burning, buy/sell offer creation and acceptance, offer cancellation, and dynamic NFT modification. + +## Key Patterns + +### NFT Transaction Types +```cpp +// NFTokenMint - Create a new NFT +// NFTokenBurn - Destroy an NFT +// NFTokenCreateOffer - Create a buy or sell offer +// NFTokenCancelOffer - Cancel an existing offer +// NFTokenAcceptOffer - Accept a buy or sell offer (execute trade) +// NFTokenModify - Modify NFT metadata (dynamic NFTs) +``` + +### NFTokenUtils - Shared Utilities (~1025 lines) +```cpp +// Key utility functions: +findToken() // Find an NFT in owner's token pages +insertToken() // Add NFT to owner's directory +removeToken() // Remove NFT from owner's directory +deleteTokenOffer() // Clean up a single offer +removeTokenOffersWithLimit() // Batch cleanup with limit +notTooManyOffers() // Check offer count limits +changeTokenURI() // Update NFT URI (dynamic NFTs) + +struct TokenAndPage { + STObject token; + std::shared_ptr page; +}; +``` + +### Token Storage in Pages +```cpp +// NFTs are stored in paginated directories +// Each page holds multiple tokens +// Pages are linked as a doubly-linked list +// insertToken/removeToken manage page splits and merges +``` + +### Feature Gates +```cpp +featureNFTokenMintOffer // Combined mint + offer +fixRemoveNFTokenAutoTrustLine // Fix for auto trust line removal +featureDynamicNFT // NFTokenModify support +``` + +### Offer Directory Structure +```cpp +// Buy offers and sell offers stored in separate directories +// Indexed by token ID +// Offers can have expiration times +// Offers can specify a destination (private offers) +``` + +## Common Pitfalls +- Token page management is complex - always use NFTokenUtils functions +- Offer cleanup has limits (`removeTokenOffersWithLimit`) - don't assume all offers removed +- `notTooManyOffers()` must be checked before creating new offers +- Dynamic NFT modification requires `featureDynamicNFT` amendment +- Transfer fees only apply when the NFT issuer is not a party to the trade +- Burning an NFT with outstanding offers requires offer cleanup + +## Key Files +- `src/libxrpl/tx/transactors/NFT/NFTokenMint.cpp` - Token minting +- `src/libxrpl/tx/transactors/NFT/NFTokenBurn.cpp` - Token destruction +- `src/libxrpl/tx/transactors/NFT/NFTokenCreateOffer.cpp` - Offer creation +- `src/libxrpl/tx/transactors/NFT/NFTokenAcceptOffer.cpp` - Offer acceptance (trade) +- `src/libxrpl/tx/transactors/NFT/NFTokenCancelOffer.cpp` - Offer cancellation +- `src/libxrpl/tx/transactors/NFT/NFTokenModify.cpp` - Dynamic NFT changes +- `include/xrpl/tx/transactors/NFT/NFTokenUtils.h` - Shared utilities (~1025 lines) diff --git a/.claude/skills/libxrpl/tx/transactors/Offer.md b/.claude/skills/libxrpl/tx/transactors/Offer.md new file mode 100644 index 0000000000..3f23b53e22 --- /dev/null +++ b/.claude/skills/libxrpl/tx/transactors/Offer.md @@ -0,0 +1,56 @@ +# Offer Transactors Best Practices + +## Description +Use when working with DEX offer transaction types in `src/libxrpl/tx/transactors/Offer/`. Covers order creation and cancellation on the native decentralized exchange. + +## Responsibility +Implements decentralized exchange order management for the native XRPL order book. Handles offer creation (with matching/crossing), cancellation, and order book management. + +## Key Patterns + +### Offer Transaction Types +```cpp +// CreateOffer (~854 lines) - Create a new DEX order +// - Validates amounts, currency pairs, account state +// - Attempts to cross with existing offers (matching engine) +// - Remaining amount becomes a standing order if not fully filled +// - Handles self-crossing, expired offers, unfunded offers + +// CancelOffer - Remove an existing order +// - Validates caller owns the offer +// - Removes offer from order book directory +``` + +### Offer Crossing (Matching Engine) +```cpp +// CreateOffer performs offer crossing inline: +// 1. Look up existing offers on the opposite side +// 2. Match at the offer's quality (exchange rate) +// 3. Consume matched offers (partial or full) +// 4. Place remaining amount as standing order +// This is the core DEX matching engine +``` + +### Quality and Order Books +```cpp +// Quality = exchange rate between TakerPays and TakerGets +// Order books indexed by currency pair and sorted by quality +// Lower quality number = better rate for taker +``` + +### Ticket Support +```cpp +// Offers can use tickets for sequence management +// Feature gate: featureTickets +``` + +## Common Pitfalls +- CreateOffer is one of the most complex transactors (~854 lines) - be thorough with changes +- Offer crossing modifies multiple ledger entries atomically +- Self-crossing (same account on both sides) has special handling +- Expired and unfunded offers are cleaned up during crossing +- Always validate that TakerPays and TakerGets are different assets + +## Key Files +- `src/libxrpl/tx/transactors/Offer/CreateOffer.cpp` - Order creation and matching (~854 lines) +- `src/libxrpl/tx/transactors/Offer/CancelOffer.cpp` - Order cancellation diff --git a/.claude/skills/libxrpl/tx/transactors/PermissionedDomain.md b/.claude/skills/libxrpl/tx/transactors/PermissionedDomain.md new file mode 100644 index 0000000000..da66823a65 --- /dev/null +++ b/.claude/skills/libxrpl/tx/transactors/PermissionedDomain.md @@ -0,0 +1,36 @@ +# PermissionedDomain Transactors Best Practices + +## Description +Use when working with permissioned domain transaction types in `src/libxrpl/tx/transactors/PermissionedDomain/`. Covers domain-based access control for the DEX. + +## Responsibility +Implements domain-based access control for permissioned DEX operations. Allows creating and deleting permissioned domains that gate who can participate in certain trading activities. + +## Key Patterns + +### PermissionedDomain Transaction Types +```cpp +// PermissionedDomainSet - Create or update a permissioned domain +// PermissionedDomainDelete - Remove a permissioned domain +``` + +### Integration with Payments +```cpp +// Payments can reference a domain via sfDomainID field +// The domain gates which accounts can participate +// Used for regulated/permissioned trading environments +``` + +### Feature Gate +```cpp +ctx.rules.enabled(featurePermissionedDEX) +``` + +## Common Pitfalls +- Domains are referenced by other transactions (Payments) - deletion must check for references +- Always validate the feature gate before domain operations +- Domain ID matching is exact - no partial matches + +## Key Files +- `src/libxrpl/tx/transactors/PermissionedDomain/PermissionedDomainSet.cpp` - Create/update domain +- `src/libxrpl/tx/transactors/PermissionedDomain/PermissionedDomainDelete.cpp` - Remove domain diff --git a/.claude/skills/libxrpl/tx/transactors/Vault.md b/.claude/skills/libxrpl/tx/transactors/Vault.md new file mode 100644 index 0000000000..33f5b8b94d --- /dev/null +++ b/.claude/skills/libxrpl/tx/transactors/Vault.md @@ -0,0 +1,61 @@ +# Vault Transactors Best Practices + +## Description +Use when working with vault transaction types in `src/libxrpl/tx/transactors/Vault/`. Covers vault creation, configuration, deposits, withdrawals, deletion, and clawback. + +## Responsibility +Implements the vault mechanism for asset holding and loan collateral management. Allows creating vaults, depositing/withdrawing assets, configuring vault parameters, and managing vault lifecycle. + +## Key Patterns + +### Vault Transaction Types +```cpp +// VaultCreate - Create a new vault +// VaultSet - Configure vault parameters +// VaultDelete - Remove an empty vault +// VaultDeposit - Deposit assets into a vault +// VaultWithdraw - Withdraw assets from a vault +// VaultClawback - Issuer clawback from vault +``` + +### Feature Gate +```cpp +ctx.rules.enabled(featureSingleAssetVault) +``` + +### Batch Transaction Restriction +```cpp +// Vault transactions are DISABLED in batch transactions +// Listed in Batch::disabledTxTypes alongside Lending +// Cannot be included in atomic batch operations +``` + +### Depth Limiting for Recursive Operations +```cpp +// Vault operations may involve recursive state checks +// Use depth parameter to prevent infinite recursion +TER checkVaultState(ReadView const& view, AccountID const& id, int depth = 0); +if (depth > maxDepth) return tecINTERNAL; +``` + +### Integration with Lending +```cpp +// Vaults serve as collateral for the lending protocol +// VaultDeposit/Withdraw affect loan collateralization +// Vault state changes may trigger loan state recalculation +``` + +## Common Pitfalls +- Vault operations are disabled in batch transactions +- Vaults can only be deleted when empty +- Clawback has different authorization requirements than regular withdrawal +- Always respect depth limits in recursive vault state checks +- Vault operations may interact with lending protocol state + +## Key Files +- `src/libxrpl/tx/transactors/Vault/VaultCreate.cpp` - Vault creation +- `src/libxrpl/tx/transactors/Vault/VaultSet.cpp` - Configuration +- `src/libxrpl/tx/transactors/Vault/VaultDelete.cpp` - Deletion +- `src/libxrpl/tx/transactors/Vault/VaultDeposit.cpp` - Asset deposit +- `src/libxrpl/tx/transactors/Vault/VaultWithdraw.cpp` - Asset withdrawal +- `src/libxrpl/tx/transactors/Vault/VaultClawback.cpp` - Issuer clawback diff --git a/.claude/skills/xrpld/app.md b/.claude/skills/xrpld/app.md new file mode 100644 index 0000000000..321011e558 --- /dev/null +++ b/.claude/skills/xrpld/app.md @@ -0,0 +1,57 @@ +# App Module Best Practices + +## Description +Use when working with the main application layer in `src/xrpld/app/`. Covers the Application singleton, ledger management, consensus adapters, services, and runtime coordination. + +## Responsibility +Contains the main application logic and runtime coordination for the rippled server. The Application singleton provides access to all services. Sub-modules handle ledger management, consensus, fee voting, amendments, path finding, and transaction queuing. + +## Key Patterns + +### Application Singleton +```cpp +// Application is the master interface - access all services through it +class Application { + virtual Config& config() = 0; + virtual Logs& logs() = 0; + virtual JobQueue& getJobQueue() = 0; + virtual LedgerMaster& getLedgerMaster() = 0; + virtual NetworkOPs& getOPs() = 0; + virtual NodeStore::Database& getNodeStore() = 0; + // ... many more service accessors +}; +// Implemented by ApplicationImp (hidden in .cpp) +``` + +### ServiceRegistry Pattern +```cpp +// Services are injected via ServiceRegistry from libxrpl +// Application provides centralized access to all registered services +``` + +### Master Mutex +```cpp +// Recursive mutex protects shared state: +using MutexType = std::recursive_mutex; +// Protects: open ledger, server state, consensus engine +// Use std::lock_guard for access +``` + +### Module Interface Pattern +```cpp +// Public interface: Module.h (abstract) +// Implementation: ModuleImp.h/cpp (hidden) +// Factory: make_Module() returns unique_ptr +``` + +## Common Pitfalls +- Never access Application services before setup() completes +- Always acquire master mutex when modifying open ledger or consensus state +- Use `std::recursive_mutex` (not plain mutex) - multiple services may lock re-entrantly +- Never create a second Application instance + +## Key Files +- `src/xrpld/app/main/Application.h` - Core application interface +- `src/xrpld/app/main/Application.cpp` - Implementation (150+ includes) +- `src/xrpld/app/main/BasicApp.h` - Base application services +- `src/xrpld/app/main/GRPCServer.h` - gRPC server integration diff --git a/.claude/skills/xrpld/app/consensus.md b/.claude/skills/xrpld/app/consensus.md new file mode 100644 index 0000000000..e570b7be84 --- /dev/null +++ b/.claude/skills/xrpld/app/consensus.md @@ -0,0 +1,47 @@ +# App Consensus Module Best Practices + +## Description +Use when working with RCL consensus adapters in `src/xrpld/app/consensus/`. Bridges the generic consensus algorithm to rippled-specific types. + +## Responsibility +Adapts the generic consensus algorithm (in `xrpld/consensus/`) to work with rippled application types. Provides concrete type adapters for transactions, transaction sets, and ledgers. + +## Key Patterns + +### RCL Adapters +```cpp +// RCLCxTx - Adapts SHAMapItem as a consensus transaction +// RCLCxTxSet - Adapts SHAMap as a consensus transaction set +// RCLCxLedger - Adapts Ledger as a consensus ledger +// RCLConsensus - Glues generic consensus to rippled Application +``` + +### Adapter Pattern +```cpp +// Generic consensus works with abstract types via CRTP +// RCL adapters provide concrete implementations +class RCLConsensus : public Consensus { + // Implements required methods using rippled types + // e.g., acquireLedger(), proposeTx(), relay() +}; +``` + +### Validation Handling +```cpp +// RCLValidations tracks validation messages from the network +// Maps to the generic Validations<> template +// Handles trusted vs untrusted validators +``` + +## Common Pitfalls +- Adapter methods must match the CRTP interface exactly - compiler errors are cryptic +- Never import generic consensus types into adapter code - always go through the adapter +- RCLConsensus holds references to Application services - ensure Application outlives it + +## Key Files +- `src/xrpld/app/consensus/RCLConsensus.h` - Main consensus orchestrator +- `src/xrpld/app/consensus/RCLConsensus.cpp` - Implementation +- `src/xrpld/app/consensus/RCLValidations.h` - Validation handling +- `src/xrpld/app/consensus/RCLCxTx.h` - Transaction adapter +- `src/xrpld/app/consensus/RCLCxTxSet.h` - Transaction set adapter +- `src/xrpld/app/consensus/RCLCxLedger.h` - Ledger adapter diff --git a/.claude/skills/xrpld/app/ledger.md b/.claude/skills/xrpld/app/ledger.md new file mode 100644 index 0000000000..c529a239c2 --- /dev/null +++ b/.claude/skills/xrpld/app/ledger.md @@ -0,0 +1,67 @@ +# App Ledger Module Best Practices + +## Description +Use when working with ledger management in `src/xrpld/app/ledger/`. Covers ledger storage, retrieval, history, and the Ledger class itself. + +## Responsibility +Manages the lifecycle of ledger objects: creation, storage, retrieval, history tracking, inbound acquisition from network, and order book caching. The Ledger class is the central data structure. + +## Key Patterns + +### Ledger Class +```cpp +// Ledger is composed of two SHAMaps: +// 1. State Map - Account roots, order books, ledger entries (STLedgerEntry) +// 2. Transaction Map - Transactions and metadata for that ledger + +class Ledger final : public std::enable_shared_from_this, + public CountedObject { + // Can be mutable (sole ownership) or immutable (shared, read-only) + // Genesis ledger has special constructor +}; +``` + +### Mutable vs Immutable +```cpp +// Mutable: Only one owner, can be modified +// Immutable: Shared via shared_ptr, read-only +// Transition: mutable -> immutable when accepted +// Never modify an immutable ledger +``` + +### LedgerMaster +```cpp +// Manages the chain of validated ledgers +// Tracks: current, validated, closed ledgers +// Handles ledger transitions during consensus +``` + +### Inbound Ledger Acquisition +```cpp +// InboundLedgers manages acquiring missing ledgers from peers +// InboundTransactions handles transaction set acquisition +// Both use async fetch with timeout and retry +``` + +### Iterator Adapters +```cpp +// sles_iter_impl - Iterate over SLE (state entries) +// txs_iter_impl - Iterate over transactions +// Efficient iteration without copying +``` + +## Common Pitfalls +- Never modify an immutable ledger - check mutability first +- Ledger must be shared via shared_ptr (enable_shared_from_this) +- Genesis ledger construction is special - don't use for normal ledgers +- LedgerMaster state transitions must be atomic with consensus +- CountedObject tracking helps detect leaks - don't disable it + +## Key Files +- `src/xrpld/app/ledger/Ledger.h` - Core ledger class +- `src/xrpld/app/ledger/LedgerMaster.h` - Ledger chain management +- `src/xrpld/app/ledger/LedgerHistory.h` - Historical tracking +- `src/xrpld/app/ledger/LedgerCleaner.h` - Online deletion +- `src/xrpld/app/ledger/InboundLedgers.h` - Network acquisition +- `src/xrpld/app/ledger/OrderBookDB.h` - Order book cache +- `src/xrpld/app/ledger/TransactionMaster.h` - Transaction lookup diff --git a/.claude/skills/xrpld/app/ledger/detail.md b/.claude/skills/xrpld/app/ledger/detail.md new file mode 100644 index 0000000000..7b1721818c --- /dev/null +++ b/.claude/skills/xrpld/app/ledger/detail.md @@ -0,0 +1,18 @@ +# App Ledger Detail Module Best Practices + +## Description +Use when working with ledger implementation details in `src/xrpld/app/ledger/detail/`. Internal helpers for the ledger module. + +## Responsibility +Internal implementation details for the app/ledger module. Contains private helpers for ledger state management, iteration, and storage operations. + +## Key Patterns + +### Detail Namespace Convention +- Code in `detail/` is internal to the `app/ledger` module +- Never include detail headers from outside `app/ledger` +- If you need functionality, use the public `app/ledger/` headers instead + +## Common Pitfalls +- Detail implementations may change without API compatibility +- Never expose detail types in public interfaces diff --git a/.claude/skills/xrpld/app/main.md b/.claude/skills/xrpld/app/main.md new file mode 100644 index 0000000000..7bf0aa111d --- /dev/null +++ b/.claude/skills/xrpld/app/main.md @@ -0,0 +1,54 @@ +# App Main Module Best Practices + +## Description +Use when working with application initialization and lifecycle in `src/xrpld/app/main/`. Covers Application startup, shutdown, and core services. + +## Responsibility +Application initialization, lifecycle management, and core service wiring. Contains the Application interface and its implementation, gRPC server, load management, node identity, and the node store scheduler. + +## Key Patterns + +### Application Lifecycle +```cpp +// 1. Construct Application (parse config, create services) +// 2. setup() - Initialize all services, open databases +// 3. run() - Main event loop +// 4. signalStop() - Graceful shutdown +// 5. Destructor - Clean up resources +``` + +### Node Identity +```cpp +// NodeIdentity manages the node's public/private key pair +// Used for peer handshake, session signatures, and cluster membership +// Keys persisted in wallet_db +``` + +### Load Manager +```cpp +// Tracks server load across all subsystems +// Triggers load-based fee escalation +// Monitors job queue depth and execution time +``` + +### gRPC Server +```cpp +// Optional gRPC server alongside JSON-RPC +// Uses proto definitions from include/xrpl/proto/ +// Separate handler set from JSON-RPC +``` + +## Common Pitfalls +- setup() must complete before any service is used +- signalStop() should be called for graceful shutdown - avoid hard kills +- Node identity keys must never be logged or exposed +- Load manager affects fee escalation - test under load + +## Key Files +- `src/xrpld/app/main/Application.h` - Core interface +- `src/xrpld/app/main/Application.cpp` - Implementation +- `src/xrpld/app/main/BasicApp.h` - Base services +- `src/xrpld/app/main/GRPCServer.h` - gRPC integration +- `src/xrpld/app/main/LoadManager.h` - Load tracking +- `src/xrpld/app/main/NodeIdentity.h` - Node key management +- `src/xrpld/app/main/NodeStoreScheduler.h` - Async DB scheduler diff --git a/.claude/skills/xrpld/app/misc.md b/.claude/skills/xrpld/app/misc.md new file mode 100644 index 0000000000..e2f2968e78 --- /dev/null +++ b/.claude/skills/xrpld/app/misc.md @@ -0,0 +1,75 @@ +# App Misc Module Best Practices + +## Description +Use when working with application services in `src/xrpld/app/misc/`. Covers fee voting, amendments, SHAMapStore, transaction queue, validator management, and NetworkOPs. + +## Responsibility +Collection of application-level services: fee voting system, amendment mechanism, online deletion (SHAMapStore), transaction queue (TxQ), validator key/list management, and NetworkOPs (the central operations coordinator). + +## Key Patterns + +### Fee Voting +```cpp +// Validators vote on fee schedules every 256 ledgers ("voting ledgers") +// Pseudo-transactions injected to set fees +// Majority vote determines new fee schedule +// FeeVote.h - voting logic +// FeeEscalation.md - escalation documentation +``` + +### Amendment Mechanism +```cpp +// Network-wide ledger rule changes +// Requires 80% validator approval sustained for 2 weeks +// Tracked as pseudo-transactions in each ledger +// AmendmentTableImpl.h manages tracking and state +``` + +### SHAMapStore (Online Delete) +```cpp +// Prunes old ledger history automatically +// Uses rotation between two databases +// Configurable deletion intervals +// Must not delete data needed for active operations +``` + +### Transaction Queue (TxQ) +```cpp +// Queues transactions when ledger is full +// Priority based on fee level +// Handles fee escalation under load +// TxQ.h - queue implementation +``` + +### Validator Management +```cpp +// ValidatorKeys.h - Node's own validator keys +// ValidatorList.h - Trusted validator list (UNL) +// ValidatorSite.h - Sites serving validator lists +// Keys loaded from config, lists fetched from URLs +``` + +### NetworkOPs +```cpp +// Central operations coordinator - the "god object" +// Coordinates: consensus, ledger acceptance, transaction submission +// NetworkOPs.cpp is one of the largest files in the codebase +// Access via app.getOPs() +``` + +## Common Pitfalls +- Fee voting only happens on voting ledgers (every 256) - don't trigger manually +- Amendments require 2-week sustained 80% approval - no fast path +- SHAMapStore deletion must respect the advisory_delete safety window +- TxQ priority depends on current fee escalation level +- NetworkOPs is massive - changes here affect many systems + +## Key Files +- `src/xrpld/app/misc/FeeVote.h` - Fee voting system +- `src/xrpld/app/misc/AmendmentTableImpl.h` - Amendment tracking +- `src/xrpld/app/misc/SHAMapStore.h` - Online deletion +- `src/xrpld/app/misc/TxQ.h` - Transaction queue +- `src/xrpld/app/misc/ValidatorKeys.h` - Validator key management +- `src/xrpld/app/misc/ValidatorList.h` - Trusted validator list +- `src/xrpld/app/misc/NetworkOPs.cpp` - Central operations +- `src/xrpld/app/misc/README.md` - Architecture documentation diff --git a/.claude/skills/xrpld/app/misc/detail.md b/.claude/skills/xrpld/app/misc/detail.md new file mode 100644 index 0000000000..054d4d6278 --- /dev/null +++ b/.claude/skills/xrpld/app/misc/detail.md @@ -0,0 +1,18 @@ +# App Misc Detail Module Best Practices + +## Description +Use when working with internal service implementation details in `src/xrpld/app/misc/detail/`. Internal helpers for the misc services module. + +## Responsibility +Internal implementation details for app/misc services (fee voting internals, amendment table implementation, SHAMapStore internals, etc.). + +## Key Patterns + +### Detail Namespace Convention +- Code in `detail/` is internal to the `app/misc` module +- Implementation classes (e.g., AmendmentTableImpl) live here +- Never include detail headers from outside `app/misc` + +## Common Pitfalls +- Detail implementations may change without API compatibility +- Always use the public `app/misc/` interfaces diff --git a/.claude/skills/xrpld/app/paths.md b/.claude/skills/xrpld/app/paths.md new file mode 100644 index 0000000000..195a109d77 --- /dev/null +++ b/.claude/skills/xrpld/app/paths.md @@ -0,0 +1,53 @@ +# App Paths Module Best Practices + +## Description +Use when working with payment path finding in `src/xrpld/app/paths/`. Covers the path finding algorithm, trust line caching, and AMM liquidity integration. + +## Responsibility +Implements the XRP Ledger payment path finding algorithm at the application level. Manages path requests, trust line caching, and integration with Automated Market Maker liquidity. + +## Key Patterns + +### Path Finding +```cpp +// Pathfinder: Algorithm that finds payment paths between accounts +// Considers: trust lines, order books, AMM pools +// Returns: Set of paths ranked by cost/quality +``` + +### Path Request Management +```cpp +// PathRequest - Individual path find request +// PathRequests - Manages collection of active requests +// Requests can be one-shot or subscribed (streaming updates) +``` + +### Trust Line Caching +```cpp +// RippleLineCache caches trust line data +// Avoids repeated ledger lookups during path finding +// Cache is invalidated on ledger close +// TrustLine.h provides the trust line representation +``` + +### AMM Integration +```cpp +// AMMLiquidity.h - Integrates AMM pools into path finding +// AMMOffer.h - Represents AMM as a synthetic offer +// AMM pools are treated as a special offer type in the path finder +``` + +## Common Pitfalls +- Path finding is computationally expensive - respect search depth limits +- Trust line cache must be invalidated on ledger close +- AMM liquidity changes with pool state - don't cache AMM offers across ledgers +- Path subscriptions can be memory-intensive with many clients + +## Key Files +- `src/xrpld/app/paths/Pathfinder.h` - Path finding algorithm +- `src/xrpld/app/paths/PathRequest.h` - Individual request handling +- `src/xrpld/app/paths/PathRequests.h` - Request collection management +- `src/xrpld/app/paths/RippleLineCache.h` - Trust line caching +- `src/xrpld/app/paths/TrustLine.h` - Trust line representation +- `src/xrpld/app/paths/AMMLiquidity.h` - AMM pool integration +- `src/xrpld/app/paths/AMMOffer.h` - Synthetic AMM offers diff --git a/.claude/skills/xrpld/app/paths/detail.md b/.claude/skills/xrpld/app/paths/detail.md new file mode 100644 index 0000000000..a1bee4cfa4 --- /dev/null +++ b/.claude/skills/xrpld/app/paths/detail.md @@ -0,0 +1,18 @@ +# App Paths Detail Module Best Practices + +## Description +Use when working with path finding implementation details in `src/xrpld/app/paths/detail/`. Internal helpers for the path finding module. + +## Responsibility +Internal implementation details for the path finding algorithm, including search heuristics, cost calculation helpers, and internal data structures. + +## Key Patterns + +### Detail Namespace Convention +- Code in `detail/` is internal to the `app/paths` module +- Contains algorithm-specific helpers not needed by callers +- Never include detail headers from outside `app/paths` + +## Common Pitfalls +- Path finding internals are performance-sensitive - profile before modifying +- Detail implementations may change without API compatibility diff --git a/.claude/skills/xrpld/app/rdb.md b/.claude/skills/xrpld/app/rdb.md new file mode 100644 index 0000000000..edb872688e --- /dev/null +++ b/.claude/skills/xrpld/app/rdb.md @@ -0,0 +1,39 @@ +# App RDB Module Best Practices + +## Description +Use when working with application-level database operations in `src/xrpld/app/rdb/`. Covers database abstractions and backend implementations. + +## Responsibility +Application-level relational database operations. Provides interfaces for peer finding data storage, SQLite backend implementation, and database operation details. + +## Key Patterns + +### Interface-Based Design +```cpp +// PeerFinder.h - Abstract interface for peer data storage +// Backend implementations in backend/ subdirectory +// Allows swapping database backends without changing callers +``` + +### SQLite Backend +```cpp +// SQLiteDatabase.h - Primary backend implementation +// Uses SOCI wrapper from libxrpl/rdb +// Handles: peer data, transaction history, ledger metadata +``` + +### Backend Abstraction +```cpp +// backend/ directory contains concrete implementations +// backend/detail/ has implementation-specific helpers +// detail/ has shared implementation details +``` + +## Common Pitfalls +- Always use the abstract interface, not the SQLite backend directly +- Database operations should be off the main thread (use job queue) +- Respect the SOCI wrapper patterns from libxrpl/rdb + +## Key Files +- `src/xrpld/app/rdb/PeerFinder.h` - Peer data interface +- `src/xrpld/app/rdb/backend/SQLiteDatabase.h` - SQLite implementation diff --git a/.claude/skills/xrpld/app/rdb/backend.md b/.claude/skills/xrpld/app/rdb/backend.md new file mode 100644 index 0000000000..f955eff8c3 --- /dev/null +++ b/.claude/skills/xrpld/app/rdb/backend.md @@ -0,0 +1,31 @@ +# App RDB Backend Module Best Practices + +## Description +Use when working with database backend implementations in `src/xrpld/app/rdb/backend/`. Covers concrete database implementations. + +## Responsibility +Concrete database backend implementations for the app/rdb module. Primary implementation is SQLiteDatabase. + +## Key Patterns + +### SQLiteDatabase +```cpp +// Primary backend implementation using SQLite via SOCI +// Handles: peer storage, transaction history, ledger metadata +// Thread-safe via session-per-thread pattern from libxrpl/rdb +``` + +### Backend Detail +```cpp +// backend/detail/ contains SQLite-specific helpers +// Schema creation, migration, and optimization queries +``` + +## Common Pitfalls +- Always use parameterized queries via SOCI - never raw string SQL +- Database files can grow large - implement periodic VACUUM +- WAL checkpoint scheduling prevents unbounded WAL growth + +## Key Files +- `src/xrpld/app/rdb/backend/SQLiteDatabase.h` - SQLite implementation +- `src/xrpld/app/rdb/backend/detail/` - SQLite-specific helpers diff --git a/.claude/skills/xrpld/app/rdb/backend/detail.md b/.claude/skills/xrpld/app/rdb/backend/detail.md new file mode 100644 index 0000000000..142573e6ba --- /dev/null +++ b/.claude/skills/xrpld/app/rdb/backend/detail.md @@ -0,0 +1,11 @@ +# App RDB Backend Detail Module Best Practices + +## Description +Use when working with database backend implementation details in `src/xrpld/app/rdb/backend/detail/`. SQLite-specific internal helpers. + +## Responsibility +SQLite-specific implementation details: schema definitions, migration scripts, query optimization, and SOCI binding helpers. + +## Common Pitfalls +- Schema migrations must be backwards-compatible +- Never include these headers from outside the rdb/backend module diff --git a/.claude/skills/xrpld/app/rdb/detail.md b/.claude/skills/xrpld/app/rdb/detail.md new file mode 100644 index 0000000000..39f0ca1f92 --- /dev/null +++ b/.claude/skills/xrpld/app/rdb/detail.md @@ -0,0 +1,18 @@ +# App RDB Detail Module Best Practices + +## Description +Use when working with database implementation details in `src/xrpld/app/rdb/detail/`. Internal helpers for the relational database module. + +## Responsibility +Internal implementation details for app-level database operations, including SQL query helpers and schema management. + +## Key Patterns + +### Detail Namespace Convention +- Code in `detail/` is internal to the `app/rdb` module +- Contains SQL query construction and result parsing helpers +- Never include detail headers from outside `app/rdb` + +## Common Pitfalls +- SQL queries must use parameterized bindings (SOCI style) - never string concatenation +- Detail implementations may change without API compatibility diff --git a/.claude/skills/xrpld/app/tx.md b/.claude/skills/xrpld/app/tx.md new file mode 100644 index 0000000000..2a6166a100 --- /dev/null +++ b/.claude/skills/xrpld/app/tx.md @@ -0,0 +1,34 @@ +# App Tx Module Best Practices + +## Description +Use when working with application-level transaction handling in `src/xrpld/app/tx/`. Covers transaction submission, validation, and application-layer processing. + +## Responsibility +Application-level transaction handling that bridges the protocol-layer transaction processing (libxrpl/tx) with the running server. Handles transaction submission, validation, and integration with the consensus process. + +## Key Patterns + +### Relationship to libxrpl/tx +```cpp +// libxrpl/tx: Protocol-level transaction processing (Transactor, preflight, preclaim, doApply) +// xrpld/app/tx: Application-level orchestration (submission, queuing, consensus integration) +// This module calls into libxrpl/tx for actual transaction execution +``` + +### Transaction Submission Flow +```cpp +// 1. Client submits transaction via RPC +// 2. app/tx validates and queues transaction +// 3. Transaction enters TxQ (app/misc/TxQ) +// 4. Consensus selects transactions for next ledger +// 5. libxrpl/tx executes selected transactions +``` + +## Common Pitfalls +- Don't duplicate transaction validation logic - defer to libxrpl/tx +- Application-level checks (queue depth, fee escalation) happen here, not in libxrpl +- Transaction metadata is generated at this level after execution + +## Key Files +- `src/xrpld/app/tx/` - Application transaction handling +- `src/xrpld/app/tx/detail/` - Implementation details diff --git a/.claude/skills/xrpld/app/tx/detail.md b/.claude/skills/xrpld/app/tx/detail.md new file mode 100644 index 0000000000..a587e73bab --- /dev/null +++ b/.claude/skills/xrpld/app/tx/detail.md @@ -0,0 +1,11 @@ +# App Tx Detail Module Best Practices + +## Description +Use when working with application transaction handling details in `src/xrpld/app/tx/detail/`. Internal helpers for transaction submission and processing. + +## Responsibility +Internal implementation details for application-level transaction handling, including submission validation, queue integration, and metadata generation. + +## Common Pitfalls +- Don't duplicate libxrpl/tx validation logic here +- Detail implementations may change without API compatibility diff --git a/.claude/skills/xrpld/consensus.md b/.claude/skills/xrpld/consensus.md new file mode 100644 index 0000000000..9880837822 --- /dev/null +++ b/.claude/skills/xrpld/consensus.md @@ -0,0 +1,59 @@ +# Consensus Module Best Practices + +## Description +Use when working with the generic consensus algorithm in `src/xrpld/consensus/`. This is the application-independent consensus implementation. + +## Responsibility +Implements the generic consensus algorithm separate from application-specific types. Uses CRTP (Curiously Recurring Template Pattern) to allow the application layer to plug in concrete types without virtual dispatch overhead. + +## Key Patterns + +### CRTP Design +```cpp +// Generic consensus uses CRTP - derived class provides concrete types +template +class Consensus { + // Calls static_cast(this)->method() for app-specific behavior + // No virtual dispatch overhead +}; + +// Application adapter: +class RCLConsensus : public Consensus { + // Provides concrete types: RCLCxTx, RCLCxTxSet, RCLCxLedger +}; +``` + +### Consensus Phases +```cpp +// Open -> Establish -> Accept +// Open: Collecting transactions +// Establish: Proposing and voting on transaction set +// Accept: Applying agreed-upon transaction set to ledger +``` + +### Consensus Parameters (ConsensusParms.h) +```cpp +// Timing parameters for consensus rounds +// These are tuned for network behavior - don't change without careful analysis +``` + +### Disputed Transactions +```cpp +// DisputedTx tracks transactions where validators disagree +// Votes are collected and transaction is included/excluded based on threshold +``` + +## Common Pitfalls +- Never modify consensus parameters without understanding network-wide impact +- CRTP means compilation errors from type mismatches appear in template instantiation - read errors carefully +- The generic consensus module should NEVER depend on application-specific types (Ledger, STTx, etc.) +- Always test consensus changes with multi-node simulation + +## Key Files +- `src/xrpld/consensus/Consensus.h` - Main consensus class (extensively documented) +- `src/xrpld/consensus/ConsensusParms.h` - Timing parameters +- `src/xrpld/consensus/ConsensusProposal.h` - Proposal structures +- `src/xrpld/consensus/DisputedTx.h` - Transaction dispute tracking +- `src/xrpld/consensus/LedgerTiming.h` - Ledger timing calculations +- `src/xrpld/consensus/LedgerTrie.h` - Transaction set representation +- `src/xrpld/consensus/Validations.h` - Generic validation tracking diff --git a/.claude/skills/xrpld/core.md b/.claude/skills/xrpld/core.md new file mode 100644 index 0000000000..ca789d532c --- /dev/null +++ b/.claude/skills/xrpld/core.md @@ -0,0 +1,55 @@ +# Core Module Best Practices + +## Description +Use when working with core configuration and system services in `src/xrpld/core/`. Covers Config, time keeping, and network identity. + +## Responsibility +System-level configuration and core services. The Config class extends BasicConfig from libxrpl with rippled-specific settings. Provides time keeping and network ID management. + +## Key Patterns + +### Config Class +```cpp +// Config extends BasicConfig from libxrpl +class Config : public BasicConfig { + // SizedItem enum for memory-dependent configuration + enum SizedItem { siSweepInterval, siNodeCacheSize, ... }; + + // FeeSetup for fee parameters + struct FeeSetup { + XRPAmount reference_fee; + XRPAmount account_reserve; + XRPAmount owner_reserve; + }; + + // Access sections by name + auto const& section = config["server"]; +}; +``` + +### Configuration Sections +```cpp +// Section names defined in ConfigSections.h +static constexpr char const* SECTION_NODE_DB = "node_db"; +static constexpr char const* SECTION_VALIDATORS = "validators"; +// Always use constants, never string literals +``` + +### Gradual Refactoring +```cpp +// Legacy config uses mixed patterns - refactoring is ongoing +// New code should follow the Section-based approach +// Deprecated patterns are documented with TODO comments +``` + +## Common Pitfalls +- Always use `ConfigSections.h` constants for section names +- Config extends BasicConfig - check both for available methods +- SizedItem values scale with node size configuration - don't hardcode sizes +- Never modify Config after Application startup + +## Key Files +- `src/xrpld/core/Config.h` - Configuration object +- `src/xrpld/core/ConfigSections.h` - Section name constants +- `src/xrpld/core/TimeKeeper.h` - System time tracking +- `src/xrpld/core/NetworkIDServiceImpl.h` - Network ID implementation diff --git a/.claude/skills/xrpld/core/detail.md b/.claude/skills/xrpld/core/detail.md new file mode 100644 index 0000000000..e95540c856 --- /dev/null +++ b/.claude/skills/xrpld/core/detail.md @@ -0,0 +1,11 @@ +# Core Detail Module Best Practices + +## Description +Use when working with core configuration implementation details in `src/xrpld/core/detail/`. Internal helpers for the Config system. + +## Responsibility +Internal implementation details for the core configuration module, including config parsing helpers and platform-specific abstractions. + +## Common Pitfalls +- Never include detail headers from outside the core module +- Config parsing must handle all edge cases gracefully (missing sections, invalid values) diff --git a/.claude/skills/xrpld/overlay.md b/.claude/skills/xrpld/overlay.md new file mode 100644 index 0000000000..9ddbb9cb93 --- /dev/null +++ b/.claude/skills/xrpld/overlay.md @@ -0,0 +1,74 @@ +# Overlay Module Best Practices + +## Description +Use when working with P2P networking in `src/xrpld/overlay/`. Covers peer connections, protocol negotiation, message relay, and clustering. + +## Responsibility +Manages peer-to-peer connections and the overlay network protocol. Handles HTTP/1.1 upgrade handshake, session signatures (MITM prevention), Protocol Buffer message serialization, message compression, and cluster node management. + +## Key Patterns + +### HTTP/1.1 Upgrade Handshake +```cpp +// Connection starts as HTTP, upgrades to ripple protocol +// Custom headers: +// Connect-As, Public-Key, Session-Signature +// Network-ID, Network-Time +// Closed-Ledger, Previous-Ledger +// Remote-IP, Local-IP, Crawl +``` + +### Session Signature (MITM Prevention) +```cpp +// Binds SSL/TLS session to node identities +// Each peer signs the shared SSL session data +// Prevents man-in-the-middle attacks at the protocol level +``` + +### Message Serialization +```cpp +// Google Protocol Buffers for all p2p messages +// Messages are compressed before transmission +// Compression.h handles LZ4/no-compression selection +``` + +### Peer Management +```cpp +// Overlay manages the set of connected peers +class Overlay { + virtual Peer::ptr findPeerByShortID(Peer::id_t) = 0; + virtual void send(std::shared_ptr const&) = 0; // Broadcast + virtual void relay(Message const&, uint256 const& suppression) = 0; +}; +``` + +### Clustering +```cpp +// Multiple rippled nodes can form a cluster +// Cluster nodes: share load, distribute crypto operations +// Cluster membership verified via node public keys +``` + +### Reduce Relay +```cpp +// ReduceRelayCommon.h - Minimize redundant message relay +// Uses HashRouter for message deduplication +// Peers track which messages they've already seen +``` + +## Common Pitfalls +- Always validate session signatures during handshake - never skip +- Never send uncompressed messages to peers that advertise compression support +- Cluster keys must be pre-configured - no dynamic cluster joining +- Message suppression via HashRouter is critical for network health - never bypass +- Protocol Buffer messages must match the expected schema version + +## Key Files +- `src/xrpld/overlay/Overlay.h` - Main overlay manager interface +- `src/xrpld/overlay/Peer.h` - Peer connection representation +- `src/xrpld/overlay/PeerSet.h` - Collection of peers +- `src/xrpld/overlay/Cluster.h` - Cluster management +- `src/xrpld/overlay/Message.h` - Message structure +- `src/xrpld/overlay/Compression.h` - Message compression +- `src/xrpld/overlay/ReduceRelayCommon.h` - Relay optimization +- `src/xrpld/overlay/README.md` - Comprehensive protocol documentation diff --git a/.claude/skills/xrpld/overlay/detail.md b/.claude/skills/xrpld/overlay/detail.md new file mode 100644 index 0000000000..506f778709 --- /dev/null +++ b/.claude/skills/xrpld/overlay/detail.md @@ -0,0 +1,27 @@ +# Overlay Detail Module Best Practices + +## Description +Use when working with P2P networking implementation details in `src/xrpld/overlay/detail/`. Internal helpers for the overlay module. + +## Responsibility +Internal implementation details for the overlay networking layer, including protocol message handling, peer connection state machines, and handshake implementation. + +## Key Patterns + +### PeerImp +```cpp +// PeerImp is the concrete implementation of the Peer interface +// Manages: SSL connection, protocol state, message queuing +// Uses enable_shared_from_this for async callback safety +``` + +### OverlayImpl +```cpp +// OverlayImpl is the concrete implementation of Overlay +// Manages: listening sockets, peer lifecycle, broadcast +``` + +## Common Pitfalls +- Peer connection state machine transitions must be atomic +- Never access PeerImp internals from outside overlay/detail/ +- Message queuing must respect back-pressure limits diff --git a/.claude/skills/xrpld/peerfinder.md b/.claude/skills/xrpld/peerfinder.md new file mode 100644 index 0000000000..be01868423 --- /dev/null +++ b/.claude/skills/xrpld/peerfinder.md @@ -0,0 +1,58 @@ +# PeerFinder Module Best Practices + +## Description +Use when working with network discovery in `src/xrpld/peerfinder/`. Covers peer bootstrap, cache management, and connection slot strategy. + +## Responsibility +Bootstraps into the XRP Ledger network and discovers peers. Manages bootcache (persistent addresses ranked by success), livecache (ephemeral recently-seen peers), and connection slot allocation. + +## Key Patterns + +### Three-Stage Connection Strategy +```cpp +// Stage 1: Connect to fixed peers (configured addresses) +// Stage 2: Try Livecache addresses (recently seen, with open slots) +// Stage 3: Fall back to Bootcache (persistent, ranked by valence) +``` + +### Bootcache (Persistent) +```cpp +// Persistent store of peer addresses ranked by "valence" (connection success) +// Higher valence = more reliable peer +// Persisted across restarts +// Used as fallback when livecache is empty +``` + +### Livecache (Ephemeral) +```cpp +// Recently seen peers with available connection slots +// Uses hop counts for distance estimation +// Random distribution for load balancing +// Not persisted - rebuilt on restart via gossip +``` + +### Slot Management +```cpp +// Slot states: accept, connect, connected, active, closing +// Slot properties: Inbound/Outbound, Fixed, Cluster +// Slots track connection lifecycle from handshake to disconnect +``` + +### Callback Pattern +```cpp +// Abstract interface for socket operations +// PeerFinder doesn't directly manage sockets +// Delegates I/O to the overlay layer via callbacks +``` + +## Common Pitfalls +- Fixed peers should always be tried first (Stage 1) - they are trusted +- Bootcache valence can decay over time - implement proper aging +- Livecache entries expire quickly - don't rely on stale data +- Slot limits prevent connection exhaustion - never bypass them +- Always check README.md for algorithm details before modifying + +## Key Files +- `src/xrpld/peerfinder/PeerfinderManager.h` - Main manager interface +- `src/xrpld/peerfinder/Slot.h` - Connection slot representation +- `src/xrpld/peerfinder/README.md` - Extensive design documentation diff --git a/.claude/skills/xrpld/peerfinder/detail.md b/.claude/skills/xrpld/peerfinder/detail.md new file mode 100644 index 0000000000..4f87bdefad --- /dev/null +++ b/.claude/skills/xrpld/peerfinder/detail.md @@ -0,0 +1,21 @@ +# PeerFinder Detail Module Best Practices + +## Description +Use when working with peer discovery implementation details in `src/xrpld/peerfinder/detail/`. Internal helpers for the peerfinder module. + +## Responsibility +Internal implementation details for peer discovery: bootcache persistence, livecache management, slot state machine, and connection strategy implementation. + +## Key Patterns + +### Logic Class +```cpp +// The main implementation class for peer finding +// Implements the three-stage connection strategy +// Manages bootcache and livecache state +``` + +## Common Pitfalls +- Bootcache persistence must be atomic to prevent corruption +- Livecache expiration must be checked on every access +- Never include detail headers from outside peerfinder/ diff --git a/.claude/skills/xrpld/perflog.md b/.claude/skills/xrpld/perflog.md new file mode 100644 index 0000000000..37f2fb2d9a --- /dev/null +++ b/.claude/skills/xrpld/perflog.md @@ -0,0 +1,31 @@ +# PerfLog Module Best Practices + +## Description +Use when working with performance logging in `src/xrpld/perflog/`. Covers performance instrumentation and metric collection. + +## Responsibility +Performance logging and instrumentation for the rippled server. Tracks timing data, throughput metrics, and operational statistics for monitoring and debugging. + +## Key Patterns + +### Performance Logging Interface +```cpp +// Abstract interface for performance data collection +// Implementations can log to file, export to monitoring systems, etc. +// Enabled/disabled via configuration +``` + +### Detail Namespace +```cpp +// Implementation details in detail/ subdirectory +// Not part of public API +``` + +## Common Pitfalls +- Performance logging should have minimal overhead when disabled +- Never log sensitive data (keys, balances) in performance logs +- Ensure timestamps use consistent clock sources + +## Key Files +- `src/xrpld/perflog/` - Performance logging implementation +- `src/xrpld/perflog/detail/` - Implementation details diff --git a/.claude/skills/xrpld/perflog/detail.md b/.claude/skills/xrpld/perflog/detail.md new file mode 100644 index 0000000000..e877eab294 --- /dev/null +++ b/.claude/skills/xrpld/perflog/detail.md @@ -0,0 +1,11 @@ +# PerfLog Detail Module Best Practices + +## Description +Use when working with performance logging implementation details in `src/xrpld/perflog/detail/`. Internal helpers for the perflog module. + +## Responsibility +Internal implementation details for performance logging, including metric collection, formatting, and output management. + +## Common Pitfalls +- Performance logging overhead must be minimal when disabled +- Never include detail headers from outside perflog/ diff --git a/.claude/skills/xrpld/rpc.md b/.claude/skills/xrpld/rpc.md new file mode 100644 index 0000000000..e5d7ca19c7 --- /dev/null +++ b/.claude/skills/xrpld/rpc.md @@ -0,0 +1,91 @@ +# RPC Module Best Practices + +## Description +Use when working with RPC request handling in `src/xrpld/rpc/`. Covers command dispatch, handler implementation, coroutine suspension, and the gRPC interface. + +## Responsibility +HTTP/JSON and gRPC RPC interface to rippled. Dispatches requests to 40+ command handlers, manages request context, supports coroutine-based suspension for async operations, and handles user roles/permissions. + +## Key Patterns + +### RPC Handler Pattern +```cpp +// Each handler is a function taking context, returning Json::Value +Json::Value doMyCommand(RPC::JsonContext& context) { + // Validate parameters + if (!context.params.isMember("field")) + return RPC::missing_field_error("field"); + + // Access application services + auto& app = context.app; + + // Build response + Json::Value result(Json::objectValue); + result["status"] = "success"; + return result; +} +``` + +### Coroutine Suspension +```cpp +// RPC handlers can suspend for async operations +// Key types: +// Callback - 0-argument function +// Continuation - Takes callback, promises to call it later +// Suspend - Function from coroutine that takes continuation +// Coroutine - Function given suspend to enable suspension + +// This allows handlers to yield without blocking threads +``` + +### Request Context +```cpp +struct JsonContext { + Application& app; + Resource::Charge& loadType; + Json::Value params; + beast::Journal j; + Role role; // User, Admin, Identified, etc. +}; +``` + +### Role-Based Access +```cpp +enum class Role { GUEST, USER, ADMIN, IDENTIFIED, PROXY, FORBID }; +// Handlers specify minimum required role +// Admin handlers only accessible from admin IP ranges +``` + +### Error Handling +```cpp +// Standard error helpers: +RPC::missing_field_error("field_name"); +RPC::invalid_field_error("field_name"); +RPC::make_error(rpcINVALID_PARAMS, "description"); +// Errors injected into JSON response +``` + +### gRPC Handlers +```cpp +// Separate handler set for gRPC interface +// Defined in GRPCHandlers.h +// Use Protocol Buffer request/response types +// Convert to/from native types at boundary +``` + +## Common Pitfalls +- Always validate parameters before accessing them +- Check user Role before executing privileged operations +- Use coroutine suspension for any operation that might block +- Never return internal data structures directly - always convert to JSON +- Handler functions are in `handlers/` directory - one file per command or group +- gRPC handlers must convert proto types to native types at the boundary + +## Key Files +- `src/xrpld/rpc/RPCHandler.h` - Command dispatcher +- `src/xrpld/rpc/Context.h` - RPC context/state +- `src/xrpld/rpc/Status.h` - RPC status codes +- `src/xrpld/rpc/Role.h` - User role/permissions +- `src/xrpld/rpc/GRPCHandlers.h` - gRPC integration +- `src/xrpld/rpc/handlers/` - Individual command handlers (40+) +- `src/xrpld/rpc/README.md` - Coroutine documentation diff --git a/.claude/skills/xrpld/rpc/detail.md b/.claude/skills/xrpld/rpc/detail.md new file mode 100644 index 0000000000..4cae58856b --- /dev/null +++ b/.claude/skills/xrpld/rpc/detail.md @@ -0,0 +1,11 @@ +# RPC Detail Module Best Practices + +## Description +Use when working with RPC implementation details in `src/xrpld/rpc/detail/`. Internal helpers for the RPC module. + +## Responsibility +Internal implementation details for RPC handling, including request parsing, response formatting, coroutine machinery, and middleware. + +## Common Pitfalls +- Coroutine state must be carefully managed to prevent leaks +- Never include detail headers from outside rpc/ diff --git a/.claude/skills/xrpld/rpc/handlers.md b/.claude/skills/xrpld/rpc/handlers.md new file mode 100644 index 0000000000..88074a2cfc --- /dev/null +++ b/.claude/skills/xrpld/rpc/handlers.md @@ -0,0 +1,74 @@ +# RPC Handlers Module Best Practices + +## Description +Use when adding or modifying RPC command handlers in `src/xrpld/rpc/handlers/`. Contains 40+ individual RPC command implementations. + +## Responsibility +Individual RPC command handler implementations. Each file implements one or more related RPC commands following the standard handler pattern. + +## Key Patterns + +### Handler Function Signature +```cpp +// Standard handler pattern +Json::Value doMyCommand(RPC::JsonContext& context) { + // 1. Validate parameters + if (!context.params.isMember("required_field")) + return RPC::missing_field_error("required_field"); + + // 2. Check permissions + // (Role already verified by dispatcher based on handler metadata) + + // 3. Access application services + auto& app = context.app; + auto& ledger = context.ledgerMaster.getValidatedLedger(); + + // 4. Execute logic + // ... + + // 5. Build and return response + Json::Value result(Json::objectValue); + result["status"] = "success"; + return result; +} +``` + +### Parameter Validation +```cpp +// Use standard error helpers +RPC::missing_field_error("field_name"); // Required field missing +RPC::invalid_field_error("field_name"); // Field has wrong type/value +RPC::make_error(rpcINVALID_PARAMS, "description"); // Generic error +``` + +### Adding a New Handler +1. Create a new .cpp file in `handlers/` +2. Implement the handler function following the pattern above +3. Register the command in the handler dispatch table +4. Document the command parameters and response format + +### Common Handler Files +``` +AccountInfo.cpp - account_info command +AccountLines.cpp - account_lines (trust lines) +AccountOffers.cpp - account_offers +Submit.cpp - submit (transaction submission) +Subscribe.cpp - subscribe (event streaming) +LedgerData.cpp - ledger_data +ServerInfo.cpp - server_info +Fee1.cpp - fee command +Tx.cpp - tx (transaction lookup) +BookOffers.cpp - book_offers (order book) +``` + +## Common Pitfalls +- Always validate ALL parameters before using them +- Never return internal data structures - convert to JSON at the boundary +- Respect Role-based access control - admin handlers must check role +- Handlers should be stateless - all state comes from context +- Use coroutine suspension for any blocking operation (DB queries, network) +- Error responses must follow the standard error format + +## Key Files +- `src/xrpld/rpc/handlers/` - All handler implementations +- `src/xrpld/rpc/RPCHandler.h` - Dispatch table and registration diff --git a/.claude/skills/xrpld/shamap.md b/.claude/skills/xrpld/shamap.md new file mode 100644 index 0000000000..16cd3974be --- /dev/null +++ b/.claude/skills/xrpld/shamap.md @@ -0,0 +1,32 @@ +# SHAMap (xrpld) Module Best Practices + +## Description +Use when working with application-level SHAMap operations in `src/xrpld/shamap/`. Covers NodeFamily and application integration with the Merkle tree. + +## Responsibility +Application-level integration of the SHAMap (Merkle radix tree) with the rippled server. Provides NodeFamily for managing tree node relationships and connecting the generic SHAMap to the node store. + +## Key Patterns + +### NodeFamily +```cpp +// NodeFamily connects SHAMap to the persistent NodeStore +// Provides: database access, tree node creation, hash verification +// Each SHAMap references a Family for storage operations +``` + +### Relationship to libxrpl/shamap +```cpp +// libxrpl/shamap: Generic Merkle tree implementation +// xrpld/shamap: Application-specific integration (NodeFamily, storage) +// The generic tree doesn't know about databases - NodeFamily bridges the gap +``` + +## Common Pitfalls +- Always use NodeFamily to create SHAMap instances connected to storage +- The libxrpl SHAMap is the implementation - this module is the glue layer +- Don't duplicate SHAMap logic here - extend via NodeFamily only + +## Key Files +- `src/xrpld/shamap/NodeFamily.h` - Family relationship management +- `src/xrpld/shamap/NodeFamily.cpp` - Implementation