Я тоже с этим недавно сталкивался. После проверки некоторых связанных проблем и документов временное решение для меня - перезапустить узел, который вы нашли Failed to invoke chaincode name "qscc"
в его журнале:
Вот соответствующий комментарий Маниша Сетхи для объяснения того, что происходит за запросом бухгалтерской книги:
Ledger предоставляет два набора API, один набор API относится к чтению состояний и манипулированию ими, а другой набор API относится к запросу состояния блокчейна (например, GetBlockByNumber
и GetTransactionByID
). Первый набор API предоставляется через имитатор транзакций и (предназначен для использования цепного кода во время моделирования транзакций), а второй набор API предоставляется в виде прямых API в интерфейсе бухгалтерской книги (и предназначен для клиентов, чтобы узнать состояние бухгалтерской книги ).
Принимая во внимание вышесказанное, неявное допущение в дизайне бухгалтерской книги заключалось в том, что единый маршрут ограничивает его использование только одним из вышеуказанного набора API. Цепной код ограничивается API-интерфейсами, связанными с состоянием, и клиенту, запрашивающему состояние книги, не потребуется создавать симулятор.
Однако на более высоких уровнях API-интерфейсы, связанные со статусом регистра, представляются через цепной код (точнее, qscc
), вышеприведенное предположение нарушается. Путь выполнения для ответа на запросы состояния книги получает симулятор транзакций до того, как он достигает кода qscc (который фактически не использует симулятор транзакций).
Более конкретно, дополнительное ограничение на эти два набора API связано с тем фактом, что два независимых внешних вызова любого из API бухгалтерской книги должны дать воспринимаемое понятие атомарной фиксации для хранилища блоков и состояния. Например, это не должно происходить, когда клиент запрашивает API GetBlockchainInfo
и обнаруживает, что блок номер 10 зафиксирован, но когда он отправляет последующий запрос состояния, запрос возвращает состояние с блока 9 (поскольку обновление состояния для блок 10 все еще находится на рассмотрении). Это реализуется парой блокировок. Одна блокировка синхронизирует состояние между имитацией и заданным коммитом, а другая синхронизирует вызовы, связанные с состоянием главной книги, с общей фиксацией. Это делается для достижения лучшей производительности путем остановки моделирования до минимума (только когда обновления фактически выгружаются на диск) за счет запросов, связанных с состоянием регистра. Поскольку qscc использует имитатор транзакций, вышеупомянутое взаимодействие приводит к сообщенной тупиковой ситуации. Я полагаю, что в будущем одним из предложений было представить API, связанные со статусом главной книги, через интерфейс grpc, который решит эту проблему. Однако ниже я приведу три варианта полноты ...
qscc путь, чтобы не завладеть имитатором транзакции (что также желательно в противном случае, так как имитатор транзакций является дорогим ресурсом, так как для синхронизации с фиксацией требуется блокировка чтения на указанном b, и, следовательно, его следует использовать только для симуляции транзакции ).
Альтернативное исправление может заключаться в реализации вышеупомянутого воспринимаемого понятия атомарной фиксации в хранилище блоков и состоянии с помощью одного более крупного уровня блокировки, но это повлияет на пропускную способность, а не желаемое решение.
Реализовать воспринимаемое понятие атомарного коммита, но по-другому ..., что требует некоторой значительной работы во взаимодействии между хранилищем главной книги и заявленной б. В скорлупе гайки, обнажая хранилище книги, двухфазный коммит. На первом шаге мы добавляем блок, а затем на втором шаге обновляем BlockchainInfo и blockindexes, синхронизированные с установленными обновлениями.
Учитывая вышесказанное, так как первый в любом случае желателен, мое предложение будет исправить это для 1.1 и 1.2.