Перейти к основному содержимому

@hlf-core/transport

Транспорт в hlf-core намеренно разнесён на три пакета, и прежде чем говорить о клиенте, стоит назвать всю тройку. @hlf-core/transport-common держит протокол — конверты, подпись, nonce, константы. @hlf-core/transport-chaincode это сторона chaincode. А @hlf-core/transport, о котором здесь и речь, это клиентская сторона. Общий пакет посередине не роскошь: он гарантирует, что клиент и chaincode говорят на одном и том же языке конвертов.

Главный класс — TransportFabric, наследник TransportImpl из @ts-core. Отсюда и привычные connect, send, sendListen, и доступ к api: FabricApiClient. По флагу isReadonly транспорт сам выбирает, вызвать evaluate или submit, так что прикладному коду об этом думать не нужно. Если chaincode бросил доменную ошибку, parseChaincodeError восстанавливает её из обёртки Fabric обратно в ExtendedError с кодом — то есть ровно в том виде, в каком её бросил обработчик.

const transport = new TransportFabric(logger, settings);
await transport.connect();
const user = await transport.sendListen(new UserGetCommand(uid));
await transport.sendListen(new UserAddCommand(dto), {userId, signature});

Ответ на изменяющую команду приходит не сразу, а из блока, и разбирает его TransportFabricBlockParser. Он превращает блок в типизированный ITransportFabricBlock и связывает события с транзакциями по хэшу, так что у события появляются requestId и код валидации. По requestId клиент и сопоставляет пришедший ответ с исходной командой.

Отдельно стоит batch-режим — TransportFabricBatch и TransportFabricBlockParserBatch. В нём изменяющие команды не ждут ответа поодиночке: chaincode накапливает их и исполняет одной транзакцией, а ответы приходят позже, из блока, как карта «хэш → ответ». Это тот случай, когда мы сознательно жертвуем мгновенностью ответа ради пропускной способности и стоимости endorsement. Readonly-команды в batch не попадают — им это и не нужно.

Настройки подключения клиентского транспорта (ITransportFabricConnectionSettings) добавляют к настройкам сети параметры переподключения, и здесь стоит знать об одном умолчании: isExitApplicationOnDisconnect включён, то есть при разрыве соединения процесс по умолчанию завершается. Поведение разумное для сервиса под присмотром оркестратора, но знать о нём нужно заранее.