§
    Í™Ájx8  ã                  óü   — d 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m	Z	m
Z
mZmZmZ ddlmZmZ ddlmZ 	 ddlmZmZmZ n# e$ r ddlmZmZmZ Y nw xY we G d„ d	¦  «        ¦   «         Z G d
„ d¦  «        ZdS )z¤
Distributed Two-Phase Commit (2PC) Instant Buyout Trade Engine for FreeExile.
Provides atomic trades, immutable ledger, and zero-duplication guarantees (0% dupe).
é    )ÚannotationsN)ÚDictÚOptionalÚTupleÚAnyÚList)Ú	dataclassÚfield)ÚPath)ÚStashItemProxyÚSQLiteAccountStashÚSQLiteAccountsProxyc                  ól   — e Zd ZU ded<   ded<   ded<   ded<   ded<   dZd	ed
<   dZded<   dZd	ed<   dS )Ú	StashItemÚstrÚ	item_uuidÚowner_account_idÚ	item_nameÚasking_price_currencyÚintÚasking_price_amountFÚboolÚ	is_lockedNzOptional[str]Úlocked_by_txÚis_scourge_soulbound)Ú__name__Ú
__module__Ú__qualname__Ú__annotations__r   r   r   © ó    ú6C:\Projects\FreeExile\server\trade\two_phase_commit.pyr   r      s|   € € € € € € à€N€N�NØÐÐÑØ€N€N�NØÐÐÑØÐÐÑØ€IÐÐÐÑØ"&€LÐ&Ð&Ð&Ñ&Ø!&ÐÐ&Ð&Ð&Ñ&Ð&Ð&r!   r   c                  óÒ   — e Zd Zd0d1d„Zd„ Zed2d„¦   «         Zed3d„¦   «         Zej        d4d„¦   «         Zd5d„Z	d6d„Z
d7d„Zd8d„Zd9d„Zd:d„Zd;d „Zd<d!„Zd=d'„Zd>d*„Zd?d@d-„Zd=d.„Zd/S )AÚInstantBuyoutEngineç        údata/trade_ledger.dbÚmarket_tax_rateÚfloatÚdb_pathr   c                óð  — || _         t          j        ¦   «         | _        |dk    rœt	          |¦  «                             ¦   «         s{t	          t          ¦  «                             ¦   «         j        j        j        }t          ||z  ¦  «        | _
        t	          | j
        ¦  «        j                             dd¬¦  «         n|| _
        t          j        | j
        dd¬¦  «        | _        t          j        | j        _        | j                             d¦  «         | j                             d¦  «         | j                             d	¦  «         |                      ¦   «          t'          | ¦  «        | _        d S )
