Beispiel #1
0
 def _revert_state_changes_for_PK(self, addresses_state, chain_manager):
     addr_from_pk = bytes(QRLHelper.getAddress(self.PK))
     if addr_from_pk in addresses_state:
         if self.addr_from != addr_from_pk:
             addresses_state[addr_from_pk].transaction_hashes.remove(self.txhash)
         addresses_state[addr_from_pk].decrease_nonce()
         addresses_state[addr_from_pk].unset_ots_key(self.ots_key, chain_manager)
Beispiel #2
0
    def validate_slave(self, addr_from_state: AddressState,
                       addr_from_pk_state: AddressState):
        addr_from_pk = bytes(QRLHelper.getAddress(self.PK))
        # Validate Slave for CoinBase txn is no more required
        if isinstance(self, CoinBase):
            master_address = self.addr_to
            allowed_access_types = [0, 1]
        else:
            master_address = self.addr_from
            allowed_access_types = [0]

        if self.master_addr == addr_from_pk:
            logger.warning('Matching master_addr field and address from PK')
            return False

        if addr_from_pk != master_address:
            if str(self.PK) not in addr_from_state.slave_pks_access_type:
                logger.warning("Public key and address don't match")
                return False

            access_type = addr_from_pk_state.slave_pks_access_type[str(
                self.PK)]
            if access_type not in allowed_access_types:
                logger.warning('Access Type %s', access_type)
                logger.warning(
                    'Slave Address doesnt have sufficient permission')
                return False

        return True
    def apply_on_state(self, addresses_state):
        addr_from_pk = bytes(QRLHelper.getAddress(self.PK))
        owner_processed = False
        addr_from_processed = False
        addr_from_pk_processed = False

        for initial_balance in self.initial_balances:
            if initial_balance.address == self.owner:
                owner_processed = True
            if initial_balance.address == self.addr_from:
                addr_from_processed = True
            if initial_balance.address == addr_from_pk:
                addr_from_pk_processed = True
            if initial_balance.address in addresses_state:
                addresses_state[initial_balance.address].tokens[
                    bin2hstr(self.txhash).encode()] += initial_balance.amount
                addresses_state[initial_balance.address].transaction_hashes.append(self.txhash)

        if self.owner in addresses_state and not owner_processed:
            addresses_state[self.owner].transaction_hashes.append(self.txhash)

        if self.addr_from in addresses_state:
            addresses_state[self.addr_from].balance -= self.fee
            if not addr_from_processed:
                addresses_state[self.addr_from].transaction_hashes.append(self.txhash)

        if addr_from_pk in addresses_state:
            if self.addr_from != addr_from_pk:
                if not addr_from_pk_processed:
                    addresses_state[addr_from_pk].transaction_hashes.append(self.txhash)
            addresses_state[addr_from_pk].increase_nonce()
            addresses_state[addr_from_pk].set_ots_key(self.ots_key)
Beispiel #4
0
    def unapply_on_state(self, addresses_state, state):
        addr_from_pk = bytes(QRLHelper.getAddress(self.PK))
        owner_processed = False
        addr_from_processed = False
        addr_from_pk_processed = False

        for initial_balance in self.initial_balances:
            if initial_balance.address == self.owner:
                owner_processed = True
            if initial_balance.address == self.addr_from:
                addr_from_processed = True
            if initial_balance.address == addr_from_pk:
                addr_from_pk_processed = True
            if initial_balance.address in addresses_state:
                token_tx_hash = bin2hstr(self.txhash)
                addresses_state[initial_balance.address].tokens[
                    token_tx_hash] -= initial_balance.amount
                if addresses_state[initial_balance.address].tokens[token_tx_hash] == 0:
                    del addresses_state[initial_balance.address].tokens[token_tx_hash]
                addresses_state[initial_balance.address].transaction_hashes.remove(self.txhash)

        if self.owner in addresses_state and not owner_processed:
            addresses_state[self.owner].transaction_hashes.remove(self.txhash)

        if self.addr_from in addresses_state:
            addresses_state[self.addr_from].balance += self.fee
            if not addr_from_processed:
                addresses_state[self.addr_from].transaction_hashes.remove(self.txhash)

        if addr_from_pk in addresses_state:
            if self.addr_from != addr_from_pk:
                if not addr_from_pk_processed:
                    addresses_state[addr_from_pk].transaction_hashes.remove(self.txhash)
            addresses_state[addr_from_pk].decrease_nonce()
            addresses_state[addr_from_pk].unset_ots_key(self.ots_key, state)
