VOOZH about

URL: https://deepwiki.com/stefanak-michal/php-bolt-driver/5.1-protocol-v1-and-v2-foundation

⇱ Protocol V1 and V2 - Foundation | stefanak-michal/php-bolt-driver | DeepWiki


Loading...
Last indexed: 14 February 2026 (a283bd)
Menu

Protocol V1 and V2 - Foundation

Purpose and Scope

This document covers the Bolt Protocol versions 1 and 2, which establish the foundational message set and communication patterns for the Bolt protocol. V1 and V2 are functionally identical, implementing the baseline operations required for query execution without explicit transaction support or streaming control.

These protocols provide:

  • Simple connection initialization via INIT message
  • Basic query execution with RUN
  • Monolithic result retrieval with PULL_ALL and DISCARD_ALL
  • Connection recovery via RESET and ACK_FAILURE

For transaction support introduced in V3, see Protocol V3 - Transaction Support. For parameterized streaming in V4+, see Protocol V4.x Series - Streaming and Routing.

Sources: src/protocol/V1.php src/protocol/V2.php


Protocol Class Structure

Both V1 and V2 extend AProtocol and compose identical functionality through PHP traits. The only difference is the protocol version number reported during negotiation.


Trait Composition Pattern: The library uses PHP traits to enable message reuse across protocol versions. V1 and V2 share all message implementations from the \Bolt\protocol\v1 namespace.

Sources: src/protocol/V1.php12-23 src/protocol/V2.php12-23


Message Catalog

The V1/V2 protocols support six message types:

MessageSignatureDescriptionValid States
INIT0x01Connection authorizationCONNECTED
RUN0x10Execute Cypher queryREADY
PULL_ALL0x3FRetrieve all result recordsSTREAMING
DISCARD_ALL0x2FDiscard all result recordsSTREAMING
RESET0x0FInterrupt and return to ready stateAny (except DEFUNCT)
ACK_FAILURE0x0EAcknowledge failure and return to ready stateFAILED

Key Limitation: V1/V2 lack transaction control messages (BEGIN, COMMIT, ROLLBACK) and parameterized streaming (PULL n, DISCARD n). These are added in V3 and V4 respectively.

Sources: src/protocol/v1/InitMessage.php src/protocol/v1/RunMessage.php src/protocol/v1/PullAllMessage.php src/protocol/v1/DiscardAllMessage.php src/protocol/v1/ResetMessage.php src/protocol/v1/AckFailureMessage.php


Handshake and Authentication (INIT)

INIT Message

The INIT message authenticates the connection immediately after the version negotiation handshake completes.


Message Structure

The init() method sends a PackStream-encoded message:

src/protocol/v1/InitMessage.php17-22

Parameters:

  • userAgent (string): Client identification, e.g., "bolt-php"
  • authToken (array): Dictionary containing authentication credentials

Standard authToken format:


State Transition

INIT transitions the connection from CONNECTED to READY on success, or to DEFUNCT on failure. Once in READY state, the client can execute queries.

Sources: src/protocol/v1/InitMessage.php tests/protocol/V1Test.php27-60


Query Execution (RUN)

RUN Message

The RUN message submits a Cypher query for execution. The query result is not returned immediately—it must be retrieved with PULL_ALL or discarded with DISCARD_ALL.


Message Structure

src/protocol/v1/RunMessage.php17-22

Parameters:

  • query (string): Cypher query statement
  • parameters (array): Query parameters as associative array (converted to object)

Example:


Encoding Details

The message signature is 0x10. Parameters are packed as a PackStream dictionary (empty object {} if no parameters).

Sources: src/protocol/v1/RunMessage.php tests/protocol/V1Test.php65-102


Result Streaming

PULL_ALL Message

The PULL_ALL message retrieves all remaining records from the result stream. The server sends RECORD messages followed by a final SUCCESS.


Implementation

src/protocol/v1/PullAllMessage.php18-23

The pullAll() method adds the message to the pipeline. Results are retrieved via getResponses(), which yields an iterator:

src/protocol/v1/PullAllMessage.php29-35

The iterator yields Response objects until it encounters a non-RECORD signature (typically SUCCESS or FAILURE).

Usage:


DISCARD_ALL Message

The DISCARD_ALL message discards all remaining records without transmitting them to the client. This is more efficient when only metadata (e.g., row count) is needed.

src/protocol/v1/DiscardAllMessage.php17-22

Signature: 0x2F

State Transition: STREAMINGREADY

Sources: src/protocol/v1/PullAllMessage.php src/protocol/v1/DiscardAllMessage.php tests/protocol/V1Test.php107-165


Connection Management

RESET Message

The RESET message interrupts any ongoing operation and returns the connection to READY state. It's used for recovery when a query is interrupted or the connection is in an unknown state.

src/protocol/v1/ResetMessage.php (full trait not shown in files, but referenced)

Signature: 0x0F

Behavior:

  • Cancels any streaming results
  • Rolls back any active operations (though V1/V2 have no explicit transactions)
  • Transitions to READY on success, DEFUNCT on failure

Usage:


ACK_FAILURE Message

