Bump solana to 0.5.0 (#48)

* Bump solana to 0.5.0

* Use TxOpts

* Use non-deprecated MemcmpOpts

* Fix lint errors
This commit is contained in:
Michael Huang 2020-10-05 21:02:12 -05:00 committed by GitHub
parent c7a7d61f01
commit d38cd2eef7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 50 additions and 96 deletions

30
Pipfile.lock generated
View File

@ -144,11 +144,11 @@
},
"solana": {
"hashes": [
"sha256:0bb866b3a046ad41f06ad9ad94b7ee9f7e2209c20c038c240f15b17ffd6c97bc",
"sha256:f9dd7391e628e1bf7c611cf4445936c84f03ec7551db7f400ef68a5fc2c8cfea"
"sha256:42719df91c08c20ab7eebc7b349aedb4602e46e0e55bfda520a41230e51cde48",
"sha256:74d70dc476106d560418869693033d9bb300ba8c07dd6dafe8e46ce988237267"
],
"index": "pypi",
"version": "==0.3.1"
"version": "==0.5.0"
},
"typing-extensions": {
"hashes": [
@ -394,11 +394,11 @@
},
"flake8": {
"hashes": [
"sha256:15e351d19611c887e482fb960eae4d44845013cc142d42896e9862f775d8cf5c",
"sha256:f04b9fcbac03b0a3e58c0ab3a0ecc462e023a9faf046d57794184028123aa208"
"sha256:749dbbd6bfd0cf1318af27bf97a14e28e5ff548ef8e5b1566ccfb25a11e7c839",
"sha256:aadae8761ec651813c24be05c6f7b4680857ef6afaae4651a4eccaef97ce6c3b"
],
"index": "pypi",
"version": "==3.8.3"
"version": "==3.8.4"
},
"idna": {
"hashes": [
@ -648,11 +648,11 @@
},
"nbconvert": {
"hashes": [
"sha256:68335477288aab8a9b9ec03002dce59b4eb1ca967116741ec218a4e78c129efd",
"sha256:d8549f62e739a4d51f275c2932b1783ee5039dde07a2b71de70c0296a42c8394"
"sha256:39e9f977920b203baea0be67eea59f7b37a761caa542abe80f5897ce3cf6311d",
"sha256:cbbc13a86dfbd4d1b5dee106539de0795b4db156c894c2c5dc382062bbc29002"
],
"markers": "python_version >= '3.6'",
"version": "==6.0.6"
"version": "==6.0.7"
},
"nbformat": {
"hashes": [
@ -833,11 +833,11 @@
},
"pytest": {
"hashes": [
"sha256:1cd09785c0a50f9af72220dd12aa78cfa49cbffc356c61eab009ca189e018a33",
"sha256:d010e24666435b39a4cf48740b039885642b6c273a3f77be3e7e03554d2806b7"
"sha256:7a8190790c17d79a11f847fba0b004ee9a8122582ebff4729a082c109e81a4c9",
"sha256:8f593023c1a0f916110285b6efd7f99db07d59546e3d8c36fc60e2ab05d3be92"
],
"index": "pypi",
"version": "==6.1.0"
"version": "==6.1.1"
},
"pytest-cov": {
"hashes": [
@ -1107,11 +1107,11 @@
},
"zipp": {
"hashes": [
"sha256:43f4fa8d8bb313e65d8323a3952ef8756bf40f9a5c3ea7334be23ee4ec8278b6",
"sha256:b52f22895f4cfce194bc8172f3819ee8de7540aa6d873535a8668b730b8b411f"
"sha256:64ad89efee774d1897a58607895d80789c59778ea02185dd846ac38394a8642b",
"sha256:eed8ec0b8d1416b2ca33516a37a08892442f3954dee131e92cfd92d8fe3e7066"
],
"markers": "python_version >= '3.6'",
"version": "==3.2.0"
"version": "==3.3.0"
}
}
}

View File

@ -7,6 +7,7 @@ from typing import List
from solana.account import Account
from solana.publickey import PublicKey
from solana.rpc.api import Client
from solana.rpc.types import RPCResponse, TxOpts
from solana.system_program import CreateAccountParams, create_account
from solana.sysvar import SYSVAR_RENT_PUBKEY
from solana.transaction import Transaction, TransactionInstruction
@ -38,12 +39,8 @@ class Market:
self,
conn: Client,
market_state: MarketState,
opts: t.MarketOpts = t.MarketOpts(),
) -> None:
self._skip_preflight = opts.skip_preflight
self._confirmations = opts.confirmations
self._conn = conn
self.state = market_state
@staticmethod
@ -52,11 +49,10 @@ class Market:
conn: Client,
market_address: PublicKey,
program_id: PublicKey = instructions.DEFAULT_DEX_PROGRAM_ID,
opts: t.MarketOpts = t.MarketOpts(),
) -> Market:
"""Factory method to create a Market."""
market_state = MarketState.load(conn, market_address, program_id)
return Market(conn, market_state, opts)
return Market(conn, market_state)
def support_srm_fee_discounts(self) -> bool:
raise NotImplementedError("support_srm_fee_discounts not implemented")
@ -145,7 +141,8 @@ class Market:
limit_price: int,
max_quantity: int,
client_id: int = 0,
): # TODO: Add open_orders_address_key param and fee_discount_pubkey
opts: TxOpts = TxOpts(),
) -> RPCResponse: # TODO: Add open_orders_address_key param and fee_discount_pubkey
transaction = Transaction()
signers: List[Account] = [owner]
open_order_accounts = self.find_open_orders_accounts_for_owner(owner.public_key())
@ -224,7 +221,7 @@ class Market:
)
)
# TODO: extract `make_place_order_transaction`.
return self._send_transaction(transaction, *signers)
return self._conn.send_transaction(transaction, *signers, opts=opts)
@staticmethod
def _get_lamport_need_for_sol_wrapping(
@ -275,10 +272,11 @@ class Market:
)
)
def cancel_order_by_client_id(self, owner: Account, open_orders_account: PublicKey, client_id: int) -> str:
txs = Transaction()
txs.add(self.make_cancel_order_by_client_id_instruction(owner, open_orders_account, client_id))
return self._send_transaction(txs, owner)
def cancel_order_by_client_id(
self, owner: Account, open_orders_account: PublicKey, client_id: int, opts: TxOpts = TxOpts()
) -> RPCResponse:
txs = Transaction().add(self.make_cancel_order_by_client_id_instruction(owner, open_orders_account, client_id))
return self._conn.send_transaction(txs, owner, opts=opts)
def make_cancel_order_by_client_id_instruction(
self, owner: Account, open_orders_account: PublicKey, client_id: int
@ -294,13 +292,13 @@ class Market:
)
)
def cancel_order(self, owner: Account, order: t.Order) -> str:
def cancel_order(self, owner: Account, order: t.Order, opts: TxOpts = TxOpts()) -> RPCResponse:
txn = Transaction().add(self.make_cancel_order_instruction(owner.public_key(), order))
return self._send_transaction(txn, owner)
return self._conn.send_transaction(txn, owner, opts=opts)
def match_orders(self, fee_payer: Account, limit: int) -> str:
def match_orders(self, fee_payer: Account, limit: int, opts: TxOpts = TxOpts()) -> RPCResponse:
txn = Transaction().add(self.make_match_orders_instruction(limit))
return self._send_transaction(txn, fee_payer)
return self._conn.send_transaction(txn, fee_payer, opts=opts)
def make_cancel_order_instruction(self, owner: PublicKey, order: t.Order) -> TransactionInstruction:
params = instructions.CancelOrderParams(
@ -336,14 +334,6 @@ class Market:
base_wallet: PublicKey,
quote_wallet: PublicKey,
referrer_quote_wallet: PublicKey,
opts: TxOpts = TxOpts(),
) -> str:
raise NotImplementedError("settle_funds not implemented")
def _send_transaction(self, transaction: Transaction, *signers: Account) -> str:
res = self._conn.send_transaction(transaction, *signers, skip_preflight=self._skip_preflight)
if self._confirmations > 0:
self.logger.warning("Cannot confirm transaction yet.")
signature = res.get("result")
if not signature:
raise Exception("Transaction not sent successfully")
return str(signature)

