U
    •uÄc	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   úR/var/www/html/VBACK/school/venv/lib/python3.8/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&td |¡ƒ‚t |ƒtkr>t|ƒdksLtd |¡ƒ‚t |ƒtkr`|dksdt‚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ÚAssertionErrorÚ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ÚpublicZ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t‚t|ƒtkst‚| jr(t‚|| _d| _| jjdt	| j
ƒt | jjdd… ¡ ¡ d� z¤| d¡I dH | _t| jƒtkr’t| jƒdks–t‚| d| j¡I dH | _| jsºtd	ƒ‚| jd
 }t|ƒtkrÜt|ƒdksàt‚tj|d�| _| d| jj¡I dH }W n   | ¡  ‚ Y nX t|d ƒtk�r@t|d ƒ|d< |d dk�sVt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é
   )Úaddressr4   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)   r&   Ústrr@   r?   r-   Údebugr	   r6   ÚbinasciiÚb2a_hexr3   r4   ÚdecodeÚcallr/   r5   r'   r(   r;   Ú	ExceptionÚuuidÚUUIDZ_channel_oidZleaver   r<   r=   Úinfor
   )r   ÚsessionZconsumer_idrF   Úpayment_balancer   r   r   Ústartš   sD    
þ 


  ÿzSimpleBuyer.startc                 Ã   s    | j s
t‚d| _ | j d¡ dS )z#
        Stop buying keys.
        FzOk, buyer delegate stopped.N)r@   r)   r-   rV   r   r   r   r   ÚstopÔ   s    
zSimpleBuyer.stopc                 Ã   s2   | j r| j  ¡ st‚| 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_attachedr)   rR   r;   )r   rX   r   r   r   r   Þ   s    zSimpleBuyer.balancec                 Ã   sV   | j r| j  ¡ st‚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[   r)   ÚosÚurandomrR   r5   )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t‚t |ƒtkr0|dks4t‚t |ƒtksDt‚| jd }| jd }d}| jd }t | jd dd	… ¡}|| j	kr¨| j
jd
ttj|d�ƒd� �n| 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�rXtdd | jjtj|d�t|
d ƒt| jd ƒ¡ƒ‚| j|
 }|dk �rh| j�r4d	}|  ¡ }|�rŽ|d }|�r4| 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&||||
||¡ z0| j d | j&||||t|
ƒt|ƒ|¡	I d	H }W n‚ tk
�r* } z|j'dk�r|  (¡  |‚W 5 d	}~X Y nH t)k
�rp } z(| j
 'd!¡ | j
 *¡  || j	|< |‚W 5 d	}~X Y nX |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�rBtd+d, | jj| j|d# ¡ƒ‚| j|
 |k�rttd+d- | jj| j|
 |d% ¡ƒ‚|| _|| _|  0|| j,||||||¡ |d. }t"j1 2| j¡}z| 3|¡}W nH t"j4j5k
�r } z$|| j	|< td/d0 | jj|¡ƒ‚W 5 d	}~X Y nX t"j6 7|¡| j	|< |  8¡ } | j
j9d1| 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k�r|!d8 �rò| j
jd9| jjttj|d�ƒd:� |!d7 }!t: ;d;¡I d	H  �q®t<| j	| t)ƒ�r&| j	| }|‚z| j	|  3|¡}"W n> t"j4j5k
�rx } ztd/d< | jj|¡ƒ‚W 5 d	}~X Y nX zt= >|"¡}#W n> t=j?j@k
�rÆ } ztd=d> | jj|¡ƒ‚W 5 d	}~X Y nX |#S )?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)Z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: {})Ar&   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   r0   r   r9   r4   Úencoder7   ÚencodingZ
RawEncoderÚ_save_transaction_phase1r5   ÚerrorrZ   rS   Zfailurer   r.   ÚwarnrP   rQ   Ú_save_transaction_phase2r8   Z	SealedBoxZdecryptÚ
exceptionsZCryptoErrorZsecretZ	SecretBoxÚcount_transactionsrV   r,   ÚsleeprL   Úcbor2ÚloadsÚdecoderZCBORDecodeError)$r   r   Z
serializerZ
ciphertextrd   rF   Zcurrent_block_numberre   rf   Úquoter   r   Zlast_txZtxnsrg   rh   ri   r   rp   r   Z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  sv   



ÿ

 ÿ,ÿ

ø


üø



ýÿ


ýÿ

    þø	

    ýýÿÿÿ  ÿ
(
ö
 ÿ
((zSimpleBuyer.unwrapc	              	   C   s\   || j k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   rp   r   r   r   r   r   Útx1Úkey_idxr   r   r   rw     s    

z$SimpleBuyer._save_transaction_phase1c	              	   C   sð   || j krtd t |¡¡ƒ‚| j | }	| j|	 d rJtd t |¡¡ƒ‚| j|	 d }
t||||||||ƒ}|
j|jks~t‚|
j	|j	ksŽt‚|
j
|j
ksžt‚|
j|jks®t‚|
j|jks¾t‚|
j|jksÎt‚|
j|jksÞt‚|| 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   )r   rF   rn   rp   r   r   r   r   r   r‹   rŠ   Útx2r   r   r   rz     s"    

ÿz$SimpleBuyer._save_transaction_phase2Tr   c                 C   s‚   t |ƒtkst‚t |ƒtkr$|dks(t‚d}g }||k r~t| jƒ|kr~| j|  }|rf|d r||d r|| |¡ |d7 }q0q~q0|S )zQ

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

        :return:
        r   )ÚcompleteÚpendingr�   r   r‘   )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_complete)N)N)Tr   )r    r!   r"   Ú__doc__r-   r   rY   rZ   r   rb   rc   r†   rw   rz   rt   r|   r–   r—   r   r   r   r   r#   N   s    E:


 r&

r#   )rT   rO   Úpprintr   r^   r~   Znacl.secretr7   Z
nacl.utilsZnacl.exceptionsZnacl.publicr,   Zautobahn.wamp.exceptionr   Zautobahn.wamp.protocolr   Z_utilr   r   r1   Úutilr	   r
   Z_eip712_channel_closer   r   Úobjectr   r#   r   r   r   r   Ú<module>   s"   