Nz:memory:T)ÚparentsÚexist_okg      >@F)ÚtimeoutÚcheck_same_threadzPRAGMA journal_mode=WAL;zPRAGMA synchronous=NORMAL;zPRAGMA busy_timeout = 30000;)r'   Ú	threadingÚRLockÚ_lockr   Úis_absoluteÚ__file__ÚresolveÚparentr   r)   ÚmkdirÚsqlite3ÚconnectÚconnÚRowÚrow_factoryÚexecuteÚ_init_dbr   Úaccounts)Úselfr'   r)   Úbase_dirs       r"   Ú__init__zInstantBuyoutEngine.__init__+   s+  € Ø.ˆÔÝ”_Ñ&Ô&ˆŒ
à�jÒ Ð ­¨g©¬×)BÒ)BÑ)DÔ)DÐ Ý�H‘~”~×-Ò-Ñ/Ô/Ô6Ô=ÔDˆHÝ˜x¨'Ñ1Ñ2Ô2ˆDŒLÝ�”ÑÔÔ%×+Ò+°DÀ4Ð+ÑHÔHÐHÐHà"ˆDŒLå”O D¤L¸$ÐRWÐXÑXÔXˆŒ	Ý '¤ˆŒ	ÔØŒ	×ÒÐ4Ñ5Ô5Ð5ØŒ	×ÒÐ6Ñ7Ô7Ð7ØŒ	×ÒÐ8Ñ9Ô9Ð9Ø�Š‰ŒˆÝ+¨DÑ1Ô1ˆŒˆˆr!   c                óˆ  — | j         5  | j        5  | j                             d¦  «         | j                             d¦  «         | j                             d¦  «         | j                             d¦  «         | j                             d¦  «         d d d ¦  «         n# 1 swxY w Y   d d d ¦  «         d S # 1 swxY w Y   d S )Nzµ
                CREATE TABLE IF NOT EXISTS accounts (
                    account_id TEXT PRIMARY KEY,
                    balances TEXT DEFAULT '{}'
                )
            a±  
                CREATE TABLE IF NOT EXISTS items (
                    item_uuid TEXT PRIMARY KEY,
                    owner_account_id TEXT,
                    item_name TEXT,
                    asking_price_currency TEXT,
                    asking_price_amount INTEGER,
                    is_locked INTEGER,
                    locked_by_tx TEXT,
                    is_scourge_soulbound INTEGER
                )
            aµ  
                CREATE TABLE IF NOT EXISTS transactions (
                    tx_id TEXT PRIMARY KEY,
                    timestamp_ms INTEGER,
                    item_uuid TEXT,
                    item_name TEXT,
                    seller_account_id TEXT,
                    buyer_account_id TEXT,
                    currency TEXT,
                    amount INTEGER,
                    status TEXT
                )
            z©
                CREATE TABLE IF NOT EXISTS engine_state (
                    key TEXT PRIMARY KEY,
                    value_int INTEGER
                )
            zRINSERT OR IGNORE INTO engine_state (key, value_int) VALUES ('total_tax_burned', 0)©r1   r9   r<   )r?   s    r"   r=   zInstantBuyoutEngine._init_db>   s‹  € ØŒZð &	tð &	t˜œð &	tð &	tØŒI×Òð ñ ô ð ð ŒI×Òð ñ ô ð ð ŒI×Òð ñ ô ð ð ŒI×Òð ñ ô ð ð ŒI×ÒÐrÑsÔsÐsðM&	tð &	tð &	tñ &	tô &	tð &	tð &	tð &	tð &	tð &	tð &	tøøøð &	tð &	tð &	tð &	tð &	tð &	tð &	tñ &	tô &	tð &	tð &	tð &	tð &	tð &	tð &	tð &	tøøøð &	tð &	tð &	tð &	tð &	tð &	ts5   ˆB7�BBÂB7ÂB#	Â#B7Â&B#	Â'B7Â7B;Â>B;ÚreturnúList[Dict[str, Any]]c                óÜ   — | j         5  | j                             ¦   «         }|                     d¦  «         d„ |                     ¦   «         D ¦   «         cd d d ¦  «         S # 1 swxY w Y   d S )Nz4SELECT * FROM transactions ORDER BY timestamp_ms ASCc                ó,   — g | ]}t          |¦  «        ‘ŒS r    )Údict)Ú.0Úrows     r"   ú