Beispiel #5
0
    def validate_all(self, state_container: StateContainer, check_nonce=True) -> bool:
        if self.pbdata.WhichOneof('transactionType') == 'coinbase':
            if not self._validate_extended(state_container):
                return False
            return True

        if not self.validate(True):  # It also calls _validate_custom
            return False
        if not self.validate_slave(state_container):
            return False
        if not self._validate_extended(state_container):
            return False

        addr_from_pk = bytes(QRLHelper.getAddress(self.PK))
        addr_from_pk_state = state_container.addresses_state[addr_from_pk]

        expected_nonce = addr_from_pk_state.nonce + 1

        if check_nonce and self.nonce != expected_nonce:
            logger.warning('nonce incorrect, invalid tx')
            logger.warning('subtype: %s', self.type)
            logger.warning('%s actual: %s expected: %s',
                           OptimizedAddressState.bin_to_qaddress(addr_from_pk),
                           self.nonce,
                           expected_nonce)
            return False

        if state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(addr_from_pk_state.address,
                                                                              self.ots_key):
            logger.warning('pubkey reuse detected: invalid tx %s', bin2hstr(self.txhash))
            logger.warning('subtype: %s', self.type)
            return False

        return True
Beispiel #6
0
 def address_is_valid(address: bytes) -> bool:
     # Warning: Never pass this validation True for Coinbase Address
     if not QRLHelper.addressIsValid(address):
         return False
     if address[0:1] == b'\x11':
         return False
     return True
Beispiel #7
0
    def revert_state_changes(self, addresses_state, chain_manager):
        addr_from_pk = bytes(QRLHelper.getAddress(self.PK))
        owner_processed = False
        addr_from_processed = False
        addr_from_pk_processed = False

        for initial_balance in self.initial_balances:
            if initial_balance.address == self.owner:
                owner_processed = True
            if initial_balance.address == self.addr_from:
                addr_from_processed = True
            if initial_balance.address == addr_from_pk:
                addr_from_pk_processed = True
            if initial_balance.address in addresses_state:
                addresses_state[initial_balance.address].update_token_balance(self.txhash,
                                                                              initial_balance.amount * -1)
                addresses_state[initial_balance.address].transaction_hashes.remove(self.txhash)

        if self.owner in addresses_state and not owner_processed:
            addresses_state[self.owner].transaction_hashes.remove(self.txhash)

        if self.addr_from in addresses_state:
            addresses_state[self.addr_from].balance += self.fee
            if not addr_from_processed and self.addr_from != self.owner:
                addresses_state[self.addr_from].transaction_hashes.remove(self.txhash)

        if addr_from_pk in addresses_state:
            if self.addr_from != addr_from_pk and addr_from_pk != self.owner:
                if not addr_from_pk_processed:
                    addresses_state[addr_from_pk].transaction_hashes.remove(self.txhash)
            addresses_state[addr_from_pk].decrease_nonce()
            addresses_state[addr_from_pk].unset_ots_key(self.ots_key, chain_manager)
Beispiel #8
0
    def validate_slave(self, addr_from_state: AddressState,
                       addr_from_pk_state: AddressState):
        addr_from_pk = bytes(QRLHelper.getAddress(self.PK))

        master_address = self._get_master_address()
        allowed_access_types = self._get_allowed_access_types()

        if self.master_addr == addr_from_pk:
            logger.warning('Matching master_addr field and address from PK')
            return False

        if addr_from_pk != master_address:
            if str(self.PK) not in addr_from_state.slave_pks_access_type:
                logger.warning("Public key and address don't match")
                return False

            access_type = addr_from_pk_state.slave_pks_access_type[str(
                self.PK)]
            if access_type not in allowed_access_types:
                logger.warning('Access Type %s', access_type)
                logger.warning(
                    'Slave Address doesnt have sufficient permission')
                return False

        return True