The ACK_FAILURE message acknowledges a FAILURE response from the server, allowing the connection to recover from FAILED state back to READY.

src/protocol/v1/AckFailureMessage.php18-23

Signature: 0x0E

State Transition: FAILEDREADY (or DEFUNCT if acknowledgement fails)

Workflow:

  1. Server sends FAILURE in response to an error (e.g., syntax error in query)
  2. Connection enters FAILED state
  3. Client sends ACK_FAILURE
  4. Server sends SUCCESS
  5. Connection returns to READY state

Until ACK_FAILURE is sent, all subsequent messages receive IGNORED responses.

Sources: src/protocol/v1/ResetMessage.php src/protocol/v1/AckFailureMessage.php tests/protocol/V1Test.php170-211


Server State Transitions

The V1/V2 protocols use a simplified state machine with four primary states:


State Descriptions

StateDescriptionValid Messages
CONNECTEDProtocol negotiated, awaiting authenticationINIT
READYAuthenticated, ready for queriesRUN, RESET
STREAMINGQuery executing, results availablePULL_ALL, DISCARD_ALL, RESET
FAILEDQuery failed, awaiting acknowledgementACK_FAILURE, RESET
INTERRUPTEDConnection interrupted, awaiting resetRESET
DEFUNCTConnection terminatedNone (terminal state)

State Management Implementation

State transitions are handled by the v1\ServerStateTransition trait, which is used by both V1 and V2. The trait defines serverStateTransition() method that updates the serverState property based on message type and response signature.

Sources: tests/protocol/V1Test.php52-59 tests/protocol/V1Test.php89-101


Message Pipelining

V1/V2 support message pipelining, allowing multiple requests to be sent before reading responses. This reduces round-trip latency.


Implementation:

Each message method (e.g., run(), pullAll()) adds the message type to $this->pipelinedMessages array. The getResponse() or getResponses() methods read from the connection and match responses to pipelined messages.

Example:


Sources: src/protocol/v1/InitMessage.php19-21 src/protocol/v1/RunMessage.php19-21 src/protocol/v1/PullAllMessage.php20-22


Response Signatures

Server responses use specific PackStream signatures to indicate message type:

SignatureValueNameDescription
SUCCESS0x70SuccessOperation completed successfully
RECORD0x71RecordData record from result stream
IGNORED0x7EIgnoredMessage ignored (connection in FAILED or INTERRUPTED state)
FAILURE0x7FFailureOperation failed with error details

Response Structure

Responses are represented by the Response class with three properties:

  • message: The client message that triggered the response (from Message enum)
  • signature: The response signature (from Signature enum)
  • content: Response payload (object with metadata or record fields)

FAILURE content structure:


SUCCESS content structure:


Sources: tests/protocol/V1Test.php29-32 tests/protocol/V1Test.php109-114


Encoding Example

The following shows the binary PackStream encoding for a simple query workflow:

INIT Message

0001b2 Structure (2 fields), signature 0x01
000988626f6c742d706870 String "bolt-php" (userAgent)
0001a3 Dictionary (3 fields)
 000786736368656d65 String "scheme"
 0006856261736963 String "basic"
 000a897072696e636970616c String "principal"
 00058475736572 String "user"
 000c8b63726564656e7469616c73 String "credentials"
 00098870617373776f7264 String "password"

RUN Message

0001b2 Structure (2 fields), signature 0x10
00098852455455524e2031 String "RETURN 1"
0001a0 Empty dictionary {} (no parameters)

PULL_ALL Message

0001b0 Structure (0 fields), signature 0x3F
00013f Signature byte

These hex encodings are verified in the test suite using the $writeBuffer mock.

Sources: tests/protocol/V1Test.php33-44 tests/protocol/V1Test.php73-87 tests/protocol/V1Test.php115-118


V1 vs V2 Differences

Protocol Version 2 is identical to Version 1 in terms of available messages and behavior. The only difference is the version number negotiated during the handshake.

Both protocols:

  • Use the same six messages
  • Share identical message signatures
  • Have identical state transitions
  • Support the same structures (Node, Relationship, Path)

The V2 designation exists primarily for Neo4j versioning purposes and potential future divergence (which never materialized—V3 became the next distinct protocol).

Sources: src/protocol/V2.php12-23 tests/protocol/V2Test.php17-22


Limitations

V1/V2 protocols have the following limitations addressed in later versions:

  1. No Transaction Support: Queries execute in auto-commit mode. Explicit transaction control (BEGIN/COMMIT/ROLLBACK) is introduced in V3.

  2. Monolithic Streaming: PULL_ALL retrieves all records in one operation. Parameterized streaming (PULL n) for batch processing is added in V4.

  3. INIT Handshake: Authentication is bundled with connection initialization. V3 separates these with HELLO, and V5 further separates authentication with LOGON.

  4. No Routing: Cluster routing capabilities are added in V4.3.

  5. No element_id: Graph structures use numeric id fields. Composite database support with element_id is added in V5.

For these advanced features, applications should negotiate higher protocol versions when available.

Sources: src/protocol/V1.php src/protocol/V3.php src/protocol/V4.php