首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >锯齿验证器没有注册自定义事务处理器。记录“for该类型”消息

锯齿验证器没有注册自定义事务处理器。记录“for该类型”消息
EN

Stack Overflow用户
提问于 2022-03-23 13:25:11
回答 2查看 159关注 0票数 1

我正试图为锯齿树构建一个自定义事务处理程序,但是我遇到了一堵墙,从那时起我就一直被困在那里。我使用本地计算机(使用本指南)上的对接器创建了锯齿测试网络。为了测试我的自定义事务处理器,我修改了对接器撰写文件,以便将验证器-0和rest-api-0的端口发布到主机上。我试着从浏览器中访问rest,它运行得很好。但是,当我试图运行自定义事务处理器时,问题就会发生。验证器终端上的日志显示如下消息:

代码语言:javascript
复制
sawtooth-validator-default-0 | [2022-03-23 13:17:21.492 INFO     dispatch] received a message of type TP_REGISTER_REQUEST from d9de3f928215c306cf719fba501bae475c209cb41cad6efd55b410d7918dfe657f0f9211580c8b3249baec3aaf87d0fc84b58aee1c1501b8c65a7c8fc1ad14f8 but have no handler for that type

修改后的docker组合文件如下

代码语言:javascript
复制
# Copyright 2019 Cargill Incorporated
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

version: '3.6'

volumes:
  pbft-shared:

services:

# -------------=== rest api ===-------------

  rest-api-0:
    image: hyperledger/sawtooth-rest-api:nightly
    container_name: sawtooth-rest-api-default-0
    # expose:
    #   - 8008
    ports:
        - 8008:8008
    command: |
      bash -c "
        sawtooth-rest-api \
          --connect tcp://validator-0:4004 \
          --bind rest-api-0:8008
      "
    stop_signal: SIGKILL

  rest-api-1:
    image: hyperledger/sawtooth-rest-api:nightly
    container_name: sawtooth-rest-api-default-1
    expose:
      - 8008
    command: |
      bash -c "
        sawtooth-rest-api \
          --connect tcp://validator-1:4004 \
          --bind rest-api-1:8008
      "
    stop_signal: SIGKILL

  rest-api-2:
    image: hyperledger/sawtooth-rest-api:nightly
    container_name: sawtooth-rest-api-default-2
    expose:
      - 8008
    command: |
      bash -c "
        sawtooth-rest-api \
          --connect tcp://validator-2:4004 \
          --bind rest-api-2:8008
      "
    stop_signal: SIGKILL

  rest-api-3:
    image: hyperledger/sawtooth-rest-api:nightly
    container_name: sawtooth-rest-api-default-3
    expose:
      - 8008
    command: |
      bash -c "
        sawtooth-rest-api \
          --connect tcp://validator-3:4004 \
          --bind rest-api-3:8008
      "
    stop_signal: SIGKILL

  rest-api-4:
    image: hyperledger/sawtooth-rest-api:nightly
    container_name: sawtooth-rest-api-default-4
    expose:
      - 8008
    command: |
      bash -c "
        sawtooth-rest-api \
          --connect tcp://validator-4:4004 \
          --bind rest-api-4:8008
      "
    stop_signal: SIGKILL

# -------------=== shell ===-------------

  shell:
    image: hyperledger/sawtooth-shell:nightly
    container_name: sawtooth-shell-default
    volumes:
      - pbft-shared:/pbft-shared
    command: |
      bash -c "
        sawtooth keygen
        tail -f /dev/null
      "
    stop_signal: SIGKILL

