Esempio n. 1
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.PRIMARIES.nm,
               IterableField(
                   LimitedLengthStringField(max_length=NAME_FIELD_LIMIT))),
              (f.ORIGINAL_VIEW_NO.nm,
               NonNegativeNumberField()), (f.PLUGIN_FIELDS.nm,
                                           AnyMapField(optional=True,
                                                       nullable=True)))
Esempio n. 2
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))),
        (f.ORIGINAL_VIEW_NO.nm, NonNegativeNumberField()),
    )
Esempio n. 3
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)
        # 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
Esempio n. 4
0
class RevocRegEntryValueField(MessageValidator):
    schema = (
        (PREV_ACCUM, NonEmptyStringField(optional=True)),
        (ACCUM, NonEmptyStringField()),
        (ISSUED, IterableField(inner_field_type=IntegerField(), optional=True)),
        (REVOKED, IterableField(inner_field_type=IntegerField(), optional=True))
    )
Esempio n. 5
0
class ViewChange(MessageBase):
    typename = VIEW_CHANGE
    schema = (
        (f.VIEW_NO.nm, NonNegativeNumberField()),
        (f.STABLE_CHECKPOINT.nm, NonNegativeNumberField()),
        (f.PREPARED.nm, IterableField(BatchIDField())
         ),  # list of tuples (view_no, pp_view_no, pp_seq_no, pp_digest)
        (f.PREPREPARED.nm, IterableField(BatchIDField())
         ),  # list of tuples (view_no, pp_view_no, pp_seq_no, pp_digest)
        (f.CHECKPOINTS.nm, IterableField(AnyField())
         )  # list of Checkpoints TODO: should we change to tuples?
    )

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        checkpoints = []
        for chk in self.checkpoints:
            if isinstance(chk, dict):
                checkpoints.append(Checkpoint(**chk))
        if checkpoints:
            self.checkpoints = checkpoints

        # The field `prepared` can to be a list of BatchIDs or of dicts.
        # If its a list of dicts then we need to deserialize it.
        if self.prepared and isinstance(self.prepared[0], dict):
            self.prepared = [
                BatchID(**bid) for bid in self.prepared
                if isinstance(bid, dict)
            ]
        # The field `preprepared` can to be a list of BatchIDs or of dicts.
        # If its a list of dicts then we need to deserialize it.
        if self.preprepared and isinstance(self.preprepared[0], dict):
            self.preprepared = [
                BatchID(**bid) for bid in self.preprepared
                if isinstance(bid, dict)
            ]

    def _asdict(self):
        result = super()._asdict()
        checkpoints = []
        for chk in self.checkpoints:
            if isinstance(chk, dict):
                continue
            checkpoints.append(chk._asdict())
        if checkpoints:
            result[f.CHECKPOINTS.nm] = checkpoints
        # The field `prepared` can to be a list of BatchIDs or of dicts.
        # If its a list of BatchID then we need to serialize it.
        if self.prepared and isinstance(self.prepared[0], BatchID):
            result[f.PREPARED.nm] = [bid._asdict() for bid in self.prepared]
        # The field `preprepared` can to be a list of BatchIDs or of dicts.
        # If its a list of BatchID then we need to serialize it.
        if self.preprepared and isinstance(self.preprepared[0], BatchID):
            result[f.PREPREPARED.nm] = [
                bid._asdict() for bid in self.preprepared
            ]
        return result
Esempio n. 6
0
class ViewChange(MessageBase):
    typename = VIEW_CHANGE
    schema = (
        (f.VIEW_NO.nm, NonNegativeNumberField()),
        (f.STABLE_CHECKPOINT.nm, NonNegativeNumberField()),
        (f.PREPARED.nm, IterableField(AnyField())),  # list of PrePrepare
        (f.PREPREPARED.nm, IterableField(AnyField())),  # list of PrePrepare
        (f.CHECKPOINTS.nm, IterableField(AnyField()))  # list of Checkpoint
    )
Esempio n. 7
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_seq_no, pp_digest)
        # that should get into new view
    )
Esempio n. 8
0
class ViewChange(MessageBase):
    typename = VIEW_CHANGE
    schema = (
        (f.VIEW_NO.nm, NonNegativeNumberField()),
        (f.STABLE_CHECKPOINT.nm, NonNegativeNumberField()),
        (f.PREPARED.nm, IterableField(BatchIDField())),  # list of tuples (view_no, pp_seq_no, pp_digest)
        (f.PREPREPARED.nm, IterableField(BatchIDField())),  # list of tuples (view_no, pp_seq_no, pp_digest)
        (f.CHECKPOINTS.nm, IterableField(AnyField()))  # list of Checkpoints TODO: should we change to tuples?
    )