<listcomp>z7InstantBuyoutEngine.transaction_log.<locals>.<listcomp>l   s   € Ð8Ð8Ð8 #•D˜‘I”IÐ8Ð8Ð8r!   )r1   r9   Úcursorr<   Úfetchall)r?   Úcurs     r"   Útransaction_logz#InstantBuyoutEngine.transaction_logg   s­   € àŒZð 	9ð 	9Ø”)×"Ò"Ñ$Ô$ˆCØ�KŠKÐNÑOÔOÐOØ8Ð8¨¯ª©¬Ð8Ñ8Ô8ð	9ð 	9ð 	9ð 	9ñ 	9ô 	9ð 	9ð 	9ð 	9ð 	9ð 	9ð 	9øøøð 	9ð 	9ð 	9ð 	9ð 	9ð 	9s   ˆAA!Á!A%Á(A%r   c                óà   — | j         5  | j                             ¦   «         }|                     d¦  «         |                     ¦   «         }|r|d         ndcd d d ¦  «         S # 1 swxY w Y   d S )NzASELECT value_int FROM engine_state WHERE key = 'total_tax_burned'Ú	value_intr   ©r1   r9   rL   r<   Úfetchone)r?   rN   rJ   s      r"   Útotal_tax_burnedz$InstantBuyoutEngine.total_tax_burnedn   s³   € àŒZð 	2ð 	2Ø”)×"Ò"Ñ$Ô$ˆCØ�KŠKÐ[Ñ\Ô\Ð\Ø—,’,‘.”.ˆCØ'*Ð1�3�{Ô#Ð#°ð		2ð 	2ð 	2ð 	2ñ 	2ô 	2ð 	2ð 	2ð 	2ð 	2ð 	2ð 	2øøøð 	2ð 	2ð 	2ð 	2ð 	2ð 	2s   ˆAA#Á#A'Á*A'ÚvalueÚNonec                ó¼   — | j         5  | j        5  | j                             d|f¦  «         d d d ¦  «         n# 1 swxY w Y   d d d ¦  «         d S # 1 swxY w Y   d S )NzDUPDATE engine_state SET value_int = ? WHERE key = 'total_tax_burned'rC   )r?   rU   s     r"   rT   z$InstantBuyoutEngine.total_tax_burnedv   s  € àŒZð 	pð 	p˜œð 	pð 	pØŒI×ÒÐdÐglÐfnÑoÔoÐoð	pð 	pð 	pñ 	pô 	pð 	pð 	pð 	pð 	pð 	pð 	pøøøð 	pð 	pð 	pð 	pð 	pð 	pð 	pñ 	pô 	pð 	pð 	pð 	pð 	pð 	pð 	pð 	pøøøð 	pð 	pð 	pð 	pð 	pð 	pó.   ˆA�9­A¹=	½AÁ =	ÁAÁAÁAÚ
account_idr   c                óÐ   — | j         5  | j                             ¦   «         }|                     d|f¦  «         |                     ¦   «         d ucd d d ¦  «         S # 1 swxY w Y   d S )Nz+SELECT 1 FROM accounts WHERE account_id = ?rR   )r?   rY   rN   s      r"   Úaccount_existsz"InstantBuyoutEngine.account_exists{   s¨   € ØŒZð 	.ð 	.Ø”)×"Ò"Ñ$Ô$ˆCØ�KŠKÐEÈ
À}ÑUÔUÐUØ—<’<‘>”>¨Ð-ð	.ð 	.ð 	.ð 	.ñ 	.ô 	.ð 	.ð 	.ð 	.ð 	.ð 	.ð 	.øøøð 	.ð 	.ð 	.ð 	.ð 	.ð 	.s   ˆAAÁAÁ"Ac                ó¼   — | j         5  | j        5  | j                             d|f¦  «         d d d ¦  «         n# 1 swxY w Y   d d d ¦  «         d S # 1 swxY w Y   d S )Nz6INSERT OR IGNORE INTO accounts (account_id) VALUES (?)rC   ©r?   rY   s     r"   Úensure_accountz"InstantBuyoutEngine.ensure_account�   s  € ØŒZð 	gð 	g˜œð 	gð 	gØŒI×ÒÐVÐYcÐXeÑfÔfÐfð	gð 	gð 	gñ 	gô 	gð 	gð 	gð 	gð 	gð 	gð 	gøøøð 	gð 	gð 	gð 	gð 	gð 	gð 	gñ 	gô 	gð 	gð 	gð 	gð 	gð 	gð 	gð 	gøøøð 	gð 	gð 	gð 	gð 	gð 	grX   r   c                óL   — |                       |¦  «         t          | |¦  «        S )N)r^   r   r]   s     r"   Úregister_accountz$InstantBuyoutEngine.register_account…   s&   € Ø×Ò˜JÑ'Ô'Ð'Ý! $¨
Ñ3Ô3Ð3r!   Úcurrencyc                óL  — | j         5  | j                             ¦   «         }|                     d|f¦  «         |                     ¦   «         }|s	 d d d ¦  «         dS t          j        |d         ¦  «        }|                     |d¦  «        cd d d ¦  «         S # 1 swxY w Y   d S )Nú2SELECT balances FROM accounts WHERE account_id = ?r   Úbalances)r1   r9   rL   r<   rS   ÚjsonÚloadsÚget)r?   rY   ra   rN   rJ   rd   s         r"   Úget_balancezInstantBuyoutEngine.get_balance‰   sþ   € ØŒZð 	-ð 	-Ø”)×"Ò"Ñ$Ô$ˆCØ�KŠKÐLÈzÈmÑ\Ô\Ð\Ø—,’,‘.”.ˆCØð Øð	-ð 	-ð 	-ñ 	-ô 	-ð 	-ð 	-ð 	-õ ”z # j¤/Ñ2Ô2ˆHØ—<’< ¨!Ñ,Ô,ð	-ð 	-ð 	-ð 	-ñ 	-ô 	-ð 	-ð 	-ð 	-ð 	-ð 	-ð 	-øøøð 	-ð 	-ð 	-ð 	-ð 	-ð 	-s   ˆABÁ/BÂBÂ BÚamountc                óÐ  — |                       |¦  «         | j        5  | j        5  | j                             ¦   «         }|                     d|f¦  «         |                     ¦   «         }|rt          j        |d         ¦  «        ni }|||<   |                     dt          j        |¦  «        |f¦  «         d d d ¦  «         n# 1 swxY w Y   d d d ¦  «         d S # 1 swxY w Y   d S )Nrc   rd   ú5UPDATE accounts SET balances = ? WHERE account_id = ?)	r^   r1   r9   rL   r<   rS   re   rf   Údumps)r?   rY   ra   ri   rN   rJ   rd   s          r"   Úset_balancezInstantBuyoutEngine.set_balance“   s‰  € Ø×Ò˜JÑ'Ô'Ð'ØŒZð 	uð 	u˜œð 	uð 	uØ”)×"Ò"Ñ$Ô$ˆCØ�KŠKÐLÈzÈmÑ\Ô\Ð\Ø—,’,‘.”.ˆCØ69ÐA•t”z # j¤/Ñ2Ô2Ð2¸rˆHØ!'ˆH�XÑØ�KŠKÐOÕRVÔR\Ð]eÑRfÔRfÐhrÐQsÑtÔtÐtð	uð 	uð 	uñ 	uô 	uð 	uð 	uð 	uð 	uð 	uð 	uøøøð 	uð 	uð 	uð 	uð 	uð 	uð 	uñ 	uô 	uð 	uð 	uð 	uð 	uð 	uð 	uð 	uøøøð 	uð 	uð 	uð 	uð 	uð 	us5   �C¥BCÂ7CÃC	ÃCÃ
C	ÃCÃCÃ"Cr   úOptional[StashItem]c                ó®  — | j         5  | j                             ¦   «         }|                     d|f¦  «         |                     ¦   «         }|s	 d d d ¦  «         d S t          |d         |d         |d         |d         |d         t          |d         ¦  «        |d         t          |d	         ¦  «        ¬
¦  «        cd d d ¦  «         S # 1 swxY w Y   d S )Nz'SELECT * FROM items WHERE item_uuid = ?r   r   r   r   r   r   r   r   )r   r   r   r   r   r   r   r   )r1   r9   rL   r<   rS   r   r   )r?   r   rN   rJ   s       r"   Úget_itemzInstantBuyoutEngine.get_item�   s@  € ØŒZð 	ð 	Ø”)×"Ò"Ñ$Ô$ˆCØ�KŠKÐAÀIÀ<ÑPÔPÐPØ—,’,‘.”.ˆCØð Øð	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	õ Ø˜kÔ*Ø!$Ð%7Ô!8Ø˜kÔ*Ø&)Ð*AÔ&BØ$'Ð(=Ô$>Ý˜s ;Ô/Ñ0Ô0Ø  Ô0Ý%)¨#Ð.DÔ*EÑ%FÔ%Fð	ñ 	ô 	ð	ð 	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	ð 	ð 	s   ˆAC
ÁA C
Ã
CÃCÚitemr   c                óN  — | j         5  | j        5  | j                             d|j        |j        |j        |j        |j        t          |j	        ¦  «        |j
        t          |j        ¦  «        f¦  «         d d d ¦  «         n# 1 swxY w Y   d d d ¦  «         d S # 1 swxY w Y   d S )Nzÿ
                INSERT OR REPLACE INTO items 
                (item_uuid, owner_account_id, item_name, asking_price_currency, asking_price_amount, is_locked, locked_by_tx, is_scourge_soulbound)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?)
            )r1   r9   r<   r   r   r   r   r   r   r   r   r   )r?   rq   s     r"   Úupsert_itemzInstantBuyoutEngine.upsert_item¯   s)  € ØŒZð 	ð 	˜œð 	ð 	ØŒI×Òð ð
 ” Ô 5°t´~ÀtÔGaØÔ(­#¨d¬nÑ*=Ô*=¸tÔ?PÕRUÐVZÔVoÑRpÔRpðñ	ô ð ð	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	ð 	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	ð 	ð 	s5   ˆB�A&BÁ6BÂB	ÂBÂ	B	Â
BÂBÂ!Bc                ó,  — | j         5  | j        5  |                      |¦  «        }|r!|j        rt	          d|› d|j        › �¦  «        ‚| j                             d|f¦  «         d d d ¦  «         n# 1 swxY w Y   d d d ¦  «         d S # 1 swxY w Y   d S )NzCannot delete item z: locked by transaction z%DELETE FROM items WHERE item_uuid = ?)r1   r9   rp   r   Ú
ValueErrorr   r<   )r?   r   rq   s      r"   Údelete_itemzInstantBuyoutEngine.delete_itemº   sQ  € ØŒZð 	Uð 	U˜œð 	Uð 	UØ—=’= Ñ+Ô+ˆDØð o˜œð oÝ Ð!m°yÐ!mÐ!mÐZ^ÔZkÐ!mÐ!mÑnÔnÐnØŒI×ÒÐEÈ	À|ÑTÔTÐTð		Uð 	Uð 	Uñ 	Uô 	Uð 	Uð 	Uð 	Uð 	Uð 	Uð 	Uøøøð 	Uð 	Uð 	Uð 	Uð 	Uð 	Uð 	Uñ 	Uô 	Uð 	Uð 	Uð 	Uð 	Uð 	Uð 	Uð 	Uøøøð 	Uð 	Uð 	Uð 	Uð 	Uð 	Us5   ˆB	�AA1Á%B	Á1A5	Á5B	Á8A5	Á9B	Â	BÂBÚbuyer_account_idÚseller_account_idÚoffered_currencyÚoffered_amountúTuple[bool, str, Optional[str]]c                ó^  — | j         5  |                      |¦  «        }|r|j        |k    r	 ddd¦  «         dS |                      |¦  «        r|                      |¦  «        s	 ddd¦  «         dS ||k    r	 ddd¦  «         dS |j        r	 ddd¦  «         dS |j        r	 ddd¦  «         dS |j        |k    s||j        k     r!dd|j        › d	|j        › �dfcddd¦  «         S | j         	                    ¦   «         }| 
                    d