# -------------=== validators ===-------------

  validator-0:
    image: hyperledger/sawtooth-validator:nightly
    container_name: sawtooth-validator-default-0
    # expose:
    #   - 4004
    #   - 5050
    #   - 8800
    ports:
        - "4004:4004"
        - "5050:5050"
        - "8800:8800"
    volumes:
      - pbft-shared:/pbft-shared
    command: |
      bash -c "
        if [ -e /pbft-shared/validators/validator-0.priv ]; then
          cp /pbft-shared/validators/validator-0.pub /etc/sawtooth/keys/validator.pub
          cp /pbft-shared/validators/validator-0.priv /etc/sawtooth/keys/validator.priv
        fi &&
        if [ ! -e /etc/sawtooth/keys/validator.priv ]; then
          sawadm keygen
          mkdir -p /pbft-shared/validators || true
          cp /etc/sawtooth/keys/validator.pub /pbft-shared/validators/validator-0.pub
          cp /etc/sawtooth/keys/validator.priv /pbft-shared/validators/validator-0.priv
        fi &&
        if [ ! -e config-genesis.batch ]; then
          sawset genesis -k /etc/sawtooth/keys/validator.priv -o config-genesis.batch
        fi &&
        while [[ ! -f /pbft-shared/validators/validator-1.pub || \
                 ! -f /pbft-shared/validators/validator-2.pub || \
                 ! -f /pbft-shared/validators/validator-3.pub || \
                 ! -f /pbft-shared/validators/validator-4.pub ]];
        do sleep 1; done
        echo sawtooth.consensus.pbft.members=\\['\"'$$(cat /pbft-shared/validators/validator-0.pub)'\"','\"'$$(cat /pbft-shared/validators/validator-1.pub)'\"','\"'$$(cat /pbft-shared/validators/validator-2.pub)'\"','\"'$$(cat /pbft-shared/validators/validator-3.pub)'\"','\"'$$(cat /pbft-shared/validators/validator-4.pub)'\"'\\] &&
        if [ ! -e config.batch ]; then
         sawset proposal create \
            -k /etc/sawtooth/keys/validator.priv \
            sawtooth.consensus.algorithm.name=pbft \
            sawtooth.consensus.algorithm.version=1.0 \
            sawtooth.consensus.pbft.members=\\['\"'$$(cat /pbft-shared/validators/validator-0.pub)'\"','\"'$$(cat /pbft-shared/validators/validator-1.pub)'\"','\"'$$(cat /pbft-shared/validators/validator-2.pub)'\"','\"'$$(cat /pbft-shared/validators/validator-3.pub)'\"','\"'$$(cat /pbft-shared/validators/validator-4.pub)'\"'\\] \
            sawtooth.publisher.max_batches_per_block=1200 \
            -o config.batch
        fi &&
        if [ ! -e /var/lib/sawtooth/genesis.batch ]; then
          sawadm genesis config-genesis.batch config.batch
        fi &&
        if [ ! -e /root/.sawtooth/keys/my_key.priv ]; then
          sawtooth keygen my_key
        fi &&
        sawtooth-validator -vv \
          --endpoint tcp://validator-0:8800 \
          --bind component:tcp://eth0:4004 \
          --bind consensus:tcp://eth0:5050 \
          --bind network:tcp://eth0:8800 \
          --scheduler parallel \
          --peering static \
          --maximum-peer-connectivity 10000
      "

  validator-1:
    image: hyperledger/sawtooth-validator:nightly
    container_name: sawtooth-validator-default-1
    expose:
      - 4004
      - 5050
      - 8800
    volumes:
      - pbft-shared:/pbft-shared
    command: |
      bash -c "
        if [ -e /pbft-shared/validators/validator-1.priv ]; then
          cp /pbft-shared/validators/validator-1.pub /etc/sawtooth/keys/validator.pub
          cp /pbft-shared/validators/validator-1.priv /etc/sawtooth/keys/validator.priv
        fi &&
        if [ ! -e /etc/sawtooth/keys/validator.priv ]; then
          sawadm keygen
          mkdir -p /pbft-shared/validators || true
          cp /etc/sawtooth/keys/validator.pub /pbft-shared/validators/validator-1.pub
          cp /etc/sawtooth/keys/validator.priv /pbft-shared/validators/validator-1.priv
        fi &&
        sawtooth keygen my_key &&
        sawtooth-validator -vv \
          --endpoint tcp://validator-1:8800 \
          --bind component:tcp://eth0:4004 \
          --bind consensus:tcp://eth0:5050 \
          --bind network:tcp://eth0:8800 \
          --scheduler parallel \
          --peering static \
          --maximum-peer-connectivity 10000 \
          --peers tcp://validator-0:8800
      "

  validator-2:
    image: hyperledger/sawtooth-validator:nightly
    container_name: sawtooth-validator-default-2
    expose:
      - 4004
      - 5050
      - 8800
    volumes:
      - pbft-shared:/pbft-shared
    command: |
      bash -c "
        if [ -e /pbft-shared/validators/validator-2.priv ]; then
          cp /pbft-shared/validators/validator-2.pub /etc/sawtooth/keys/validator.pub
          cp /pbft-shared/validators/validator-2.priv /etc/sawtooth/keys/validator.priv
        fi &&
        if [ ! -e /etc/sawtooth/keys/validator.priv ]; then
          sawadm keygen
          mkdir -p /pbft-shared/validators || true
          cp /etc/sawtooth/keys/validator.pub /pbft-shared/validators/validator-2.pub
          cp /etc/sawtooth/keys/validator.priv /pbft-shared/validators/validator-2.priv
        fi &&
        sawtooth keygen my_key &&
        sawtooth-validator -vv \
          --endpoint tcp://validator-2:8800 \
          --bind component:tcp://eth0:4004 \
          --bind consensus:tcp://eth0:5050 \
          --bind network:tcp://eth0:8800 \
          --scheduler parallel \
          --peering static \
          --maximum-peer-connectivity 10000 \
          --peers tcp://validator-0:8800 \
          --peers tcp://validator-1:8800
      "

  validator-3:
    image: hyperledger/sawtooth-validator:nightly
    container_name: sawtooth-validator-default-3
    expose:
      - 4004
      - 5050
      - 8800
    volumes:
      - pbft-shared:/pbft-shared
    command: |
      bash -c "
        if [ -e /pbft-shared/validators/validator-3.priv ]; then
         cp /pbft-shared/validators/validator-3.pub /etc/sawtooth/keys/validator.pub
         cp /pbft-shared/validators/validator-3.priv /etc/sawtooth/keys/validator.priv
        fi &&
        if [ ! -e /etc/sawtooth/keys/validator.priv ]; then
         sawadm keygen
         mkdir -p /pbft-shared/validators || true
         cp /etc/sawtooth/keys/validator.pub /pbft-shared/validators/validator-3.pub
         cp /etc/sawtooth/keys/validator.priv /pbft-shared/validators/validator-3.priv
        fi &&
        sawtooth keygen my_key &&
        sawtooth-validator -vv \
          --endpoint tcp://validator-3:8800 \
          --bind component:tcp://eth0:4004 \
          --bind consensus:tcp://eth0:5050 \
          --bind network:tcp://eth0:8800 \
          --scheduler parallel \
          --peering static \
          --maximum-peer-connectivity 10000 \
          --peers tcp://validator-0:8800 \
          --peers tcp://validator-1:8800 \
          --peers tcp://validator-2:8800
      "

  validator-4:
    image: hyperledger/sawtooth-validator:nightly
    container_name: sawtooth-validator-default-4
    expose:
      - 4004
      - 5050
      - 8800
    volumes:
      - pbft-shared:/pbft-shared
    command: |
      bash -c "
        if [ -e /pbft-shared/validators/validator-4.priv ]; then
          cp /pbft-shared/validators/validator-4.pub /etc/sawtooth/keys/validator.pub
          cp /pbft-shared/validators/validator-4.priv /etc/sawtooth/keys/validator.priv
        fi &&
        if [ ! -e /etc/sawtooth/keys/validator.priv ]; then
          sawadm keygen
          mkdir -p /pbft-shared/validators || true
          cp /etc/sawtooth/keys/validator.pub /pbft-shared/validators/validator-4.pub
          cp /etc/sawtooth/keys/validator.priv /pbft-shared/validators/validator-4.priv
        fi &&
        sawtooth keygen my_key &&
        sawtooth-validator -vv \
          --endpoint tcp://validator-4:8800 \
          --bind component:tcp://eth0:4004 \
          --bind consensus:tcp://eth0:5050 \
          --bind network:tcp://eth0:8800 \
          --scheduler parallel \
          --peering static \
          --maximum-peer-connectivity 10000 \
          --peers tcp://validator-0:8800 \
          --peers tcp://validator-1:8800 \
          --peers tcp://validator-2:8800 \
          --peers tcp://validator-3:8800
      "

