示例#1
0
class ClientClaimDefSubmitOperation(MessageValidator):
    schema = (
        (TXN_TYPE, ConstantField(CLAIM_DEF)),
        (REF, TxnSeqNoField()),
        (DATA, ClaimDefField()),
        (SIGNATURE_TYPE, NonEmptyStringField()),
    )
示例#2
0
class ClientClaimDefGetOperation(MessageValidator):
    schema = (
        (TXN_TYPE, ConstantField(GET_CLAIM_DEF)),
        (REF, TxnSeqNoField()),
        (ORIGIN, NonEmptyStringField()),
        (SIGNATURE_TYPE, NonEmptyStringField()),
    )
示例#3
0
文件: types.py 项目: umtyzc/indy-node
class ClientClaimDefGetOperation(MessageValidator):
    schema = (
        (TXN_TYPE, ConstantField(GET_CLAIM_DEF)),
        (REF, TxnSeqNoField()),
        (ORIGIN, IdentifierField()),
        (SIGNATURE_TYPE, LimitedLengthStringField(max_length=SIGNATURE_TYPE_FIELD_LIMIT)),
    )
示例#4
0
文件: types.py 项目: umtyzc/indy-node
class ClientClaimDefSubmitOperation(MessageValidator):
    schema = (
        (TXN_TYPE, ConstantField(CLAIM_DEF)),
        (REF, TxnSeqNoField()),
        (DATA, ClaimDefField()),
        (SIGNATURE_TYPE, LimitedLengthStringField(max_length=SIGNATURE_TYPE_FIELD_LIMIT)),
    )
示例#5
0
class ClientClaimDefGetOperation(MessageValidator):
    schema = (
        (TXN_TYPE, ConstantField(GET_CLAIM_DEF)),
        (CLAIM_DEF_SCHEMA_REF, TxnSeqNoField()),
        (CLAIM_DEF_FROM, IdentifierField()),
        (CLAIM_DEF_SIGNATURE_TYPE, LimitedLengthStringField(max_length=SIGNATURE_TYPE_FIELD_LIMIT)),
        (CLAIM_DEF_TAG, LimitedLengthStringField(max_length=256, optional=True)),
    )
示例#6
0
class ClientClaimDefSubmitOperation(MessageValidator):
    schema = (
        (TXN_TYPE, ConstantField(CLAIM_DEF)),
        (CLAIM_DEF_SCHEMA_REF, TxnSeqNoField()),
        (CLAIM_DEF_PUBLIC_KEYS, ClaimDefField()),
        (CLAIM_DEF_SIGNATURE_TYPE, LimitedLengthStringField(max_length=SIGNATURE_TYPE_FIELD_LIMIT)),
        (CLAIM_DEF_TAG, LimitedLengthStringField(max_length=256)),
    )
示例#7
0
class PublicInputField(AnyMapField):
    public_address_field = PublicAddressField()
    seq_no_field = TxnSeqNoField()

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

        addr_error = self.public_address_field.validate(val["address"])
        if addr_error:
            return addr_error
        amt_error = self.seq_no_field.validate(val["seqNo"])
        if amt_error:
            return amt_error