Beispiel #9
0
    def apply_on_state(self, addresses_state):
        if self.addr_from in addresses_state:
            addresses_state[self.addr_from].tokens[bin2hstr(
                self.token_txhash).encode()] -= self.total_amount
            if addresses_state[self.addr_from].tokens[bin2hstr(
                    self.token_txhash).encode()] == 0:
                del addresses_state[self.addr_from].tokens[bin2hstr(
                    self.token_txhash).encode()]
            addresses_state[self.addr_from].balance -= self.fee
            addresses_state[self.addr_from].transaction_hashes.append(
                self.txhash)

        for index in range(0, len(self.addrs_to)):
            addr_to = self.addrs_to[index]
            amount = self.amounts[index]
            if addr_to in addresses_state:
                if self.addr_from != addr_to:
                    addresses_state[addr_to].transaction_hashes.append(
                        self.txhash)
                addresses_state[addr_to].tokens[bin2hstr(
                    self.token_txhash).encode()] += amount

        addr_from_pk = bytes(QRLHelper.getAddress(self.PK))
        if addr_from_pk in addresses_state:
            if self.addr_from != addr_from_pk:
                addresses_state[addr_from_pk].transaction_hashes.append(
                    self.txhash)
            addresses_state[addr_from_pk].increase_nonce()
            addresses_state[addr_from_pk].set_ots_key(self.ots_key)
    def revert(self, state_container, multi_sig_spend, addresses_state: dict,
               paginated_tx_hash: PaginatedData, current_block_number: int,
               threshold: int) -> bool:
        if not self.executed:
            return True

        if self.total_weight < threshold:
            return False

        if current_block_number > self.expiry_block_number:
            return False
        addresses_state[self.multi_sig_address].update_balance(
            state_container, multi_sig_spend.total_amount)

        addr_from_pk = bytes(QRLHelper.getAddress(multi_sig_spend.PK))
        for index in range(0, len(multi_sig_spend.addrs_to)):
            addr_to = multi_sig_spend.addrs_to[index]
            address_state = addresses_state[addr_to]
            if addr_to not in (multi_sig_spend.addr_from, addr_from_pk):
                paginated_tx_hash.remove(address_state, multi_sig_spend.txhash)
            address_state.update_balance(state_container,
                                         multi_sig_spend.amounts[index],
                                         subtract=True)

        self._data.executed = False
        return True
Beispiel #11
0
 def _apply_state_changes_for_PK(self, addresses_state: dict):
     addr_from_pk = bytes(QRLHelper.getAddress(self.PK))
     if addr_from_pk in addresses_state:
         if self.addr_from != addr_from_pk:
             addresses_state[addr_from_pk].transaction_hashes.append(self.txhash)
         addresses_state[addr_from_pk].increase_nonce()
         addresses_state[addr_from_pk].set_ots_key(self.ots_key)
Beispiel #12
0
    def calc_addr_ots_hash(tx):
        addr = tx.master_addr
        if not addr:
            addr = bytes(QRLHelper.getAddress(tx.PK))

        addr_ots_hash = sha2_256(
            addr + tx.ots_key.to_bytes(8, byteorder='big', signed=False))

        return addr_ots_hash
