o
    èó·i	m  ã                   @   sÈ   d dl Z d dlZd dlmZ d dlZd dlZd dlZd dlZd dl	Zd dl
Zd dlZd dlmZ d dlmZ ddlmZmZ d dlZddlmZmZ dd	lmZmZ G d
d„ deƒZG dd„ deƒZdS )é    N)Úpformat)ÚApplicationError)ÚApplicationSessioné   )Úunpack_uint256Úpack_uint256é   )ÚhlÚhlval)Úsign_eip712_channel_closeÚrecover_eip712_channel_closec                   @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )ÚTransactionc	           	      C   s4   || _ || _|| _|| _|| _|| _|| _|| _d S ©N©ÚchannelÚdelegateÚpubkeyÚkey_idÚchannel_seqÚamountÚbalanceÚ	signature)	Úselfr   r   r   r   r   r   r   r   © r   úYC:\Users\psant\Downloads\PAF backend\school\venv\Lib\site-packages\autobahn/xbr/_buyer.pyÚ__init__3   s   
zTransaction.__init__c              	   C   s*   | j | j| j| j| j| j| j| jdœ}|S )Nr   r   )r   Úresr   r   r   Úmarshal=   s   ø
zTransaction.marshalc                 C   s   t |  ¡ ƒS r   )r   r   ©r   r   r   r   Ú__str__J   s   zTransaction.__str__N)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r   r   r   1   s    
r   c                   @   s‚   e Zd ZdZdZdd„ Zdd„ Zdd„ Zd	d
„ Zddd„Z	ddd„Z
dd„ Zdd„ Zdd„ Zd dd„Zdd„ Zdd„ Zdd„ ZdS )!ÚSimpleBuyerz®
    Simple XBR buyer component. This component can be used by a XBR buyer delegate to
    handle the automated buying of data encryption keys from the XBR market maker.
    Nc                 C   sö   t |ƒtkrt|ƒdksJ d |¡ƒ‚t |ƒtkrt|ƒdks&J d |¡ƒ‚t |ƒtkr0|dks2J ‚t ¡ | _|| _d| _	|| _
tj |¡| _d| _| jj ¡ | _d| _tjj ¡ | _|| _d| _d| _d| _i | _d| _d| _d| _i | _ g | _!dS )	a  

        :param market_maker_adr:
        :type market_maker_adr:

        :param buyer_key: Consumer delegate (buyer) private Ethereum key.
        :type buyer_key: bytes

        :param max_price: Maximum price we are willing to buy per key.
        :type max_price: int
        é   z0market_maker_adr must be bytes[20], but got "{}"é    z.buyer delegate must be bytes[32], but got "{}"r   NFT)"ÚtypeÚbytesÚlenÚformatÚintÚtxaioZmake_loggerÚlogÚ_market_maker_adrÚ_xbrmm_configÚ	_pkey_rawÚeth_keysÚkeysZ
PrivateKeyÚ_pkeyZ_acctÚ
public_keyZto_canonical_addressÚ_addrÚ_caddrÚnaclÚpublicÚgenerateÚ_receive_keyÚ
_max_priceÚ_channelÚ_balanceÚ_seqÚ_keysÚ_sessionÚ_runningÚ_auto_close_channelÚ_transaction_idxÚ_transactions)r   Zmarket_maker_adrZ	buyer_keyZ	max_pricer   r   r   r   U   s,   &&

zSimpleBuyer.__init__c                 Ã   sŽ  �t |tƒsJ ‚t|ƒtksJ ‚| jrJ ‚|| _d| _| jjdt| j	ƒt
 | jjdd… ¡ ¡ d� zR| d¡I dH | _t| jƒtkrJt| jƒdksLJ ‚| d| j¡I dH | _| js^td	ƒ‚| jd
 }t|ƒtkrot|ƒdksqJ ‚tj|d�| _| d| jj¡I dH }W n   | ¡  ‚ t|d ƒtkr�t|d ƒ|d< |d dks§tdƒ‚|d | _|d | _| jjdt| jƒt| jƒt| jƒd� | jS )a–  
        Start buying keys to decrypt XBR data by calling ``unwrap()``.

        :param session: WAMP session over which to communicate with the XBR market maker.
        :type session: :class:`autobahn.wamp.protocol.ApplicationSession`

        :param consumer_id: XBR consumer ID.
        :type consumer_id: str

        :return: Current remaining balance in payment channel.
        :rtype: int
        TzSStart buying from consumer delegate address {address} (public key 0x{public_key}..)Né
   )Úaddressr3   zxbr.marketmaker.get_configr$   z*xbr.marketmaker.get_active_payment_channelzno active payment channel foundÚchannel_oidé   ©r'   ú+xbr.marketmaker.get_payment_channel_balanceÚ	remainingr   z1no off-chain balance remaining on payment channelÚseqzvOk, buyer delegate started [active payment channel {channel_oid} with remaining balance {remaining} at sequence {seq}])rF   rJ   rK   )Ú
