Перейти к содержанию

Bet Acceptance и граница согласованности

Раздел 06

Тип материала — глубокий архитектурный разбор. HYPOTHETICAL — модель, схемы и числа. INFERENCE — протокол и критерии выбора.

Контракт команды

Запрос содержит tenant, wallet, idempotency key, selection, stake, currency и согласованную клиентом quote version. Канонический fingerprint включает все параметры, меняющие эффект. Сначала выполняются authentication и проверка формата. Затем ищется сохранённый результат по scoped key. Совпавший fingerprint возвращает исходный результат даже после изменения odds. Другой fingerprint даёт конфликт. Authorizer проверяет eligibility и юрисдикцию. Внешние risk calls имеют deadline и версионированный ответ с expiry, связанный с запросом.

Состояния и границы

Requested означает приём команды. Accepted означает durable запись ставки с согласованным резервом. Settled означает учётный расчёт по версии результата. Payout имеет отдельную идентичность и подтверждение.

stateDiagram-v2
 [*] --> Requested
 Requested --> Accepted: Commit bet and hold
 Requested --> Rejected: Guard rejects
 Accepted --> Settled: Commit journal
 Accepted --> Voided: Release or reverse
 Settled --> Settled: Approved correction revision
flowchart LR
 Q[Authoritative quote and policy] --> T[Bet and wallet transaction]
 C[Scoped command identity] --> T
 T --> H[Bet and hold]
 T --> O[Outbox]
 O --> K[Kafka and projections]

Нормальная последовательность

  1. Проверить размер stake, currency scale, selection и право игрока.
  2. Получить ограниченное по времени risk evidence. Если оно истекло, запросить новое или применить отказ согласно policy.
  3. В transaction защитить область уникальности запроса и wallet position. Проверить текущий quote и status под общим guard либо по протоколу version fence. При stale quote вернуть requote с новым согласием клиента. Повтор уже принятой команды разрешается до проверки текущей цены.
  4. Проверить active limits, available funds и exposure. Для двух ставок с одного wallet проверка и изменение позиции должны сериализоваться. Если market state находится у другого writer, отдельно доказать условия действительности quote token. Обычный RPC read оставляет окно между проверкой и commit.
  5. Зафиксировать bet, hold, outcome, версии правил и outbox одним commit. Ответить accepted после commit. Relay доставляет committed fact независимо от клиентского ответа.
sequenceDiagram
 participant C as Client
 participant A as Acceptance API
 participant R as Risk authority
 participant D as Bet and wallet DB
 participant B as Broker
 C->>A: Submit quote version and key
 A->>R: Evaluate bounded request
 R-->>A: Versioned decision evidence
 A->>D: Recheck guards and commit bet hold outcome outbox
 D-->>A: Durable accepted result
 A-->>C: Accepted with bet ID
 D->>B: Relay committed outbox fact

Отказ и восстановление

sequenceDiagram
 participant C as Client
 participant A as Acceptance API
 participant D as Authoritative DB
 C->>A: Submit request K
 A->>D: Commit accepted and hold
 D--xA: ACK lost
 C->>A: Retry K with identical payload
 A->>D: Resolve stored result by K
 D-->>C: Same bet and hold identity
Точка отказа Durable state Восстановление
До commit Ставка и hold отсутствуют Повтор того же ключа проходит guard
После commit до HTTP response Accepted и один hold Lookup возвращает прежнюю ставку
После commit до publish Accepted, outbox pending Relay публикует стабильный event ID
После broker ACK до marker Accepted, доставка может повториться Consumer проверяет identity в своей effect boundary
Две команды по 70 при available 100 Одна может удержать 70, остаток 30 Вторая проверяет актуальное состояние и отклоняется

Kafka ACK подтверждает запись сообщения в пределах broker contract. Сообщение BetRequested не подтверждает проверку средств, действительность quote или durable reserve. Событие BetAccepted публикуется из committed outbox. При remote wallet вместо общей транзакции нужен pending protocol с идемпотентным резервом, fencing и проверкой завершения. Release допускается только при доказанном отказе либо отмене. Произвольный timeout может застать успешное принятие.

Сверка и проверка

Сравнить accepted bet IDs и holds по currency, scoped operation keys, odds revisions и publish frontier. Проверять orphan holds и несогласованные terminal states. Измерять accepted response latency и outbox lag отдельно. Контракт транзакций сверяется с документацией PostgreSQL, а граница broker delivery с Kafka. PostgreSQL 17 isolation · Kafka 4.1 design