Пример #1
0
class PrePrepare(MessageBase):
    typename = PREPREPARE
    schema = (
        (f.INST_ID.nm, NonNegativeNumberField()),
        (f.VIEW_NO.nm, NonNegativeNumberField()),
        (f.PP_SEQ_NO.nm, NonNegativeNumberField()),
        (f.PP_TIME.nm, TimestampField()),
        (f.REQ_IDR.nm,
         IterableField(
             LimitedLengthStringField(max_length=DIGEST_FIELD_LIMIT))),
        (f.DISCARDED.nm, NonNegativeNumberField()),
        (f.DIGEST.nm, LimitedLengthStringField(max_length=DIGEST_FIELD_LIMIT)),
        (f.LEDGER_ID.nm, LedgerIdField()),
        (f.STATE_ROOT.nm, MerkleRootField(nullable=True)),
        (f.TXN_ROOT.nm, MerkleRootField(nullable=True)),
        # TODO: support multiple multi-sigs for multiple previous batches
        (f.BLS_MULTI_SIG.nm,
         BlsMultiSignatureField(optional=True, nullable=True)),
        (f.PLUGIN_FIELDS.nm, AnyMapField(optional=True, nullable=True)),
    )
Пример #2
0
class Prepare(MessageBase):
    typename = PREPARE
    schema = (
        (f.INST_ID.nm, NonNegativeNumberField()),
        (f.VIEW_NO.nm, NonNegativeNumberField()),
        (f.PP_SEQ_NO.nm, NonNegativeNumberField()),
        (f.PP_TIME.nm, TimestampField()),
        (f.DIGEST.nm, LimitedLengthStringField(max_length=DIGEST_FIELD_LIMIT)),
        (f.STATE_ROOT.nm, MerkleRootField(nullable=True)),
        (f.TXN_ROOT.nm, MerkleRootField(nullable=True)),
    )
Пример #3
0
class Commit(MessageBase):
    typename = COMMIT
    schema = (
        (f.INST_ID.nm, NonNegativeNumberField()),
        (f.VIEW_NO.nm, NonNegativeNumberField()),
        (f.PP_SEQ_NO.nm, NonNegativeNumberField()),
        (f.BLS_SIG.nm,
         LimitedLengthStringField(max_length=BLS_SIG_LIMIT, optional=True)),
        # PLUGIN_FIELDS is not used in Commit as of now but adding for
        # consistency
        (f.PLUGIN_FIELDS.nm, AnyMapField(optional=True, nullable=True)))
Пример #4
0
class ClientNYMOperation(MessageValidator):
    schema = (
        (TXN_TYPE, ConstantField(NYM)),
        (ALIAS, LimitedLengthStringField(max_length=ALIAS_FIELD_LIMIT, optional=True)),
        (VERKEY, VerkeyField(optional=True)),
        (TARGET_NYM, DestNymField()),
        (ROLE, RoleField(optional=True)),
        # TODO: validate role using ChooseField,
        # do roles list expandable form outer context
    )
    schema_is_strict = False
Пример #5
0
class ConsistencyProof(MessageBase):
    typename = CONSISTENCY_PROOF
    schema = (
        (f.LEDGER_ID.nm, LedgerIdField()),
        (f.SEQ_NO_START.nm, NonNegativeNumberField()),
        (f.SEQ_NO_END.nm, NonNegativeNumberField()),
        (f.VIEW_NO.nm, NonNegativeNumberField()),
        (f.PP_SEQ_NO.nm, NonNegativeNumberField()),
        (f.OLD_MERKLE_ROOT.nm, MerkleRootField()),
        (f.NEW_MERKLE_ROOT.nm, MerkleRootField()),
        (f.HASHES.nm, IterableField(LimitedLengthStringField(max_length=HASH_FIELD_LIMIT))),
    )