Esempio n. 9
0
class NewView(MessageBase):
    typename = NEW_VIEW
    schema = (
        (f.VIEW_NO.nm, NonNegativeNumberField()),
        (f.VIEW_CHANGES.nm, IterableField(
            AnyField())),  # list of tuples (node_name, view_change_digest)
        (f.CHECKPOINT.nm, AnyField()),  # Checkpoint to be selected as stable
        (f.PREPREPARES.nm, IterableField(AnyField())
         )  # list of PrePrepares that should get into new view
    )
Esempio n. 10
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.BLS_MULTI_SIGS.nm,
         IterableField(optional=True,
                       inner_field_type=BlsMultiSignatureField(
                           optional=True, nullable=True))),
        (f.ORIGINAL_VIEW_NO.nm,
         NonNegativeNumberField(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]))

        bls_sigs = input_as_dict.get(f.BLS_MULTI_SIGS.nm, None)
        if bls_sigs is not None:
            sub = []
            for sig in bls_sigs:
                sub.append((sig[0], tuple(sig[1]), tuple(sig[2])))
            input_as_dict[f.BLS_MULTI_SIGS.nm] = tuple(sub)

        return input_as_dict
Esempio n. 11
0
class Batch(MessageBase):
    typename = BATCH

    schema = (
        (f.MSGS.nm, IterableField(SerializedValueField())),
        (f.SIG.nm, SignatureField(max_length=SIGNATURE_FIELD_LIMIT)),
    )
Esempio n. 12
0
class BackupInstanceFaulty(MessageBase):
    typename = BACKUP_INSTANCE_FAULTY
    schema = (
        (f.VIEW_NO.nm, NonNegativeNumberField()),
        (f.INSTANCES.nm, IterableField(NonNegativeNumberField())),
        (f.REASON.nm, NonNegativeNumberField())
    )
Esempio n. 13
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
Esempio n. 14
0
class ThreePCState(MessageBase):
    typename = THREE_PC_STATE
    schema = (
        (f.INST_ID.nm, NonNegativeNumberField()),
        (f.MSGS.nm, IterableField(ClientMessageValidator(
            operation_schema_is_strict=True))),
    )
Esempio n. 15
0
class TxnFeesField(FixedLengthField):
    _base_types = (list, tuple)
    inputs_validator = PublicInputsField()
    outputs_validator = PublicOutputsField()
    signatures_validator = IterableField(
        SignatureField(max_length=SIGNATURE_FIELD_LIMIT))

    def __init__(self, **kwargs):
        super().__init__(length=3, **kwargs)

    def _specific_validation(self, val):
        error = super()._specific_validation(val)
        if error:
            return error

        error = self.inputs_validator.validate(val[0])
        if error:
            return error

        error = self.outputs_validator.validate(val[1])
        if error:
            return error

        error = self.signatures_validator.validate(val[2])
        if error:
            return error

        if len(val[0]) != len(val[2]):
            return 'Number of signatures and number of inputs should match but are {} and {} ' \
                   'respectively.'.format(len(val[2]), len(val[0]))
Esempio n. 16
0
class SchemaField(MessageValidator):
    schema = (
        (SCHEMA_NAME, LimitedLengthStringField(max_length=NAME_FIELD_LIMIT)),
        (SCHEMA_VERSION, VersionField(components_number=(2, 3,), max_length=VERSION_FIELD_LIMIT)),
        (SCHEMA_ATTR_NAMES, IterableField(
            LimitedLengthStringField(max_length=NAME_FIELD_LIMIT),
            min_length=1)),
    )
Esempio n. 17
0
def test_min_max_checks():
    validator = IterableField(NonNegativeNumberField(), min_length=3,
                              max_length=10)
    assert validator.validate(list(range(2)))

    for i in range(3, 11):
        assert not validator.validate(list(range(i)))

    assert validator.validate(list(range(12)))