isinstancer   r&   Ústrr@   r?   r,   Údebugr	   r5   ÚbinasciiÚb2a_hexr2   r3   ÚdecodeÚcallr.   r4   r'   r(   r;   Ú	ExceptionÚuuidÚUUIDZ_channel_oidZleaver   r<   r=   Úinfor
   )r   ÚsessionZconsumer_idrF   Úpayment_balancer   r   r   Ústartš   sB   €
þ 


ÿzSimpleBuyer.startc                 Ã   s"   �| j sJ ‚d| _ | j d¡ dS )z#
        Stop buying keys.
        FzOk, buyer delegate stopped.N)r@   r,   rV   r   r   r   r   ÚstopÔ   s   €
zSimpleBuyer.stopc                 Ã   s4   �| j r	| j  ¡ sJ ‚| j  d| jd ¡I dH }|S )a–  
        Return current balance of payment channel:

        * ``amount``: The initial amount with which the payment channel was opened.
        * ``remaining``: The remaining amount of XBR in the payment channel that can be spent.
        * ``inflight``: The amount of XBR allocated to buy transactions that are currently processed.

        :return: Current payment balance.
        :rtype: dict
        rI   rF   N)r?   Úis_attachedrR   r;   )r   rX   r   r   r   r   Þ   s   €zSimpleBuyer.balancec                 Ã   sX   �| j r	| j  ¡ sJ ‚t d¡}| j  d|| j||¡I dH }|d |d |d dœ}|S )z‰

        :param amount:
        :type amount:

        :param details:
        :type details:

        :return:
        :rtype:
        é@   z$xbr.marketmaker.open_payment_channelNr   rJ   Úinflight)r   rJ   r]   )r?   r[   ÚosÚurandomrR   r4   )r   Z
buyer_addrr   Údetailsr   Úpayment_channelr   r   r   r   Úopen_channelï   s   €

