Ejemplo n.º 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)),
    )
Ejemplo n.º 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)),
    )
Ejemplo n.º 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)))
Ejemplo n.º 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
Ejemplo n.º 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))),
    )
Ejemplo n.º 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)))
Ejemplo n.º 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')
Ejemplo n.º 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)),
    )
Ejemplo n.º 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')
Ejemplo n.º 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)),
    )
Ejemplo n.º 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
Ejemplo n.º 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())))
Ejemplo n.º 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))
Ejemplo n.º 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)),
    )
Ejemplo n.º 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))),
    )
Ejemplo n.º 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
Ejemplo n.º 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)),
    )
Ejemplo n.º 18
0
def test_empty_string():
    validator = LimitedLengthStringField(max_length=1)
    assert validator.validate("")
Ejemplo n.º 19
0
class GetSchemaField(MessageValidator):
    schema = (
        (SCHEMA_NAME, LimitedLengthStringField(max_length=NAME_FIELD_LIMIT)),
        (SCHEMA_VERSION, VersionField(version_cls=SchemaVersion)),
        (ORIGIN, IdentifierField(optional=True))
    )
Ejemplo n.º 20
0
class ClientGetAttribOperation(MessageValidator):
    schema = (
        (TXN_TYPE, ConstantField(GET_ATTR)),
        (TARGET_NYM, IdentifierField(optional=True)),
        (RAW, LimitedLengthStringField(max_length=RAW_FIELD_LIMIT)),
    )
Ejemplo n.º 21
0
class GetFeeMsg(MessageBase):
    schema = (
        (TXN_TYPE, ConstantField(GET_FEE)),
        (FEES_ALIAS, LimitedLengthStringField(max_length=FEE_ALIAS_LENGTH)),
    )
Ejemplo n.º 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)),
    )
Ejemplo n.º 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)),
    )
Ejemplo n.º 24
0
class ClientRevocRegEntrySubmitField(MessageValidator):
    schema = ((TXN_TYPE, ConstantField(REVOC_REG_ENTRY)),
              (REVOC_REG_DEF_ID, NonEmptyStringField()),
              (REVOC_TYPE,
               LimitedLengthStringField()), (VALUE, RevocRegEntryValueField()))
Ejemplo n.º 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)),
    )
Ejemplo n.º 26
0
class GetContextField(MessageValidator):
    schema = ((CONTEXT_NAME,
               LimitedLengthStringField(max_length=NAME_FIELD_LIMIT)),
              (CONTEXT_VERSION, VersionField(version_cls=ContextVersion)))
Ejemplo n.º 27
0
def test_incorrect_max_length():
    with pytest.raises(PlenumValueError):
        LimitedLengthStringField(max_length=0)
    with pytest.raises(PlenumValueError):
        LimitedLengthStringField(max_length=-1)
Ejemplo n.º 28
0
def test_long_string():
    validator = LimitedLengthStringField(max_length=1)
    assert validator.validate("xx")
Ejemplo n.º 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))
    )
Ejemplo n.º 30
0
def test_valid_string():
    validator = LimitedLengthStringField(max_length=1)
    assert not validator.validate("x")