|f¦  «         |                     ¦   «         }|r"|d         rt          j        |d         ¦  «        ni }	|	                     |d¦  «        }
|
|k     rdd|
› d	|› d|› �dfcddd¦  «         S dt          j        ¦   «         j        dd…         › dt%          t'          j        ¦   «         dz  ¦  «        › �}|	|xx         |z  cc<   | j        5  | j         
                    dt          j        |	¦  «        |f¦  «         | j         
                    d||f¦  «         | j         
                    d|t%          t'          j        ¦   «         dz  ¦  «        ||j        ||||f¦  «         ddd¦  «         n# 1 swxY w Y   dd|fcddd¦  «         S # 1 swxY w Y   dS )zIPhase 1 (Prepare): Lock item, escrow buyer funds, and record PREPARED tx.N)FzAITEM_ALREADY_SOLD: Item not found in seller stash or already soldN)Fz4TRANSACTION_ABORTED: Invalid buyer or seller accountN)Fz0TRANSACTION_ABORTED: Cannot purchase own listingN)FzCTRANSACTION_ABORTED: Item is scourge soulbound and cannot be tradedN)FzFTRANSACTION_ABORTED: Item is currently locked in another pending tradeNFz0TRANSACTION_ABORTED: Price mismatch: item costs ú rc   rd   r   z3TRANSACTION_ABORTED: Insufficient funds: buyer has z, needs Útx_é   Ú_iè  rk   zDUPDATE items SET is_locked = 1, locked_by_tx = ? WHERE item_uuid = ?zþ
                    INSERT INTO transactions 
                    (tx_id, timestamp_ms, item_uuid, item_name, seller_account_id, buyer_account_id, currency, amount, status)
                    VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'PREPARED')
                TzPrepared successfully)r1   rp   r   r[   r   r   r   r   r9   rL   r<   rS   re   rf   rg   ÚuuidÚuuid4Úhexr   Útimerl   r   )r?   rw   rx   r   ry   rz   rq   rN   rJ   Ú