Beispiel #13
0
    def apply(self, state: State, state_container: StateContainer) -> bool:
        addr_from_pk = bytes(QRLHelper.getAddress(self.PK))
        owner_processed = False
        addr_from_processed = False
        addr_from_pk_processed = False

        for initial_balance in self.initial_balances:
            if initial_balance.address == self.owner:
                owner_processed = True
            if initial_balance.address == self.addr_from:
                addr_from_processed = True
            if initial_balance.address == addr_from_pk:
                addr_from_pk_processed = True

            # If a QRL address has been mentioned multiple times in initial balance
            # then check if that address has already been initialized with some token
            # balance, if found, then add the new balance the already initialized balance
            if (initial_balance.address,
                    self.txhash) in state_container.tokens.data:
                state_container.tokens.data[(
                    initial_balance.address,
                    self.txhash)].balance += initial_balance.amount
            else:
                state_container.tokens.data[(
                    initial_balance.address, self.txhash)] = TokenBalance(
                        balance=initial_balance.amount,
                        decimals=self.decimals,
                        tx_hash=self.txhash,
                        delete=False)
            address_state = state_container.addresses_state[
                initial_balance.address]
            state_container.paginated_tx_hash.insert(address_state,
                                                     self.txhash)
            state_container.paginated_tokens_hash.insert(
                address_state, self.txhash)

        if not owner_processed:
            address_state = state_container.addresses_state[self.owner]
            state_container.paginated_tx_hash.insert(address_state,
                                                     self.txhash)

        address_state = state_container.addresses_state[self.addr_from]
        address_state.update_balance(state_container, self.fee, subtract=True)
        if not addr_from_processed and self.addr_from != self.owner:
            state_container.paginated_tx_hash.insert(address_state,
                                                     self.txhash)

        address_state = state_container.addresses_state[addr_from_pk]
        if self.addr_from != addr_from_pk and addr_from_pk != self.owner:
            if not addr_from_pk_processed:
                state_container.paginated_tx_hash.insert(
                    address_state, self.txhash)
        address_state.increase_nonce()
        state_container.paginated_bitfield.set_ots_key(
            state_container.addresses_state, addr_from_pk, self.ots_key)

        return True
Beispiel #14
0
    def _revert_state_changes_for_PK(self,
                                     state_container: StateContainer) -> bool:
        addr_from_pk = bytes(QRLHelper.getAddress(self.PK))
        address_state = state_container.addresses_state[addr_from_pk]
        if self.addr_from != addr_from_pk:
            state_container.paginated_tx_hash.remove(address_state, self.txhash)
        address_state.decrease_nonce()
        state_container.paginated_bitfield.unset_ots_key(state_container.addresses_state, addr_from_pk, self.ots_key)

        return True
Beispiel #15
0
    def unapply_on_state(self, addresses_state, state):
        if self.addr_from in addresses_state:
            addresses_state[self.addr_from].balance += self.fee
            addresses_state[self.addr_from].transaction_hashes.remove(self.txhash)

        addr_from_pk = bytes(QRLHelper.getAddress(self.PK))
        if addr_from_pk in addresses_state:
            if self.addr_from != addr_from_pk:
                addresses_state[addr_from_pk].transaction_hashes.remove(self.txhash)
            addresses_state[addr_from_pk].decrease_nonce()
            addresses_state[addr_from_pk].unset_ots_key(self.ots_key, state)
    def apply_on_state(self, addresses_state):
        if self.addr_from in addresses_state:
            addresses_state[self.addr_from].balance -= self.fee
            addresses_state[self.addr_from].transaction_hashes.append(self.txhash)

        addr_from_pk = bytes(QRLHelper.getAddress(self.PK))
        if addr_from_pk in addresses_state:
            if self.addr_from != addr_from_pk:
                addresses_state[addr_from_pk].transaction_hashes.append(self.txhash)
            addresses_state[addr_from_pk].increase_nonce()
            addresses_state[addr_from_pk].set_ots_key(self.ots_key)
Beispiel #17
0
    def unapply_on_state(self, addresses_state, state):
        if self.addr_from in addresses_state:
            addresses_state[self.addr_from].balance += self.fee
            for index in range(0, len(self.slave_pks)):
                addresses_state[self.addr_from].remove_slave_pks_access_type(self.slave_pks[index])
            addresses_state[self.addr_from].transaction_hashes.remove(self.txhash)

        addr_from_pk = bytes(QRLHelper.getAddress(self.PK))
        if addr_from_pk in addresses_state:
            if self.addr_from != addr_from_pk:
                addresses_state[addr_from_pk].transaction_hashes.remove(self.txhash)
            addresses_state[addr_from_pk].decrease_nonce()
            addresses_state[addr_from_pk].unset_ots_key(self.ots_key, state)