示例#8
0
class TokenWallet(Wallet):
    txn_seq_no_valdator = TxnSeqNoField()

    def __init__(self,
                 name: str = None,
                 supportedDidMethods: DidMethods = None):
        super().__init__(name, supportedDidMethods)
        self.addresses = OrderedDict()  # type: OrderedDict[str, Address]
        self.reply_handlers = {
            GET_UTXO: self.handle_get_utxo_response,
            XFER_PUBLIC: self.handle_xfer
        }

    def add_new_address(self, address: Address = None, seed=None):
        assert address or seed
        if not address:
            address = Address(seed=seed)
        assert address.address not in self.addresses
        self.addresses[address.address] = address

    def sign_using_output(self,
                          id,
                          seq_no,
                          op: Dict = None,
                          request: Request = None):
        assert lxor(op, request)
        if op:
            request = Request(reqId=Request.gen_req_id(),
                              operation=op,
                              protocolVersion=CURRENT_PROTOCOL_VERSION)
        # existing_inputs = request.operation.get(INPUTS, [])
        # request.operation[INPUTS] = [[id, seq_no], ]
        # payload = deepcopy(request.signingState(id))
        # # TEMPORARY
        # payload[OPERATION].pop(SIGS)
        # payload.pop(f.IDENTIFIER.nm)
        #
        # signature = self.addresses[id].signer.sign(payload)
        # request.operation[INPUTS] = existing_inputs + [[id, seq_no], ]
        # TODO: Account for `extra` field
        payload = [[
            {
                "address": id,
                "seqNo": seq_no
            },
        ], request.operation[OUTPUTS]]
        signature = self.addresses[id].signer.sign(payload)
        request.operation[INPUTS] = request.operation.get(INPUTS, []) + [
            {
                "address": id,
                "seqNo": seq_no
            },
        ]
        request.operation[SIGS].append(signature)
        return request

    def get_all_wallet_utxos(self):
        return {
            address: address.all_utxos
            for address in self.addresses.values()
        }

    def get_all_address_utxos(self, address):
        if address in self.addresses:
            return {self.addresses[address]: self.addresses[address].all_utxos}
        else:
            return {}

    def get_total_wallet_amount(self):
        return sum(addr.total_amount for addr in self.addresses.values())

    def get_total_address_amount(self, address):
        if address in self.addresses:
            return self.addresses[address].total_amount
        else:
            return 0

    def on_reply_from_network(self, observer_name, req_id, frm, result,
                              num_replies):
        try:
            typ = get_type(result)
        except KeyError:
            # For queries
            typ = result[TXN_TYPE]
        if typ and typ in self.reply_handlers:
            self.reply_handlers[typ](result)

    def handle_get_utxo_response(self, response):
        self._update_outputs(response[OUTPUTS])

    def handle_xfer(self, response):
        data = get_payload_data(response)
        seq_no = get_seq_no(response)
        self._update_inputs(data[INPUTS])
        self._update_outputs(data[OUTPUTS], seq_no)

    def _update_inputs(self, inputs):
        for inp in inputs:
            addr = inp["address"]
            seq_no = inp["seqNo"]
            if addr in self.addresses:
                self.addresses[addr].spent(seq_no)

    def _update_outputs(self, outputs, txn_seq_no=None):
        for output in outputs:
            try:
                addr = output["address"]
                val = output["amount"]
                try:
                    seq_no = output["seqNo"]
                except KeyError as ex:
                    if txn_seq_no and isinstance(txn_seq_no, int):
                        seq_no = txn_seq_no
                    else:
                        raise ex
            except Exception:
                raise ValueError('Cannot handle output {}'.format(output))
            if addr in self.addresses:
                self.addresses[addr].add_utxo(seq_no, val)

    def get_min_utxo_ge(self, amount, address=None) -> Optional[Tuple]:
        # Get minimum utxo greater than or equal to `amount`
        def get_address_utxos(address):
            for (seq_no, amount) in address.all_utxos:
                yield {
                    "address": address.address,
                    "seqNo": seq_no,
                    "amount": amount
                }

        if address:
            all_utxos = get_address_utxos(self.addresses[address])
        else:
            all_utxos = [
                utxo for address in self.addresses.values()
                for utxo in get_address_utxos(address)
            ]

        filtered = filter(lambda utxo: utxo["amount"] >= amount, all_utxos)
        return min(filtered, key=lambda utxo: utxo["amount"], default=None)

    def get_val(self, address, seq_no):
        # Get value of unspent output (address and seq_no), can raise KeyError
        return self.addresses[address].outputs[0][seq_no]
示例#9
0
class ClientGetTxnOperation(MessageValidator):
    schema = (
        (TXN_TYPE, ConstantField(GET_TXN)),
        (f.LEDGER_ID.nm, LedgerIdField(optional=True)),
        (DATA, TxnSeqNoField()),
    )
from plenum.common.messages.fields import TxnSeqNoField

validator = TxnSeqNoField()


def test_valid_txn_seq_no():
    assert validator.validate(-1) == "cannot be smaller than 1"
    assert validator.validate(0) == "cannot be smaller than 1"
    assert validator.validate(2.2) == "expected types 'int', got 'float'"
    assert validator.validate('') == "expected types 'int', got 'str'"
    assert validator.validate(1) is None
    assert validator.validate(200) is None
示例#11
0
class ClientGetTxnOperation(MessageValidator):
    schema = (
        (TXN_TYPE, ConstantField(GET_TXN)),
        (DATA, TxnSeqNoField()),
    )
示例#12
0
from plenum.common.constants import TXN_TYPE
from plenum.common.exceptions import InvalidClientRequest
from plenum.common.messages.fields import IterableField, TxnSeqNoField
from plenum.common.request import Request

from sovtoken.constants import MINT_PUBLIC, XFER_PUBLIC, GET_UTXO, INPUTS, SIGS, ADDRESS, OUTPUTS, FROM_SEQNO
from sovtoken.messages.fields import PublicOutputField, PublicOutputsField, PublicInputsField

PUBLIC_OUTPUT_VALIDATOR = IterableField(PublicOutputField())
PUBLIC_OUTPUTS_VALIDATOR = PublicOutputsField()
PUBLIC_INPUTS_VALIDATOR = PublicInputsField()
FROM_VALIDATOR = TxnSeqNoField()


def outputs_validate(request: Request):
    operation = request.operation
    if OUTPUTS not in operation:
        raise InvalidClientRequest(request.identifier, request.reqId,
                                   "{} needs to be present".format(OUTPUTS))
    return PUBLIC_OUTPUTS_VALIDATOR.validate(operation[OUTPUTS])


def inputs_validate(request: Request):
    operation = request.operation
    if INPUTS not in operation:
        raise InvalidClientRequest(request.identifier, request.reqId,
                                   "{} needs to be present".format(INPUTS))
    if SIGS not in operation:
        raise InvalidClientRequest(request.identifier, request.reqId,
                                   "{} needs to be present".format(SIGS))
    # THIS IS TEMPORARY. The new format of requests will take an array of signatures