Esempio n. 18
0
class Reelection(MessageBase):
    typename = REELECTION

    schema = (
        (f.INST_ID.nm, NonNegativeNumberField()),
        (f.ROUND.nm, NonNegativeNumberField()),
        (f.TIE_AMONG.nm, IterableField(TieAmongField(max_length=TIE_IDR_FIELD_LIMIT))),
        (f.VIEW_NO.nm, NonNegativeNumberField()),
    )
Esempio n. 19
0
class SetContextField(MessageValidator):
    context = (
        (CONTEXT_NAME, LimitedLengthStringField(max_length=NAME_FIELD_LIMIT)),
        (CONTEXT_VERSION, VersionField(version_cls=ContextVersion)),
        (CONTEXT_CONTEXT_ARRAY, IterableField(
            LimitedLengthStringField(max_length=NAME_FIELD_LIMIT),
            min_length=1,
            max_length=CONTEXT_ATTRIBUTES_LIMIT)),
    )
Esempio n. 20
0
class SchemaField(MessageValidator):
    schema = (
        (NAME, NonEmptyStringField()),
        (VERSION, VersionField(components_number=(
            2,
            3,
        ))),
        (ATTR_NAMES, IterableField(NonEmptyStringField())),
    )
Esempio n. 21
0
class SchemaField(MessageValidator):
    schema = (
        (SCHEMA_NAME, LimitedLengthStringField(max_length=NAME_FIELD_LIMIT)),
        (SCHEMA_VERSION, VersionField(version_cls=SchemaVersion)),
        (SCHEMA_ATTR_NAMES, IterableField(
            LimitedLengthStringField(max_length=NAME_FIELD_LIMIT),
            min_length=1,
            max_length=SCHEMA_ATTRIBUTES_LIMIT)),
    )
Esempio n. 22
0
class CatchupRep(MessageBase):
    typename = CATCHUP_REP
    schema = (
        (f.LEDGER_ID.nm, LedgerIdField()),
        # TODO: turn on validation, the cause is INDY-388
        # (f.TXNS.nm, MapField(key_field=StringifiedNonNegativeNumberField(),
        #                      value_field=ClientMessageValidator(operation_schema_is_strict=False))),
        (f.TXNS.nm, AnyValueField()),
        (f.CONS_PROOF.nm, IterableField(Base58Field(byte_lengths=(32, )))),
    )
Esempio n. 23
0
class Ordered(MessageBase):
    typename = ORDERED
    schema = (
        (f.INST_ID.nm, NonNegativeNumberField()),
        (f.VIEW_NO.nm, NonNegativeNumberField()),
        (f.REQ_IDR.nm, IterableField(RequestIdentifierField())),
        (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)),
    )
Esempio n. 24
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))),
    )
Esempio n. 25
0
class CurrentState(MessageBase):
    """
    Node sends this kind of message for nodes which
    suddenly reconnected (lagged). It contains information about current
    pool state, like view no, primary etc.
    """
    typename = CURRENT_STATE

    schema = (
        (f.VIEW_NO.nm, NonNegativeNumberField()),
        (f.PRIMARY.nm, IterableField(AnyField())),  # ViewChangeDone
    )
Esempio n. 26
0
class ConstraintListField(MessageValidator):
    schema = ((CONSTRAINT_ID, ChooseField(values=ConstraintsEnum.values())),
              (AUTH_CONSTRAINTS, IterableField(AnyField())))

    def _validate_message(self, val):
        constraints = val.get(AUTH_CONSTRAINTS)
        if not constraints:
            self._raise_invalid_message("Fields {} should not be an empty "
                                        "list.".format(AUTH_CONSTRAINTS))
        for constraint in constraints:
            error_msg = ConstraintField(ConstraintEntityField(),
                                        self).validate(constraint)
            if error_msg:
                self._raise_invalid_message(error_msg)
Esempio n. 27
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)),
    )
Esempio n. 28
0
 def _transform_field(self, field, old_field_type, new_field_type):
     if isinstance(field, old_field_type):
         return new_field_type()
     elif self.__is_iterable_and_contains_type(field, old_field_type):
         return IterableField(new_field_type())
     elif isinstance(field, MapField):
         key = field.key_field
         val = field.value_field
         if isinstance(field.key_field, old_field_type):
             key = new_field_type()
         if isinstance(field.value_field, old_field_type):
             val = new_field_type()
         return MapField(key, val)
     return field
Esempio n. 29
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())))
Esempio n. 30
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=True))),
              (f.LEDGER_ID.nm, LedgerIdField()),
              (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()))