Beispiel #18
0
 def ParseAddress(self, request: qrl_pb2.ParseAddressReq, context) -> qrl_pb2.ParseAddressResp:
     response = qrl_pb2.ParseAddressResp()
     response.is_valid = QRLHelper.addressIsValid(request.address)
     descriptor = QRLDescriptor.fromBytes(request.address[:3])
     hf_dict = {0: 'SHA2-256', 1: 'SHAKE-128', 2: 'SHAKE-256', 3: 'RESERVED'}
     ss_dict = {0: 'XMSS', 1: 'XMSS-MT'}
     af_dict = {0: 'SHA2-256', 1: 'RESERVED', 3: 'RESERVED'}
     response.desc.hash_function = hf_dict[descriptor.getHashFunction()]
     response.desc.tree_height = descriptor.getHeight()
     response.desc.signatures = 2**response.desc.tree_height
     response.desc.signature_scheme = ss_dict[descriptor.getSignatureType()]
     response.desc.address_format = af_dict[descriptor.getAddrFormatType()]
     return response
Beispiel #19
0
    def get_slaves_by_address(self, address: bytes, item_per_page: int, page_number: int):
        if item_per_page > config.dev.data_per_page or item_per_page == 0:
            return None
        slave_hashes = self._load_slave_transaction_hashes(address, item_per_page, page_number)

        response = qrl_pb2.GetSlavesByAddressResp()
        for tx_hash in slave_hashes:
            tx, _ = self._chain_manager.get_tx_metadata(tx_hash)
            for index in range(0, len(tx.slave_pks)):
                transaction_detail = qrl_pb2.SlaveDetail(slave_address=bytes(QRLHelper.getAddress(tx.slave_pks[index])),
                                                         access_type=tx.access_types[index])
                response.slaves_detail.extend([transaction_detail])

        return response
    def apply_on_state(self, addresses_state):
        if self.addr_from in addresses_state:
            addresses_state[self.addr_from].balance -= self.fee
            for index in range(0, len(self.slave_pks)):
                addresses_state[self.addr_from].add_slave_pks_access_type(self.slave_pks[index],
                                                                          self.access_types[index])
            addresses_state[self.addr_from].transaction_hashes.append(self.txhash)

        addr_from_pk = bytes(QRLHelper.getAddress(self.PK))
        if addr_from_pk in addresses_state:
            if self.addr_from != addr_from_pk:
                addresses_state[addr_from_pk].transaction_hashes.append(self.txhash)
            addresses_state[addr_from_pk].increase_nonce()
            addresses_state[addr_from_pk].set_ots_key(self.ots_key)
Beispiel #21
0
    def apply(self,
              state: State,
              state_container: StateContainer) -> bool:
        address_state = state_container.addresses_state[self.addr_from]
        address_state.update_balance(state_container, self.fee, subtract=True)
        state_container.paginated_tx_hash.insert(address_state, self.txhash)

        if self.addr_to:
            addr_from_pk = bytes(QRLHelper.getAddress(self.PK))
            address_state = state_container.addresses_state[self.addr_to]
            if self.addr_to not in (self.addr_from, addr_from_pk):
                state_container.paginated_tx_hash.insert(address_state, self.txhash)
                state_container.paginated_inbox_message.insert(address_state, self.txhash)

        return self._apply_state_changes_for_PK(state_container)