üýzSimpleBuyer.open_channelc                 Ã   s   �dS )z[
        Requests to close the currently active payment channel.

        :return:
        Nr   )r   r`   r   r   r   Úclose_channel  s    zSimpleBuyer.close_channelc           $      Ã   s¢  �t |ƒtkrt|ƒdksJ ‚t |ƒtkr|dv sJ ‚t |ƒtks#J ‚| jd }| jd }d}| jd }t | jd dd	… ¡}|| jv rU| j	j
d
ttj|d�ƒd� �np| j	j
dttj|d�ƒd� d| j|< | j d|¡I d	H }	t|	d ƒ}
| j	j
dttj|d�ƒtt|
d ƒƒd� |
| jkr¬tdd | jjtj|d�t|
d ƒt| jd ƒ¡ƒ‚| j|
 }|dk �r3| j�rd	}|  ¡ }|rÆ|d }|�r| j}| j}d}t| j||||||||ƒ	}| j	j
dtj|d�|t|d ƒ|d� | j d||||t|ƒ|||¡	I d	H  tdd | jjtj|d�|t|d ƒ¡ƒ‚tdd | jjtj|d�t| jd ƒt|
d ƒ¡ƒ‚| jjj t!j"j#d�}| jd }d}t| j||||||||ƒ	}|  $|| j%||||
||¡ z| j d | j%||||t|
ƒt|ƒ|¡	I d	H }W n7 t�y� } z|j&dk�r‰|  '¡  |‚d	}~w t(�y­ } z| j	 &d!¡ | j	 )¡  || j|< |‚d	}~ww |d" }|d# }t|d$ ƒ}t|d% ƒ}t|d& ƒ}t*|||||||d|ƒ	}|| j+k�rÿ| j	j,d'| jjtt -|¡ .¡ ƒtt -| j+¡ .¡ ƒd(� td)d* | jj¡ƒ‚| jd |k�rtd+d, | jj| j|d# ¡ƒ‚| j|
 |k�r/td+d- | jj| j|
 |d% ¡ƒ‚|| _|| _|  /|| j+||||||¡ |d. }t!j0 1| j¡}z| 2|¡}W n t!j3j4�ys } z|| j|< td/d0 | jj|¡ƒ‚d	}~ww t!j5 6|¡| j|< |  7¡ } | j	j8d1| jjtd2d3d4�ttj|d�ƒttt|d ƒƒd5 d3d4�tt -|d6 ¡ .¡ ƒtt|d ƒƒtt|d ƒƒtt -|¡ .¡ ƒ| d7�
 d}!| j| du �rù|!d8 �ré| j	j
d9| jjttj|d�ƒd:� |!d7 }!t9 :d;¡I d	H  | j| du �sÏt;| j| t(ƒ�r	| j| }|‚z
| j|  2|¡}"W n t!j3j4�y- } ztd/d< | jj|¡ƒ‚d	}~ww zt< =|"¡}#W |#S  t<j>j?�yP } ztd=d> | jj|¡ƒ‚d	}~ww )?aO  
        Decrypt XBR data. This functions will potentially make the buyer call the
        XBR market maker to buy data encryption keys from the XBR provider.

        :param key_id: ID of the data encryption used for decryption
            of application payload.
        :type key_id: bytes

        :param serializer: Application payload serializer.
        :type serializer: str

        :param ciphertext: Ciphertext of encrypted application payload to
            decrypt.
        :type ciphertext: bytes

        :return: Decrypted application payload.
        :rtype: object
        rG   )ZcborÚ
market_oidrF   r   Úverifying_chain_idÚverifying_contract_adrr   Nz>Key {key_id} already in key store (or currently being bought).rH   )r   z1Key {key_id} not yet in key store - buying key ..Fzxbr.marketmaker.get_quoteZpricez-Key {key_id} has current price quote {amount}l     ÈNÎZo)r   r   zxbr.error.max_price_exceededzR{}.unwrap() - key {} needed cannot be bought: price {} exceeds maximum price of {}r   Tz‚auto-closing payment channel {channel_oid} [close_seq={close_seq}, close_balance={close_balance}, close_is_final={close_is_final}])rF   Ú	close_seqÚclose_balanceÚclose_is_finalzxbr.marketmaker.close_channelzxbr.error.channel_closedzu{}.unwrap() - key {} cannot be bought: payment channel {} ran empty and we initiated close at remaining balance of {}zxbr.error.insufficient_balancez_{}.unwrap() - key {} cannot be bought: insufficient balance {} in payment channel for amount {})Úencoderzxbr.marketmaker.buy_keyz8Encountered error while calling market maker to buy key!r   r   Úamount_paidrJ   r]   zv{klass}.unwrap()::XBRSIG[8/8] - EIP712 signature invalid: signer_address={signer_address}, delegate_adr={delegate_adr})ÚklassÚsigner_addressÚdelegate_adrzxbr.error.invalid_signaturezQ{}.unwrap()::XBRSIG[8/8] - EIP712 signature invalid or not signed by market makerzxbr.error.invalid_transactionz^{}.buy_key(): invalid transaction (channel sequence number mismatch - expected {}, but got {})z_{}.buy_key(): invalid transaction (channel remaining amount mismatch - expected {}, but got {})Ú
sealed_keyzxbr.error.decryption_failedz6{}.unwrap() - could not unseal data encryption key: {}zÌ{klass}.unwrap() - {tx_type} key {key_id} bought for {amount_paid} [payment_channel={payment_channel}, remaining={remaining}, inflight={inflight}, buyer_pubkey={buyer_pubkey}, transactions={transactions}]z
XBR BUY   Zmagenta)Úcolorz XBRra   )	rl   Ztx_typer   rk   ra   rJ   r]   Úbuyer_pubkeyZtransactionséd   zG{klass}.unwrap() - waiting for key "{key_id}" currently being bought ..)rl   r   gš™™™™™É?z1{}.unwrap() - failed to unwrap encrypted data: {}z xbr.error.deserialization_failedz;{}.unwrap() - failed to deserialize application payload: {})@r&   r'   r(   rM   r;   r.   rO   Úa2b_hexr>   r,   rN   r	   rT   rU   r?   rR   r   r*   r:   r   r)   Ú	__class__r    r<   rA   Úpast_transactionsr=   r   r/   r   r9   r3   Úencoder6   ÚencodingZ
RawEncoderÚ_save_transaction_phase1r4   ÚerrorrZ   rS   Zfailurer   r-   ÚwarnrP   rQ   Ú_save_transaction_phase2r7   Z	SealedBoxZdecryptÚ
exceptionsZCryptoErrorÚsecretZ	SecretBoxÚcount_transactionsrV   r+   ÚsleeprL   Úcbor2ÚloadsÚdecoderZCBORDecodeError)$r   r   Ú
serializerZ
ciphertextrd   rF   Zcurrent_block_numberre   rf   Úquoter   r   Zlast_txZtxnsrg   rh   ri   r   rq   r   Úis_finalZreceiptÚeZmarketmaker_signatureZmarketmaker_channel_seqZmarketmaker_amount_paidZmarketmaker_remainingZmarketmaker_inflightrm   ro   Z
unseal_boxÚkeyZtransactions_countZlog_counterÚmessageÚpayloadr   r   r   Úunwrap  st  €




ÿ
ÿ
,ÿ

ø


ü
ø


ýÿ


ýÿ

þø	€

€üýýÿÿÿÿ
€þ
ö
ÿû
€þü€þzSimpleBuyer.unwrapc	              	   C   s\   || j v rtd t |¡¡ƒ‚t||||||||ƒ}	t| jƒ}
| j |	dg¡ |
| j |< dS )úí

        :param channel_oid:
        :param delegate_adr:
        :param buyer_pubkey:
        :param key_id:
        :param channel_seq:
        :param amount:
        :param balance:
        :param signature:
        :return:
        z;save_transaction_phase1: duplicate transaction for key 0x{}N)	rB   ÚRuntimeErrorr)   rO   rP   r   r(   rC   Úappend)r   rF   rn   rq   r   r   r   r   r   Útx1Úkey_idxr   r   r   rx     s   

z$SimpleBuyer._save_transaction_phase1c	              	   C   sð   || j vrtd t |¡¡ƒ‚| j | }	| j|	 d r%td t |¡¡ƒ‚| j|	 d }
t||||||||ƒ}|
j|jks?J ‚|
j|jksGJ ‚|
j	|j	ksOJ ‚|
j
|j
ksWJ ‚|
j|jks_J ‚|
j|jksgJ ‚|
j|jksoJ ‚|| j|	 d< dS )r‹   z;save_transaction_phase2: transaction for key 0x{} not foundr   z;save_transaction_phase2: duplicate transaction for key 0x{}r   N)rB   rŒ   r)   rO   rP   rC   r   r   r   r   r   r   r   r   )r   rF   rn   rq   r   r   r   r   r   r�   rŽ   Útx2r   r   r   r{     s"   

ÿz$SimpleBuyer._save_transaction_phase2Tr   c                 C   sŒ   t |ƒtksJ ‚t |ƒtkr|dksJ ‚d}g }||k rDt| jƒ|kr=| j|  }|r3|d r<|d r<| |¡ |d7 }n	 |S ||k s|S )zQ

        :param filter_complete:
        :param limit:
        :return:
        r   r   N)r&   Úboolr*   r(   rC   r�   )r   Zfilter_completeÚlimitÚnr   Ztxr   r   r   ru   B  s   
€øzSimpleBuyer.past_transactionsc                 C   sH   dddœ}| j D ]\}}|r|r|d  d7  < q|d  d7  < q|S )z

        :return:
        r   )ÚcompleteÚpendingr”   r   r•   N)rC   )r   r   rŽ   r�   r   r   r   r~   X  s   þzSimpleBuyer.count_transactionsc                 C   s    | j  |d¡}|r| j| S dS )ú2

        :param key_id:
        :return:
        N©rB   ÚgetrC   )r   r   Úidxr   r   r   Úget_transactionh  s   
ÿzSimpleBuyer.get_transactionc                 C   s,   | j  |d¡}|r| j| \}}|o|S dS )r–   NFr—   )r   r   r™   rŽ   r�   r   r   r   Úis_completer  s
   zSimpleBuyer.is_completer   )Tr   )r    r!   r"   Ú__doc__r,   r   rY   rZ   r   rb   rc   rŠ   rx   r{   ru   r~   rš   r›   r   r   r   r   r#   N   s"    E:


 r
&
r#   )rT   rO   Úpprintr   r^   r€   Znacl.secretr6   Z
nacl.utilsZnacl.exceptionsZnacl.publicr+   Zautobahn.wamp.exceptionr   Zautobahn.wamp.protocolr   Z_utilr   r   r0   Úutilr	   r
   Z_eip712_channel_closer   r   Úobjectr   r#   r   r   r   r   Ú<module>   s$   