def _validate_custom(self): for amount in self.amounts: if amount == 0: logger.warning('Amount cannot be 0 - %s', self.amounts) logger.warning('TransferTokenTransaction') return False if self.fee < 0: logger.info('TransferTokenTransaction [%s] Invalid Fee = %d', bin2hstr(self.txhash), self.fee) return False if len(self.addrs_to) != len(self.amounts): logger.warning( '[TransferTokenTransaction] Mismatch number of addresses to & amounts' ) logger.warning('>> Length of addresses_to %s', len(self.addrs_to)) logger.warning('>> Length of amounts %s', len(self.amounts)) return False if not OptimizedAddressState.address_is_valid(self.addr_from): logger.warning( '[TransferTokenTransaction] Invalid address addr_from: %s', bin2hstr(self.addr_from)) return False for addr_to in self.addrs_to: if not OptimizedAddressState.address_is_valid(addr_to): logger.warning( '[TransferTokenTransaction] Invalid address addr_to: %s', bin2hstr(addr_to)) return False return True
def _validate_custom(self): if len(self.signatories) == 0: logger.warning("[MultiSigCreate] No Signatories found") return False for weight in self.weights: if weight == 0: logger.warning('Weight cannot be 0 - %s', weight) logger.warning('Invalid MultiSigCreate Transaction') return False if self.fee < 0: logger.warning('MultiSigCreate [%s] Invalid Fee = %d', bin2hstr(self.txhash), self.fee) return False if self.total_weight < self.threshold: logger.warning( '[MultiSigCreate] Validation failed for %s because: Insufficient weight', bin2hstr(self.txhash)) logger.warning('Total weight: %s, Threshold: %s', self.total_weight, self.threshold) return False if len(set(self.signatories)) != len(self.signatories): logger.warning( '[MultiSigCreate] Signatories list include duplicate signatories' ) return False if len(self.signatories) != len(self.weights): logger.warning( '[MultiSigCreate] Mismatch number of signatories & weights') logger.warning('>> Length of signatories %s', len(self.signatories)) logger.warning('>> Length of weights %s', len(self.weights)) return False if not OptimizedAddressState.address_is_valid(self.addr_from): logger.warning('[MultiSigCreate] Invalid address addr_from: %s', bin2hstr(self.addr_from)) return False for signatory in self.signatories: if not OptimizedAddressState.address_is_valid(signatory): logger.warning('[MultiSigCreate] Invalid address addr_to: %s', bin2hstr(signatory)) return False return True
def _load_multi_sig_spend_txn_hashes(self, address: bytes, item_per_page: int, page_number: int, mode: int) -> list: if OptimizedAddressState.address_is_valid(address): address_state = self._chain_manager.get_optimized_address_state(address) elif MultiSigAddressState.address_is_valid(address): address_state = self._chain_manager.get_multi_sig_address_state(address) else: return [] start_item_index = max(0, address_state.multi_sig_spend_count() - item_per_page * page_number) end_item_index = min(address_state.multi_sig_spend_count(), start_item_index + item_per_page) if mode > 0: start_item_index = 0 end_item_index = address_state.multi_sig_spend_count() transaction_hashes = self._chain_manager.get_multi_sig_spend_txn_hashes(address, start_item_index) actual_start_item_index = (start_item_index // config.dev.data_per_page) * config.dev.data_per_page multi_sig_spend_txn_hashes = transaction_hashes[start_item_index - actual_start_item_index:] while actual_start_item_index < end_item_index and len(multi_sig_spend_txn_hashes) < item_per_page: actual_start_item_index += config.dev.data_per_page multi_sig_spend_txn_hashes.extend(self._chain_manager.get_multi_sig_spend_txn_hashes(address, actual_start_item_index)) return multi_sig_spend_txn_hashes[:item_per_page][-1::-1]
def get_optimized_address_state(self, address: bytes) -> OptimizedAddressState: if address != config.dev.coinbase_address and not OptimizedAddressState.address_is_valid(address): raise ValueError("Invalid Address") address_state = self._chain_manager.get_optimized_address_state(address) return address_state
def get_block_to_mine(self, wallet_address, tx_pool, last_block, last_block_difficulty) -> list: dev_config = self._chain_manager.get_config_by_block_number(last_block.block_number + 1) try: mining_address = bytes(hstr2bin(wallet_address[1:].decode())) if not OptimizedAddressState.address_is_valid(mining_address): raise ValueError("[get_block_to_mine] Invalid Wallet Address %s", wallet_address) except Exception as e: raise ValueError("Error while decoding wallet address %s", e) if self._mining_block: if last_block.headerhash == self._mining_block.prev_headerhash: if self._mining_block.transactions[0].coinbase.addr_to == mining_address: return [bin2hstr(self._mining_block.mining_blob(dev_config)), int(bin2hstr(self._current_difficulty), 16)] else: self._mining_block.update_mining_address(dev_config, mining_address) # Updates only Miner Address self.prepare_next_unmined_block_template(mining_address, tx_pool, last_block, last_block_difficulty, dev_config=dev_config) return [bin2hstr(self._mining_block.mining_blob(dev_config)), int(bin2hstr(self._current_difficulty), 16)]
def _validate_extended(self, state_container: StateContainer): if len(self.symbol ) > state_container.current_dev_config.max_token_symbol_length: logger.warning('Token Symbol Length exceeds maximum limit') logger.warning('Found Symbol Length %s', len(self.symbol)) logger.warning( 'Expected Symbol length %s', state_container.current_dev_config.max_token_symbol_length) return False if len(self.name ) > state_container.current_dev_config.max_token_name_length: logger.warning('Token Name Length exceeds maximum limit') logger.warning('Found Name Length %s', len(self.symbol)) logger.warning( 'Expected Name length %s', state_container.current_dev_config.max_token_name_length) return False if not OptimizedAddressState.address_is_valid(self.addr_from): logger.warning('Invalid address addr_from: %s', bin2hstr(self.addr_from)) return False tx_balance = state_container.addresses_state[self.addr_from].balance if not OptimizedAddressState.address_is_valid(self.owner): logger.warning('Invalid address owner_addr: %s', bin2hstr(self.owner)) return False for address_balance in self.initial_balances: if not OptimizedAddressState.address_is_valid( address_balance.address): logger.warning('Invalid address in initial_balances: %s', bin2hstr(address_balance.address)) return False if tx_balance < self.fee: logger.warning( 'TokenTxn State validation failed for %s because: Insufficient funds', bin2hstr(self.txhash)) logger.warning('balance: %s, Fee: %s', tx_balance, self.fee) return False return True
def test_generate_multi_sig_address(self): creation_tx_hash = bytes( hstr2bin("5a4c37ef7e5b7cc5a2a58ab730269ed8" "f4cbf08a005dc3508e31465535e1d6bb")) address = MultiSigAddressState.generate_multi_sig_address( creation_tx_hash) expected_address = bytes( hstr2bin("1100003674370317e1cac0ca13f896ab5b6472a" "261ba0d2b2961d3adba1b9060f6e8f7fe2088fb")) self.assertEqual(address, expected_address) self.assertFalse(OptimizedAddressState.address_is_valid(address))
def _validate_custom(self) -> bool: if len(self.message_hash) == 0: logger.warning('Message cannot be empty') return False if len(self.addr_to) > 0 and not (OptimizedAddressState.address_is_valid(self.addr_to)): logger.warning('[MessageTransaction] Invalid address addr_to: %s', bin2hstr(self.addr_to)) return False if self.fee < 0: logger.info('State validation failed for %s because: Negative send', bin2hstr(self.txhash)) return False return True
def _validate_custom(self): for amount in self.amounts: if amount == 0: logger.warning('Amount cannot be 0 - %s', self.amounts) logger.warning('Invalid TransferTransaction') return False if self.fee < 0: logger.warning('MultiSigSpend [%s] Invalid Fee = %d', bin2hstr(self.txhash), self.fee) return False if len(self.addrs_to) == 0: logger.warning('[MultiSigSpend] No addrs_to found') return False if len(self.addrs_to) != len(self.amounts): logger.warning('[MultiSigSpend] Mismatch number of addresses to & amounts') logger.warning('>> Length of addrs_to %s', len(self.addrs_to)) logger.warning('>> Length of amounts %s', len(self.amounts)) return False if not MultiSigAddressState.address_is_valid(self.multi_sig_address): logger.warning('[MultiSigSpend] Invalid MultiSig Address') logger.warning('Multi Sig Address %s', self.multi_sig_address) return False if not OptimizedAddressState.address_is_valid(self.addr_from): logger.warning('[MultiSigSpend] Invalid address addr_from: %s', bin2hstr(self.addr_from)) return False for addr_to in self.addrs_to: if not (OptimizedAddressState.address_is_valid(addr_to) or MultiSigAddressState.address_is_valid(addr_to)): logger.warning('[MultiSigSpend] Invalid address addr_to: %s', bin2hstr(addr_to)) return False return True
def _validate_extended(self, state_container: StateContainer): dev_config = state_container.current_dev_config block_number = state_container.block_number if self.master_addr != dev_config.coinbase_address: logger.warning('Master address doesnt match with coinbase_address') logger.warning('%s %s', bin2hstr(self.master_addr), bin2hstr(dev_config.coinbase_address)) return False if not OptimizedAddressState.address_is_valid(self.addr_to): logger.warning('Invalid address addr_from: %s addr_to: %s', bin2hstr(self.master_addr), bin2hstr(self.addr_to)) return False if self.nonce != block_number + 1: logger.warning('Nonce %s doesnt match with block_number %s', self.nonce, block_number) return False return self._validate_custom()
def get_ots(self, address: bytes, page_from: int, page_count: int, unused_ots_index_from: int) -> (list, Optional[int], bool): if not OptimizedAddressState.address_is_valid(address): return None, None, None max_bitfield = 2 ** OptimizedAddressState.get_height_from_address(address) max_pages = (max_bitfield // config.dev.ots_tracking_per_page) + 1 page_from = min(page_from, max_pages) max_pages = min(page_from + page_count - 1, max_pages) bitfields = list() for page in range(page_from, max_pages + 1): bitfield = self._chain_manager.get_bitfield(address, page) bitfields.append(qrl_pb2.OTSBitfieldByPage(ots_bitfield=bitfield, page_number=page)) unused_ots_index = self._chain_manager.get_unused_ots_index2(address, unused_ots_index_from) unused_ots_index_found = unused_ots_index is not None return bitfields, unused_ots_index, unused_ots_index_found
def parse_qaddress(qaddress: str, check_multi_sig_address=False) -> bytes: """ Converts from a Qaddress to an Address. qaddress: 'Q' + hexstring representation of an XMSS tree's address check_multi_sig_address: Flag if multi sig address should be checked :param qaddress: :return: """ try: qaddress = parse_hexblob(qaddress[1:]) if not OptimizedAddressState.address_is_valid(qaddress): print("checking for multi_sig_address ", check_multi_sig_address) if check_multi_sig_address: print("checking for multi_sig_address") if not MultiSigAddressState.address_is_valid(qaddress): raise ValueError("Invalid Addresss ", qaddress) else: raise ValueError("Invalid Addresss ", qaddress) except Exception as e: raise ValueError("Failed To Decode Address", e) return qaddress
def get_address_is_used(self, address: bytes) -> bool: if not OptimizedAddressState.address_is_valid(address): raise ValueError("Invalid Address") return self._chain_manager.get_address_is_used(address)
def test_address_is_valid(self): address = bytes( hstr2bin("110000000000000000000000000000000000000" "000000000000000000000000000000000000000")) self.assertFalse(OptimizedAddressState.address_is_valid(address))