Beispiel #22
0
    def revert(self, state: State, state_container: StateContainer) -> bool:
        addr_from_pk = bytes(QRLHelper.getAddress(self.PK))
        owner_processed = False
        addr_from_processed = False
        addr_from_pk_processed = False

        for initial_balance in self.initial_balances:
            if initial_balance.address == self.owner:
                owner_processed = True
            if initial_balance.address == self.addr_from:
                addr_from_processed = True
            if initial_balance.address == addr_from_pk:
                addr_from_pk_processed = True

            address_state = state_container.addresses_state[
                initial_balance.address]
            state_container.tokens.data[(initial_balance.address,
                                         self.txhash)] = TokenBalance(
                                             balance=0, delete=True)
            state_container.paginated_tx_hash.remove(address_state,
                                                     self.txhash)
            state_container.paginated_tokens_hash.remove(
                address_state, self.txhash)

        if not owner_processed:
            address_state = state_container.addresses_state[self.owner]
            state_container.paginated_tx_hash.remove(address_state,
                                                     self.txhash)

        address_state = state_container.addresses_state[self.addr_from]
        address_state.update_balance(state_container, self.fee)
        if not addr_from_processed and self.addr_from != self.owner:
            state_container.paginated_tx_hash.remove(address_state,
                                                     self.txhash)

        address_state = state_container.addresses_state[addr_from_pk]
        if self.addr_from != addr_from_pk and addr_from_pk != self.owner:
            if not addr_from_pk_processed:
                state_container.paginated_tx_hash.remove(
                    address_state, self.txhash)
        address_state.decrease_nonce()
        state_container.paginated_bitfield.unset_ots_key(
            state_container.addresses_state, addr_from_pk, self.ots_key)

        return True
Beispiel #23
0
    def apply(self,
              state: State,
              state_container: StateContainer) -> bool:
        address_state = state_container.addresses_state[self.addr_from]
        address_state.update_balance(state_container, self.total_amount + self.fee, subtract=True)
        state_container.paginated_tx_hash.insert(address_state, self.txhash)

        addr_from_pk = bytes(QRLHelper.getAddress(self.PK))
        for index in range(0, len(self.addrs_to)):
            addr_to = self.addrs_to[index]
            amount = self.amounts[index]
            address_state = state_container.addresses_state[addr_to]
            address_state.update_balance(state_container, amount)
            if addr_to in (self.addr_from, addr_from_pk):
                continue
            state_container.paginated_tx_hash.insert(address_state, self.txhash)

        return self._apply_state_changes_for_PK(state_container)
    def apply_on_state(self, addresses_state):
        if self.addr_from in addresses_state:
            addresses_state[self.addr_from].balance -= (self.total_amount + self.fee)
            addresses_state[self.addr_from].transaction_hashes.append(self.txhash)

        for index in range(0, len(self.addrs_to)):
            addr_to = self.addrs_to[index]
            amount = self.amounts[index]
            if addr_to in addresses_state:
                addresses_state[addr_to].balance += amount
                if addr_to == self.addr_from:
                    continue
                addresses_state[addr_to].transaction_hashes.append(self.txhash)

        addr_from_pk = bytes(QRLHelper.getAddress(self.PK))
        if addr_from_pk in addresses_state:
            if self.addr_from != addr_from_pk:
                addresses_state[addr_from_pk].transaction_hashes.append(self.txhash)
            addresses_state[addr_from_pk].increase_nonce()
            addresses_state[addr_from_pk].set_ots_key(self.ots_key)
    def validate_slave(self, addr_from_state, addr_from_pk_state):
        addr_from_pk = bytes(QRLHelper.getAddress(self.PK))
        if isinstance(self, CoinBase):
            master_address = self.addr_to
            allowed_access_types = [0, 1]
        else:
            master_address = self.addr_from
            allowed_access_types = [0]

        if addr_from_pk != master_address:
            if str(self.PK) not in addr_from_state.slave_pks_access_type:
                logger.warning('Public key and address dont match')
                return False

            access_type = addr_from_pk_state.slave_pks_access_type[str(self.PK)]
            if access_type not in allowed_access_types:
                logger.warning('Access Type %s', access_type)
                logger.warning('Slave Address doesnt have sufficient permission')
                return False

        return True
    def apply(self, state_container, multi_sig_spend, addresses_state: dict,
              paginated_tx_hash: PaginatedData, current_block_number: int,
              threshold: int) -> bool:
        # TODO: return False if executed
        if self.executed:
            return True

        if self.total_weight < threshold:
            return False

        if current_block_number > self.expiry_block_number:
            return False

        if multi_sig_spend.total_amount > addresses_state[
                self.multi_sig_address].balance:
            logger.info(
                "[VoteStats] Insufficient funds to execute Multi Sig Spend")
            logger.info("Multi Sig Spend Amount: %s, Funds Available: %s",
                        multi_sig_spend.total_amount,
                        addresses_state[self.multi_sig_address].balance)
            logger.info("Multi Sig Spend txn hash: %s",
                        bin2hstr(multi_sig_spend.txhash))
            logger.info("Multi Sig Address: %s",
                        bin2hstr(multi_sig_spend.multi_sig_address))
            return False

        addresses_state[self.multi_sig_address].update_balance(
            state_container, multi_sig_spend.total_amount, subtract=True)

        addr_from_pk = bytes(QRLHelper.getAddress(multi_sig_spend.PK))
        for index in range(0, len(multi_sig_spend.addrs_to)):
            addr_to = multi_sig_spend.addrs_to[index]
            address_state = addresses_state[addr_to]
            if addr_to not in (multi_sig_spend.addr_from, addr_from_pk):
                paginated_tx_hash.insert(address_state, multi_sig_spend.txhash)
            address_state.update_balance(state_container,
                                         multi_sig_spend.amounts[index])

        self._data.executed = True
        return True
