New blockchains, improvements for db engine class

pull/1059/head
kompotkot 2024-04-22 09:39:19 +00:00
rodzic 262ea4c792
commit 1bb23eeda4
5 zmienionych plików z 322 dodań i 49 usunięć

Wyświetl plik

@ -31,6 +31,7 @@ from moonstreamdbv3.models import (
SepoliaLabel,
PolygonLabel,
MumbaiLabel,
AmoyLabel,
XDaiLabel,
ZkSyncEraLabel,
ZkSyncEraSepoliaLabel,
@ -41,6 +42,9 @@ from moonstreamdbv3.models import (
XaiSepoliaLabel,
AvalancheLabel,
AvalancheFujiLabel,
BlastLabel,
BlastSepoliaLabel,
ProofOfPlayApexLabel,
StarknetLabel,
StarknetSepoliaLabel,
)
@ -52,6 +56,7 @@ def include_symbol(tablename, schema):
SepoliaLabel.__tablename__,
PolygonLabel.__tablename__,
MumbaiLabel.__tablename__,
AmoyLabel.__tablename__,
XDaiLabel.__tablename__,
ZkSyncEraLabel.__tablename__,
ZkSyncEraSepoliaLabel.__tablename__,
@ -62,6 +67,9 @@ def include_symbol(tablename, schema):
XaiSepoliaLabel.__tablename__,
AvalancheLabel.__tablename__,
AvalancheFujiLabel.__tablename__,
BlastLabel.__tablename__,
BlastSepoliaLabel.__tablename__,
ProofOfPlayApexLabel.__tablename__,
StarknetLabel.__tablename__,
StarknetSepoliaLabel.__tablename__,
}

Wyświetl plik

