Устройство сети: организации, политики, блоки
Зачем это нужно
В прошлой главе сеть поднялась одной командой, и канал создался второй. Это удобно, пока всё работает. Как только что-то откажет — а откажет обязательно, — придётся понимать, что именно эти команды сделали.
Настройки канала не спрятаны в конфигурационном файле на диске. Они лежат внутри самого канала, в его первом блоке, и меняются такой же транзакцией, как любая запись. Достать их можно в любой момент и прочитать глазами.
Эта глава — про то, что там лежит: кто состоит в канале, по каким правилам принимаются решения, как из потока сделок получаются блоки и почему у Fabric нет откатов.
Достаём настройки канала
peer channel fetch config config_block.pb -o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
-c pgk --tls --cafile "$ORDERER_CA"
INFO [cli.common] readBlock -> Received block: 2
Двоичный файл превращается в читаемый JSON отдельной утилитой:
configtxlator proto_decode --input config_block.pb --type common.Block --output config.json
configtxlator — «переводчик» между двоичным форматом и JSON в обе стороны. Именно через него меняют настройки канала: скачали, перевели в JSON, поправили, перевели обратно, отправили как транзакцию.
Кто состоит в канале
В расшифрованных настройках интересна ветка channel_group.groups.Application:
организации канала: Org1MSP, Org2MSP
Две организации. Каждая описана своим MSP — набором сертификатов, по которым сеть узнаёт «своих». Английское сокращение расшифровывается как «поставщик услуг членства», но по сути это ответ на вопрос: какие подписи считать подписями этой организации.
Личность одного участника — четыре вещи в папке:
signcerts/— сертификат: кто вы, из какой организации, какая роль;keystore/— закрытый ключ, которым подписываются запросы;cacerts/— корневой сертификат организации: кем вы заверены;tlscacerts/— корень для шифрования соединения.
Роль записана прямо в сертификате, в поле подразделения:
subject=... OU=admin, CN=Admin@org1.example.com ← человек-администратор
subject=... OU=peer, CN=peer0.org1.example.com ← узел
Роль — не пометка для красоты. Политики ссылаются именно на неё: «подтверждать сделки может только PEER», «менять настройки — только ADMIN». Выдали человеку сертификат с ролью peer — он получил права узла.
Политики: два уровня
Самое важное место настроек — политики. Здесь легко запутаться, потому что они двухуровневые.
Уровень канала — правила вида «сколько организаций должны согласиться»:
Readers → ANY of Readers
Writers → ANY of Writers
Endorsement → MAJORITY of Endorsement
LifecycleEndorsement → MAJORITY of LifecycleEndorsement
Admins → MAJORITY of Admins
Читается так: «чтобы прочитать — достаточно любой организации; чтобы подтвердить сделку — нужно большинство организаций».
Уровень организации — правила вида «чьи подписи считаются подписью организации»:
Org1MSP:
Endorsement → Org1MSP/PEER
Writers → Org1MSP/ADMIN, Org1MSP/CLIENT
Readers → Org1MSP/ADMIN, Org1MSP/PEER, Org1MSP/CLIENT
Admins → Org1MSP/ADMIN
Сложим два уровня. Правило «подтвердить сделку» на канале — MAJORITY of Endorsement. Организаций две, большинство из двух — это две. Правило Endorsement у каждой организации — подпись её пира. Итого: сделку должны подписать пиры обеих организаций. Это и есть тот самый ответ, из-за которого в следующих главах будут отказы.
Двухуровневость — не усложнение ради усложнения. Она позволяет добавить в канал третью организацию, ничего не переписывая на верхнем уровне: правило MAJORITY само начнёт означать «двое из трёх».
Опорный пир
В настройках каждой организации есть отдельное поле:
anchor peers Org1: {"anchor_peers":[{"host":"peer0.org1.example.com","port":7051}]}
Опорный пир — тот узел организации, через который с ней знакомятся пиры других организаций. Пиры внутри канала непрерывно обмениваются сведениями о том, кто жив и у кого какая высота цепочки. Чтобы этот обмен начался между разными организациями, каждая должна объявить хотя бы один адрес, доступный снаружи.
Забыть объявить опорный пир — классическая ошибка. Сеть при этом работает: каждая организация живёт своей жизнью, блоки получает от упорядочивателя. Не работает ровно одно — сбор подписей с чужих пиров, потому что клиент не знает их адресов. Проявляется это на первой же сделке, требующей двух подписей.
В учебной сети network.sh createChannel объявляет опорные пиры сам — в выводе видны строки Anchor peer set for org 'Org1MSP'. В настоящей сети это отдельный шаг.
Как получаются блоки
В открытой сети блок появляется, когда кто-то выиграл соревнование. Здесь соревнования нет: блок собирает назначенная служба по трём простым правилам.
В настройках это выглядит так:
BatchTimeout: {"timeout":"2s"}
BatchSize: {"max_message_count":10, "preferred_max_bytes":524288, "absolute_max_bytes":103809024}
Отсюда два следствия, которые видно на практике сразу. Одиночная команда выполняется до двух секунд — это не тормоза, это таймаут пачки. А под нагрузкой задержка падает: блок закрывается по счётчику раньше таймаута.
Почему нет откатов
Тип согласия между упорядочивателями записан там же:
тип согласия: etcdraft
Это алгоритм с выбранным лидером: один упорядочиватель ведёт, остальные повторяют за ним и следят, жив ли он. Умер лидер — оставшиеся выбирают нового. Никаких параллельных цепочек при этом не возникает.
Отсюда главное практическое отличие от открытых сетей: окончательность наступает сразу. Сделка попала в блок — значит попала. Нет понятия «дождитесь двенадцати подтверждений», нет ситуации «более длинная ветка победила и ваша сделка исчезла». Вся логика ожидания, которую в открытых сетях пишут вокруг подтверждений, здесь не нужна.
Ценой этому — доверие к составу упорядочивателей. Если все они принадлежат одной организации, она может перестать принимать чужие сделки. Поэтому в настоящей сети упорядочиватели держат разные организации, и это вопрос договора, а не алгоритма.
Проверить окончательность легко — высота цепочки растёт монотонно:
peer channel getinfo -c pgk
Blockchain info: {"height":16,"currentBlockHash":"oBJv5Ze+nYyrtkzhdRYCJbsG2DhMkoxS3+5nG0r0mdI=","previousBlockHash":"+miykifz3th0/2OROHtXRRV998Z5oF1LeVLh8jDEjwo="}
Типичные ошибки
Ошибка 1. Имя в сертификате не совпало с адресом.
Error: failed to create deliver client for orderer: orderer client failed to connect to
localhost:7050: failed to create new connection: context deadline exceeded
Стучимся на localhost, а в сертификате упорядочивателя написано orderer.example.com. Лечится флагом --ordererTLSHostnameOverride orderer.example.com — он есть почти в каждой команде этой главы и выглядит как шум ровно до первого такого отказа.
Ошибка 2. Забыли --tls и --cafile.
Учебная сеть поднята с обязательным шифрованием. Без этих флагов соединение не установится вообще, а сообщение будет про таймаут — то есть совершенно не про причину.
Ошибка 3. Попытка прочитать .pb глазами.
Блок настроек — двоичный protobuf. cat покажет мусор. Нужен configtxlator proto_decode.
Ошибка 4. Правка политики на нижнем уровне вместо верхнего.
Хотели «пусть подтверждать может одна организация», полезли в Org1MSP и поменяли там. Не сработает: «сколько организаций» задаётся на уровне канала (MAJORITY → ANY), а внутри организации написано только, чья подпись годится.
Шпаргалка по главе
| Что нужно | Команда |
|---|---|
| Скачать настройки канала | peer channel fetch config c.pb -c pgk --tls --cafile "$ORDERER_CA" |
| Перевести в JSON | configtxlator proto_decode --input c.pb --type common.Block |
| Перевести обратно | configtxlator proto_encode --input c.json --type common.Config |
| Высота цепочки | peer channel getinfo -c pgk |
| Скачать любой блок | peer channel fetch 5 b5.pb -c pgk |
| Скачать последний блок | peer channel fetch newest last.pb -c pgk |
| Посмотреть роль в сертификате | openssl x509 -in cert.pem -noout -subject |
Словарь главы
| Термин | Что это |
|---|---|
| Блок настроек | Блок канала, в котором лежит его конфигурация; таких блоков за жизнь канала несколько |
configtxlator | Переводчик между двоичным форматом и JSON в обе стороны |
| Политика канала | Правило «сколько организаций должны согласиться»: ANY или MAJORITY |
| Политика организации | Правило «чья подпись считается подписью организации»: роли ADMIN, PEER, CLIENT |
| Опорный пир | Узел, по адресу которого с организацией знакомятся пиры остальных |
BatchTimeout | Сколько ждать перед закрытием блока — в учебной сети 2 секунды |
etcdraft | Согласие упорядочивателей с выбранным лидером; отсюда окончательность без подтверждений |
| Окончательность | Свойство сети: попавшая в блок сделка не может исчезнуть из-за другой ветки |
Цель: скорость ≥ 90 зн/мин, точность ≥ 88%
peer channel fetch config config_block.pb -c pgk
Что должен уметь после главы
- скачать настройки канала и перевести их в читаемый вид;
- назвать организации канала и прочитать их политики;
- сложить два уровня политик и сказать, сколько подписей нужно на сделку;
- объяснить, зачем нужен опорный пир и что сломается без него;
- назвать три условия закрытия блока и объяснить задержку в две секунды;
- объяснить, почему в Fabric не бывает откатов и чем за это платят.
Проверка по главе
Сводная проверка по всей главе: 10 вопросов, 5:00 на всё, без подсказок по ходу. Вопросы показываются по одному, ответ изменить нельзя. Если время выйдет — экзамен завершится с тем, что успел ответить. Пересдавать можно сколько угодно раз.
Куда дальше: проверенные ресурсы
- Политики Fabric — два уровня и все виды правил.
- Membership Service Provider — что такое MSP и как устроена личность.
- Обновление настроек канала — весь цикл через
configtxlator. - Служба упорядочивания — Raft, нарезка блоков, окончательность.
Комментарии
Обсуждение живёт в GitHub Discussions и грузится с чужого домена — поэтому только по нажатию.