def _get_latest_block_info(self, context): bc = get_data(context, BlockInfoConfig, CONFIG_ADDRESS) if not bc: raise InvalidTransaction('Block config not found') LOGGER.info(f'Current latest block number: {bc.latest_block + 1}') block = get_data(context, BlockInfo, BlockInfoClient.create_block_address(bc.latest_block)) if not block: raise InvalidTransaction(f'Block "{bc.latest_block + 1}" ' f'not found') LOGGER.info(f'Block with number successfully loaded: ' f'{block.block_num + 1}') return block
def _get_setting_entry(context, address): from remme.tp.basic import get_data # noqa try: entry = get_data(context, Setting, address) except FutureTimeoutError: LOGGER.warning('Timeout occured on context.get_state([%s])', address) raise InternalError('Unable to get {}'.format(address)) return entry if entry else Setting()
def _revoke_pub_key(self, context, signer_pubkey, transaction_payload): data = get_data(context, PubKeyStorage, transaction_payload.address) if data is None: raise InvalidTransaction('No such pub key.') if signer_pubkey != data.owner: raise InvalidTransaction('Only owner can revoke the pub key.') if data.revoked: raise InvalidTransaction('The pub key is already revoked.') data.revoked = True LOGGER.info('Revoked the pub key on address {}'.format(transaction_payload.address)) return {transaction_payload.address: data}
def _genesis(self, context, pub_key, genesis_payload): signer_key = self.make_address_from_data(pub_key) genesis_status = get_data(context, GenesisStatus, GENESIS_ADDRESS) if not genesis_status: genesis_status = GenesisStatus() elif genesis_status.status: raise InvalidTransaction('Genesis is already initialized.') genesis_status.status = True account = Account() account.balance = genesis_payload.total_supply LOGGER.info( 'Generated genesis transaction. Issued {} tokens to address {}'. format(genesis_payload.total_supply, signer_key)) return {signer_key: account, GENESIS_ADDRESS: genesis_status}
def get_swap_info_from_swap_id(self, context, swap_id, to_raise_exception=True): swap_info = get_data(context, AtomicSwapInfo, self.make_address_from_data(swap_id)) if to_raise_exception and not swap_info: raise InvalidTransaction( 'Atomic swap was not initiated for {} swap id!'.format( swap_id)) if swap_info and swap_info.is_closed: raise InvalidTransaction( 'No operations can be done upon the swap: {} ' ' as it is already closed.'.format(swap_id)) return swap_info
def get_swap_info_from_swap_id(self, context, swap_id, to_raise_exception=True): swap_info = get_data(context, AtomicSwapInfo, self.make_address_from_data(swap_id)) if to_raise_exception and not swap_info: raise InvalidTransaction(f'Atomic swap was not initiated ' f'for {swap_id} swap id!') if swap_info and swap_info.state in [ AtomicSwapInfo.CLOSED, AtomicSwapInfo.EXPIRED ]: raise InvalidTransaction('No operations can be done upon ' f'the swap: {swap_id} ' ' as it is already closed.') return swap_info
def get_account_by_address(context, address): account = get_data(context, Account, address) if account is None: return Account() return account
def _store_pub_key(self, context, signer_pubkey, transaction_payload): address = self.make_address_from_data(transaction_payload.public_key) LOGGER.info('Pub key address {}'.format(address)) data = get_data(context, PubKeyStorage, address) if data: raise InvalidTransaction('This pub key is already registered.') cert_signer_pubkey = load_pem_public_key( transaction_payload.public_key.encode('utf-8'), backend=default_backend()) try: ehs_bytes = binascii.unhexlify( transaction_payload.entity_hash_signature) eh_bytes = binascii.unhexlify(transaction_payload.entity_hash) except binascii.Error: LOGGER.debug( f'entity_hash_signature {transaction_payload.entity_hash_signature}' ) LOGGER.debug(f'entity_hash {transaction_payload.entity_hash}') raise InvalidTransaction( 'Entity hash or signature not a hex format') # FIXME: For support PKCS1v15 and PSS LOGGER.warn('HAZARD: Detecting padding for verification') sigerr = 0 pkcs = padding.PKCS1v15() pss = padding.PSS(mgf=padding.MGF1(hashes.SHA512()), salt_length=padding.PSS.MAX_LENGTH) for _padding in (pkcs, pss): try: cert_signer_pubkey.verify(ehs_bytes, eh_bytes, _padding, hashes.SHA512()) LOGGER.warn('HAZARD: Padding found: %s', _padding.name) except InvalidSignature: sigerr += 1 if sigerr == 2: raise InvalidTransaction('Invalid signature') valid_from = datetime.fromtimestamp(transaction_payload.valid_from) valid_to = datetime.fromtimestamp(transaction_payload.valid_to) if valid_to - valid_from > PUB_KEY_MAX_VALIDITY: raise InvalidTransaction( 'The public key validity exceeds the maximum value.') data = PubKeyStorage() data.owner = signer_pubkey data.payload.CopyFrom(transaction_payload) data.revoked = False account_address = AccountHandler.make_address_from_data(signer_pubkey) account = get_account_by_address(context, account_address) if ENABLE_ECONOMY: if account.balance < PUB_KEY_STORE_PRICE: raise InvalidTransaction( 'Not enough tokens to register a new pub key. Current balance: {}' .format(account.balance)) account.balance -= PUB_KEY_STORE_PRICE if address not in account.pub_keys: account.pub_keys.append(address) return {address: data, account_address: account}