Skip to content

v0.7.0

Latest

Choose a tag to compare

@github-actions github-actions released this 30 Sep 05:40
· 14 commits to main since this release
5d4ea9e

Added

  • Integrity verification for downloaded build dependencies: SHA256 checksum verification of Zig compiler archives using the official ziglang.org index.json, and git tag verification for TigerBeetle source clones (#128)
  • Release artifact checksums: each native library asset in GitHub Releases now includes a per-file .sha256 file and a combined SHA256SUMS.txt for batch verification (#128)
  • CI integrity verification: build-lib job verifies checksums of built native libraries, and test-matrix job logs the Docker image digest for traceability (#128)
  • Documentation explaining how consumers can verify release artifacts using the published checksums (#128)
  • Documented synchronous wait model in NativeClient: class-level PHPDoc explains the polling approach, thread-safety limitations, and CPU usage characteristics (#123)
  • NativeClient::POLL_INTERVAL_USECONDS constant (100 µs) makes the polling interval explicit and configurable (#123)
  • NativeClient::waitInterval() method extracted from pollForCompletion() for testability and subclass override (#123)
  • Unit tests verifying polling interval constant values, waitInterval() sleep duration, and pollForCompletion() deadline enforcement (#123)
  • BackendFactory::create() now accepts an optional $libPath parameter for specifying an explicit trusted native library path (#127)
  • FFI security documentation in README covering trust model, loading precedence, and best practices (#127)
  • Native library loading precedence documented in ARCHITECTURE.md, including security rationale for omitting system-wide paths (#127)
  • Documented create operation result semantics in README: positional correspondence, isCreated()/getStatus()/getTimestamp(), partial failure, linked events chain, and LINKED_EVENT_CHAIN_OPEN/LINKED_EVENT_FAILED behaviour (#136)
  • Documentation consistency tests verifying the presence of create-result sections and key terms in README (#136)
  • Optional GMP-accelerated Uint128::fromString() and Uint128::toString() when ext-gmp is available, providing significantly faster decimal parsing and formatting for high-volume conversion workloads (#126)
  • Unit tests for AccountBalance DTO class covering constructor, getters, default values, readonly nature, zero values, max timestamp, and edge cases (#176)
  • Uint128 now implements \Stringable interface with __toString() delegating to toString(), enabling string interpolation and string|Stringable type hint usage (#168)
  • Client lifecycle, concurrency, and close() behaviour documented in README, including long-running process considerations and thread-safety guidance (#137)
  • Unit tests in DocumentationTest verifying the presence of lifecycle/concurrency/timeout sections in README (#137)
  • UnknownStatusException for clear, actionable error messages when native library returns an unrecognized enum status value during response parsing (#133)
  • CreateAccountResultBatch::getResult() and CreateTransferResultBatch::getResult() now throw UnknownStatusException instead of raw \ValueError when a status value is unknown (#133)
  • NativeClient initialization now handles unknown InitStatus values gracefully, throwing InitializationException instead of \ValueError (#133)
  • Unit tests covering unknown enum status handling for all response batch types, malformed buffer edge cases, and clear error message verification (#133)
  • CI generates source coverage reports (clover XML) during unit test execution and enforces a minimum 80% element coverage threshold (#135)
  • bin/check-coverage.php script to validate coverage percentage against a configurable threshold in CI (#135)
  • Fully implemented ChangeEventsFilterBatch with setAccountId()/getAccountId() methods for filtering change events by account (#117)
  • CI workflow now executes both unit and functional PHPUnit suites, with distinct steps for each (#107)
  • Unit tests for QueryFilter DTO class covering constructor, getters, default values, readonly nature, and max value edge cases (#175)
  • CI provisions a version-pinned (0.17.4) tb_client native library before running functional tests, ensuring FFI-backed tests no longer silently skip in CI (#108)
  • AccountBatch::isFound() and TransferBatch::isFound() methods for detecting missing records in lookup results (#112)
  • Lookup behaviour (ordering, missing-record zeroed struct) documented in README and ClientInterface docblocks (#112)
  • NativeClient lifecycle and failure-mode tests covering initialisation success/failure, request completion, native error statuses, timeout, and deinitialisation idempotency (#134)
  • CrazyGoat\Elephas\Internal\BinaryRange helper with assertUint8/16/32/64 static checks (#120)
  • CrazyGoat\Elephas\Exception\InvalidBatchCursorException thrown by batch getters and setters when the cursor position is outside the populated range (#119)
  • Client::withTimeout() factory and RequestTimeoutException for configurable, domain-specific request timeouts (#122)
  • NativeClient accepts a $timeoutSeconds constructor parameter forwarded through BackendFactory and FfiBackend (#122)
  • Client::queryAccounts() and Client::queryTransfers() now implement the full QueryFilter round-trip (pack QueryFilter → submit QUERY_ACCOUNTS/QUERY_TRANSFERS → decode AccountBatch/TransferBatch), resolving the misleading "not implemented" public contract (#114)
  • Optional BCMath-accelerated Uint128::fromString() and Uint128::toString() when ext-bcmath is available, providing a secondary acceleration path when GMP is not installed (#126)
  • Transparent fallback: Uint128 automatically selects GMP → BCMath → pure-PHP based on extension availability, with consistent results across all paths (#126)
  • Unit tests verifying cross-implementation consistency, byte-level round-trips, overflow detection, and factory method agreement across all conversion paths (#126)

Changed

  • CI TigerBeetle containers: investigated removing --privileged; determined it is still required for both format and start commands due to io_uring restrictions in the GitHub Actions CI environment. Findings documented in ARCHITECTURE.md (#130)
  • Account DTO fields debitsPending, debitsPosted, creditsPending, creditsPosted changed from int to Uint128 to match TigerBeetle 128-bit ranges (#118)
  • Transfer DTO field amount changed from int to Uint128 to match TigerBeetle 128-bit range (#118)
  • Removed bogus fields debitsReserved, creditsReserved, debitsAccepted, creditsAccepted from Account DTO — these fields do not exist in the native tb_account_t struct (#118)
  • Native library auto-detection now only searches project-local paths (resources/lib/), removing system-wide fallbacks (/usr/local/lib, /usr/lib) to prevent accidental loading of untrusted or version-mismatched libraries via FFI (#127)
  • NativeClient::detectLibraryPath() no longer searches system directories; users requiring a custom path must provide an explicit $libPath (#127)
  • Updated ROADMAP.md — moved ROADMAP.md and community health files (.github/SECURITY.md, issue/PR templates) from "Remaining" to "Completed" in the v0.4.0 milestone, reflecting their actual implementation status (#169)
  • Replaced assert() calls with explicit exception-throwing validation at public and native boundaries so that validation cannot be silently disabled by PHP assertion settings (#121)
  • NativeClient FFI calls (tb_client_init, tb_client_submit, tb_client_deinit) extracted to overridable protected methods, enabling controlled test doubles without a real native library (#134)
  • CreateAccountResult and CreateTransferResult no longer expose a synthetic getId() derived from the TigerBeetle-assigned timestamp. Both classes now provide getTimestamp(): int reflecting the actual timestamp returned by TigerBeetle for each created or rejected event. This aligns the public API with the native TigerBeetle tb_create_account_result_t / tb_create_transfer_result_t struct contract (TB 0.17.x) where each result carries a uint64_t timestamp and a uint32_t status (#111)
  • NativeClient request completion no longer confuses TB_PACKET_OK (status 0) with an incomplete/pending packet. A sentinel status value (0xFFFFFFFF) is now used to track the pending state, allowing status 0 to be correctly interpreted as a successful response (#109)
  • NativeClient::submit() now retains a PHP reference to the FFI data buffer for the full native request lifetime, preventing a potential use-after-free when the CData backing the request payload is garbage-collected while tb_client still holds the raw pointer (#110)
  • CI now fails when the TigerBeetle or FFI dependencies are unavailable, instead of letting the functional tests skip silently (#131)
  • Placeholder assertions in the functional tests replaced with meaningful checks (#132)
  • Git hook installation is now opt-in and non-destructive (#129)
  • Batch construction is faster for large batches, using per-struct buffers (#125)

Removed

  • Removed unused CrazyGoat\Elephas\Internal\Packet class and its test (PacketTest) — the native request flow uses tb_packet_t directly via FFI, making the PHP-level Packet abstraction redundant (#124)

Fixed

  • Corrected Uint128::toHex() documentation in README (no 0x prefix) and Id::fromString() return type (now Uint128 instead of string) (#116)
  • PHPStan memory limit set to 512M in composer lint script to prevent out-of-memory failures during static analysis (#138)
  • Removed stale TODO: implement comments from Transfer, Account, and ChangeEventsFilterBatch public DTO classes (#117)
  • All batch fromBuffer() factories now reject malformed buffers whose size is not an exact multiple of the expected struct size, preventing partial-record deserialization (#113)
  • Batch getters and setters on AccountBatch, TransferBatch, IdBatch, AccountFilterBatch, QueryFilterBatch, AccountBalanceBatch, CreateAccountResultBatch, and CreateTransferResultBatch now fail fast with a dedicated InvalidBatchCursorException when called before add() (or on a buffer created from an empty response), instead of silently writing into or reading from the pre-allocated buffer while the logical length remains zero (#119)
  • Integer setters on AccountBatch, TransferBatch, QueryFilterBatch, and AccountFilterBatch now validate that values fit their declared unsigned width (uint8/uint16/uint32/uint64) before binary packing. Negative or oversized values now raise IntegerOverflowException with the offending field name and accepted range, instead of being silently reinterpreted by pack() (#120)
  • Native library platform paths are aligned between the code, the releases and the documentation (#115)