@ -0,0 +1,185 @@
"""Amoy, Blast and Apex blockchains
Revision ID: e9e1b43f49e1
Revises: 994e614b5500
Create Date: 2024-04-22 09:35:56.509834
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision: str = 'e9e1b43f49e1'
down_revision: Union[str, None] = '994e614b5500'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('amoy_labels',
sa.Column('id', sa.UUID(), nullable=False),
sa.Column('label', sa.VARCHAR(length=256), nullable=False),
sa.Column('transaction_hash', sa.VARCHAR(length=128), nullable=False),
sa.Column('log_index', sa.Integer(), nullable=True),
sa.Column('block_number', sa.BigInteger(), nullable=False),
sa.Column('block_hash', sa.VARCHAR(length=256), nullable=False),
sa.Column('block_timestamp', sa.BigInteger(), nullable=False),
sa.Column('caller_address', sa.VARCHAR(length=64), nullable=True),
sa.Column('origin_address', sa.VARCHAR(length=64), nullable=True),
sa.Column('address', sa.VARCHAR(length=64), nullable=True),
sa.Column('label_name', sa.Text(), nullable=True),
sa.Column('label_type', sa.VARCHAR(length=64), nullable=True),
sa.Column('label_data', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text("TIMEZONE('utc', statement_timestamp())"), nullable=False),
sa.PrimaryKeyConstraint('id', name=op.f('pk_amoy_labels')),
sa.UniqueConstraint('id', name=op.f('uq_amoy_labels_id'))
)
op.create_index('ix_amoy_labels_addr_block_num', 'amoy_labels', ['address', 'block_number'], unique=False)
op.create_index('ix_amoy_labels_addr_block_ts', 'amoy_labels', ['address', 'block_timestamp'], unique=False)
op.create_index(op.f('ix_amoy_labels_address'), 'amoy_labels', ['address'], unique=False)
op.create_index(op.f('ix_amoy_labels_block_number'), 'amoy_labels', ['block_number'], unique=False)
op.create_index(op.f('ix_amoy_labels_caller_address'), 'amoy_labels', ['caller_address'], unique=False)
op.create_index(op.f('ix_amoy_labels_label'), 'amoy_labels', ['label'], unique=False)
op.create_index(op.f('ix_amoy_labels_label_name'), 'amoy_labels', ['label_name'], unique=False)
op.create_index(op.f('ix_amoy_labels_label_type'), 'amoy_labels', ['label_type'], unique=False)
op.create_index(op.f('ix_amoy_labels_origin_address'), 'amoy_labels', ['origin_address'], unique=False)
op.create_index(op.f('ix_amoy_labels_transaction_hash'), 'amoy_labels', ['transaction_hash'], unique=False)
op.create_table('blast_labels',
sa.Column('id', sa.UUID(), nullable=False),
sa.Column('label', sa.VARCHAR(length=256), nullable=False),
sa.Column('transaction_hash', sa.VARCHAR(length=128), nullable=False),
sa.Column('log_index', sa.Integer(), nullable=True),
sa.Column('block_number', sa.BigInteger(), nullable=False),
sa.Column('block_hash', sa.VARCHAR(length=256), nullable=False),
sa.Column('block_timestamp', sa.BigInteger(), nullable=False),
sa.Column('caller_address', sa.VARCHAR(length=64), nullable=True),
sa.Column('origin_address', sa.VARCHAR(length=64), nullable=True),
sa.Column('address', sa.VARCHAR(length=64), nullable=True),
sa.Column('label_name', sa.Text(), nullable=True),
sa.Column('label_type', sa.VARCHAR(length=64), nullable=True),
sa.Column('label_data', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text("TIMEZONE('utc', statement_timestamp())"), nullable=False),
sa.PrimaryKeyConstraint('id', name=op.f('pk_blast_labels')),
sa.UniqueConstraint('id', name=op.f('uq_blast_labels_id'))
)
op.create_index('ix_blast_labels_addr_block_num', 'blast_labels', ['address', 'block_number'], unique=False)
op.create_index('ix_blast_labels_addr_block_ts', 'blast_labels', ['address', 'block_timestamp'], unique=False)
op.create_index(op.f('ix_blast_labels_address'), 'blast_labels', ['address'], unique=False)
op.create_index(op.f('ix_blast_labels_block_number'), 'blast_labels', ['block_number'], unique=False)
op.create_index(op.f('ix_blast_labels_caller_address'), 'blast_labels', ['caller_address'], unique=False)
op.create_index(op.f('ix_blast_labels_label'), 'blast_labels', ['label'], unique=False)
op.create_index(op.f('ix_blast_labels_label_name'), 'blast_labels', ['label_name'], unique=False)
op.create_index(op.f('ix_blast_labels_label_type'), 'blast_labels', ['label_type'], unique=False)
op.create_index(op.f('ix_blast_labels_origin_address'), 'blast_labels', ['origin_address'], unique=False)
op.create_index(op.f('ix_blast_labels_transaction_hash'), 'blast_labels', ['transaction_hash'], unique=False)
op.create_table('blast_sepolia_labels',
sa.Column('id', sa.UUID(), nullable=False),
sa.Column('label', sa.VARCHAR(length=256), nullable=False),
sa.Column('transaction_hash', sa.VARCHAR(length=128), nullable=False),
sa.Column('log_index', sa.Integer(), nullable=True),
sa.Column('block_number', sa.BigInteger(), nullable=False),
sa.Column('block_hash', sa.VARCHAR(length=256), nullable=False),
sa.Column('block_timestamp', sa.BigInteger(), nullable=False),
sa.Column('caller_address', sa.VARCHAR(length=64), nullable=True),
sa.Column('origin_address', sa.VARCHAR(length=64), nullable=True),
sa.Column('address', sa.VARCHAR(length=64), nullable=True),
sa.Column('label_name', sa.Text(), nullable=True),
sa.Column('label_type', sa.VARCHAR(length=64), nullable=True),
sa.Column('label_data', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text("TIMEZONE('utc', statement_timestamp())"), nullable=False),
sa.PrimaryKeyConstraint('id', name=op.f('pk_blast_sepolia_labels')),
sa.UniqueConstraint('id', name=op.f('uq_blast_sepolia_labels_id'))
)
op.create_index('ix_blast_sepolia_labels_addr_block_num', 'blast_sepolia_labels', ['address', 'block_number'], unique=False)
op.create_index('ix_blast_sepolia_labels_addr_block_ts', 'blast_sepolia_labels', ['address', 'block_timestamp'], unique=False)
op.create_index(op.f('ix_blast_sepolia_labels_address'), 'blast_sepolia_labels', ['address'], unique=False)
op.create_index(op.f('ix_blast_sepolia_labels_block_number'), 'blast_sepolia_labels', ['block_number'], unique=False)
op.create_index(op.f('ix_blast_sepolia_labels_caller_address'), 'blast_sepolia_labels', ['caller_address'], unique=False)
op.create_index(op.f('ix_blast_sepolia_labels_label'), 'blast_sepolia_labels', ['label'], unique=False)
op.create_index(op.f('ix_blast_sepolia_labels_label_name'), 'blast_sepolia_labels', ['label_name'], unique=False)
op.create_index(op.f('ix_blast_sepolia_labels_label_type'), 'blast_sepolia_labels', ['label_type'], unique=False)
op.create_index(op.f('ix_blast_sepolia_labels_origin_address'), 'blast_sepolia_labels', ['origin_address'], unique=False)
op.create_index(op.f('ix_blast_sepolia_labels_transaction_hash'), 'blast_sepolia_labels', ['transaction_hash'], unique=False)
op.create_table('proofofplay_apex_labels',
sa.Column('id', sa.UUID(), nullable=False),
sa.Column('label', sa.VARCHAR(length=256), nullable=False),
sa.Column('transaction_hash', sa.VARCHAR(length=128), nullable=False),
sa.Column('log_index', sa.Integer(), nullable=True),
sa.Column('block_number', sa.BigInteger(), nullable=False),
sa.Column('block_hash', sa.VARCHAR(length=256), nullable=False),
sa.Column('block_timestamp', sa.BigInteger(), nullable=False),
sa.Column('caller_address', sa.VARCHAR(length=64), nullable=True),
sa.Column('origin_address', sa.VARCHAR(length=64), nullable=True),
sa.Column('address', sa.VARCHAR(length=64), nullable=True),
sa.Column('label_name', sa.Text(), nullable=True),
sa.Column('label_type', sa.VARCHAR(length=64), nullable=True),
sa.Column('label_data', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text("TIMEZONE('utc', statement_timestamp())"), nullable=False),
sa.PrimaryKeyConstraint('id', name=op.f('pk_proofofplay_apex_labels')),
sa.UniqueConstraint('id', name=op.f('uq_proofofplay_apex_labels_id'))
)
op.create_index('ix_proofofplay_apex_labels_addr_block_num', 'proofofplay_apex_labels', ['address', 'block_number'], unique=False)
op.create_index('ix_proofofplay_apex_labels_addr_block_ts', 'proofofplay_apex_labels', ['address', 'block_timestamp'], unique=False)
op.create_index(op.f('ix_proofofplay_apex_labels_address'), 'proofofplay_apex_labels', ['address'], unique=False)
op.create_index(op.f('ix_proofofplay_apex_labels_block_number'), 'proofofplay_apex_labels', ['block_number'], unique=False)
op.create_index(op.f('ix_proofofplay_apex_labels_caller_address'), 'proofofplay_apex_labels', ['caller_address'], unique=False)
op.create_index(op.f('ix_proofofplay_apex_labels_label'), 'proofofplay_apex_labels', ['label'], unique=False)
op.create_index(op.f('ix_proofofplay_apex_labels_label_name'), 'proofofplay_apex_labels', ['label_name'], unique=False)
op.create_index(op.f('ix_proofofplay_apex_labels_label_type'), 'proofofplay_apex_labels', ['label_type'], unique=False)
op.create_index(op.f('ix_proofofplay_apex_labels_origin_address'), 'proofofplay_apex_labels', ['origin_address'], unique=False)
op.create_index(op.f('ix_proofofplay_apex_labels_transaction_hash'), 'proofofplay_apex_labels', ['transaction_hash'], unique=False)
op.create_index('ix_arbitrum_nova_labels_addr_block_ts', 'arbitrum_nova_labels', ['address', 'block_timestamp'], unique=False)
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index(op.f('ix_proofofplay_apex_labels_transaction_hash'), table_name='proofofplay_apex_labels')
op.drop_index(op.f('ix_proofofplay_apex_labels_origin_address'), table_name='proofofplay_apex_labels')
op.drop_index(op.f('ix_proofofplay_apex_labels_label_type'), table_name='proofofplay_apex_labels')
op.drop_index(op.f('ix_proofofplay_apex_labels_label_name'), table_name='proofofplay_apex_labels')
op.drop_index(op.f('ix_proofofplay_apex_labels_label'), table_name='proofofplay_apex_labels')
op.drop_index(op.f('ix_proofofplay_apex_labels_caller_address'), table_name='proofofplay_apex_labels')
op.drop_index(op.f('ix_proofofplay_apex_labels_block_number'), table_name='proofofplay_apex_labels')
op.drop_index(op.f('ix_proofofplay_apex_labels_address'), table_name='proofofplay_apex_labels')
op.drop_index('ix_proofofplay_apex_labels_addr_block_ts', table_name='proofofplay_apex_labels')
op.drop_index('ix_proofofplay_apex_labels_addr_block_num', table_name='proofofplay_apex_labels')
op.drop_table('proofofplay_apex_labels')
op.drop_index(op.f('ix_blast_sepolia_labels_transaction_hash'), table_name='blast_sepolia_labels')
op.drop_index(op.f('ix_blast_sepolia_labels_origin_address'), table_name='blast_sepolia_labels')
op.drop_index(op.f('ix_blast_sepolia_labels_label_type'), table_name='blast_sepolia_labels')
op.drop_index(op.f('ix_blast_sepolia_labels_label_name'), table_name='blast_sepolia_labels')
op.drop_index(op.f('ix_blast_sepolia_labels_label'), table_name='blast_sepolia_labels')
op.drop_index(op.f('ix_blast_sepolia_labels_caller_address'), table_name='blast_sepolia_labels')
op.drop_index(op.f('ix_blast_sepolia_labels_block_number'), table_name='blast_sepolia_labels')
op.drop_index(op.f('ix_blast_sepolia_labels_address'), table_name='blast_sepolia_labels')
op.drop_index('ix_blast_sepolia_labels_addr_block_ts', table_name='blast_sepolia_labels')
op.drop_index('ix_blast_sepolia_labels_addr_block_num', table_name='blast_sepolia_labels')
op.drop_table('blast_sepolia_labels')
op.drop_index(op.f('ix_blast_labels_transaction_hash'), table_name='blast_labels')
op.drop_index(op.f('ix_blast_labels_origin_address'), table_name='blast_labels')
op.drop_index(op.f('ix_blast_labels_label_type'), table_name='blast_labels')
op.drop_index(op.f('ix_blast_labels_label_name'), table_name='blast_labels')
op.drop_index(op.f('ix_blast_labels_label'), table_name='blast_labels')
op.drop_index(op.f('ix_blast_labels_caller_address'), table_name='blast_labels')
op.drop_index(op.f('ix_blast_labels_block_number'), table_name='blast_labels')
op.drop_index(op.f('ix_blast_labels_address'), table_name='blast_labels')
op.drop_index('ix_blast_labels_addr_block_ts', table_name='blast_labels')
op.drop_index('ix_blast_labels_addr_block_num', table_name='blast_labels')
op.drop_table('blast_labels')
op.drop_index(op.f('ix_amoy_labels_transaction_hash'), table_name='amoy_labels')
op.drop_index(op.f('ix_amoy_labels_origin_address'), table_name='amoy_labels')
op.drop_index(op.f('ix_amoy_labels_label_type'), table_name='amoy_labels')
op.drop_index(op.f('ix_amoy_labels_label_name'), table_name='amoy_labels')
op.drop_index(op.f('ix_amoy_labels_label'), table_name='amoy_labels')
op.drop_index(op.f('ix_amoy_labels_caller_address'), table_name='amoy_labels')
op.drop_index(op.f('ix_amoy_labels_block_number'), table_name='amoy_labels')
op.drop_index(op.f('ix_amoy_labels_address'), table_name='amoy_labels')
op.drop_index('ix_amoy_labels_addr_block_ts', table_name='amoy_labels')
op.drop_index('ix_amoy_labels_addr_block_num', table_name='amoy_labels')
op.drop_table('amoy_labels')
# ### end Alembic commands ###

Wyświetl plik

@ -7,7 +7,7 @@ import os
from contextlib import contextmanager
from typing import Generator, Optional
from sqlalchemy import create_engine
from sqlalchemy import create_engine, Engine
from sqlalchemy.orm import Session, sessionmaker
logging.basicConfig(level=logging.INFO)
@ -21,35 +21,35 @@ try:
MOONSTREAM_DB_URI_READ_ONLY = os.environ.get("MOONSTREAM_DB_URI_READ_ONLY")
if MOONSTREAM_DB_URI_READ_ONLY is None:
raise Warning("MOONSTREAM_DB_URI_READ_ONLY environment variable must be set")
MOONSTREAM_POOL_SIZE_RAW = os.environ.get("MOONSTREAM_POOL_SIZE")
MOONSTREAM_POOL_SIZE = 1
try:
if MOONSTREAM_POOL_SIZE_RAW is not None:
MOONSTREAM_POOL_SIZE = int(MOONSTREAM_POOL_SIZE_RAW)
except:
raise ValueError(
f"Could not parse MOONSTREAM_POOL_SIZE as int: {MOONSTREAM_POOL_SIZE_RAW}"
)
MOONSTREAM_DB_STATEMENT_TIMEOUT_MILLIS_RAW = os.environ.get(
"MOONSTREAM_DB_STATEMENT_TIMEOUT_MILLIS"
)
MOONSTREAM_DB_STATEMENT_TIMEOUT_MILLIS = 30000
try:
if MOONSTREAM_DB_STATEMENT_TIMEOUT_MILLIS_RAW is not None:
MOONSTREAM_DB_STATEMENT_TIMEOUT_MILLIS = int(
MOONSTREAM_DB_STATEMENT_TIMEOUT_MILLIS_RAW
)
except:
raise ValueError(
f"MOONSTREAM_DB_STATEMENT_TIMEOUT_MILLIS must be an integer: {MOONSTREAM_DB_STATEMENT_TIMEOUT_MILLIS_RAW}"
)
except ValueError as e:
raise ValueError(e)
except Warning:
logger.warning("Database variables not set")
MOONSTREAM_POOL_SIZE_RAW = os.environ.get("MOONSTREAM_POOL_SIZE")
MOONSTREAM_POOL_SIZE = 1
try:
if MOONSTREAM_POOL_SIZE_RAW is not None:
MOONSTREAM_POOL_SIZE = int(MOONSTREAM_POOL_SIZE_RAW)
except:
raise ValueError(
f"Could not parse MOONSTREAM_POOL_SIZE as int: {MOONSTREAM_POOL_SIZE_RAW}"
)
MOONSTREAM_DB_STATEMENT_TIMEOUT_MILLIS_RAW = os.environ.get(
"MOONSTREAM_DB_STATEMENT_TIMEOUT_MILLIS"
)
MOONSTREAM_DB_STATEMENT_TIMEOUT_MILLIS = 30000
try:
if MOONSTREAM_DB_STATEMENT_TIMEOUT_MILLIS_RAW is not None:
MOONSTREAM_DB_STATEMENT_TIMEOUT_MILLIS = int(
MOONSTREAM_DB_STATEMENT_TIMEOUT_MILLIS_RAW
)
except:
raise ValueError(
f"MOONSTREAM_DB_STATEMENT_TIMEOUT_MILLIS must be an integer: {MOONSTREAM_DB_STATEMENT_TIMEOUT_MILLIS_RAW}"
)
def create_moonstream_engine(
url: str,
@ -57,7 +57,7 @@ def create_moonstream_engine(
statement_timeout: int,
pool_pre_ping: bool = False,
schema: Optional[str] = None,
):
) -> Engine:
# Pooling: https://docs.sqlalchemy.org/en/14/core/pooling.html#sqlalchemy.pool.QueuePool
# Statement timeout: https://stackoverflow.com/a/44936982
options = f"-c statement_timeout={statement_timeout}"
@ -71,22 +71,28 @@ def create_moonstream_engine(
)
class MoonstreamDBEngine:
def __init__(self, schema: Optional[str] = None) -> None:
class DBEngine:
def __init__(self, url: str, schema: Optional[str] = None) -> None:
self._engine = create_moonstream_engine(
url=MOONSTREAM_DB_URI, # type: ignore
url=url, # type: ignore
pool_size=MOONSTREAM_POOL_SIZE,
statement_timeout=MOONSTREAM_DB_STATEMENT_TIMEOUT_MILLIS,
schema=schema,
)
@property
def engine(self) -> Engine:
return self._engine
class MoonstreamDBEngine(DBEngine):
def __init__(self, schema: Optional[str] = None) -> None:
super().__init__(url=MOONSTREAM_DB_URI, schema=schema)
self._session_local = sessionmaker(bind=self.engine)
self._yield_db_session_ctx = contextmanager(self.yield_db_session)
@property
def engine(self):
return self._engine
@property
def session_local(self):
return self._session_local
@ -110,29 +116,27 @@ class MoonstreamDBEngine:
session.close()
class MoonstreamDBEngineRO:
class MoonstreamDBEngineRO(DBEngine):
def __init__(self, schema: Optional[str] = None) -> None:
self._RO_engine = create_moonstream_engine(
url=MOONSTREAM_DB_URI_READ_ONLY, # type: ignore
pool_size=MOONSTREAM_POOL_SIZE,
statement_timeout=MOONSTREAM_DB_STATEMENT_TIMEOUT_MILLIS,
schema=schema,
)
self._RO_session_local = sessionmaker(bind=self.RO_engine)
self._RO_yield_db_session_ctx = contextmanager(self.yield_db_read_only_session)
super().__init__(url=MOONSTREAM_DB_URI_READ_ONLY, schema=schema)
@property
def RO_engine(self):
return self._RO_engine
def engine(self):
raise AttributeError(
"RO_engine should be used instead of engine for read-only access."
)
@property
def RO_engine(self) -> Engine:
return self._engine
@property
def RO_session_local(self):
return self._RO_session_local
return self._session_local
@property
def RO_yield_db_session_ctx(self):
return self._RO_yield_db_session_ctx
return self._yield_db_session_ctx
def yield_db_read_only_session(self) -> Generator[Session, None, None]:
"""
@ -140,7 +144,7 @@ class MoonstreamDBEngineRO:
As per FastAPI docs:
https://fastapi.tiangolo.com/tutorial/sql-databases/#create-a-dependency
"""
session = self._RO_session_local()
session = self._session_local()
try:
yield session
finally:

Wyświetl plik

@ -193,6 +193,25 @@ class MumbaiLabel(EvmBasedLabel): # type: ignore
)
class AmoyLabel(EvmBasedLabel): # type: ignore
__tablename__ = "amoy_labels"
__table_args__ = (
Index(
"ix_amoy_labels_addr_block_num",
"address",
"block_number",
unique=False,
),
Index(
"ix_amoy_labels_addr_block_ts",
"address",
"block_timestamp",
unique=False,
),
)
class XDaiLabel(EvmBasedLabel): # type: ignore
__tablename__ = "xdai_labels"
@ -383,6 +402,63 @@ class AvalancheFujiLabel(EvmBasedLabel): # type: ignore
)
class BlastLabel(EvmBasedLabel): # type: ignore
__tablename__ = "blast_labels"
__table_args__ = (
Index(
"ix_blast_labels_addr_block_num",
"address",
"block_number",
unique=False,
),
Index(
"ix_blast_labels_addr_block_ts",
"address",
"block_timestamp",
unique=False,
),
)
class BlastSepoliaLabel(EvmBasedLabel): # type: ignore
__tablename__ = "blast_sepolia_labels"
__table_args__ = (
Index(
"ix_blast_sepolia_labels_addr_block_num",
"address",
"block_number",
unique=False,
),
Index(
"ix_blast_sepolia_labels_addr_block_ts",
"address",
"block_timestamp",
unique=False,
),
)
class ProofOfPlayApexLabel(EvmBasedLabel): # type: ignore
__tablename__ = "proofofplay_apex_labels"
__table_args__ = (
Index(
"ix_proofofplay_apex_labels_addr_block_num",
"address",
"block_number",
unique=False,
),
Index(
"ix_proofofplay_apex_labels_addr_block_ts",
"address",
"block_timestamp",
unique=False,
),
)
class StarknetLabel(EvmBasedLabel): # type: ignore
__tablename__ = "starknet_labels"

Wyświetl plik

@ -1 +1 @@
0.0.2
0.0.3