buyer_balsÚ	buyer_balÚtx_ids               r"   Úprepare_buyoutz"InstantBuyoutEngine.prepare_buyoutÁ   sÍ  € ð ŒZð '	8ð '	8Ø—=’= Ñ+Ô+ˆDØð h˜4Ô0Ð4EÒEÐEØgð'	8ð '	8ð '	8ñ '	8ô '	8ð '	8ð '	8ð '	8ð
 ×&Ò&Ð'8Ñ9Ô9ð [À×ATÒATÐUeÑAfÔAfð [ØZð'	8ð '	8ð '	8ñ '	8ô '	8ð '	8ð '	8ð '	8ð  Ð#4Ò4Ð4ØVð'	8ð '	8ð '	8ñ '	8ô '	8ð '	8ð '	8ð '	8ð Ô(ð jØið'	8ð '	8ð '	8ñ '	8ô '	8ð '	8ð '	8ð '	8ð Œ~ð mØlð'	8ð '	8ð '	8ñ '	8ô '	8ð '	8ð '	8ð '	8ð" Ô)Ð-=Ò=Ð=ÀÐRVÔRjÒAjÐAjØð  IÐQUÔQið  Ið  IÐlpô  mGð  Ið  Ið  KOð  Oð%'	8ð '	8ð '	8ð '	8ñ '	8ô '	8ð '	8ð '	8ð( ”)×"Ò"Ñ$Ô$ˆCØ�KŠKÐLÐO_ÐNaÑbÔbÐbØ—,’,‘.”.ˆCØ8;ÐWÀÀJÄÐW�œ C¨
