service/sdk_validator/resdb_validator/models.py (31 lines of code) (raw):

# Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you 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. from service.sdk_validator.resdb_validator.exceptions import (InvalidSignature, DuplicateTransaction) from service.sdk_validator.resdb_validator.transaction import Transaction from service.sdk_validator.resdb_validator.utils import (validate_txn_obj, validate_key) class Transaction(Transaction): ASSET = 'asset' METADATA = 'metadata' DATA = 'data' def validate(self, resdb=None, current_transactions=[]): """Validate transaction spend Args: resdb (ResDB): an instantiated resdb_validator.ResDB object. Returns: The transaction (Transaction) if the transaction is valid else it raises an exception describing the reason why the transaction is invalid. Raises: ValidationError: If the transaction is invalid """ input_conditions = [] if self.operation == Transaction.CREATE: duplicates = any(txn for txn in current_transactions if txn.id == self.id) if resdb and resdb.is_committed(self.id) or duplicates: raise DuplicateTransaction('transaction `{}` already exists' .format(self.id)) if not self.inputs_valid(input_conditions): raise InvalidSignature('Transaction signature is invalid.') elif self.operation == Transaction.TRANSFER: self.validate_transfer_inputs(resdb, current_transactions) return self @classmethod def from_dict(cls, tx_body): #TODO schema validation return super().from_dict(tx_body, True) # @classmethod # def validate_schema(cls, tx_body): # validate_transaction_schema(tx_body) # validate_txn_obj(cls.ASSET, tx_body[cls.ASSET], cls.DATA, validate_key) # validate_txn_obj(cls.METADATA, tx_body, cls.METADATA, validate_key) # validate_language_key(tx_body[cls.ASSET], cls.DATA) # validate_language_key(tx_body, cls.METADATA) class FastTransaction: """A minimal wrapper around a transaction dictionary. This is useful for when validation is not required but a routine expects something that looks like a transaction, for example during block creation. Note: immutability could also be provided """ def __init__(self, tx_dict): self.data = tx_dict @property def id(self): return self.data['id'] def to_dict(self): return self.data