From 97e6c156ab57e1d18a1cd8cb022964c6fe0b674e Mon Sep 17 00:00:00 2001 From: Shea Ketsdever Date: Sun, 19 Dec 2021 15:13:01 -0800 Subject: [PATCH] Add nft_trades table to db --- .../3c54832385e3_create_nft_trades_table.py | 41 +++++++++++++++++++ mev_inspect/classifiers/helpers.py | 2 +- mev_inspect/classifiers/specs/opensea.py | 2 +- mev_inspect/crud/nft_trades.py | 28 +++++++++++++ mev_inspect/inspect_block.py | 7 +++- mev_inspect/models/nft_trades.py | 21 ++++++++++ mev_inspect/nft_trades.py | 8 ++-- mev_inspect/schemas/classifiers.py | 2 +- .../schemas/{nft_trade.py => nft_trades.py} | 0 9 files changed, 103 insertions(+), 8 deletions(-) create mode 100644 alembic/versions/3c54832385e3_create_nft_trades_table.py create mode 100644 mev_inspect/crud/nft_trades.py create mode 100644 mev_inspect/models/nft_trades.py rename mev_inspect/schemas/{nft_trade.py => nft_trades.py} (100%) diff --git a/alembic/versions/3c54832385e3_create_nft_trades_table.py b/alembic/versions/3c54832385e3_create_nft_trades_table.py new file mode 100644 index 0000000..9807db5 --- /dev/null +++ b/alembic/versions/3c54832385e3_create_nft_trades_table.py @@ -0,0 +1,41 @@ + + +"""Create NFT Trades table + +Revision ID: 3c54832385e3 +Revises: 15ba9c27ee8a +Create Date: 2021-12-19 22:50:28.936516 + +""" +import sqlalchemy as sa +from alembic import op + +# revision identifiers, used by Alembic. +revision = "3c54832385e3" +down_revision = "15ba9c27ee8a" +branch_labels = None +depends_on = None + +def upgrade(): + op.create_table( + "nft_trades", + sa.Column("created_at", sa.TIMESTAMP, server_default=sa.func.now()), + sa.Column("abi_name", sa.String(1024), nullable=False), + sa.Column("transaction_hash", sa.String(66), nullable=False), + sa.Column("transaction_position", sa.Numeric, nullable=False), + sa.Column("block_number", sa.Numeric, nullable=False), + sa.Column("trace_address", sa.String(256), nullable=False), + sa.Column("protocol", sa.String(256), nullable=False), + sa.Column("error", sa.String(256), nullable=True), + sa.Column("seller_address", sa.String(256), nullable=False), + sa.Column("buyer_address", sa.String(256), nullable=False), + sa.Column("payment_token", sa.String(256), nullable=False), + sa.Column("payment_amount", sa.Numeric, nullable=False), + sa.Column("collection_address", sa.String(256), nullable=False), + sa.Column("token_id", sa.Numeric, nullable=False), + sa.PrimaryKeyConstraint("transaction_hash", "trace_address"), + ) + + +def downgrade(): + op.drop_table("nft_trades") diff --git a/mev_inspect/classifiers/helpers.py b/mev_inspect/classifiers/helpers.py index de99e18..c242371 100644 --- a/mev_inspect/classifiers/helpers.py +++ b/mev_inspect/classifiers/helpers.py @@ -1,5 +1,5 @@ from typing import List, Optional, Sequence -from mev_inspect.schemas.nft_trade import NftTrade +from mev_inspect.schemas.nft_trades import NftTrade from mev_inspect.schemas.swaps import Swap from mev_inspect.schemas.traces import ClassifiedTrace, DecodedCallTrace diff --git a/mev_inspect/classifiers/specs/opensea.py b/mev_inspect/classifiers/specs/opensea.py index 2507134..630bfa2 100644 --- a/mev_inspect/classifiers/specs/opensea.py +++ b/mev_inspect/classifiers/specs/opensea.py @@ -1,7 +1,7 @@ from typing import List, Optional from mev_inspect.classifiers.helpers import _filter_transfers, create_nft_trade_from_transfers from mev_inspect.schemas.classifiers import ClassifierSpec, NftTradeClassifier -from mev_inspect.schemas.nft_trade import NftTrade +from mev_inspect.schemas.nft_trades import NftTrade from mev_inspect.schemas.traces import DecodedCallTrace, Protocol from mev_inspect.schemas.transfers import ETH_TOKEN_ADDRESS, Transfer diff --git a/mev_inspect/crud/nft_trades.py b/mev_inspect/crud/nft_trades.py new file mode 100644 index 0000000..1317b03 --- /dev/null +++ b/mev_inspect/crud/nft_trades.py @@ -0,0 +1,28 @@ +import json +from typing import List + +from mev_inspect.models.nft_trades import NftTradeModel +from mev_inspect.schemas.nft_trades import NftTrade + + +def delete_nft_trades_for_block( + db_session, + block_number: int, +) -> None: + ( + db_session.query(NftTradeModel) + .filter(NftTradeModel.block_number == block_number) + .delete() + ) + + db_session.commit() + + +def write_nft_trades( + db_session, + nft_trades: List[NftTrade], +) -> None: + models = [NftTradeModel(**json.loads(nft_trade.json())) for nft_trade in nft_trades] + + db_session.bulk_save_objects(models) + db_session.commit() diff --git a/mev_inspect/inspect_block.py b/mev_inspect/inspect_block.py index e633b24..f581c55 100644 --- a/mev_inspect/inspect_block.py +++ b/mev_inspect/inspect_block.py @@ -26,19 +26,21 @@ from mev_inspect.crud.punks import ( write_punk_snipes, ) from mev_inspect.crud.sandwiches import delete_sandwiches_for_block, write_sandwiches -from mev_inspect.nft_trades import get_nft_trades from mev_inspect.crud.swaps import delete_swaps_for_block, write_swaps from mev_inspect.crud.traces import ( delete_classified_traces_for_block, write_classified_traces, ) from mev_inspect.crud.transfers import delete_transfers_for_block, write_transfers +from mev_inspect.crud.nft_trades import delete_nft_trades_for_block, write_nft_trades + from mev_inspect.liquidations import get_liquidations from mev_inspect.miner_payments import get_miner_payments from mev_inspect.punks import get_punk_bid_acceptances, get_punk_bids, get_punk_snipes from mev_inspect.sandwiches import get_sandwiches from mev_inspect.swaps import get_swaps from mev_inspect.transfers import get_transfers +from mev_inspect.nft_trades import get_nft_trades logger = logging.getLogger(__name__) @@ -125,6 +127,9 @@ async def inspect_block( nft_trades = get_nft_trades(classified_traces) logger.info(f"Block: {block_number} -- Found {len(nft_trades)} nft trades") + delete_nft_trades_for_block(inspect_db_session, block_number) + write_nft_trades(inspect_db_session, nft_trades) + miner_payments = get_miner_payments( block.miner, block.base_fee_per_gas, classified_traces, block.receipts ) diff --git a/mev_inspect/models/nft_trades.py b/mev_inspect/models/nft_trades.py new file mode 100644 index 0000000..db55084 --- /dev/null +++ b/mev_inspect/models/nft_trades.py @@ -0,0 +1,21 @@ +from sqlalchemy import ARRAY, Column, Integer, Numeric, String + +from .base import Base + + +class NftTradeModel(Base): + __tablename__ = "nft_trades" + + abi_name = Column(String, nullable=False) + transaction_hash = Column(String, primary_key=True) + transaction_position = Column(Numeric, nullable=True) + block_number = Column(Numeric, nullable=False) + trace_address = Column(ARRAY(Integer), primary_key=True) + protocol = Column(String, nullable=True) + error = Column(String, nullable=True) + seller_address = Column(String, nullable=False) + buyer_address = Column(String, nullable=False) + payment_token = Column(String, nullable=False) + payment_amount = Column(Numeric, nullable=False) + collection_address = Column(String, nullable=False) + token_id = Column(Numeric, nullable=False) diff --git a/mev_inspect/nft_trades.py b/mev_inspect/nft_trades.py index 710a087..eb35c62 100644 --- a/mev_inspect/nft_trades.py +++ b/mev_inspect/nft_trades.py @@ -1,7 +1,7 @@ from typing import List, Optional from mev_inspect.classifiers.specs import get_classifier from mev_inspect.schemas.classifiers import NftTradeClassifier -from mev_inspect.schemas.nft_trade import NftTrade +from mev_inspect.schemas.nft_trades import NftTrade from mev_inspect.schemas.traces import Classification, ClassifiedTrace, DecodedCallTrace from mev_inspect.schemas.transfers import Transfer from mev_inspect.traces import get_traces_by_transaction_hash @@ -38,13 +38,13 @@ def _get_nft_trades_for_transaction( trace.trace_address, traces, ) - nft_transfer = _parse_trade( + nft_trade = _parse_trade( trace, remove_child_transfers_of_transfers(child_transfers), ) - if nft_transfer is not None: - nft_trades.append(nft_transfer) + if nft_trade is not None: + nft_trades.append(nft_trade) return nft_trades diff --git a/mev_inspect/schemas/classifiers.py b/mev_inspect/schemas/classifiers.py index 06597f4..03eb548 100644 --- a/mev_inspect/schemas/classifiers.py +++ b/mev_inspect/schemas/classifiers.py @@ -6,7 +6,7 @@ from pydantic import BaseModel from .swaps import Swap from .traces import Classification, DecodedCallTrace, Protocol from .transfers import Transfer -from .nft_trade import NftTrade +from .nft_trades import NftTrade class Classifier(ABC): diff --git a/mev_inspect/schemas/nft_trade.py b/mev_inspect/schemas/nft_trades.py similarity index 100% rename from mev_inspect/schemas/nft_trade.py rename to mev_inspect/schemas/nft_trades.py