¤OÑ4Ô4Ð4ÐUWˆJØ"ŸšÐ'7¸Ñ;Ô;ˆIØ˜>Ò)Ð)Øð  KÐT]ð  Kð  KÐ`pð  Kð  Kð  {Ið  Kð  Kð  MQð  Qð5'	8ð '	8ð '	8ð '	8ñ '	8ô '	8ð '	8ð '	8ð8 J�$œ*™,œ,Ô*¨3¨B¨3Ô/ÐIÐIµ#µd´i±k´kÀ$Ñ6FÑ2GÔ2GÐIÐIˆEØÐ'Ð(Ð(Ô(¨NÑ:Ð(Ð(Ñ(Ø”ð Yð YØ”	×!Ò!Ð"YÕ\`Ô\fÐgqÑ\rÔ\rð  uEð  \Fñ  Gô  Gð  GØ”	×!Ò!Ð"hÐkpÐr{Ðj|Ñ}Ô}Ð}Ø”	×!Ò!ð #ð �S¥¤¡¤¨tÑ!3Ñ4Ô4°iÀÄÐQbÐdtð  wGð  IWð  Xñ	Yô Yð YðYð Yð Yñ Yô Yð Yð Yð Yð Yð Yð Yøøøð Yð Yð Yð Yð Ð0°%Ð7ðO'	8ð '	8ð '	8ð '	8ñ '	8ô '	8ð '	8ð '	8ð '	8ð '	8ð '	8ð '	8øøøð '	8ð '	8ð '	8ð '	8ð '	8ð '	8sa   ˆ$J"¹+J"Á1J"ÂJ"ÂJ"Â/*J"Ã&BJ"ÆAJ"Ç$BJÉ:J"ÊJ
	Ê
J"ÊJ
	ÊJ"Ê"J&Ê)J&r‡   úTuple[bool, str]c                ó°  — | j         5  | j                             ¦   «         }|                     d|f¦  «         |                     ¦   «         }|r|d         dk    r	 ddd¦  «         dS |d         }|d         }|d         }|d	         }|d
         }t          || j        z  ¦  «        }	||	z
  }
|                     d|f¦  «         |                     ¦   «         }|r"|d         rt          j        |d         ¦  «        ni }| 	                    |d¦  «        |
z   ||<   | j        5  | j                             dt          j
        |¦  «        |f¦  «         | j                             d||f¦  «         | j                             d|f¦  «         | j                             d|	f¦  «         ddd¦  «         n# 1 swxY w Y   	 ddd¦  «         dS # 1 swxY w Y   dS )zPPhase 2 (Commit): Credit seller minus burned tax, transfer item, mark COMMITTED.ú*SELECT * FROM transactions WHERE tx_id = ?ÚstatusÚPREPAREDN)FzCTRANSACTION_ABORTED: Transaction not found or not in PREPARED stater   rw   rx   ra   ri   rc   rd   r   rk   z­
                    UPDATE items 
                    SET owner_account_id = ?, is_locked = 0, locked_by_tx = NULL 
                    WHERE item_uuid = ?
                z<UPDATE transactions SET status = 'COMMITTED' WHERE tx_id = ?zPUPDATE engine_state SET value_int = value_int + ? WHERE key = 'total_tax_burned')Tz%Instant buyout committed successfully)r1   r9   rL   r<   rS   r   r'   re   rf   rg   rl   )r?   r‡   rN   Útxr   Úbuyer_idÚ	seller_idra   ri   Ú
tax_burnedÚseller_creditrJ   Úseller_balss                r"   Úcommit_buyoutz!InstantBuyoutEngine.commit_buyoutó   sÜ  € àŒZð 	Að 	AØ”)×"Ò"Ñ$Ô$ˆCØ�KŠKÐDÀuÀhÑOÔOÐOØ—’‘”ˆBØð d˜˜Hœ¨Ò3Ð3Øcð	Að 	Að 	Añ 	Aô 	Að 	Að 	Að 	Að ˜;œˆIØÐ,Ô-ˆHØÐ.Ô/ˆIØ˜*”~ˆHØ˜”\ˆFå˜V dÔ&:Ñ:Ñ;Ô;ˆJØ" ZÑ/ˆMà�KŠKÐLÈyÈlÑ[Ô[Ð[Ø—,’,‘.”.ˆCØ9<ÐXÀÀZÄÐX�$œ* S¨¤_Ñ5Ô5Ð5ÐVXˆKØ$/§O¢O°H¸aÑ$@Ô$@À=Ñ$PˆK˜Ñ!à”ð Eð EØ”	×!Ò!Ð"YÕ\`Ô\fÐgrÑ\sÔ\sÐu~Ð[ñ  Aô  Að  AØ”	×!Ò!ð #ð  	Ð*ñ	,ô ,ð ,ð
 ”	×!Ò!Ð"`ÐchÐbjÑkÔkÐkØ”	×!Ò!Ð"tð  xBð  wDñ  Eô  Eð  EðEð Eð Eñ Eô Eð Eð Eð Eð Eð Eð Eøøøð Eð Eð Eð Eð Að?	Að 	Að 	Añ 	Aô 	Að 	Að 	Að 	Að 	Að 	Að 	Að 	Aøøøð 	Að 	Að 	Að 	Að 	Að 	As>   ˆAGÁ)B8GÄ!BF2Æ&GÆ2F6	Æ6GÆ9F6	Æ:GÇGÇGúTransaction abortedÚreasonc                ó   — | j         5  | j                             ¦   «         }|                     d|f¦  «         |                     ¦   «         }|�r |d         dk    �r|d         }|d         }|d         }|d         }|                     d|f¦  «         |                     ¦   «         }	|	r"|	d	         rt          j        |	d	         ¦  «        ni }