Пример #6
0
class Ordered(MessageBase):
    typename = ORDERED
    schema = ((f.INST_ID.nm,
               NonNegativeNumberField()), (f.VIEW_NO.nm,
                                           NonNegativeNumberField()),
              (f.VALID_REQ_IDR.nm,
               IterableField(
                   LimitedLengthStringField(max_length=DIGEST_FIELD_LIMIT))),
              (f.INVALID_REQ_IDR.nm,
               IterableField(
                   LimitedLengthStringField(max_length=DIGEST_FIELD_LIMIT))),
              (f.PP_SEQ_NO.nm, NonNegativeNumberField()), (f.PP_TIME.nm,
                                                           TimestampField()),
              (f.LEDGER_ID.nm,
               LedgerIdField()), (f.STATE_ROOT.nm,
                                  MerkleRootField(nullable=True)),
              (f.TXN_ROOT.nm, MerkleRootField(nullable=True)),
              (f.AUDIT_TXN_ROOT_HASH.nm,
               MerkleRootField(nullable=True)), (f.PLUGIN_FIELDS.nm,
                                                 AnyMapField(optional=True,
                                                             nullable=True)))
Пример #7
0
class ClientAttribOperation(MessageValidator):
    schema = (
        (TXN_TYPE, ConstantField(ATTRIB)),
        (TARGET_NYM, IdentifierField(optional=True)),
        (RAW, JsonField(max_length=JSON_FIELD_LIMIT, optional=True)),
        (ENC,
         LimitedLengthStringField(max_length=ENC_FIELD_LIMIT, optional=True)),
        (HASH, Sha256HexField(optional=True)),
    )

    def _validate_message(self, msg):
        self._validate_field_set(msg)
        if RAW in msg:
            self.__validate_raw_field(msg[RAW])

    def _validate_field_set(self, msg):
        fields_n = sum(1 for f in (RAW, ENC, HASH) if f in msg)
        if fields_n == 0:
            self._raise_missed_fields(RAW, ENC, HASH)
        if fields_n > 1:
            self._raise_invalid_message(
                "only one field from {}, {}, {} is expected".format(
                    RAW, ENC, HASH))

    def __validate_raw_field(self, raw_field):
        raw = self.__decode_raw_field(raw_field)
        if not isinstance(raw, dict):
            self._raise_invalid_fields(RAW, type(raw), 'should be a dict')
        if len(raw) != 1:
            self._raise_invalid_fields(RAW, raw,
                                       'should contain one attribute')
        if ENDPOINT in raw:
            self.__validate_endpoint_ha_field(raw[ENDPOINT])

    def __decode_raw_field(self, raw_field):
        return json.loads(raw_field)

    def __validate_endpoint_ha_field(self, endpoint):
        if endpoint is None:
            return  # remove the attribute, valid case
        HA_NAME = 'ha'
        ha = endpoint.get(HA_NAME)
        if ha is None:
            return  # remove ha attribute, valid case
        if ':' not in ha:
            self._raise_invalid_fields(
                ENDPOINT, endpoint, "invalid endpoint format "
                "ip_address:port")
        ip, port = ha.split(':')
        if not is_network_ip_address_valid(ip):
            self._raise_invalid_fields('ha', ha, 'invalid endpoint address')
        if not is_network_port_valid(port):
            self._raise_invalid_fields('ha', ha, 'invalid endpoint port')
Пример #8
0
class ClientPoolUpgradeOperation(MessageValidator):
    schema = (
        (TXN_TYPE, ConstantField(POOL_UPGRADE)),
        (ACTION, ChooseField(values=(
            START,
            CANCEL,
        ))),
        (SCHEMA_VERSION, VersionField(version_cls=TopPkgDefVersion)),
        # TODO replace actual checks (idr, datetime)
        (SCHEDULE,
         MapField(IdentifierField(), NonEmptyStringField(), optional=True)),
        (SHA256, Sha256HexField()),
        (TIMEOUT, NonNegativeNumberField(optional=True)),
        (JUSTIFICATION,
         LimitedLengthStringField(max_length=JUSTIFICATION_MAX_SIZE,
                                  optional=True,
                                  nullable=True)),
        (NAME, LimitedLengthStringField(max_length=NAME_FIELD_LIMIT)),
        (FORCE, BooleanField(optional=True)),
        (REINSTALL, BooleanField(optional=True)),
        (PACKAGE,
         LimitedLengthStringField(max_length=NAME_FIELD_LIMIT, optional=True)),
    )