Beispiel #27
0
    def validate_slave(self, state_container: StateContainer) -> bool:
        addr_from_pk = bytes(QRLHelper.getAddress(self.PK))

        master_address = self._get_master_address()
        allowed_access_types = self._get_allowed_access_types()

        if self.master_addr == addr_from_pk:
            logger.warning('Matching master_addr field and address from PK')
            return False

        if addr_from_pk != master_address:
            if (self.addr_from, self.PK) not in state_container.slaves.data:
                logger.warning("Public key and address doesn't match")
                return False

            slave_access_type = state_container.slaves.data[(self.addr_from, self.PK)].access_type
            if slave_access_type not in allowed_access_types:
                logger.warning('Access Type %s', slave_access_type)
                logger.warning('Slave Address doesnt have sufficient permission')
                return False

        return True
Beispiel #28
0
    def apply(self, state: State, state_container: StateContainer) -> bool:
        address_state = state_container.addresses_state[self.addr_from]
        address_state.update_balance(state_container, self.fee, subtract=True)
        state_container.paginated_tx_hash.insert(address_state, self.txhash)

        multi_sig_address_state = MultiSigAddressState.get_default(
            self.txhash, self.signatories, self.weights, self.threshold)
        state_container.addresses_state[
            multi_sig_address_state.address] = multi_sig_address_state
        state_container.paginated_tx_hash.insert(multi_sig_address_state,
                                                 self.txhash)

        addr_from_pk = bytes(QRLHelper.getAddress(self.PK))
        for index in range(0, len(self.signatories)):
            signatory = self.signatories[index]
            address_state = state_container.addresses_state[signatory]
            if signatory not in (self.addr_from, addr_from_pk):
                state_container.paginated_tx_hash.insert(
                    address_state, self.txhash)
            state_container.paginated_multisig_address.insert(
                address_state, multi_sig_address_state.address)

        return self._apply_state_changes_for_PK(state_container)
Beispiel #29
0
    def revert(self, state: State, state_container: StateContainer) -> bool:
        address_state = state_container.addresses_state[self.addr_from]
        address_state.update_balance(state_container, self.fee)
        state_container.paginated_tx_hash.remove(address_state, self.txhash)

        multi_sig_address = MultiSigAddressState.generate_multi_sig_address(
            self.txhash)
        MultiSigAddressState.remove_multi_sig_address_state(
            state, multi_sig_address, state_container.batch)

        addr_from_pk = bytes(QRLHelper.getAddress(self.PK))
        for index in range(0, len(self.signatories)):
            signatory = self.signatories[index]
            address_state = state_container.addresses_state[signatory]
            if signatory not in (self.addr_from, addr_from_pk):
                state_container.paginated_tx_hash.remove(
                    address_state, self.txhash)
            state_container.paginated_multisig_address.remove(
                address_state, multi_sig_address)

        if multi_sig_address in state_container.addresses_state:
            del state_container.addresses_state[multi_sig_address]

        return self._revert_state_changes_for_PK(state_container)
