# Keyless Observer Service
## Введение
Сервис представляет из себя кеширующую базу данных для нод различных блокчейнов, оптимизированную для массового обслуживания.
Кодовая база, которую берем за основу : https://github.com/trezor/blockbook
Сервис-монолит с встроенным хранилищем необходимо разделить на три микро-сервиса без хранения состояний.
Ключевыми сложностями является построение оптимальной структуры данных для каждого блокчейна и лаконичного и достаточного API.
## Этапы разработки(Вехи)
0. Создания слоя моделей данных для https://github.com/apple/foundationdb .
1. Из референсного сервиса - с внутренним хранилищем необходимо выделить сервис произволитель данных, который получает данные с rpc ноды, выбирает необходимые данные и транслирует их во внешние потребители(хранилище, пользовательский кеш). Предусмотреть возможность запуска сервиса для части нод, пере-запуска сервиса после останова. Сервис должен поддерживать работу с сервисом обнаружения сервисов hashicorp consul.
> **пока отложен**
> 2. Второй выделяемый сервис - потребитель, при старте запрашивает с базы набор идентификаторов необходимых данных, потребляемых клиентом и хранит в памяти процесса. При обновлении датасета уведомляет пользователя подписанного на датасет.
3. Третий сервис доставляет напрямую запрошенные данные клиенту.
4. Добавить TRON, EOS и LND(Тестовый и Продуктивной сети).
5. Добавить модель и API слой пользовательского пасспорта.
6. Добавить TS модель и сервисы производители для мониторинга за состоянием инфраструктуры.
## Структуры данных
Смена хранилища данных предпологает переработку кодовой базы с системы, разделение сервиса на стейтлесс приложение по работе с
Структуры данных для большинства блокчейнов уже определены, в референсном сервисе, модель предусматривает деление блокчейнов на два типа: UXTO модель(BTC) и модель пользовательских Аккаунтов(ETH).
На поздних этапах реализации будет добавленна модель для LND, EOS и TS.
## gRPC
REST и WS API трансформируем в gRPC
```grpc
service ChainService {
// 1. Get status: Returns current status of KeylessObserver and connected backend
rpc GetStatus(Empty) returns (Status) {}
// 2. Get address: Returns balances and transactions of an address.
// The returned transactions are sorted by block height, newest blocks first.
rpc GetAddress(AddressStateRequest) returns (stream AddressStateList) {}
// 3. Get transaction: Returns "normalized" data about transaction, which has the same general structure for all supported coins.
// It does not return coin specific fields (for example information about Zcash shielded addresses).
// 3.1. for Bitcoin-type coins
rpc GetTransactionUXTO(TxID) returns (TxDataUXTO)
// 3.2. for Ethereum-type coins
rpc GetTransactionETH(TxID) returns (TxDataETH)
// 4. Get transaction specific: Returns transaction data in the exact format as returned by backend,
// including all coin specific fields.
rpc GetTransactionSpecific(TxID) returns (TxDataSpecific)
// 5. Send transaction: Sends new transaction to backend
rpc SendTransaction(TxSignedHex) returns (TxResult)
// 6. Get utxo Returns array of unspent transaction outputs of address or xpub,
// applicable only for Bitcoin-type coins. By default, the list contains both confirmed and unconfirmed transactions.
// The query parameter confirmed-true disables return of unconfirmed transactions.
// The returned utxos are sorted by block height, newest blocks first.
// For xpubs the response also contains address and derivation path of the utxo.
rpc GetUTXO(Address) returns (stream Outputs)
// 7. Get block hash
rpc GetBlockHash(BlockHeight) returns (stream BlockHash)
// 8. Returns information about block with transactions, subject to paging.
rpc GetBlock(Block) returns (BlockInfo)
// 9. Returns Estimate Fees
rpc GetEstimateFee(NumberOfBlocks) return (stream EstimateFees)
}
```