Пример #9
0
class ClientMessageValidator(MessageValidator):
    schema = (
        (f.IDENTIFIER.nm, IdentifierField(optional=True, nullable=True)),
        (f.REQ_ID.nm, NonNegativeNumberField()),
        (OPERATION, ClientOperationField()),
        (f.SIG.nm,
         SignatureField(max_length=SIGNATURE_FIELD_LIMIT, optional=True)),
        (f.DIGEST.nm,
         LimitedLengthStringField(max_length=DIGEST_FIELD_LIMIT,
                                  optional=True)),
        (f.PROTOCOL_VERSION.nm, ProtocolVersionField()),
        (f.TAA_ACCEPTANCE.nm, ClientTAAAcceptance(optional=True)),
        (f.SIGS.nm,
         MapField(IdentifierField(),
                  SignatureField(max_length=SIGNATURE_FIELD_LIMIT),
                  optional=True,
                  nullable=True)),
    )

    def __init__(self, operation_schema_is_strict, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # Following code is for support of non-strict schema
        # TODO: refactor this
        # TODO: this (and all related functionality) can be removed when
        # when fixed problem with transaction serialization (INDY-338)
        # Adding fields from enabled plugins to schema.
        self.schema = self.schema + tuple(PLUGIN_CLIENT_REQUEST_FIELDS.items())
        if operation_schema_is_strict:
            operation_field_index = 2
            op = ClientOperationField(
                schema_is_strict=operation_schema_is_strict)
            schema = list(self.schema)
            schema[operation_field_index] = (OPERATION, op)
            self.schema = tuple(schema)

    def validate(self, dct):
        super().validate(dct)
        identifier = dct.get(f.IDENTIFIER.nm, None)
        signatures = dct.get(f.SIGS.nm, None)
        signature = dct.get(f.SIG.nm, None)
        if signatures and signature:
            self._raise_invalid_message(
                'Request must not contains both fields "signatures" and "signature"'
            )
        if identifier and signatures and identifier not in signatures:
            self._raise_invalid_message(
                'The identifier is not contained in signatures')
        if not (identifier or signatures):
            self._raise_invalid_message(
                'Missing both signatures and identifier')
Пример #10
0
class PrePrepare(MessageBase):
    typename = PREPREPARE
    schema = (
        (f.INST_ID.nm, NonNegativeNumberField()),
        (f.VIEW_NO.nm, NonNegativeNumberField()),
        (f.PP_SEQ_NO.nm, NonNegativeNumberField()),
        (f.PP_TIME.nm, TimestampField()),
        (f.REQ_IDR.nm, IterableField(RequestIdentifierField())),
        (f.DISCARDED.nm, NonNegativeNumberField()),
        (f.DIGEST.nm, LimitedLengthStringField(max_length=DIGEST_FIELD_LIMIT)),
        (f.LEDGER_ID.nm, LedgerIdField()),
        (f.STATE_ROOT.nm, MerkleRootField(nullable=True)),
        (f.TXN_ROOT.nm, MerkleRootField(nullable=True)),
    )
Пример #11
0
class PrePrepare(MessageBase):
    schema = (
        (f.INST_ID.nm, NonNegativeNumberField()),
        (f.VIEW_NO.nm, NonNegativeNumberField()),
        (f.PP_SEQ_NO.nm, NonNegativeNumberField()),
        (f.PP_TIME.nm, TimestampField()),
        (f.REQ_IDR.nm,
         IterableField(
             LimitedLengthStringField(max_length=DIGEST_FIELD_LIMIT))),
        (f.DISCARDED.nm, SerializedValueField(nullable=True)),
        (f.DIGEST.nm, LimitedLengthStringField(max_length=DIGEST_FIELD_LIMIT)),
        (f.LEDGER_ID.nm, LedgerIdField()),
        (f.STATE_ROOT.nm, MerkleRootField(nullable=True)),
        (f.TXN_ROOT.nm, MerkleRootField(nullable=True)),
        (f.SUB_SEQ_NO.nm, NonNegativeNumberField()),
        (f.FINAL.nm, BooleanField()),
        (f.POOL_STATE_ROOT_HASH.nm,
         MerkleRootField(optional=True, nullable=True)),
        (f.AUDIT_TXN_ROOT_HASH.nm, MerkleRootField(optional=True,
                                                   nullable=True)),
        # TODO: support multiple multi-sigs for multiple previous batches
        (f.BLS_MULTI_SIG.nm,
         BlsMultiSignatureField(optional=True, nullable=True)),
        (f.PLUGIN_FIELDS.nm, AnyMapField(optional=True, nullable=True)),
    )
    typename = PREPREPARE

    def _post_process(self, input_as_dict: Dict) -> Dict:
        # make validated input hashable
        input_as_dict[f.REQ_IDR.nm] = tuple(input_as_dict[f.REQ_IDR.nm])

        bls = input_as_dict.get(f.BLS_MULTI_SIG.nm, None)
        if bls is not None:
            input_as_dict[f.BLS_MULTI_SIG.nm] = (bls[0], tuple(bls[1]),
                                                 tuple(bls[2]))

        return input_as_dict
Пример #12
0
class ViewChangeDone(MessageBase):
    """
    Node sends this kind of message when view change steps done and it is
    ready to switch to the new primary.
    In contrast to 'Primary' message this one does not imply election.
    """
    typename = VIEW_CHANGE_DONE

    schema = (
        # name is nullable because this message can be sent when
        # there were no view changes and instance has no primary yet
        (f.VIEW_NO.nm, NonNegativeNumberField()),
        (f.NAME.nm,
         LimitedLengthStringField(max_length=NAME_FIELD_LIMIT, nullable=True)),
        (f.LEDGER_INFO.nm, IterableField(LedgerInfoField())))
Пример #13
0
class ClientNodeOperationData(MessageValidator):
    schema = (
        (NODE_IP, NetworkIpAddressField(optional=True)),
        (NODE_PORT, NetworkPortField(optional=True)),
        (CLIENT_IP, NetworkIpAddressField(optional=True)),
        (CLIENT_PORT, NetworkPortField(optional=True)),
        (ALIAS, LimitedLengthStringField(max_length=ALIAS_FIELD_LIMIT)),
        (SERVICES, IterableField(ChooseField(values=(VALIDATOR,)), optional=True)),
        (BLS_KEY, Base58Field(byte_lengths=(128,), optional=True)),
    )

    def _validate_message(self, dct):
        # TODO: make ha fields truly optional (needs changes in stackHaChanged)
        required_ha_fields = {NODE_IP, NODE_PORT, CLIENT_IP, CLIENT_PORT}
        ha_fields = {f for f in required_ha_fields if f in dct}
        if ha_fields and len(ha_fields) != len(required_ha_fields):
            self._raise_missed_fields(*list(required_ha_fields - ha_fields))
Пример #14
0
class ClientPoolUpgradeOperation(MessageValidator):
    schema = (
        (TXN_TYPE, ConstantField(POOL_UPGRADE)),
        (ACTION, NonEmptyStringField()),  # TODO check actual value set
        (VERSION, VersionField(components_number=(
            2,
            3,
        ))),
        # TODO replace actual checks (idr, datetime)
        (SCHEDULE,
         MapField(NonEmptyStringField(), NonEmptyStringField(),
                  optional=True)),
        (SHA256, Sha256HexField()),
        (TIMEOUT, NonNegativeNumberField(optional=True)),
        (JUSTIFICATION,
         LimitedLengthStringField(max_length=JUSTIFICATION_MAX_SIZE,
                                  optional=True,
                                  nullable=True)),
        (NAME, NonEmptyStringField(optional=True)),
        (FORCE, BooleanField(optional=True)),
        (REINSTALL, BooleanField(optional=True)),
    )
Пример #15
0
class BatchCommitted(MessageBase):
    """
    Purpose: pass to Observable after each batch is committed
    (so that Observable can propagate the data to Observers using ObservedData msg)
    """
    typename = BATCH_COMMITTED
    schema = (
        (f.REQUESTS.nm,
         IterableField(ClientMessageValidator(
             operation_schema_is_strict=OPERATION_SCHEMA_IS_STRICT))),
        (f.LEDGER_ID.nm, LedgerIdField()),
        (f.INST_ID.nm, NonNegativeNumberField()),
        (f.VIEW_NO.nm, NonNegativeNumberField()),
        (f.PP_SEQ_NO.nm, NonNegativeNumberField()),
        (f.PP_TIME.nm, TimestampField()),
        (f.STATE_ROOT.nm, MerkleRootField()),
        (f.TXN_ROOT.nm, MerkleRootField()),
        (f.SEQ_NO_START.nm, NonNegativeNumberField()),
        (f.SEQ_NO_END.nm, NonNegativeNumberField()),
        (f.AUDIT_TXN_ROOT_HASH.nm, MerkleRootField(nullable=True)),
        (f.PRIMARIES.nm, IterableField(LimitedLengthStringField(
            max_length=NAME_FIELD_LIMIT))),
    )
Пример #16
0
class NewView(MessageBase):
    typename = NEW_VIEW
    schema = (
        (f.VIEW_NO.nm, NonNegativeNumberField()),
        (f.VIEW_CHANGES.nm, IterableField(ViewChangeField())
         ),  # list of tuples (node_name, view_change_digest)
        (f.CHECKPOINT.nm,
         AnyField()),  # Checkpoint to be selected as stable (TODO: or tuple?)
        (f.BATCHES.nm, IterableField(BatchIDField())
         ),  # list of tuples (view_no, pp_view_no, pp_seq_no, pp_digest)
        (f.PRIMARY.nm, LimitedLengthStringField(optional=True))
        # that should get into new view
    )

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if isinstance(self.checkpoint, dict):
            self.checkpoint = Checkpoint(**self.checkpoint)
        # The field `batches` can to be a list of BatchIDs or of dicts.
        # If it's not a list of dicts then we don't need to deserialize it.
        if not self.batches or not isinstance(self.batches[0], dict):
            return
        self.batches = [
            BatchID(**bid) for bid in self.batches if isinstance(bid, dict)
        ]

    def _asdict(self):
        result = super()._asdict()
        chk = self.checkpoint
        if not isinstance(chk, dict):
            result[f.CHECKPOINT.nm] = chk._asdict()
        # The field `batches` can to be a list of BatchIDs or of dicts.
        # If its a list of dicts then we don't need to serialize it.
        if not self.batches or not isinstance(self.batches[0], BatchID):
            return result
        result[f.BATCHES.nm] = [bid._asdict() for bid in self.batches]
        return result
Пример #17
0
class ClientMessageValidator(MessageValidator):

    def __init__(self, operation_schema_is_strict, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # Following code is for support of non-strict schema
        # TODO: refactor this
        # TODO: this (and all related functionality) can be removed when
        # when fixed problem with transaction serialization (INDY-338)
        strict = operation_schema_is_strict
        if not strict:
            operation_field_index = 2
            op = ClientOperationField(schema_is_strict=False)
            schema = list(self.schema)
            schema[operation_field_index] = (OPERATION, op)
            self.schema = tuple(schema)

    schema = (
        (f.IDENTIFIER.nm, IdentifierField()),
        (f.REQ_ID.nm, NonNegativeNumberField()),
        (OPERATION, ClientOperationField()),
        (f.SIG.nm, SignatureField(max_length=SIGNATURE_FIELD_LIMIT, optional=True)),
        (f.DIGEST.nm, LimitedLengthStringField(max_length=DIGEST_FIELD_LIMIT, optional=True)),
        (f.PROTOCOL_VERSION.nm, ProtocolVersionField(optional=True)),
    )
Пример #18
0
def test_empty_string():
    validator = LimitedLengthStringField(max_length=1)
    assert validator.validate("")
Пример #19
0
class GetSchemaField(MessageValidator):
    schema = (
        (SCHEMA_NAME, LimitedLengthStringField(max_length=NAME_FIELD_LIMIT)),
        (SCHEMA_VERSION, VersionField(version_cls=SchemaVersion)),
        (ORIGIN, IdentifierField(optional=True))
    )
Пример #20
0
class ClientGetAttribOperation(MessageValidator):
    schema = (
        (TXN_TYPE, ConstantField(GET_ATTR)),
        (TARGET_NYM, IdentifierField(optional=True)),
        (RAW, LimitedLengthStringField(max_length=RAW_FIELD_LIMIT)),
    )
Пример #21
0
class GetFeeMsg(MessageBase):
    schema = (
        (TXN_TYPE, ConstantField(GET_FEE)),
        (FEES_ALIAS, LimitedLengthStringField(max_length=FEE_ALIAS_LENGTH)),
    )
Пример #22
0
class RsSchemaMetaField(MessageValidator):
    schema = (
        (RS_META_TYPE, ConstantField(RS_SCHEMA_META_TYPE)),
        (RS_META_NAME, LimitedLengthStringField(max_length=NAME_FIELD_LIMIT)),
        (RS_META_VERSION, VersionField(version_cls=RsMetaVersion)),
    )
Пример #23
0
class SetContextMetaField(MessageValidator):
    schema = (
        (CONTEXT_NAME, LimitedLengthStringField(max_length=NAME_FIELD_LIMIT)),
        (CONTEXT_VERSION, VersionField(version_cls=ContextVersion)),
        (RS_TYPE, ConstantField(CONTEXT_TYPE)),
    )
Пример #24
0
class ClientRevocRegEntrySubmitField(MessageValidator):
    schema = ((TXN_TYPE, ConstantField(REVOC_REG_ENTRY)),
              (REVOC_REG_DEF_ID, NonEmptyStringField()),
              (REVOC_TYPE,
               LimitedLengthStringField()), (VALUE, RevocRegEntryValueField()))
Пример #25
0
class Propagate(MessageBase):
    typename = PROPAGATE
    schema = (
        (f.REQUEST.nm, ClientMessageValidator(operation_schema_is_strict=True)),
        (f.SENDER_CLIENT.nm, LimitedLengthStringField(max_length=SENDER_CLIENT_FIELD_LIMIT, nullable=True)),
    )
Пример #26
0
class GetContextField(MessageValidator):
    schema = ((CONTEXT_NAME,
               LimitedLengthStringField(max_length=NAME_FIELD_LIMIT)),
              (CONTEXT_VERSION, VersionField(version_cls=ContextVersion)))
Пример #27
0
def test_incorrect_max_length():
    with pytest.raises(PlenumValueError):
        LimitedLengthStringField(max_length=0)
    with pytest.raises(PlenumValueError):
        LimitedLengthStringField(max_length=-1)
Пример #28
0
def test_long_string():
    validator = LimitedLengthStringField(max_length=1)
    assert validator.validate("xx")
Пример #29
0
class GetSchemaField(MessageValidator):
    schema = (
        (SCHEMA_NAME, LimitedLengthStringField(max_length=NAME_FIELD_LIMIT)),
        (SCHEMA_VERSION, VersionField(components_number=(2, 3,), max_length=VERSION_FIELD_LIMIT)),
        (ORIGIN, IdentifierField(optional=True))
    )
Пример #30
0
def test_valid_string():
    validator = LimitedLengthStringField(max_length=1)
    assert not validator.validate("x")