# -------------=== pbft engines ===-------------

  pbft-0:
    image: hyperledger/sawtooth-pbft-engine:nightly
    container_name: sawtooth-pbft-engine-default-0
    command: pbft-engine -vv --connect tcp://validator-0:5050
    stop_signal: SIGKILL

  pbft-1:
    image: hyperledger/sawtooth-pbft-engine:nightly
    container_name: sawtooth-pbft-engine-default-1
    command: pbft-engine -vv --connect tcp://validator-1:5050
    stop_signal: SIGKILL

  pbft-2:
    image: hyperledger/sawtooth-pbft-engine:nightly
    container_name: sawtooth-pbft-engine-default-2
    command: pbft-engine -vv --connect tcp://validator-2:5050
    stop_signal: SIGKILL

  pbft-3:
    image: hyperledger/sawtooth-pbft-engine:nightly
    container_name: sawtooth-pbft-engine-default-3
    command: pbft-engine -vv --connect tcp://validator-3:5050
    stop_signal: SIGKILL

  pbft-4:
    image: hyperledger/sawtooth-pbft-engine:nightly
    container_name: sawtooth-pbft-engine-default-4
    command: pbft-engine -vv --connect tcp://validator-4:5050
    stop_signal: SIGKILL

事务处理器的代码如下