|
                     |d
¦  «        |z   |
|<   | j        5  | j                             dt          j        |
¦  «        |f¦  «         | j                             d|f¦  «         | j                             d|f¦  «         ddd¦  «         n# 1 swxY w Y   dd|› �fcddd¦  «         S # 1 swxY w Y   dS )zOPhase 2 (Abort): Unlock item, refund escrowed funds, and record ABORTED status.r‹   rŒ   r�   rw   ra   ri   r   rc   rd   r   rk   zGUPDATE items SET is_locked = 0, locked_by_tx = NULL WHERE item_uuid = ?z:UPDATE transactions SET status = 'ABORTED' WHERE tx_id = ?NFzTRANSACTION_ABORTED: )	r1   r9   rL   r<   rS   re   rf   rg   rl   )r?   r‡   r–   rN   rŽ   r�   ra   ri   r   rJ   r…   s              r"   Úabort_buyoutz InstantBuyoutEngine.abort_buyout  sD  € àŒZð 	;ð 	;Ø”)×"Ò"Ñ$Ô$ˆCØ�KŠKÐDÀuÀhÑOÔOÐOØ—’‘”ˆBØñ n�b˜”l jÒ0Ñ0ØÐ0Ô1�Ø˜jœ>�Ø˜Hœ�Ø˜{œO�	Ø—’ÐPÐS[ÐR]Ñ^Ô^Ð^Ø—l’l‘n”n�Ø<?Ð[ÀCÈ
ÄOÐ[�TœZ¨¨J¬Ñ8Ô8Ð8ÐY[�
Ø'1§~¢~°hÀÑ'BÔ'BÀVÑ'K�
˜8Ñ$Ø”Yð nð nØ”I×%Ò%Ð&]Õ`dÔ`jÐkuÑ`vÔ`vð  yAð  `Bñ  Cô  Cð  CØ”I×%Ò%Ð&oÐr{Ðq}Ñ~Ô~Ð~Ø”I×%Ò%Ð&bÐejÐdlÑmÔmÐmðnð nð nñ nô nð nð nð nð nð nð nøøøð nð nð nð nð Ð:°&Ð:Ð:Ð:ð#	;ð 	;ð 	;ð 	;ñ 	;ô 	;ð 	;ð 	;ð 	;ð 	;ð 	;ð 	;øøøð 	;ð 	;ð 	;ð 	;ð 	;ð 	;s7   ˆC)FÃ1A(E%ÅFÅ%E)	Å)FÅ,E)	Å-	FÆFÆ
Fc                ó6  — | j         5  |                      |||||¬¦  «        \  }}}|r|sd|dfcddd¦  «         S |                      |¦  «        \  }	}
|	rdd|fcddd¦  «         S |                      ||
¦  «         d|
dfcddd¦  «         S # 1 swxY w Y   dS )zDUnified 2PC coordinator: prepares and commits atomically under lock.)rw   rx   r   ry   rz   FNTzInstant buyout successful)r1   rˆ   r”   r˜   )r?   rw   rx   r   ry   rz   ÚokÚmsgr‡   Ú	commit_okÚ
commit_msgs              r"   Úexecute_instant_buyoutz*InstantBuyoutEngine.execute_instant_buyout+  sZ  € ð ŒZð 	+ð 	+Ø!×0Ò0Ø!1Ø"3Ø#Ø!1Ø-ð 1ñ ô ‰NˆB��Uð ð (˜Uð (Ø˜c 4Ð'ð	+ð 	+ð 	+ð 	+ñ 	+ô 	+ð 	+ð 	+ð %)×$6Ò$6°uÑ$=Ô$=Ñ!ˆI�zØð @ØÐ8¸%Ð?ð	+ð 	+ð 	+ð 	+ñ 	+ô 	+ð 	+ð 	+ð ×Ò˜e ZÑ0Ô0Ð0Ø˜* dÐ*ð	+ð 	+ð 	+ð 	+ñ 	+ô 	+ð 	+ð 	+ð 	+ð 	+ð 	+ð 	+øøøð 	+ð 	+ð 	+ð 	+ð 	+ð 	+s   ˆ'B¼BÁ'BÂBÂBN)r%   r&   )r'   r(   r)   r   )rD   rE   )rD   r   )rU   r   rD   rV   )rY   r   rD   r   )rY   r   rD   rV   )rY   r   rD   r   )rY   r   ra   r   rD   r   )rY   r   ra   r   ri   r   rD   rV   )r   r   rD   rn   )rq   r   rD   rV   )r   r   rD   rV   )rw   r   rx   r   r   r   ry   r   rz   r   rD   r{   )r‡   r   rD   r‰   )r•   )r‡   r   r–   r   rD   r‰   )r   r   r   rA   r=   ÚpropertyrO   rT   Úsetterr[   r^   r`   rh   rm   rp   rs   rv   rˆ   r”   r˜   rž   r    r!   r"   r$   r$   *   s¯  € € € € € ð2ð 2ð 2ð 2ð 2ð&'tð 'tð 'tðR ð9ð 9ð 9ñ „Xð9ð ð2ð 2ð 2ñ „Xð2ð Ôðpð pð pñ Ôðpð.ð .ð .ð .ðgð gð gð gð4ð 4ð 4ð 4ð-ð -ð -ð -ðuð uð uð uðð ð ð ð$	ð 	ð 	ð 	ðUð Uð Uð Uð08ð 08ð 08ð 08ðd!Að !Að !Að !AðF;ð ;ð ;ð ;ð ;ð*+ð +ð +ð +ð +ð +r!   r$   )Ú__doc__Ú
__future__r   r7   r„   r�   re   r/   Útypingr   r   r   r   r   Údataclassesr	   r
   Úpathlibr   Úserver.trade.trade_proxiesr   r   r   ÚImportErrorÚtrade.trade_proxiesr   r$   r    r!   r"   ú<module>r©      s¬  ððð ð
 #Ð "Ð "Ð "Ð "Ð "Ø €€€Ø €€€Ø €€€Ø €€€Ø Ð Ð Ð Ø 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ø (Ð (Ð (Ð (Ð (Ð (Ð (Ð (Ø Ð Ð Ð Ð Ð ððð ð ð ð ð ð ð ð ð ð øð
 ð ð ð ðð ð ð ð ð ð ð ð ð ð ð ðøøøð ð'ð 'ð 'ð 'ð 'ñ 'ô 'ñ „ð'ðY+ð Y+ð Y+ð Y+ð Y+ñ Y+ô Y+ð Y+ð Y+ð Y+s   º
A ÁAÁA