From 616d929e90bb84373efaba25d57f90f8c754a53d Mon Sep 17 00:00:00 2001 From: Geoff Taylor Date: Tue, 8 Jun 2021 08:17:37 +0100 Subject: [PATCH] Removed context from Group, added name. Price lookups must now pass the context they want to use. --- Liquidation.ipynb | 6 +++--- Pandas.ipynb | 2 +- ShowAccount.ipynb | 13 +++++++------ bin/group-balance-wallet | 2 +- bin/group-balances | 2 +- bin/liquidate-single-account | 2 +- bin/liquidator-single-run | 2 +- mango/accountliquidator.py | 4 ++-- mango/group.py | 29 ++++++++++++++--------------- mango/marginaccount.py | 4 ++-- tests/test_group.py | 8 ++++---- 11 files changed, 37 insertions(+), 37 deletions(-) diff --git a/Liquidation.ipynb b/Liquidation.ipynb index cc51044..5765f0c 100644 --- a/Liquidation.ipynb +++ b/Liquidation.ipynb @@ -159,10 +159,10 @@ " else:\n", " print(\"Wallet Balances Before:\")\n", " group = mango.Group.load(context)\n", - " balances_before = group.fetch_balances(wallet.address)\n", + " balances_before = group.fetch_balances(context, wallet.address)\n", " mango.TokenValue.report(print, balances_before)\n", "\n", - " prices = group.fetch_token_prices()\n", + " prices = group.fetch_token_prices(context)\n", " margin_account = mango.MarginAccount.load(context, PublicKey(MARGIN_ACCOUNT_TO_LIQUIDATE), group)\n", " intrinsic_balance_sheets_before = margin_account.get_intrinsic_balance_sheets(group)\n", " print(\"Margin Account Before:\", intrinsic_balance_sheets_before)\n", @@ -181,7 +181,7 @@ " intrinsic_balance_sheets_after = margin_account_after_liquidation.get_intrinsic_balance_sheets(group_after)\n", " print(\"Margin Account After:\", intrinsic_balance_sheets_after)\n", " print(\"Wallet Balances After:\")\n", - " balances_after = group_after.fetch_balances(wallet.address)\n", + " balances_after = group_after.fetch_balances(context, wallet.address)\n", " mango.TokenValue.report(print, balances_after)\n", "\n", " print(\"Wallet Balances Changes:\")\n", diff --git a/Pandas.ipynb b/Pandas.ipynb index 828af15..30191e1 100644 --- a/Pandas.ipynb +++ b/Pandas.ipynb @@ -60,7 +60,7 @@ "print(f\"Done. Time taken: {time.time() - start_time}\")\n", "\n", "print(\"Loading prices...\")\n", - "prices = group.fetch_token_prices()\n", + "prices = group.fetch_token_prices(context)\n", "print(f\"Done. Time taken: {time.time() - start_time}\")\n", "\n", "print(\"Loading margin accounts...\")\n", diff --git a/ShowAccount.ipynb b/ShowAccount.ipynb index daf3bc9..8802078 100644 --- a/ShowAccount.ipynb +++ b/ShowAccount.ipynb @@ -61,7 +61,8 @@ " if ACCOUNT_TO_LOOK_UP == \"\":\n", " raise Exception(\"No account to look up - try setting the variable ACCOUNT_TO_LOOK_UP to an account public key.\")\n", "\n", - " # print(\"Context:\", default_context)\n", + " context = mango.default_context\n", + " # print(\"Context:\", context)\n", "\n", " root_account_key = publickey.PublicKey(ACCOUNT_TO_LOOK_UP)\n", " root_account = mango.AccountInfo.load(mango.default_context, root_account_key)\n", @@ -73,16 +74,16 @@ " raise Exception(f\"Account '{root_account_key}' is not a root user account.\")\n", "\n", " scout = mango.AccountScout()\n", - " group = mango.Group.load(mango.default_context)\n", - " scout_report = scout.verify_account_prepared_for_group(mango.default_context, group, root_account_key)\n", + " group = mango.Group.load(context)\n", + " scout_report = scout.verify_account_prepared_for_group(context, group, root_account_key)\n", " print(scout_report)\n", "\n", " print(\"Balances:\")\n", - " mango.TokenValue.report(print, group.fetch_balances(root_account_key))\n", + " mango.TokenValue.report(print, group.fetch_balances(context, root_account_key))\n", "\n", - " prices = group.fetch_token_prices()\n", + " prices = group.fetch_token_prices(context)\n", "\n", - " margin_accounts = mango.MarginAccount.load_all_for_owner(mango.default_context, root_account_key, group)\n", + " margin_accounts = mango.MarginAccount.load_all_for_owner(context, root_account_key, group)\n", " print(f\"Account has {len(margin_accounts)} margin account(s).\")\n", " for margin_account in margin_accounts:\n", " print(\"Margin account:\", margin_account)\n", diff --git a/bin/group-balance-wallet b/bin/group-balance-wallet index c7a86a1..f6adfc9 100755 --- a/bin/group-balance-wallet +++ b/bin/group-balance-wallet @@ -71,7 +71,7 @@ try: targets = list(map(balance_parser.parse, args.target)) logging.info(f"Targets: {targets}") - prices = group.fetch_token_prices() + prices = group.fetch_token_prices(context) logging.info(f"Prices: {prices}") if args.dry_run: diff --git a/bin/group-balances b/bin/group-balances index 3cf3e04..239d5a9 100755 --- a/bin/group-balances +++ b/bin/group-balances @@ -48,7 +48,7 @@ try: logging.info(f"Wallet address: {wallet.address}") group = mango.Group.load(context) - balances = group.fetch_balances(wallet.address) + balances = group.fetch_balances(context, wallet.address) print("Balances:") mango.TokenValue.report(print, balances) except Exception as exception: diff --git a/bin/liquidate-single-account b/bin/liquidate-single-account index bb68c28..09225ba 100755 --- a/bin/liquidate-single-account +++ b/bin/liquidate-single-account @@ -108,7 +108,7 @@ try: liquidations_publisher, liquidator_name) - prices = group.fetch_token_prices() + prices = group.fetch_token_prices(context) margin_account = mango.MarginAccount.load(context, margin_account_address, group) transaction_id = account_liquidator.liquidate(group, margin_account, prices) diff --git a/bin/liquidator-single-run b/bin/liquidator-single-run index 67a94d5..c107142 100755 --- a/bin/liquidator-single-run +++ b/bin/liquidator-single-run @@ -112,7 +112,7 @@ try: liquidation_processor.update_margin_accounts(ripe) group = mango.Group.load(context) # Refresh group data - prices = group.fetch_token_prices() + prices = group.fetch_token_prices(context) liquidation_processor.update_prices(group, prices) time_taken = time.time() - started_at diff --git a/mango/accountliquidator.py b/mango/accountliquidator.py index 898b2c2..d5e9f24 100644 --- a/mango/accountliquidator.py +++ b/mango/accountliquidator.py @@ -197,7 +197,7 @@ class ReportingAccountLiquidator(AccountLiquidator): balances = margin_account.get_intrinsic_balances(group) mam = MarginAccountMetadata(margin_account, balance_sheet, balances) - balances_before = group.fetch_balances(self.wallet.address) + balances_before = group.fetch_balances(self.context, self.wallet.address) self.logger.info("Wallet balances before:") TokenValue.report(self.logger.info, balances_before) @@ -223,7 +223,7 @@ class ReportingAccountLiquidator(AccountLiquidator): self.logger.info(f"Margin account balances after: {intrinsic_balances_after}") self.logger.info("Wallet Balances After:") - balances_after = group_after.fetch_balances(self.wallet.address) + balances_after = group_after.fetch_balances(self.context, self.wallet.address) TokenValue.report(self.logger.info, balances_after) liquidation_event = LiquidationEvent(datetime.datetime.now(), diff --git a/mango/group.py b/mango/group.py index 548ad92..52d9b1f 100644 --- a/mango/group.py +++ b/mango/group.py @@ -43,7 +43,7 @@ from .version import Version class Group(AddressableAccount): - def __init__(self, account_info: AccountInfo, version: Version, context: Context, + def __init__(self, account_info: AccountInfo, version: Version, name: str, account_flags: MangoAccountFlags, basket_tokens: typing.List[BasketToken], markets: typing.List[MarketMetadata], signer_nonce: Decimal, signer_key: PublicKey, dex_program_id: PublicKey, @@ -52,7 +52,7 @@ class Group(AddressableAccount): admin: PublicKey, borrow_limits: typing.List[TokenValue]): super().__init__(account_info) self.version: Version = version - self.context: Context = context + self.name: str = name self.account_flags: MangoAccountFlags = account_flags self.basket_tokens: typing.List[BasketToken] = basket_tokens self.markets: typing.List[MarketMetadata] = markets @@ -85,7 +85,7 @@ class Group(AddressableAccount): # stick with passing around `Token` objects. # @staticmethod - def from_layout(layout: construct.Struct, context: Context, account_info: AccountInfo, version: Version, token_lookup: TokenLookup = TokenLookup.default_lookups(), spot_market_lookup: SpotMarketLookup = SpotMarketLookup.default_lookups()) -> "Group": + def from_layout(layout: construct.Struct, name: str, account_info: AccountInfo, version: Version, token_lookup: TokenLookup = TokenLookup.default_lookups(), spot_market_lookup: SpotMarketLookup = SpotMarketLookup.default_lookups()) -> "Group": account_flags: MangoAccountFlags = MangoAccountFlags.from_layout(layout.account_flags) basket_tokens: typing.List[BasketToken] = [] @@ -122,7 +122,7 @@ class Group(AddressableAccount): maint_coll_ratio = layout.maint_coll_ratio.quantize(Decimal('.01')) init_coll_ratio = layout.init_coll_ratio.quantize(Decimal('.01')) - return Group(account_info, version, context, account_flags, basket_tokens, markets, + return Group(account_info, version, name, account_flags, basket_tokens, markets, layout.signer_nonce, layout.signer_key, layout.dex_program_id, total_deposits, total_borrows, maint_coll_ratio, init_coll_ratio, layout.srm_vault, layout.admin, borrow_limits) @@ -140,7 +140,7 @@ class Group(AddressableAccount): raise Exception( f"Group data length ({len(data)}) does not match expected size ({layouts.GROUP_V1.sizeof()} or {layouts.GROUP_V2.sizeof()})") - return Group.from_layout(layout, context, account_info, version) + return Group.from_layout(layout, context.group_name, account_info, version) @staticmethod def load(context: Context): @@ -155,19 +155,18 @@ class Group(AddressableAccount): return index return -1 - def fetch_token_prices(self) -> typing.List[TokenValue]: + def fetch_token_prices(self, context: Context) -> typing.List[TokenValue]: started_at = time.time() # Note: we can just load the oracle data in a simpler way, with: - # oracles = map(lambda market: Aggregator.load(self.context, market.oracle), self.markets) + # oracles = map(lambda market: Aggregator.load(context, market.oracle), self.markets) # but that makes a network request for every oracle. We can reduce that to just one request # if we use AccountInfo.load_multiple() and parse the data ourselves. # # This seems to halve the time this function takes. oracle_addresses = list([market.oracle for market in self.markets]) - oracle_account_infos = AccountInfo.load_multiple(self.context, oracle_addresses) - oracles = map(lambda oracle_account_info: Aggregator.parse( - self.context, oracle_account_info), oracle_account_infos) + oracle_account_infos = AccountInfo.load_multiple(context, oracle_addresses) + oracles = map(lambda oracle_account_info: Aggregator.parse(context, oracle_account_info), oracle_account_infos) prices = list(map(lambda oracle: oracle.price, oracles)) + [Decimal(1)] token_prices = [] for index, price in enumerate(prices): @@ -180,16 +179,16 @@ class Group(AddressableAccount): @staticmethod def load_with_prices(context: Context) -> typing.Tuple["Group", typing.List[TokenValue]]: group = Group.load(context) - prices = group.fetch_token_prices() + prices = group.fetch_token_prices(context) return group, prices - def fetch_balances(self, root_address: PublicKey) -> typing.List[TokenValue]: + def fetch_balances(self, context: Context, root_address: PublicKey) -> typing.List[TokenValue]: balances: typing.List[TokenValue] = [] - sol_balance = self.context.fetch_sol_balance(root_address) + sol_balance = context.fetch_sol_balance(root_address) balances += [TokenValue(SolToken, sol_balance)] for basket_token in self.basket_tokens: - balance = TokenValue.fetch_total_value(self.context, root_address, basket_token.token) + balance = TokenValue.fetch_total_value(context, root_address, basket_token.token) balances += [balance] return balances @@ -201,7 +200,7 @@ class Group(AddressableAccount): base_tokens = "\n ".join([f"{tok}".replace("\n", "\n ") for tok in self.base_tokens]) markets = "\n ".join([f"{mkt}".replace("\n", "\n ") for mkt in self.markets]) return f""" -« Group [{self.version}] {self.address}: +« Group [{self.version} - {self.name}] {self.address}: Flags: {self.account_flags} Base Tokens: {base_tokens} diff --git a/mango/marginaccount.py b/mango/marginaccount.py index 166ad24..810a482 100644 --- a/mango/marginaccount.py +++ b/mango/marginaccount.py @@ -305,7 +305,7 @@ class MarginAccount(AddressableAccount): margin_accounts = MarginAccount.load_all_for_group_with_open_orders(context, context.program_id, group) logger.info(f"Fetched {len(margin_accounts)} V1 margin accounts to process.") - prices = group.fetch_token_prices() + prices = group.fetch_token_prices(context) ripe_accounts = MarginAccount.filter_out_unripe(margin_accounts, group, prices) time_taken = time.time() - started_at @@ -367,7 +367,7 @@ class MarginAccount(AddressableAccount): for margin_account in margin_accounts: margin_account.install_open_orders_accounts(group, open_orders) - prices = group.fetch_token_prices() + prices = group.fetch_token_prices(context) ripe_accounts = MarginAccount.filter_out_unripe(margin_accounts, group, prices) time_taken = time.time() - started_at diff --git a/tests/test_group.py b/tests/test_group.py index 5c1981f..a369c53 100644 --- a/tests/test_group.py +++ b/tests/test_group.py @@ -1,5 +1,5 @@ from .context import mango -from .fakes import fake_account_info, fake_context, fake_seeded_public_key, fake_token +from .fakes import fake_account_info, fake_seeded_public_key, fake_token from decimal import Decimal @@ -8,7 +8,7 @@ import base64 def test_construction(): account_info = fake_account_info() - context = fake_context() + name = "FAKE_GROUP" account_flags = mango.MangoAccountFlags(mango.Version.V1, True, False, True, False) basket_tokens = [fake_token(), fake_token(), fake_token()] markets = [] @@ -23,14 +23,14 @@ def test_construction(): admin = fake_seeded_public_key("admin") borrow_limits = [Decimal(5), Decimal(7), Decimal(2)] - actual = mango.Group(account_info, mango.Version.V1, context, account_flags, + actual = mango.Group(account_info, mango.Version.V1, name, account_flags, basket_tokens, markets, signer_nonce, signer_key, dex_program_id, total_deposits, total_borrows, maint_coll_ratio, init_coll_ratio, srm_vault, admin, borrow_limits) assert actual is not None assert actual.logger is not None - assert actual.context == context + assert actual.name == name assert actual.account_flags == account_flags assert actual.basket_tokens == basket_tokens assert actual.markets == markets