代码语言:javascript
复制
import sys

from sawtooth_sdk.processor.core import TransactionProcessor
from sawtooth_sdk.processor.handler import TransactionHandler

from transaction_family import TransactionPayload, State, InvalidAction, \
    NAMESPACE, NAME, VERSION

import logging

logger = logging.getLogger(__name__)


class CustomTransactionHandler(TransactionHandler):

    @property
    def family_name(self):
        return NAME

    @property
    def family_versions(self):
        return [VERSION]

    @property
    def namespaces(self):
        return [NAMESPACE]

    # The argument transaction is an instance of the class Transaction that
    # is created from the protobuf definition. Also, context is an instance of
    # the class Context from the python SDK.
    def apply(self, transaction, context):
        logger.error("inside apply")
        header = transaction.header
        signer = header.signer_public_key

        print(transaction.payload)

        transaction = TransactionPayload.from_bytes(transaction.payload)
        state = State(context)

        if transaction.action == 'insert':
            state.insert(transaction.key, transaction.value)
            pass
        elif transaction.action == 'delete':
            state.delete(transaction.key)
            pass
        else:
            raise InvalidAction(transaction.action)


def main():
    processor = TransactionProcessor(url="tcp://localhost:4004")
    processor.add_handler(CustomTransactionHandler())
    processor.start()


if __name__ == '__main__':
    logging.basicConfig(filename='example.log',
                        level=logging.DEBUG)
    logger.setLevel(logging.INFO)
    logger.info("hello")
    main()

交易族模块如下:

代码语言:javascript
复制
import hashlib
import sys

import cbor2

NAME = 'custom'
NAMESPACE = hashlib.sha512(NAME.encode('utf-8')).hexdigest()[:6]
VERSION = '1.0'


def generate_address(key):
    return NAMESPACE + hashlib.sha512(str(key).encode('utf-8')).hexdigest()[
                       -64:]