Beispiel #30
0
    def test_transferCoins_sign(self):
        with set_qrl_dir('wallet_ver1'):
            with State() as db_state:
                p2p_factory = Mock(spec=P2PFactory)
                p2p_factory.pow = Mock(spec=POW)
                chain_manager = ChainManager(db_state)

                qrlnode = QRLNode(db_state, mining_address=b'')
                qrlnode.set_chain_manager(chain_manager)
                qrlnode._p2pfactory = p2p_factory
                qrlnode._pow = p2p_factory.pow
                qrlnode._peer_addresses = ['127.0.0.1', '192.168.1.1']

                service = PublicAPIService(qrlnode)

                context = Mock(spec=ServicerContext)

                alice = get_alice_xmss()
                bob = get_bob_xmss()

                request = qrl_pb2.TransferCoinsReq(
                    addresses_to=[bob.address],
                    amounts=[101],
                    fee=12,
                    xmss_pk=alice.pk
                )

                response = service.TransferCoins(request=request, context=context)
                context.set_code.assert_not_called()
                context.set_details.assert_not_called()

                self.assertIsNotNone(response)
                self.assertIsNotNone(response.extended_transaction_unsigned.tx)
                self.assertEqual('transfer', response.extended_transaction_unsigned.tx.WhichOneof('transactionType'))

                self.assertEqual(12, response.extended_transaction_unsigned.tx.fee)
                self.assertEqual(alice.pk, response.extended_transaction_unsigned.tx.public_key)
                self.assertEqual(0, response.extended_transaction_unsigned.tx.nonce)
                self.assertEqual(b'', response.extended_transaction_unsigned.tx.signature)
                self.assertEqual(b'', response.extended_transaction_unsigned.tx.transaction_hash)
                self.assertEqual(bob.address, response.extended_transaction_unsigned.tx.transfer.addrs_to[0])
                self.assertEqual(101, response.extended_transaction_unsigned.tx.transfer.amounts[0])

                tmp_hash_pre = bytes(QRLHelper.getAddress(response.extended_transaction_unsigned.tx.public_key))
                tmp_hash_pre += str(response.extended_transaction_unsigned.tx.fee).encode()
                tmp_hash_pre += response.extended_transaction_unsigned.tx.transfer.addrs_to[0]
                tmp_hash_pre += str(response.extended_transaction_unsigned.tx.transfer.amounts[0]).encode()

                self.assertEqual('010300a1da274e68c88b0ccf448e0b1916fa789b01eb2ed4e9ad565ce264c939078'
                                 '2a9c61ac02f31320103001d65d7e59aed5efbeae64246e0f3184d7c42411421eb38'
                                 '5ba30f2c1c005a85ebc4419cfd313031',
                                 bin2hstr(tmp_hash_pre))

                tmp_hash = sha256(tmp_hash_pre)

                self.assertEqual('3645f2819aba65479f9a7fad3f5d7a41a9357410a595fa02fb947bfe3ed96e0f',
                                 bin2hstr(tmp_hash))

                signed_transaction = response.extended_transaction_unsigned.tx
                signed_transaction.signature = alice.sign(tmp_hash)

                req_push = qrl_pb2.PushTransactionReq(transaction_signed=signed_transaction)

                resp_push = service.PushTransaction(req_push, context=context)
                context.set_code.assert_not_called()
                context.set_details.assert_not_called()

                self.assertIsNotNone(resp_push)
                self.assertEqual(qrl_pb2.PushTransactionResp.SUBMITTED,
                                 resp_push.error_code)
                self.assertEqual('30955fdc5e2d9dbe5fb9bf812f2e1b6c4b409a8a7c7a75f1c3e9ba1ffdd8e60e',
                                 bin2hstr(resp_push.tx_hash))