# STAN. Модель процессинга
**STAN**
Итак - с UXTO все более менее устаканилось и стало ясно. Система разделена на две части, первая инкапсулирует торговую логику и выполнение заявок пользователей, вторая предоставляет систему обработки запросов авторизации и генерации ответов авторизации перевода средств внутри канала и между слоями. Все каналы используют модель UXTO. подробнее об этом ниже.
На данном этапе - считаем что канал - это труба соеденяющая процессинг и трейдера. В дальнейшем это будет труба между любыми пользователями системы. Труба работает в два приема - (1)запрос, в котором передаются подготовленные для оформления транзакции артефакты и (2)ответ системы подготовленной и подписанной транзакцией.
Такой дизайн обеспечит достижение трех целей:
1. сохранение асинхронный, высокопроизводительный дизайн **exchange_engine**, исключение блокировок между системами
2. сокрытие внутри системы интерфейсов **processing_engine**, смягчение его режима работы
3. гибкую модель расширения функционала как с точки зрения технологий работы с каналами, так и с точки зрения обработки типов заявок, отличных от market/limit order

Итак имеем ~~три~~ четыре системы, плохо осведомленные друг о друге:
- `**execution_engine**` - это система обмена активами во втором слое, при которой продавец соглашается продать, а покупатель соглашается купить ценную бумагу в рамках транзакции. Расчет - это фактический обмен денег или какой-либо иной стоимости ценных бумаг. Работает в модели “учетной записи” в которой оперирует идентификатором канала(xpub реестра, инкапсулирующий все каналы пользователя в конкретном реестре), генерируемым для каждого реестра первого слоя - `user_ledger_id`.
- `**clearing_engine**- UXTO **реестр второго слоя**, это процесс обновления счетов участников торгов, которые приводят к расчету - блокировка средств обеспечения постановленной заявки, создания транзакции нового состояния после матчинга заявки. Отвечает за работу внутри каналов для всех реестров первого слоя, вне зависимости от фактического количества каналов у пользователя - наружу он предлагает интерфейс управления абстрактным каналом, идентифицирующего пользователя/реестр первого слоя(`user_ledger_id`).
- `**settlement_engine**` **-** служба поставки транзакций открытия, закрытия и рефинансирования каналов от имени биржи, также живет в мире UXTO, оперирует `user_channel_id`
- `**revocation_engine**` **-** эта служба ****публикует ****транзакции отзыва в случае обнаружения в реестрах первого слоя транзакций установки устаревшего состояния, опубликованных трейдерами, оперирует `user_channel_id` оповещает `**clearing_engine**`
> Важный момент - придерживаемся стратегии проверки структуры транзакций и подписей к ней в **execution и clearing** системах, это выглядит избыточным - но на данном этапе главная задача обойти возможные проблемы - после достижения функциональности системы оптимизируем эту часть. Вероятно придется распределить эти проверки между системами исходя из времени выполнения.
**PS -** в случае достижения рабочей системы, следущая фаза будет нацелена на добавление функционала в торговую систему и апдейт механник работы каналов, также уже сейчас важно понимать, что я планирую использовать `**revocation_engine**` как часть инфраструктуры `**keyless_one**` в виде службы охраняющих интересы пользователей от попыток злоупотребления со стороны биржи
**Важно учесть что биржевая система имеет компоненты критичные к задержкам:**
- `**execution_engine**` - эта часть процессинга, включенная в exchange_engine //
**Компоненты не критичные к задержкам:**
- `**clearing_engine**` - отвечает за корректную смену состояния между пользователями(не забывая о комисии биржи) //
- `**settlement_engine**` - отвечает за открытие/закрытие/ребалансировку каналов //
- `**revocation_engine**` - система предотвращения публикации отмененных состояний
Функционал биржи, который призван обеспечить STAN -> обмен между трейдерами актива А на актив Б, для обеспечения гибкости все средства обеспечивающие заявки в стакане - переходят на баланс `**clearing_engine**`, после исполнения(match) заявки средства обеспечивающие исполнения переходят на баланс трейдера. Для получения транзакции смены состояния трейдеру необходимо воспользоваться интерфейсом веб-терминала и запросить ее. В автоматическом режиме трейдер получает оповещение об исполнении в общем потоке.
Процессы системы оптимальней всего воспринимать как конвейер трансформаций над заявкой. (Постановка, Исполнение, Запрос актуального состояния, Ре-балансировка канала, Перевод средств на холодные счета)
**1. Процесс {регистрации | аутентификации} на бирже:**

**2. Процесс постановки заявки на обмен:**

****
**2. Исполнение выставленной заявки**:
**3. Запрос актуальных commit_tx на канал пользовтеля:**
**4. Ре-балансировка(открытия/закрытия/изменения сальдо) канала:**
**5. Внутренний процесс перевода средств биржи с горячих каналов на холодные:**
**5. Процесс открытия канала**
6**. Процесс закрытия канала**
## Исходя из всего вышесказанного предлагаемые интерфейсы
Типы данных:
```
- tx
{
inputs: [{
outpoint: {
hash: "", // хеш транзакции
index: 0 // индекс выхода транзакции
},
ScriptSig: "", // подпись скрипта
Sequence: 0xFFFFFFFF //дефолтное значение
},
...
],
outputs: [{
ScriptPubKey: "", // redeem-script (multisig)
Value: 90, // сумма для финансирования
},
{
ScriptPubKey: "", // дефолтный скрипт ()
Value: 10, // сдача
}
]
}
- segwit_tx
{
inputs: [{
outpoint: {
hash: "", // хеш транзакции (всегда транзакции финансирования)
index: 1 // индекс выхода транзакции
},
ScriptSig: "", // пустая строка
Sequence: 0xFFFFFFFF, //дефолтное значение
Witnessess: [
"", // пустая
"", // подпись иницирующей стороны
"", // подпись второй стороны
"" // redeem скрипт (из транзакции финансирования)
]
} // строго один
],
outputs: [{
ScriptPubKey: "", // скрипт
Value: 90, // сумма
},
{
ScriptPubKey: "", // скрипт
Value: 10, // сумма
}
] // строго 2 (в нашем случае)
}
```
интерфейсы:
| Вызывающая сторона | Вызываемая сторона | Интерфейс | Описание |
| ------------------ | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| USER | **execution** | **login(**<br>string stan_public_master_key,<br>string[] exchange_public_master_keys) | Логин |
| USER | **execution** | **open_channel(**<br>string trader_ledger_ID,<br>tx funding_tx,<br>segwit_tx init_commit_tx) | Открытие канала и создание транзакции финансирования |
| **execution** | **settlement** | **open_channel(**<br>string trader_ledger_ID,<br>tx funding_tx,<br>segwit_tx init_commit_tx) | Открытие канала и создание транзакции финансирования (в response вся нужная инфа) |
| **settlement** | **revocation** | **listen_tx(**<br>tx funding_tx,<br>channel_ID) | Указание revocation-демону слушать транзу |
| **execution** | **clearing** | **hold_channe****l****(** <br>string trader_ledger_ID, <br>segwit_tx trader_signed_tx, <br>string trader_rev_secret) | Изменение состояния в пользу биржи, вызывается при блокировке средств, обеспечивающих выставленную заявку. |
| **clearing** | **revocation** | **add_rev_key(**<br>segwit_tx commit_tx,<br>int channel_ID,<br>string rev_key) | Сообщение revocation с новым ключом отмены |
| **execution** | **clearing** | **match_netting(**<br>string buyer_ledger_ID, <br>string seller_ledger_ID, <br>segwit_tx buyer_commit_tx, <br>segwit_tx seller_commit_tx**,** <br>string[] rev_secrets **)** | запрос на генерацию транзакций состояния, увеличивающих баланс пользователей |
| **clearing** | **execution** | **block_channel**(<br>string user_ledger_ID,<br>int reason_code) | аварийное выключение канала пользователя |
| **revocation** | **clearing** | **block_channel**(<br>int channel_ID, <br>int reason_code) | аварийное выключение канала пользователя |
| USER | **execution** | **withdraw_request(**<br>int channel_ID,<br>segwit_tx close_tx) | Запрос на вывод средств с канала |
| **execution** | **settlement** | **withdraw_request(**<br>int channel_ID,<br>segwit_tx close_tx) | Запрос на вывод средств с канала |
| USER | **settlement** | **deposit_request(channel_ID)** | Запрос на пополнение канала |
`**settlement**` **-** работа между первым и вторым слоем
`**clearing**` - работа в канале(во втором слое)
`**revocation**` **-** предохранитель, формирует транзакцию для первого слоя, оповещает второй о событии
`**execution**` - предоставление сревиса обмена к активам, транзакции которых предоставляет первые три сервиса.
## STAN взгляд с обоих сторон
Учитывая разные парадигмы построения архитектуры приложений, вкупе с разными моделями построения реестров, для исключения недопонимания нужно устаканить этот ньюанс:
для otp_actors система выглядит так:
**Внутренние****:**
- `**order_processing_app**` - обработка заявок
- `**trade_processing_app**` - обработка матчей
- `**common_processing_app**` — обработка не связанных с торговлей сервисов авторизации(аутентификация пользователя на бирже, депонирования чат-а, депонирование торгового баланса для HFT)
- `**exchange_app**` - двигатель сопоставления заявок
**Внешние****:**
- `**clearing_app**` - смена состояний в канале
- `**settlement_app**` - открытие/закрытие/ре-финансирование каналов
- `**revocation_app**` - обработка форс-мажорных ситуаций
для micro_services система выглядит так:
> `emitter` - тот, что испускает, `collector` - тот что принимает
**Внутренние:**
- `**offchain_tx_emmiter**` производитель транзакций смены состояния
- `**offchain_tx_collector**` получатель запросов на производство транзакций смены состояния
- `**blockchain_tx_emitter**` производитель транзакций открытия/закрытия каналов
- `**blockchain_tx_collector**` получатель запросов на производство транзакций открытия/закрытия каналов
**Внешние:**
****??? -
## Каналы реестров на основе учетной записи
Для мимикрирования каналов состояний реестров построенных по модели учетной записи под модель UXTO мы используем механизм мета-транзакций, который позволяет определить пользовательский интерфейс контракта фиксации состояний, как атрибуты вызова методов контракта. Для устранения проблемы коммисий за публикацию в дорогих сетях - при открытии/закрытии канала необходимо взымать средства которых будет достаточно для публикации транзакции состояния, подписанной пользователем, но опубликованной с помощью оракла биржи.
`TBA`
## Телеметрия
Для решения задач отладки/профилирования/общего наблюдения за системой необходимо начать внедрять в обоих системах opentelemetry - стандарт сбора логов и метрик в едином формате, помимо наших систем также собирается телеметрия с ядрах хостовой ОС - этой информации должно быть достаточно для отлова узких мест при тестировании и наблюдением за производственным ландшафтом. С точки зрения golang - проблем не должно быть - основной вендор тут Uber, у них все на go. С точки зрения OTP - вроде уже все прояснили.
## API интеграциионной шины
- [Глоссарий](#глоссарий)
- [Общая информация](#общая-информация)
- [Структуры (классы)](#структуры)
- [Логин](#логин)
- [Открытие канала](#открытие-канала)
* [open_channel_user_execution](#open_channel_user_execution)
* [open_channel_execution_settlement](#open_channel_execution_settlement)
* [open_channel_settlement_revocation](#open_channel_settlement_revocation)
* [Требования к транзакции финансирования](#требования-к-транзакции-финансирования)
* [Требования к транзакции установки состояния](#требования-к-транзакции-установки-состояния)
- [Создание ордера](#создание-ордера)
* [create_order_user_execution](#create_order_user_execution)
* [create_order_execution_clearing](#create_order_execution_clearing)
- [Матчинг ордера](#матчинг-ордера)
* [match_netting_execution_settlement](#match_netting_execution_settlement)
- [Выключение канала](#выключение-канала)
* [block_channel_revocation_execution](#block_channel_revocation_execution)
- [Закрытие канала](#вывод-средств)
* [withdraw_request_user_execution](#withdraw_request_user_execution)
* [withdraw_request_execution_settlement](#withdraw_request_execution_settlement)
* [withdraw_request_settlement_revocation](#withdraw_request_settlement_revocation)
* [Требования к транзакции закрытия](#требования-к-транзакции-закрытия)
- [ER-модель для clearing/settlement/revocation](#er-модель)
## Глоссарий
* **user** - клиент на фронте
* **execution** - движок биржи
* **clearing** - установка состояний в каналах
* **revocation** - наблюдение за транзакциями и отмена при необходимости
* **settlement** - создание/закрытие каналов
## Общая информация
Пока делаем общение между всеми через websocket (???)
Имена методов содержатся в заголовках третьего уровня и обычно строятся по схеме
`общее_название_метода_вызывающая_вызываемая`
Пока предполагаю, что бинарный формат транзакций не используем, но можно впоследствии им воспользоваться.
## Структуры
### Request
Для запросов предлагаю воспользоваться такой JSON - структурой
```javascript
{
method: string, // метод запроса
id: variable, // id запроса, variable означает неопределенный тип, то есть пользоваться можно чем-угодно, можем туда nonce прикрутить потом
params: variable[] // массив параметров произвольного типа. Не уверен насколько хорошая идея, так как усложняется валидация из-за такого подхода, но зато компактно
}
```
### Response
Результат. Все далее описанные ошибки явялются значением поля `error` с этой структуры
```javascript
{
method: string, // метод запроса (тот же, что и в запросе)
id: varibale, // id, указанный в запросе
result: variable, // результат произвольного типа
error: { // ошибка, null при отсутствии
code: int, // код ошибки
message: string // сообщение об ошибке
}
}
```
### Transaction
```javascript
{
version: int, // обычно 2, но мало ли, лучше оставлю
lockTime: long(int64), //
segwit: bool, // использовался ли segwit
inputs: { // входы
hash: string, // хеш транзакции (с которой берется выход)
index: int, // индекс выхода в исходной транзакции
scriptSig: string, // подпись к скрипту
sequence: int, // здесь либо дефолтное значение 0xFFFFFFFF, либо (в случае использования в скрипте CHECK_SEQUENCE_VERIFY) другое число
witnesses: []string // подписи при segwit
}[],
outputs: { // выходы
scriptPubKey: string, // скрипт
value: long(int64) // сумма на выходе
}[]
}
```
### Enum(coins)
Поскольку enum'ы везде по-разному работают, пишу втупую (список еще дополню)
```javascript
BTC = 1
LTC = 2
```
### Enum(reasonCode)
```javascript
OK = 0
FAILED = 1
```
## Логин
Клиент должен передать xpub мастер-ключ (ключи) от своего аккаунта.
Если такого xpub не найдено, необходимо создать "учетную запись" и мастер-ключи,
отвечающие этому пользователю (я думаю, что генерить отвечающие ключи лучше в сервисах(акторах)((микро-сервисах)),
отвечающих за работу с криптой, чтобы **execution** знать не знал о каких-то ключах и
мог оперировать аккаунтами и каналами без сложностей с ключами. С другой стороны,
ключи нужно передавать только при создании канала, что вроде не очень сложно).
Если учетка уже существует нужно проверить появление новых ключей для токенов
и в случае наличия таковых запросить у settlement генерацию (или сгенерировать у себя)
### login_user_execution
##### Параметры
|тип|описание|ограничения|
|:-:|:------:|:---------:|
|string|xpub биржи|соответствие структуре xpub (префикс, длина)|
|string[]|xpub'ы для работы с различными токенами|соответствие структуре xpub|
##### Результат
##### Ошибки
### login_user_settlement
##### Параметры
|тип|описание|ограничения|
|:-:|:------:|:---------:|
|string[]|xpub'ы для работы с различными токенами|соответствие структуре xpub|
##### Результат
```javascript
{
keys: string[]
}
```
##### Ошибки
* неверный формат xpub
```json
{
"code": 400,
"message": "wrong xpub"
}
```
## Открытие канала
Для открытия канала **user** должен прислать xpub ключ соответствующей монеты для авторизации,
подписанную транзакцию финансирования с корректными входами и скриптом в выходах,
транзакцию установки начального состояния с корректным скриптом и своей подписью.
**Execution** устанавливает номер нового канала и делает запрос в **settlement**.
**settlement**, в свою очередь, посылает информацию о создании канала в **clearing** и **revocation**.
### open_channel_user_execution
##### Параметры
|тип|описание|ограничения|
|:-:|:------:|:---------:|
|Coins(enum)|номер токена|-|
|string|xpub (для конкретной монеты)|соответствие структуре xpub (префикс, длина)|
|transaction(serialized)|транзакция финансирования|Описаны [здесь](#требования-к-транзакции-финансирования)|
|transaction(serialized)|транзакция установки начального состояния|Описаны [здесь](#требования-к-транзакции-установки-состояния)|
##### Результат
```javascript
{
init: transaction (serialized) // подписанная init транзакция
}
```
##### Ошибки
### open_channel_execution_settlement
##### Параметры
|тип|описание|ограничения|
|:-:|:------:|:---------:|
|int64|id клиента|-|
|Coins(enum)|номер токена|-|
|int|индекс канала (в пространстве клиент-монета)|номер строго следущий по порядку|
|string|xpub (для конкретной монеты)|соответствие структуре xpub (префикс, длина)|
|transaction(serialized)|транзакция финансирования|Описаны [здесь](#требования-к-транзакции-финансирования)|
|transaction(serialized)|транзакция установки начального состояния|Описаны [здесь](#требования-к-транзакции-установки-состояния)|
##### Результат
```javascript
{
init: transaction (serialized) // подписанная init транзакция
}
```
##### Ошибки
* неправильный скрипт в транзакции финансирования (установки начального состояния). Например, скрипт не той формы или не те public-ключи в нем
```json
{
"code": 400,
"message": "wrong funding(init) script"
}
```
* неправильная подпись в транзакции финансирования (установки начального состояния)
```json
{
"code": 400,
"message": "wrong funding(init) signature"
}
```
* входы не найдены
```json
{
"code": 400,
"message": "wrong inputs funding(init) transaction"
}
```
* все страшно сломалось
```json
{
"code": 500,
"message": "internal error"
}
```
### open_channel_settlement_revocation
##### Параметры
|тип|описание|ограничения|
|:-:|:------:|:---------:|
|string|xprv для канала|соответствие структуре xprv (префикс, длина)|
|string|адрес redeem-скрипта|соответствие структуре адреса скрипта|
##### Результат
```javascript
{
success: true
}
```
##### Ошибки
```json
{
"code": 500,
"message": "internal error"
}
```
### Требования к транзакции финансирования
##### Входы
Все входы должны быть корректно подписаны
##### Выходы
Должен быть ровно один выход со специальным multisig-скриптом
##### Скрипт
`OP_2 <client_pub_key> <exchange_pub_ley> OP_2 OP_CHECKMULTISIG`
### Требования к транзакции установки состояния
##### Входы
Все входы - выходы транзакций финансирования с multisig-скриптом
##### Выходы
Один выход - на баланс биржи
Второй выход - выход со специальным скриптом с замком
##### Скрипт
`<exchange_pub_ley> OP_CHECKSIG OP_IF <revoke_pub_key> OP_CHECKSIG OP_ELSE OP_N OP_CHECKSEQUENCEVERIFY OP_DROP <client_public_key> OP_CHECKSIG OP_ENDIF`
## Создание ордера
Пока (временно) будем считать, что ордер меняет состояние только одного канала.
### create_order_user_execution
##### Параметры
|тип|описание|ограничения|
|:-:|:------:|:---------:|
|int64|сумма|-|
|Coins(enum)|токен|-|
|transaction(serialized)|транзакция установки следующего состояния|Описаны [здесь](#требования-к-транзакции-установки-состояния)|
|string|ключ отмены предыдущей транзакции|hex private key|
##### Результат
##### Ошибки
### create_order_execution_clearing
##### Параметры
|тип|описание|ограничения|
|:-:|:------:|:---------:|
|int64|id клиента|-|
|Coins(enum)|токен|-|
|int64|сумма|-|
|transaction(serialized)|транзакция установки следующего состояния|Описаны [здесь](#требования-к-транзакции-установки-состояния)|
|string|ключ отмены предыдущей транзакции|hex private key|
##### Результат
```javascript
{
commit: transaction (serialized)
}
```
##### Ошибки
* неправильный ключ отмены предыдущей транзакции
```json
{
"code": 400,
"message": "wrong revoke key"
}
```
* неправильный скрипт в транзакции. Например, скрипт не той формы или не те public-ключи в нем
```json
{
"code": 400,
"message": "wrong commit script"
}
```
* неправильная подпись в транзакции
```json
{
"code": 400,
"message": "wrong commit signature"
}
```
* входы не найдены
```json
{
"code": 400,
"message": "wrong inputs commit transaction"
}
```
## Матчинг ордера
Для матчинга ордеров создается канал. Инициатор - биржа. Канал создается и тут же закрывается.
Трейдер получит при следующем заходе эти транзакции, подпишет их и запушит в блокчейн.
### match_netting_execution_settlement
##### Параметры
|тип|описание|ограничения|
|:-:|:------:|:---------:|
|string|xpub клиента|соответствие структуре xpub (префикс, длина)|
|Coin(enum)|индекс токена|-|
|long(int64)|сумма|-|
##### Результат
```javascript
{
funding: transaction, // транзакция финансирования
init: transaction, // транзакция утсановки начального состояния
close: transaction // транзакция закрытия канала
}
```
##### Ошибки
* не нашлось баланса для финансирования
```json
{
"code": 400,
"message": "insufficient funds"
}
```
## Выключение канала
Аварийное выключение канала в случае жульничества со стороны трейдера или
в результате пуша транзакции последнего состояния (что вполне нормально,
просто теперь можно канал только закрыть)
### block_channel_revocation_execution
##### Параметры
|тип|описание|ограничения|
|:-:|:------:|:---------:|
|int64|id клиента|-|
|Coin(enum)|индекс токена|-|
|int|индекс канала|-|
|ReasonCode(enum)|reasonCode|-|
##### Результат
```json
{
"success": true
}
```
##### Ошибки
* все поломалось
```json
{
"code": 500,
"message": "internal error"
}
```
## Вывод средств
Вывод средств - создание транзакции закрытия и ее подпись
### withdraw_request_user_execution
##### Параметры
|тип|описание|ограничения|
|:-:|:------:|:---------:|
|Coin(enum)|индекс токена|-|
|int|индекс канала|-|
|transaction(serialized)|транзакция закрытия|Описаны [здесь](#требования-к-транзакции-закрытия)|
##### Результат
```javascript
{
close: transaction (serialized)
}
```
##### Ошибки
### withdraw_request_execution_settlement
##### Параметры
|тип|описание|ограничения|
|:-:|:------:|:---------:|
|int|id клиента|-|
|Coin(enum)|индекс токена|-|
|int|индекс канала|-|
|transaction(serialized)|транзакция закрытия|Описаны [здесь](#требования-к-транзакции-закрытия)|
##### Результат
```javascript
{
close: transaction
}
```
##### Ошибки
* нет выхода на биржу
```json
{
"code": 400,
"message": "missing exchange output"
}
```
* неправильная подпись в транзакции
```json
{
"code": 400,
"message": "wrong close signature"
}
```
* неправильный вход
```json
{
"code": 400,
"message": "wrong inputs close transaction"
}
```
### withdraw_request_settlement_revocation
##### Параметры
|тип|описание|ограничения|
|:-:|:------:|:---------:|
|string|адрес redeem-скрипта|соответствие структуре адреса скрипта|
##### Результат
```json
{
"success": true
}
```
##### Ошибки
* все поломалось
```json
{
"code": 500,
"message": "internal error"
}
```
### Требования к транзакции закрытия
##### Входы
Строго один - выход транзакции финансирования с multisig-скриптом
##### Выходы
Один из них обязательно на адрес биржи
##### Скрипт
Дополнительных требований нет
### ER модель

## Ландшафт
В общем виде имеем `DEV → QA → QC → PRD` // QC для внешних аудиторов
Для оптимизации комуникации в удаленной команде - предлагаю договорится и как можно быстрее подготовить прототип рабочей среды для DEV системы, дающей возможность запускать все компоненты всем участникам
**DEV среда**
Предлагаемая конфигурация среды на основе контейнеров, запускаемая и собираемая в соответствии со сценарием роя
Network - 10.10.0.1/24
| **runtime_type** | **runtime_name** | **domain** | **runtime_adr** | **runtime_ports** | **runtime_env** |
| ----------------- | ------------------------------ | ------------ | --------------- | ----------------- | --------------- |
| state_less_nginx | {dash, handler, modal}.keyless | Keyless | 10.10.0.1 | | |
| state_less_nginx | web.terminal.stan | Stan | 10.10.0.2 | | |
| state_full_chains | regtest.chains.stan | Stan/Keyless | 10.10.0.3 | | |
| state_less_erlang | pre_check.execution.stan | Stan | 10.10.0.4 | | |
| state_less_erlang | matching.execution.stan | Stan | 10.10.0.5 | | |
| state_less_erlang | common.stan | Stan | 10.10.0.6 | | |
| state_less_erlang | api.stan | Stan | 10.10.0.7 | | |
| state_less_golang | emitter.blockchain.stan | Stan | 10.10.0.8 | | |
| state_less_golang | collector.blockchain.stan | Stan | 10.10.0.9 | | |
| state_less_golang | emmiter.off_chain.stan | Stan | 10.10.0.10 | | |
| state_less_golang | collector.off_chain.stan | Stan | 10.10.0.11 | | |
| state_full_psql | accounts.storage.stan | Stan | 10.10.0.12 | | |
| state_full_golang | regtest.blockbook.keyless | Stan/Keyless | 10.10.0.13 | | |
| state_less_nginx | ui.portainer.stan | Stan/Keyless | 10.10.0.14 | | |
| state_less_nginx | ui.admin.stan | Stan | 10.10.0.15 | | |
**QA среда // задачи после устаканивания DEV**
Внтреннее тестирование, в процессе интеграции и перед внешним аудитом. В данном ландшафте, в целях исключения досадных ошибок придерживаемся стратегии максимальной мимикрирования под QC/PRD
Виртуальные машины для e_otp/базы, контейнерная среда для Golang микросервисов + единый контейнер для локальных тестовых блокчейн узлов
- e2e, нагрузочное и интеграционного(с публичными тест-нетами) тестирование, выявление граничной производительности компонентов системы, составление плана на работы следующего этапа
**QC среда**
Среда для внешнего тестирования, интеграция системы оркестрации клиента
- Внешний аудит, публичная тестовая среда
**PRD среда**
- Производство // **TBA**