class TransactionPayload:

    def __init__(self, payload):
        action, key, value = cbor2.loads(payload)
        self._action = action
        self._key = int(key)
        self._value = int(value)

    @property
    def action(self):
        return self._action

    @property
    def key(self):
        return self._key

    @property
    def value(self):
        return self._value

    @classmethod
    def from_bytes(cls, payload):
        return cls(payload)


class State:

    def __init__(self, context):
        self._context = context

    def insert(self, key, value):
        address = generate_address(key)
        n_req_bytes = (value.bit_length() + 7) // 8
        self._context.set_state({address: value.to_bytes(n_req_bytes,
                                                         sys.byteorder)})

    def delete(self, key):
        address = generate_address(key)
        self._context.delete_state([address])


class InvalidAction(Exception):
    def __init__(self, msg):
        self._msg = msg

    def __str__(self):
        return self._msg

最后,下面是我试图访问rest的客户机:

代码语言:javascript
复制
import random
from hashlib import sha512
import requests
import cbor2
from sawtooth_sdk.protobuf.batch_pb2 import BatchHeader, Batch, BatchList
from sawtooth_sdk.protobuf.transaction_pb2 import TransactionHeader, Transaction
from sawtooth_signing import create_context
from sawtooth_signing import CryptoFactory
from transaction_family import generate_address, NAME, VERSION
import secrets

context = create_context('secp256k1')
private_key = context.new_random_private_key()
print(private_key)
signer = CryptoFactory(context).new_signer(private_key)


def insert(key, val):
    payload_bytes = cbor2.dumps(['insert', key, val])
    address = generate_address(key)

    txn_header_bytes = TransactionHeader(
        family_name=NAME,
        family_version=VERSION,
        inputs=[address],
        outputs=[address],
        signer_public_key=signer.get_public_key().as_hex(),
        batcher_public_key=signer.get_public_key().as_hex(),
        dependencies=[],
        payload_sha512=sha512(payload_bytes).hexdigest(),
        nonce=secrets.token_hex(16),
        # nonce=hex(random.randint(0, 2**64))
    ).SerializeToString()
    signature = signer.sign(txn_header_bytes)
    txn = Transaction(header=txn_header_bytes,
                      header_signature=signature,
                      payload=payload_bytes)

    txns = [txn]
    batch_header_bytes = BatchHeader(
        signer_public_key=signer.get_public_key().as_hex(),
        transaction_ids=[txn.header_signature for txn in txns]
    ).SerializeToString()
    signature = signer.sign(batch_header_bytes)
    batch = Batch(
        header=batch_header_bytes,
        header_signature=signature,
        transactions=txns,
        trace=True
    )

    batch_list_bytes = BatchList(batches=[batch]).SerializeToString()

    print(batch_list_bytes)

    # send request
    resp = requests.post(
        'http://localhost:8008/batches',
        headers={'Content-Type': 'application/octet-stream'},
        data=batch_list_bytes)

    print(resp)
    print(resp.json())


def main():
    insert(1, 2)


if __name__ == '__main__':
    main()
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-05-03 15:29:46

我解决了问题。这是我的一个错误。我试图只运行事务处理器的一个实例。但是,每个节点都需要事务处理器的一个实例。一旦我修改了我的docker文件以包含所有五个节点的事务处理器,它就像预期的那样工作了。

如果其他人面临类似的问题,请发布这个答案。

票数 0
EN

Stack Overflow用户

发布于 2022-04-04 10:16:55

我看到你使用夜间版本的对接者图像。

夜间版本是一个由开发人员更新的版本,它不一定是一个稳定的版本。

相反,我建议您每晚替换为最新版本,这是一个更稳定的版本。我已经遇到了问题,这是我找到的让您的处理器向验证器注册的唯一方法。

您可以从docker网站上找到版本:https://hub.docker.com/u/hyperledger

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71588044

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档