View File

@ -38,13 +38,6 @@ class AccountFlags(NamedTuple):
)
class MarketOpts(NamedTuple):
skip_preflight: bool = False
""""""
confirmations: int = 10
""""""
class FilledOrder(NamedTuple):
order_id: int
""""""

View File

@ -4,7 +4,8 @@ import base64
from typing import List, NamedTuple, Sequence
from solana.publickey import PublicKey
from solana.rpc.api import Client, MemcmpOpt
from solana.rpc.api import Client
from solana.rpc.types import MemcmpOpts
from solana.system_program import CreateAccountParams, create_account
from solana.transaction import TransactionInstruction
@ -75,11 +76,11 @@ class OpenOrdersAccount:
conn: Client, market: PublicKey, owner: PublicKey, program_id: PublicKey
) -> List[OpenOrdersAccount]:
filters = [
MemcmpOpt(
MemcmpOpts(
offset=5 + 8, # 5 bytes of padding, 8 bytes of account flag
bytes=str(market),
),
MemcmpOpt(
MemcmpOpts(
offset=5 + 8 + 32, # 5 bytes of padding, 8 bytes of account flag, 32 bytes of market public key
bytes=str(owner),
),

View File

@ -4,12 +4,11 @@ import pytest
from solana.account import Account
from solana.publickey import PublicKey
from solana.rpc.api import Client
from solana.rpc.types import TxOpts
from pyserum.enums import OrderType, Side
from pyserum.market import Market
from .utils import confirm_transaction
@pytest.mark.integration
@pytest.fixture(scope="module")
@ -60,9 +59,8 @@ def test_market_load_requests(bootstrapped_market: Market):
@pytest.mark.integration
def test_match_order(bootstrapped_market: Market, stubbed_payer: Account, http_client: Client):
sig = bootstrapped_market.match_orders(stubbed_payer, 2)
confirm_transaction(http_client, sig)
def test_match_order(bootstrapped_market: Market, stubbed_payer: Account):
bootstrapped_market.match_orders(stubbed_payer, 2, TxOpts(skip_confirmation=False))
request_queue = bootstrapped_market.load_request_queue()
# 0 request after matching.
@ -85,20 +83,19 @@ def test_match_order(bootstrapped_market: Market, stubbed_payer: Account, http_c
def test_order_placement_cancellation_cycle(
bootstrapped_market: Market,
stubbed_payer: Account,
http_client: Client,
stubbed_quote_wallet: Account,
stubbed_base_wallet: Account,
):
initial_request_len = len(bootstrapped_market.load_request_queue())
sig = bootstrapped_market.place_order(
bootstrapped_market.place_order(
payer=stubbed_quote_wallet.public_key(),
owner=stubbed_payer,
side=Side.Buy,
order_type=OrderType.Limit,
limit_price=1000,
max_quantity=3000,
opts=TxOpts(skip_confirmation=False),
)
confirm_transaction(http_client, sig)
request_queue = bootstrapped_market.load_request_queue()
# 0 request after matching.
@ -112,19 +109,22 @@ def test_order_placement_cancellation_cycle(
asks = bootstrapped_market.load_asks()
assert sum(1 for _ in asks) == 0
sig = bootstrapped_market.place_order(
bootstrapped_market.place_order(
payer=stubbed_base_wallet.public_key(),
owner=stubbed_payer,
side=Side.Sell,
order_type=OrderType.Limit,
limit_price=1500,
max_quantity=3000,
opts=TxOpts(skip_confirmation=False),
)
confirm_transaction(http_client, sig)
# The two order shouldn't get executed since there is a price difference of 1
sig = bootstrapped_market.match_orders(stubbed_payer, 2)
confirm_transaction(http_client, sig)
bootstrapped_market.match_orders(
stubbed_payer,
2,
opts=TxOpts(skip_confirmation=False),
)
# There should be 1 bid order that we sent earlier.
bids = bootstrapped_market.load_bids()
@ -135,22 +135,18 @@ def test_order_placement_cancellation_cycle(
assert sum(1 for _ in asks) == 1
for bid in bids:
sig = bootstrapped_market.cancel_order(stubbed_payer, bid)
confirm_transaction(http_client, sig)
bootstrapped_market.cancel_order(stubbed_payer, bid, opts=TxOpts(skip_confirmation=False))
sig = bootstrapped_market.match_orders(stubbed_payer, 1)
confirm_transaction(http_client, sig)
bootstrapped_market.match_orders(stubbed_payer, 1, opts=TxOpts(skip_confirmation=False))
# All bid order should have been cancelled.
bids = bootstrapped_market.load_bids()
assert sum(1 for _ in bids) == 0
for ask in asks:
sig = bootstrapped_market.cancel_order(stubbed_payer, ask)
confirm_transaction(http_client, sig)
bootstrapped_market.cancel_order(stubbed_payer, ask, opts=TxOpts(skip_confirmation=False))
sig = bootstrapped_market.match_orders(stubbed_payer, 1)
confirm_transaction(http_client, sig)
bootstrapped_market.match_orders(stubbed_payer, 1, opts=TxOpts(skip_confirmation=False))
# All ask order should have been cancelled.
asks = bootstrapped_market.load_asks()

View File

@ -1,26 +0,0 @@
import time
from solana.rpc.api import Client
from solana.rpc.types import RPCResponse
DEFAULT_MAX_TIMEOUT = 30 # 30 seconds pylint: disable=invalid-name
def confirm_transaction(client: Client, tx_sig: str, time_out: int = DEFAULT_MAX_TIMEOUT) -> RPCResponse:
"""Confirm a transaction."""
elapsed_time = 0
while elapsed_time < time_out:
sleep_time = 3
if not elapsed_time:
sleep_time = 7
time.sleep(sleep_time)
else:
time.sleep(sleep_time)
resp = client.get_confirmed_transaction(tx_sig)
if resp.get("result"):
break
elapsed_time += sleep_time
if not resp.get("result"):
raise RuntimeError("could not confirm transaction: ", tx_sig)
return resp