M3 R3.1: map the required non-streamed write sequence (OpenStorageConnection is the missing step)
Static decompile mining of the 2023 R2 client corroborates the live R3.1 error: the AddNonStreamValues failure is the missing StorageService.OpenStorageConnection, which creates exactly the \.\pipe\aahStorageEngine\console,sid(...) session named in the server error. Mapped the full native sequence: HistoryService.OpenConnection (have) -> StorageService.OpenStorageConnection (MISSING) -> StorageService.RegisterTags -> AddNonStreamValuesBegin (works) -> AddNonStreamValues(btInput) (fails - no console session) -> End(commit). Two hard parts remain, each a live-production decode loop with no static shortcut: (1) reproduce the 12-arg OpenStorageConnection handshake (several args inferred); (2) decode the AddNonStreamValues btInput (C++-built, absent from decompiles; only the 44-byte packed HISTORIAN_VALUE2 is known). Documented in revision-write-path.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B6mcaT2PjRFKcogzp9UkfC
This commit is contained in:
@@ -81,14 +81,42 @@ gRPC *server* now holds the pipe, not the client). Because the error is identica
|
||||
framing, the blocker is **not** the `btInput` layout — it is a **missing storage-engine console
|
||||
session / tag-registration precondition** for the connection.
|
||||
|
||||
**Next step to finish M3 (untested):** establish the StorageService side **before**
|
||||
`AddNonStreamValues` — `StorageService.OpenStorageConnection`/`OpenStorageConnection2` to open the
|
||||
console session, then register the tag→storage mapping (`RegisterTags` / `AddTagidPairs` /
|
||||
`AddShardTagids`), then retry `AddNonStreamValues` and finally `End(bCommit=true)` + SQL read-back on
|
||||
a sandbox tag. Each of those StorageService ops has its own buffer format to RE. Raw decode artifact:
|
||||
`artifacts/reverse-engineering/grpc-nonstream-decode/batch1-decode.txt` (gitignored). Probe command:
|
||||
`grpc-nonstream-decode`; driver: `HistorianGrpcRevisionProbe.ProbeNonStreamedBuffersAsync` (candidate
|
||||
guess-bytes live in the RE tool, not `src/`).
|
||||
**Required call sequence (mapped from the 2023 R2 decompile, corroborates the error above):** the
|
||||
missing precondition is **`StorageService.OpenStorageConnection`** — it creates exactly the
|
||||
`\\.\pipe\aahStorageEngine\console,sid(...)` console session named in the failure. The native
|
||||
non-streamed write path is:
|
||||
|
||||
```
|
||||
HistoryService.OpenConnection (✅ have it — the Open2 handshake)
|
||||
→ StorageService.OpenStorageConnection (⛔ MISSING — opens the console sid session; SEPARATE
|
||||
storage session, returns its own uint handle + new GUID)
|
||||
→ StorageService.RegisterTags (register the tag→storage mapping for the session)
|
||||
→ TransactionService.AddNonStreamValuesBegin (✅ works)
|
||||
→ TransactionService.AddNonStreamValues(btInput) (⛔ currently fails here — no console session yet)
|
||||
→ TransactionService.AddNonStreamValuesEnd(bCommit=true)
|
||||
→ StorageService.CloseStorageConnection / HistoryService.CloseConnection
|
||||
```
|
||||
|
||||
`OpenStorageConnection` (gRPC `StorageService`) takes 12 args — HostName, EnginePath
|
||||
(`\\.\pipe\aahStorageEngine\console`), FreeDiskSpace, ProcessName, ProcessId, UserName, Password(+len),
|
||||
ClientType, ClientVersion, ConnectionMode, ConnectionTimeout, StorageSessionId(in/out) — and returns a
|
||||
**new** storage `Handle` (uint) + a **new** StorageSessionId GUID (distinct from the Open2 GUID).
|
||||
|
||||
**Two hard parts remain, each a separate live-production decode loop (no static shortcut):**
|
||||
1. **Reproduce the `OpenStorageConnection` handshake** — several of the 12 args are only inferable from
|
||||
the decompile (ProcessId, ClientType/Version, ConnectionMode, the password-bytes framing), so the
|
||||
exact values must be confirmed against the live server.
|
||||
2. **Decode the `AddNonStreamValues` `btInput`** — built in C++ (`SendNonStreamedValues` vtable call),
|
||||
**absent from every decompile**; only the 44-byte packed `HISTORIAN_VALUE2` struct is known. Must be
|
||||
decoded empirically once the console session exists (the batch-1 identical-error result could not
|
||||
distinguish framings precisely *because* there was no session — with a session, framings should
|
||||
diverge and the correct one becomes findable).
|
||||
|
||||
Raw decode artifact: `artifacts/reverse-engineering/grpc-nonstream-decode/batch1-decode.txt`
|
||||
(gitignored). Probe command: `grpc-nonstream-decode`; driver:
|
||||
`HistorianGrpcRevisionProbe.ProbeNonStreamedBuffersAsync` (candidate guess-bytes live in the RE tool,
|
||||
not `src/`). **Status: M3 transaction lifecycle proven; full insert blocked on the
|
||||
OpenStorageConnection handshake + btInput decode — a focused follow-up, each step a live probe.**
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user