Merge branch 'main' into add-batch-jobs-endpoint

pull/847/head
Andrey 2023-07-13 11:31:31 +03:00
commit 36d7796baf
42 zmienionych plików z 26784 dodań i 231 usunięć

Wyświetl plik

@ -7,7 +7,7 @@ on:
defaults: defaults:
run: run:
working-directory: db working-directory: moonstreamdb
jobs: jobs:
publish: publish:

Wyświetl plik

@ -82,7 +82,7 @@ Stream of event packs will be generating from recent timestamp to older and inne
**From timestamp to timestamp, from bottom to top** **From timestamp to timestamp, from bottom to top**
When `start_time` is less then `end_time`. When `start_time` is less than `end_time`.
```python ```python
for events in mc.create_stream( for events in mc.create_stream(

Wyświetl plik

@ -106,6 +106,11 @@ WYRM_HISTORICAL_CRAWL_TRANSACTIONS_TIMER_FILE="wyrm-historical-crawl-transaction
WYRM_HISTORICAL_CRAWL_EVENTS_SERVICE_FILE="wyrm-historical-crawl-events.service" WYRM_HISTORICAL_CRAWL_EVENTS_SERVICE_FILE="wyrm-historical-crawl-events.service"
WYRM_HISTORICAL_CRAWL_EVENTS_TIMER_FILE="wyrm-historical-crawl-events.timer" WYRM_HISTORICAL_CRAWL_EVENTS_TIMER_FILE="wyrm-historical-crawl-events.timer"
# ZkSync Era testnet
ZKSYNC_ERA_TESTNET_SYNCHRONIZE_SERVICE="zksync-era-testnet-synchronize.service"
ZKSYNC_ERA_TESTNET_MISSING_SERVICE_FILE="zksync-era-testnet-missing.service"
ZKSYNC_ERA_TESTNET_MISSING_TIMER_FILE="zksync-era-testnet-missing.service"
set -eu set -eu
echo echo
@ -499,3 +504,21 @@ cp "${SCRIPT_DIR}/${WYRM_HISTORICAL_CRAWL_EVENTS_SERVICE_FILE}" "/home/ubuntu/.c
cp "${SCRIPT_DIR}/${WYRM_HISTORICAL_CRAWL_EVENTS_TIMER_FILE}" "/home/ubuntu/.config/systemd/user/${WYRM_HISTORICAL_CRAWL_EVENTS_TIMER_FILE}" cp "${SCRIPT_DIR}/${WYRM_HISTORICAL_CRAWL_EVENTS_TIMER_FILE}" "/home/ubuntu/.config/systemd/user/${WYRM_HISTORICAL_CRAWL_EVENTS_TIMER_FILE}"
XDG_RUNTIME_DIR="/run/user/1000" systemctl --user daemon-reload XDG_RUNTIME_DIR="/run/user/1000" systemctl --user daemon-reload
XDG_RUNTIME_DIR="/run/user/1000" systemctl --user restart --no-block "${WYRM_HISTORICAL_CRAWL_EVENTS_TIMER_FILE}" XDG_RUNTIME_DIR="/run/user/1000" systemctl --user restart --no-block "${WYRM_HISTORICAL_CRAWL_EVENTS_TIMER_FILE}"
# ZkSync Era
echo
echo
echo -e "${PREFIX_INFO} Replacing existing ZkSync Era testnet block with transactions syncronizer service definition with ${ZKSYNC_ERA_TESTNET_SYNCHRONIZE_SERVICE}"
chmod 644 "${SCRIPT_DIR}/${ZKSYNC_ERA_TESTNET_SYNCHRONIZE_SERVICE}"
cp "${SCRIPT_DIR}/${ZKSYNC_ERA_TESTNET_SYNCHRONIZE_SERVICE}" "/home/ubuntu/.config/systemd/user/${ZKSYNC_ERA_TESTNET_SYNCHRONIZE_SERVICE}"
XDG_RUNTIME_DIR="/run/user/1000" systemctl --user daemon-reload
XDG_RUNTIME_DIR="/run/user/1000" systemctl --user restart --no-block "${ZKSYNC_ERA_TESTNET_SYNCHRONIZE_SERVICE}"
echo
echo
echo -e "${PREFIX_INFO} Replacing existing ZkSync Era testnet missing service and timer with: ${ZKSYNC_ERA_TESTNET_MISSING_SERVICE_FILE}, ${ZKSYNC_ERA_TESTNET_MISSING_TIMER_FILE}"
chmod 644 "${SCRIPT_DIR}/${ZKSYNC_ERA_TESTNET_MISSING_SERVICE_FILE}" "${SCRIPT_DIR}/${ZKSYNC_ERA_TESTNET_MISSING_TIMER_FILE}"
cp "${SCRIPT_DIR}/${ZKSYNC_ERA_TESTNET_MISSING_SERVICE_FILE}" "/home/ubuntu/.config/systemd/user/${ZKSYNC_ERA_TESTNET_MISSING_SERVICE_FILE}"
cp "${SCRIPT_DIR}/${ZKSYNC_ERA_TESTNET_MISSING_TIMER_FILE}" "/home/ubuntu/.config/systemd/user/${ZKSYNC_ERA_TESTNET_MISSING_TIMER_FILE}"
XDG_RUNTIME_DIR="/run/user/1000" systemctl --user daemon-reload
XDG_RUNTIME_DIR="/run/user/1000" systemctl --user restart --no-block "${ZKSYNC_ERA_TESTNET_MISSING_TIMER_FILE}"

Wyświetl plik

@ -0,0 +1,11 @@
[Unit]
Description=Fill missing blocks at ZkSync Era testnet database
After=network.target
[Service]
Type=oneshot
WorkingDirectory=/home/ubuntu/moonstream/crawlers/mooncrawl
EnvironmentFile=/home/ubuntu/moonstream-secrets/app.env
ExecStart=/home/ubuntu/moonstream-env/bin/python -m mooncrawl.crawler --access-id "${NB_CONTROLLER_ACCESS_ID}" blocks missing --blockchain zksync_era_testnet -n
CPUWeight=50
SyslogIdentifier=zksync-era-testnet-missing

Wyświetl plik

@ -0,0 +1,9 @@
[Unit]
Description=Fill missing blocks at ZkSync Era testnet database
[Timer]
OnBootSec=120s
OnUnitActiveSec=15m
[Install]
WantedBy=timers.target

Wyświetl plik

@ -0,0 +1,17 @@
[Unit]
Description=ZkSync Era testnet block with transactions synchronizer
StartLimitIntervalSec=300
StartLimitBurst=3
After=network.target
[Service]
Restart=on-failure
RestartSec=15s
WorkingDirectory=/home/ubuntu/moonstream/crawlers/mooncrawl
EnvironmentFile=/home/ubuntu/moonstream-secrets/app.env
ExecStart=/home/ubuntu/moonstream-env/bin/python -m mooncrawl.crawler --access-id "${NB_CONTROLLER_ACCESS_ID}" blocks synchronize --blockchain zksync_era_testnet -c 20 -j 2
CPUWeight=90
SyslogIdentifier=zksync-era-testnet-synchronize
[Install]
WantedBy=multi-user.target

Wyświetl plik

@ -27,6 +27,7 @@ from .settings import (
MOONSTREAM_POLYGON_WEB3_PROVIDER_URI, MOONSTREAM_POLYGON_WEB3_PROVIDER_URI,
MOONSTREAM_WYRM_WEB3_PROVIDER_URI, MOONSTREAM_WYRM_WEB3_PROVIDER_URI,
MOONSTREAM_XDAI_WEB3_PROVIDER_URI, MOONSTREAM_XDAI_WEB3_PROVIDER_URI,
MOONSTREAM_ZKSYNC_ERA_TESTNET_WEB3_PROVIDER_URI,
NB_ACCESS_ID_HEADER, NB_ACCESS_ID_HEADER,
NB_DATA_SOURCE_HEADER, NB_DATA_SOURCE_HEADER,
WEB3_CLIENT_REQUEST_TIMEOUT_SECONDS, WEB3_CLIENT_REQUEST_TIMEOUT_SECONDS,
@ -70,6 +71,8 @@ def connect(
web3_uri = MOONSTREAM_XDAI_WEB3_PROVIDER_URI web3_uri = MOONSTREAM_XDAI_WEB3_PROVIDER_URI
elif blockchain_type == AvailableBlockchainType.WYRM: elif blockchain_type == AvailableBlockchainType.WYRM:
web3_uri = MOONSTREAM_WYRM_WEB3_PROVIDER_URI web3_uri = MOONSTREAM_WYRM_WEB3_PROVIDER_URI
elif blockchain_type == AvailableBlockchainType.ZKSYNC_ERA_TESTNET:
web3_uri = MOONSTREAM_ZKSYNC_ERA_TESTNET_WEB3_PROVIDER_URI
else: else:
raise Exception("Wrong blockchain type provided for web3 URI") raise Exception("Wrong blockchain type provided for web3 URI")
@ -123,6 +126,19 @@ def add_block(db_session, block: Any, blockchain_type: AvailableBlockchainType)
) )
if blockchain_type == AvailableBlockchainType.XDAI: if blockchain_type == AvailableBlockchainType.XDAI:
block_obj.author = block.author block_obj.author = block.author
if blockchain_type == AvailableBlockchainType.ZKSYNC_ERA_TESTNET:
block_obj.mix_hash = block.get("mixHash", "")
block_obj.sha3_uncles = block.get("sha3Uncles", "")
block_obj.l1_batch_number = (
int(block.get("l1BatchNumber"), 0)
if block.get("l1BatchNumber") is not None
else None
)
block_obj.l1_batch_timestamp = (
int(block.get("l1BatchTimestamp"), 0)
if block.get("l1BatchTimestamp") is not None
else None
)
db_session.add(block_obj) db_session.add(block_obj)
@ -152,6 +168,17 @@ def add_block_transactions(
transaction_type=int(tx["type"], 0) if tx.get("type") is not None else None, transaction_type=int(tx["type"], 0) if tx.get("type") is not None else None,
value=tx.value, value=tx.value,
) )
if blockchain_type == AvailableBlockchainType.ZKSYNC_ERA_TESTNET:
tx_obj.l1_batch_number = (
int(tx.get("l1BatchNumber"), 0)
if tx.get("l1BatchNumber") is not None
else None
)
tx_obj.l1_batch_tx_index = (
int(tx.get("l1BatchTxIndex"), 0)
if tx.get("l1BatchTxIndex") is not None
else None
)
db_session.add(tx_obj) db_session.add(tx_obj)

Wyświetl plik

@ -130,6 +130,8 @@ def continuous_crawler(
network = Network.xdai network = Network.xdai
elif blockchain_type == AvailableBlockchainType.WYRM: elif blockchain_type == AvailableBlockchainType.WYRM:
network = Network.wyrm network = Network.wyrm
elif blockchain_type == AvailableBlockchainType.ZKSYNC_ERA_TESTNET:
network = Network.zksync_era_testnet
else: else:
raise ValueError(f"Unknown blockchain type: {blockchain_type}") raise ValueError(f"Unknown blockchain type: {blockchain_type}")

Wyświetl plik

@ -35,6 +35,7 @@ class SubscriptionTypes(Enum):
MUMBAI_BLOCKCHAIN = "mumbai_smartcontract" MUMBAI_BLOCKCHAIN = "mumbai_smartcontract"
XDAI_BLOCKCHAIN = "xdai_smartcontract" XDAI_BLOCKCHAIN = "xdai_smartcontract"
WYRM_BLOCKCHAIN = "wyrm_smartcontract" WYRM_BLOCKCHAIN = "wyrm_smartcontract"
ZKSYNC_ERA_TESTNET_BLOCKCHAIN = "zksync_era_testnet_smartcontract"
def abi_input_signature(input_abi: Dict[str, Any]) -> str: def abi_input_signature(input_abi: Dict[str, Any]) -> str:
@ -139,6 +140,8 @@ def blockchain_type_to_subscription_type(
return SubscriptionTypes.XDAI_BLOCKCHAIN return SubscriptionTypes.XDAI_BLOCKCHAIN
elif blockchain_type == AvailableBlockchainType.WYRM: elif blockchain_type == AvailableBlockchainType.WYRM:
return SubscriptionTypes.WYRM_BLOCKCHAIN return SubscriptionTypes.WYRM_BLOCKCHAIN
elif blockchain_type == AvailableBlockchainType.ZKSYNC_ERA_TESTNET:
return SubscriptionTypes.ZKSYNC_ERA_TESTNET_BLOCKCHAIN
else: else:
raise ValueError(f"Unknown blockchain type: {blockchain_type}") raise ValueError(f"Unknown blockchain type: {blockchain_type}")

Wyświetl plik

@ -68,6 +68,8 @@ def function_call_crawler(
network = Network.xdai network = Network.xdai
elif blockchain_type == AvailableBlockchainType.WYRM: elif blockchain_type == AvailableBlockchainType.WYRM:
network = Network.wyrm network = Network.wyrm
elif blockchain_type == AvailableBlockchainType.ZKSYNC_ERA_TESTNET:
network = Network.zksync_era_testnet
else: else:
raise ValueError(f"Unknown blockchain type: {blockchain_type}") raise ValueError(f"Unknown blockchain type: {blockchain_type}")

Wyświetl plik

@ -114,6 +114,14 @@ MOONSTREAM_WYRM_WEB3_PROVIDER_URI = os.environ.get(
if MOONSTREAM_WYRM_WEB3_PROVIDER_URI == "": if MOONSTREAM_WYRM_WEB3_PROVIDER_URI == "":
raise Exception("MOONSTREAM_WYRM_WEB3_PROVIDER_URI env variable is not set") raise Exception("MOONSTREAM_WYRM_WEB3_PROVIDER_URI env variable is not set")
MOONSTREAM_ZKSYNC_ERA_TESTNET_WEB3_PROVIDER_URI = os.environ.get(
"MOONSTREAM_ZKSYNC_ERA_TESTNET_WEB3_PROVIDER_URI", ""
)
if MOONSTREAM_ZKSYNC_ERA_TESTNET_WEB3_PROVIDER_URI == "":
raise Exception(
"MOONSTREAM_ZKSYNC_ERA_TESTNET_WEB3_PROVIDER_URI env variable is not set"
)
MOONSTREAM_CRAWL_WORKERS = 4 MOONSTREAM_CRAWL_WORKERS = 4
MOONSTREAM_CRAWL_WORKERS_RAW = os.environ.get("MOONSTREAM_CRAWL_WORKERS") MOONSTREAM_CRAWL_WORKERS_RAW = os.environ.get("MOONSTREAM_CRAWL_WORKERS")
try: try:

Wyświetl plik

@ -48,6 +48,7 @@ subscription_id_by_blockchain = {
"mumbai": "mumbai_smartcontract", "mumbai": "mumbai_smartcontract",
"xdai": "xdai_smartcontract", "xdai": "xdai_smartcontract",
"wyrm": "wyrm_smartcontract", "wyrm": "wyrm_smartcontract",
"zksync_era_testnet": "zksync_era_testnet_smartcontract",
} }
blockchain_by_subscription_id = { blockchain_by_subscription_id = {
@ -56,11 +57,13 @@ blockchain_by_subscription_id = {
"mumbai_blockchain": "mumbai", "mumbai_blockchain": "mumbai",
"xdai_blockchain": "xdai", "xdai_blockchain": "xdai",
"wyrm_blockchain": "wyrm", "wyrm_blockchain": "wyrm",
"zksync_era_testnet_blockchain": "zksync_era_testnet",
"ethereum_smartcontract": "ethereum", "ethereum_smartcontract": "ethereum",
"polygon_smartcontract": "polygon", "polygon_smartcontract": "polygon",
"mumbai_smartcontract": "mumbai", "mumbai_smartcontract": "mumbai",
"xdai_smartcontract": "xdai", "xdai_smartcontract": "xdai",
"wyrm_smartcontract": "wyrm", "wyrm_smartcontract": "wyrm",
"zksync_era_testnet_smartcontract": "zksync_era_testnet",
} }

Wyświetl plik

@ -2,4 +2,4 @@
Moonstream crawlers version. Moonstream crawlers version.
""" """
MOONCRAWL_VERSION = "0.3.1" MOONCRAWL_VERSION = "0.3.2"

Wyświetl plik

@ -25,6 +25,7 @@ export MOONSTREAM_POLYGON_WEB3_PROVIDER_URI="https://<connection_path_uri_to_pol
export MOONSTREAM_MUMBAI_WEB3_PROVIDER_URI="https://<connection_path_uri_to_mumbai_node>" export MOONSTREAM_MUMBAI_WEB3_PROVIDER_URI="https://<connection_path_uri_to_mumbai_node>"
export MOONSTREAM_XDAI_WEB3_PROVIDER_URI="https://<connection_path_uri_to_xdai_node>" export MOONSTREAM_XDAI_WEB3_PROVIDER_URI="https://<connection_path_uri_to_xdai_node>"
export MOONSTREAM_WYRM_WEB3_PROVIDER_URI="https://<connection_path_uri_to_wyrm_node>" export MOONSTREAM_WYRM_WEB3_PROVIDER_URI="https://<connection_path_uri_to_wyrm_node>"
export MOONSTREAM_ZKSYNC_ERA_TESTNET_WEB3_PROVIDER_URI="https://<connection_path_uri_to_zksync_era_testnet_node>"
export NB_CONTROLLER_ACCESS_ID="<access_uuid_for_moonstream_nodebalancer>" export NB_CONTROLLER_ACCESS_ID="<access_uuid_for_moonstream_nodebalancer>"
# AWS environment variables # AWS environment variables

Wyświetl plik

@ -37,7 +37,7 @@ setup(
"bugout>=0.2.8", "bugout>=0.2.8",
"chardet", "chardet",
"fastapi", "fastapi",
"moonstreamdb>=0.3.3", "moonstreamdb>=0.3.4",
"moonstream>=0.1.1", "moonstream>=0.1.1",
"moonstream-entity>=0.0.5", "moonstream-entity>=0.0.5",
"moonworm[moonstream]>=0.6.2", "moonworm[moonstream]>=0.6.2",

Wyświetl plik

@ -49,7 +49,7 @@ the schema for this Postgres database as well as migrations that you can use to
database yourself. database yourself.
The [`db/`](../db/) directory contains: The [`db/`](../db/) directory contains:
1. A Python package called `moonstreamdb` which defines the databse schema and can be used as a 1. A Python package called `moonstreamdb` which defines the database schema and can be used as a
Python library to interact with the data store. Python library to interact with the data store.
2. [Alembic](https://alembic.sqlalchemy.org/en/latest/) migrations which can be used via the 2. [Alembic](https://alembic.sqlalchemy.org/en/latest/) migrations which can be used via the
[`alembic.sh`](../db/alembic.sh) shell script to run the migrations against a Postgres database [`alembic.sh`](../db/alembic.sh) shell script to run the migrations against a Postgres database

Wyświetl plik

@ -59,11 +59,13 @@ blockchain_by_subscription_id = {
"mumbai_blockchain": "mumbai", "mumbai_blockchain": "mumbai",
"xdai_blockchain": "xdai", "xdai_blockchain": "xdai",
"wyrm_blockchain": "wyrm", "wyrm_blockchain": "wyrm",
"zksync_era_testnet_blockchain": "zksync_era_testnet",
"ethereum_smartcontract": "ethereum", "ethereum_smartcontract": "ethereum",
"polygon_smartcontract": "polygon", "polygon_smartcontract": "polygon",
"mumbai_smartcontract": "mumbai", "mumbai_smartcontract": "mumbai",
"xdai_smartcontract": "xdai", "xdai_smartcontract": "xdai",
"wyrm_smartcontract": "wyrm", "wyrm_smartcontract": "wyrm",
"zksync_era_testnet_smartcontract": "zksync_era_testnet",
} }

Wyświetl plik

@ -478,18 +478,12 @@ This CLI is configured to work with the following API URLs:
parser_moonworm_tasks_add.set_defaults(func=moonworm_tasks_add_subscription_handler) parser_moonworm_tasks_add.set_defaults(func=moonworm_tasks_add_subscription_handler)
queries_parser = subcommands.add_parser( queries_parser = subcommands.add_parser(
"queries", description="Manage Moonstream queries" "queries", description="Manage Moonstream queries"
) )
queries_parser.set_defaults(func=lambda _: queries_parser.print_help()) queries_parser.set_defaults(func=lambda _: queries_parser.print_help())
queries_subcommands = queries_parser.add_subparsers(description="Query commands")
queries_subcommands = queries_parser.add_subparsers(
description="Query commands"
)
create_query_parser = queries_subcommands.add_parser( create_query_parser = queries_subcommands.add_parser(
"create-template", description="Create query template" "create-template", description="Create query template"

Wyświetl plik

@ -24,12 +24,11 @@ from ..actions import get_all_entries_from_search, name_normalization
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def create_query_template(args: argparse.Namespace) -> None: def create_query_template(args: argparse.Namespace) -> None:
""" """
Create query template for all queries resources. Create query template for all queries resources.
""" """
query = "" query = ""
with args.query_file: with args.query_file:
query = textwrap.indent(args.query_file.read(), " ") query = textwrap.indent(args.query_file.read(), " ")
@ -39,7 +38,6 @@ def create_query_template(args: argparse.Namespace) -> None:
name = f"template_{name_normalization(args.name)}" name = f"template_{name_normalization(args.name)}"
try: try:
entry = bc.create_entry( entry = bc.create_entry(
journal_id=MOONSTREAM_QUERIES_JOURNAL_ID, journal_id=MOONSTREAM_QUERIES_JOURNAL_ID,
title=args.name, title=args.name,
@ -51,18 +49,17 @@ def create_query_template(args: argparse.Namespace) -> None:
token=MOONSTREAM_ADMIN_ACCESS_TOKEN, token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
timeout=BUGOUT_REQUEST_TIMEOUT_SECONDS, timeout=BUGOUT_REQUEST_TIMEOUT_SECONDS,
) )
except BugoutResponseException as err: except BugoutResponseException as err:
logger.error(f"Failed to create query template: {err}") logger.error(f"Failed to create query template: {err}")
return return
except Exception as err: except Exception as err:
logger.error(f"Failed to create query template: {err}") logger.error(f"Failed to create query template: {err}")
return return
logger.info(f"Query template created: {entry.id}") logger.info(f"Query template created: {entry.id}")
logger.info(f"Query template created url name: {name}") logger.info(f"Query template created url name: {name}")
### Add query id ### Add query id
try: try:
@ -81,4 +78,4 @@ def create_query_template(args: argparse.Namespace) -> None:
logger.error(f"Failed to add query id: {err}") logger.error(f"Failed to add query id: {err}")
return return
logger.info(f"Query created: {json.dumps(entry.dict(), indent=4)}") logger.info(f"Query created: {json.dumps(entry.dict(), indent=4)}")

Wyświetl plik

@ -72,6 +72,17 @@ CANONICAL_SUBSCRIPTION_TYPES = {
stripe_price_id=None, stripe_price_id=None,
active=True, active=True,
), ),
"zksync_era_testnet_smartcontract": SubscriptionTypeResourceData(
id="zksync_era_testnet_smartcontract",
name="zkSync Era testnet smartcontract",
blockchain="zksync_era_testnet",
choices=["input:address", "tag:erc721"],
description="Contracts events and tx_calls of contract of zkSync Era testnet blockchain.",
icon_url="https://s3.amazonaws.com/static.simiotics.com/moonstream/assets/zksync-era-testnet-token-logo.png",
stripe_product_id=None,
stripe_price_id=None,
active=True,
),
"ethereum_blockchain": SubscriptionTypeResourceData( "ethereum_blockchain": SubscriptionTypeResourceData(
id="ethereum_blockchain", id="ethereum_blockchain",
name="Ethereum transactions", name="Ethereum transactions",
@ -127,6 +138,17 @@ CANONICAL_SUBSCRIPTION_TYPES = {
stripe_price_id=None, stripe_price_id=None,
active=False, active=False,
), ),
"zksync_era_testnet_blockchain": SubscriptionTypeResourceData(
id="zksync_era_testnet_blockchain",
name="zkSync Era testnet transactions",
blockchain="zksync_era_testnet",
choices=["input:address", "tag:erc721"],
description="ZkSync Era testnet chain transactions subscription.",
icon_url="https://s3.amazonaws.com/static.simiotics.com/moonstream/assets/zksync-era-testnet-token-logo.png",
stripe_product_id=None,
stripe_price_id=None,
active=False,
),
"ethereum_whalewatch": SubscriptionTypeResourceData( "ethereum_whalewatch": SubscriptionTypeResourceData(
id="ethereum_whalewatch", id="ethereum_whalewatch",
name="Ethereum whale watch", name="Ethereum whale watch",

Wyświetl plik

@ -2,14 +2,17 @@
Pydantic schemas for the Moonstream HTTP API Pydantic schemas for the Moonstream HTTP API
""" """
from datetime import datetime from datetime import datetime
import json
from enum import Enum from enum import Enum
from typing import Any, Dict, List, Optional, Union, Literal from typing import Any, Dict, List, Optional, Union, Literal
from uuid import UUID from uuid import UUID
from xmlrpc.client import Boolean from xmlrpc.client import Boolean
from fastapi import Form
from pydantic import BaseModel, Field, validator from pydantic import BaseModel, Field, validator
from sqlalchemy import false from sqlalchemy import false
USER_ONBOARDING_STATE = "onboarding_state" USER_ONBOARDING_STATE = "onboarding_state"
BUGOUT_RESOURCE_QUERY_RESOLVER = "query_name_resolver" BUGOUT_RESOURCE_QUERY_RESOLVER = "query_name_resolver"
@ -47,6 +50,8 @@ class SubscriptionResourceData(BaseModel):
abi: Optional[str] abi: Optional[str]
color: Optional[str] color: Optional[str]
label: Optional[str] label: Optional[str]
description: Optional[str] = None
tags: List[str] = Field(default_factory=list)
user_id: str user_id: str
subscription_type_id: Optional[str] subscription_type_id: Optional[str]
jobs_status: Optional[List[Dict[str, Any]]] = Field(default_factory=list) jobs_status: Optional[List[Dict[str, Any]]] = Field(default_factory=list)
@ -244,6 +249,40 @@ class SubdcriptionsAbiResponse(BaseModel):
abi: str abi: str
class UpdateSubscriptionRequest(BaseModel):
color: Optional[str] = Form(None)
label: Optional[str] = Form(None)
abi: Optional[str] = Form(None)
description: Optional[str] = Form(None)
tags: Optional[List[Dict[str, str]]] = Form(None)
@validator("tags", pre=True, always=True)
def transform_to_dict(cls, v):
if isinstance(v, str):
return json.loads(v)
elif isinstance(v, list):
return v
return []
class CreateSubscriptionRequest(BaseModel):
address: str = Form(...)
subscription_type_id: str = Form(...)
color: str = Form(...)
label: str = Form(...)
abi: Optional[str] = Form(None)
description: Optional[str] = Form(None)
tags: Optional[List[Dict[str, str]]] = Form(None)
@validator("tags", pre=True, always=True)
def transform_to_dict(cls, v):
if isinstance(v, str):
return json.loads(v)
elif isinstance(v, list):
return v
return []
class DashboardMeta(BaseModel): class DashboardMeta(BaseModel):
subscription_id: UUID subscription_id: UUID
generic: Optional[List[Dict[str, str]]] generic: Optional[List[Dict[str, str]]]
@ -296,8 +335,8 @@ class QueryInfoResponse(BaseModel):
preapprove: bool = False preapprove: bool = False
approved: bool = False approved: bool = False
parameters: Dict[str, Any] = Field(default_factory=dict) parameters: Dict[str, Any] = Field(default_factory=dict)
created_at: Optional[datetime] created_at: Optional[datetime] = None
updated_at: Optional[datetime] updated_at: Optional[datetime] = None
class SuggestedQueriesResponse(BaseModel): class SuggestedQueriesResponse(BaseModel):

Wyświetl plik

@ -51,10 +51,12 @@ event_providers: Dict[str, Any] = {
moonworm_provider.PolygonMoonwormProvider.event_type: moonworm_provider.PolygonMoonwormProvider, moonworm_provider.PolygonMoonwormProvider.event_type: moonworm_provider.PolygonMoonwormProvider,
moonworm_provider.MumbaiMoonwormProvider.event_type: moonworm_provider.MumbaiMoonwormProvider, moonworm_provider.MumbaiMoonwormProvider.event_type: moonworm_provider.MumbaiMoonwormProvider,
moonworm_provider.XDaiMoonwormProvider.event_type: moonworm_provider.XDaiMoonwormProvider, moonworm_provider.XDaiMoonwormProvider.event_type: moonworm_provider.XDaiMoonwormProvider,
moonworm_provider.ZkSyncEraTestnetMoonwormProvider.event_type: moonworm_provider.ZkSyncEraTestnetMoonwormProvider,
transactions.EthereumTransactions.event_type: transactions.EthereumTransactions, transactions.EthereumTransactions.event_type: transactions.EthereumTransactions,
transactions.PolygonTransactions.event_type: transactions.PolygonTransactions, transactions.PolygonTransactions.event_type: transactions.PolygonTransactions,
transactions.MumbaiTransactions.event_type: transactions.MumbaiTransactions, transactions.MumbaiTransactions.event_type: transactions.MumbaiTransactions,
transactions.XDaiTransactions.event_type: transactions.XDaiTransactions, transactions.XDaiTransactions.event_type: transactions.XDaiTransactions,
transactions.ZkSyncEraTestnetTransactions.event_type: transactions.ZkSyncEraTestnetTransactions,
bugout.polygon_whalewatch_provider.event_type: bugout.polygon_whalewatch_provider, bugout.polygon_whalewatch_provider.event_type: bugout.polygon_whalewatch_provider,
bugout.ethereum_txpool_provider.event_type: bugout.ethereum_txpool_provider, bugout.ethereum_txpool_provider.event_type: bugout.ethereum_txpool_provider,
bugout.ethereum_whalewatch_provider.event_type: bugout.ethereum_whalewatch_provider, bugout.ethereum_whalewatch_provider.event_type: bugout.ethereum_whalewatch_provider,

Wyświetl plik

@ -21,6 +21,7 @@ ethereum_event_type = "ethereum_blockchain"
polygon_event_type = "polygon_blockchain" polygon_event_type = "polygon_blockchain"
mumbai_event_type = "mumbai_blockchain" mumbai_event_type = "mumbai_blockchain"
xdai_event_type = "xdai_blockchain" xdai_event_type = "xdai_blockchain"
zksync_era_testnet_event_type = "zksync_era_testnet_blockchain"
allowed_tags = ["tag:erc721"] allowed_tags = ["tag:erc721"]
description = f"""Event provider for transactions from the Ethereum blockchain. description = f"""Event provider for transactions from the Ethereum blockchain.
@ -413,3 +414,10 @@ XDaiMoonwormProvider = MoonwormProvider(
description="Provider for reviving transactions from XDai tables.", description="Provider for reviving transactions from XDai tables.",
streamboaundary_range_limit=2 * 60 * 60, streamboaundary_range_limit=2 * 60 * 60,
) )
ZkSyncEraTestnetMoonwormProvider = MoonwormProvider(
event_type="zksync_era_testnet_smartcontract",
blockchain=AvailableBlockchainType("zksync_era_testnet"),
description="Provider for reviving transactions from zkSync Era testnet tables.",
streamboaundary_range_limit=2 * 60 * 60,
)

Wyświetl plik

@ -475,3 +475,10 @@ XDaiTransactions = TransactionsProvider(
description="Provider for resiving transactions from XDai tables.", description="Provider for resiving transactions from XDai tables.",
streamboaundary_range_limit=2 * 60 * 60, streamboaundary_range_limit=2 * 60 * 60,
) )
ZkSyncEraTestnetTransactions = TransactionsProvider(
event_type="zksync_era_testnet_blockchain",
blockchain=AvailableBlockchainType("zksync_era_testnet"),
description="Provider for resiving transactions from ZkSync Era testnet tables.",
streamboaundary_range_limit=2 * 60 * 60,
)

Wyświetl plik

@ -7,7 +7,6 @@ from typing import Any, Dict, List, Optional, Tuple, Union
from uuid import UUID from uuid import UUID
from bugout.data import BugoutResources, BugoutJournalEntryContent, BugoutJournalEntry from bugout.data import BugoutResources, BugoutJournalEntryContent, BugoutJournalEntry
from bugout.exceptions import BugoutResponseException from bugout.exceptions import BugoutResponseException
from fastapi import APIRouter, Body, Request from fastapi import APIRouter, Body, Request
@ -157,7 +156,6 @@ async def create_query_handler(
return entry return entry
@router.get("/templates", tags=["queries"]) @router.get("/templates", tags=["queries"])
def get_suggested_queries( def get_suggested_queries(
supported_interfaces: Optional[List[str]] = None, supported_interfaces: Optional[List[str]] = None,
@ -223,7 +221,6 @@ async def get_query_handler(
) -> data.QueryInfoResponse: ) -> data.QueryInfoResponse:
token = request.state.token token = request.state.token
# normalize query name # normalize query name
try: try:
@ -234,7 +231,6 @@ async def get_query_handler(
detail=f"Provided query name can't be normalize please select different.", detail=f"Provided query name can't be normalize please select different.",
) )
# check in templates # check in templates
try: try:
@ -283,7 +279,6 @@ async def get_query_handler(
else: else:
query_id = entries.results[0].entry_url.split("/")[-1] query_id = entries.results[0].entry_url.split("/")[-1]
entry = entries.results[0] entry = entries.results[0]
try: try:
@ -312,7 +307,6 @@ async def get_query_handler(
else: else:
query_parameters[param] = None query_parameters[param] = None
print(type(entry.created_at)) print(type(entry.created_at))
return data.QueryInfoResponse( return data.QueryInfoResponse(
@ -395,7 +389,6 @@ async def update_query_data_handler(
detail=f"Provided query name can't be normalize please select different.", detail=f"Provided query name can't be normalize please select different.",
) )
# check in templates # check in templates
try: try:
@ -510,9 +503,7 @@ async def get_access_link_handler(
token=MOONSTREAM_ADMIN_ACCESS_TOKEN, token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
journal_id=MOONSTREAM_QUERIES_JOURNAL_ID, journal_id=MOONSTREAM_QUERIES_JOURNAL_ID,
query=f"tag:query_template tag:query_url:{query_name_normalized}", query=f"tag:query_template tag:query_url:{query_name_normalized}",
filters=[ filters=[f"context_type:{MOONSTREAM_QUERY_TEMPLATE_CONTEXT_TYPE}"],
f"context_type:{MOONSTREAM_QUERY_TEMPLATE_CONTEXT_TYPE}"
],
limit=1, limit=1,
) )
except BugoutResponseException as e: except BugoutResponseException as e:
@ -522,7 +513,6 @@ async def get_access_link_handler(
raise MoonstreamHTTPException(status_code=500, internal_error=e) raise MoonstreamHTTPException(status_code=500, internal_error=e)
if len(entries.results) == 0: if len(entries.results) == 0:
try: try:
query_id = get_query_by_name(query_name, token) query_id = get_query_by_name(query_name, token)
except NameNormalizationException: except NameNormalizationException:
@ -532,7 +522,6 @@ async def get_access_link_handler(
) )
try: try:
entries = bc.search( entries = bc.search(
token=MOONSTREAM_ADMIN_ACCESS_TOKEN, token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
journal_id=MOONSTREAM_QUERIES_JOURNAL_ID, journal_id=MOONSTREAM_QUERIES_JOURNAL_ID,
@ -552,7 +541,6 @@ async def get_access_link_handler(
) )
try: try:
s3_response = None s3_response = None
if entries.results[0].content: if entries.results[0].content:
@ -631,4 +619,4 @@ async def remove_query_handler(
except Exception as e: except Exception as e:
raise MoonstreamHTTPException(status_code=500, internal_error=e) raise MoonstreamHTTPException(status_code=500, internal_error=e)
return entry return entry

Wyświetl plik

@ -6,7 +6,6 @@ import hashlib
import json import json
import logging import logging
from typing import Any, Dict, List, Optional from typing import Any, Dict, List, Optional
import traceback
from bugout.exceptions import BugoutResponseException from bugout.exceptions import BugoutResponseException
from bugout.data import BugoutSearchResult from bugout.data import BugoutSearchResult
@ -29,7 +28,11 @@ from ..admin import subscription_types
from ..middleware import MoonstreamHTTPException from ..middleware import MoonstreamHTTPException
from ..reporter import reporter from ..reporter import reporter
from ..settings import bugout_client as bc, entity_client as ec from ..settings import bugout_client as bc, entity_client as ec
from ..settings import MOONSTREAM_ADMIN_ACCESS_TOKEN, THREAD_TIMEOUT_SECONDS from ..settings import (
MOONSTREAM_ADMIN_ACCESS_TOKEN,
MOONSTREAM_ENTITIES_RESERVED_TAGS,
THREAD_TIMEOUT_SECONDS,
)
from ..web3_provider import ( from ..web3_provider import (
yield_web3_provider, yield_web3_provider,
) )
@ -49,11 +52,6 @@ BUGOUT_RESOURCE_TYPE_ENTITY_SUBSCRIPTION = "entity_subscription"
async def add_subscription_handler( async def add_subscription_handler(
request: Request, request: Request,
background_tasks: BackgroundTasks, background_tasks: BackgroundTasks,
address: str = Form(...),
color: str = Form(...),
label: str = Form(...),
subscription_type_id: str = Form(...),
abi: Optional[str] = Form(None),
web3: Web3 = Depends(yield_web3_provider), web3: Web3 = Depends(yield_web3_provider),
) -> data.SubscriptionResourceData: ) -> data.SubscriptionResourceData:
""" """
@ -61,6 +59,21 @@ async def add_subscription_handler(
""" """
token = request.state.token token = request.state.token
form = await request.form()
try:
form_data = data.CreateSubscriptionRequest(**form)
except Exception as e:
raise MoonstreamHTTPException(status_code=400, detail=str(e))
address = form_data.address
color = form_data.color
label = form_data.label
abi = form_data.abi
description = form_data.description
tags = form_data.tags
subscription_type_id = form_data.subscription_type_id
if subscription_type_id != "ethereum_whalewatch": if subscription_type_id != "ethereum_whalewatch":
try: try:
address = web3.toChecksumAddress(address) address = web3.toChecksumAddress(address)
@ -124,6 +137,28 @@ async def add_subscription_handler(
address, address,
) )
if description:
content["description"] = description
allowed_required_fields = []
if tags:
allowed_required_fields = [
item
for item in tags
if not any(key in item for key in MOONSTREAM_ENTITIES_RESERVED_TAGS)
]
required_fields = [
{"type": "subscription"},
{"subscription_type_id": f"{subscription_type_id}"},
{"color": f"{color}"},
{"label": f"{label}"},
{"user_id": f"{user.id}"},
]
if allowed_required_fields:
required_fields.extend(allowed_required_fields)
try: try:
collection_id = get_entity_subscription_collection_id( collection_id = get_entity_subscription_collection_id(
resource_type=BUGOUT_RESOURCE_TYPE_ENTITY_SUBSCRIPTION, resource_type=BUGOUT_RESOURCE_TYPE_ENTITY_SUBSCRIPTION,
@ -140,13 +175,7 @@ async def add_subscription_handler(
subscription_type_id subscription_type_id
].blockchain, ].blockchain,
name=label, name=label,
required_fields=[ required_fields=required_fields,
{"type": "subscription"},
{"subscription_type_id": f"{subscription_type_id}"},
{"color": f"{color}"},
{"label": f"{label}"},
{"user_id": f"{user.id}"},
],
secondary_fields=content, secondary_fields=content,
) )
except EntityCollectionNotFoundException as e: except EntityCollectionNotFoundException as e:
@ -163,6 +192,13 @@ async def add_subscription_handler(
detail="Currently unable to get collection id", detail="Currently unable to get collection id",
) )
normalized_entity_tags = [
f"{key}:{value}"
for tag in entity.required_fields
for key, value in tag.items()
if key not in MOONSTREAM_ENTITIES_RESERVED_TAGS
]
return data.SubscriptionResourceData( return data.SubscriptionResourceData(
id=str(entity.entity_id), id=str(entity.entity_id),
user_id=str(user.id), user_id=str(user.id),
@ -170,6 +206,8 @@ async def add_subscription_handler(
color=color, color=color,
label=label, label=label,
abi=entity.secondary_fields.get("abi"), abi=entity.secondary_fields.get("abi"),
description=entity.secondary_fields.get("description"),
tags=normalized_entity_tags,
subscription_type_id=subscription_type_id, subscription_type_id=subscription_type_id,
updated_at=entity.updated_at, updated_at=entity.updated_at,
created_at=entity.created_at, created_at=entity.created_at,
@ -240,6 +278,8 @@ async def delete_subscription_handler(request: Request, subscription_id: str):
color=color, color=color,
label=label, label=label,
abi=abi, abi=abi,
description=deleted_entity.secondary_fields.get("description"),
tags=deleted_entity.required_fields,
subscription_type_id=subscription_type_id, subscription_type_id=subscription_type_id,
updated_at=deleted_entity.updated_at, updated_at=deleted_entity.updated_at,
created_at=deleted_entity.created_at, created_at=deleted_entity.created_at,
@ -303,6 +343,13 @@ async def get_subscriptions_handler(
if "label" in tag: if "label" in tag:
label = tag["label"] label = tag["label"]
normalized_entity_tags = [
f"{key}:{value}"
for tag in tags
for key, value in tag.items()
if key not in MOONSTREAM_ENTITIES_RESERVED_TAGS
]
subscriptions.append( subscriptions.append(
data.SubscriptionResourceData( data.SubscriptionResourceData(
id=str(subscription.entity_id), id=str(subscription.entity_id),
@ -311,6 +358,8 @@ async def get_subscriptions_handler(
color=color, color=color,
label=label, label=label,
abi=subscription.secondary_fields.get("abi", None), abi=subscription.secondary_fields.get("abi", None),
description=subscription.secondary_fields.get("description"),
tags=normalized_entity_tags,
subscription_type_id=subscription_type_id, subscription_type_id=subscription_type_id,
updated_at=subscription.updated_at, updated_at=subscription.updated_at,
created_at=subscription.created_at, created_at=subscription.created_at,
@ -335,9 +384,6 @@ async def update_subscriptions_handler(
request: Request, request: Request,
subscription_id: str, subscription_id: str,
background_tasks: BackgroundTasks, background_tasks: BackgroundTasks,
color: Optional[str] = Form(None),
label: Optional[str] = Form(None),
abi: Optional[str] = Form(None),
) -> data.SubscriptionResourceData: ) -> data.SubscriptionResourceData:
""" """
Get user's subscriptions. Get user's subscriptions.
@ -346,9 +392,17 @@ async def update_subscriptions_handler(
user = request.state.user user = request.state.user
update_required_fields = [] form = await request.form()
try:
form_data = data.UpdateSubscriptionRequest(**form)
except Exception as e:
raise MoonstreamHTTPException(status_code=400, detail=str(e))
update_secondary_fields = {} color = form_data.color
label = form_data.label
abi = form_data.abi
description = form_data.description
tags = form_data.tags
try: try:
collection_id = get_entity_subscription_collection_id( collection_id = get_entity_subscription_collection_id(
@ -366,7 +420,13 @@ async def update_subscriptions_handler(
subscription_type_id = None subscription_type_id = None
update_required_fields = subscription_entity.required_fields update_required_fields = [
field
for field in subscription_entity.required_fields
if any(key in field for key in MOONSTREAM_ENTITIES_RESERVED_TAGS)
]
update_secondary_fields = subscription_entity.secondary_fields
for field in update_required_fields: for field in update_required_fields:
if "subscription_type_id" in field: if "subscription_type_id" in field:
@ -377,7 +437,7 @@ async def update_subscriptions_handler(
f"Subscription entity {subscription_id} in collection {collection_id} has no subscription_type_id malformed subscription entity" f"Subscription entity {subscription_id} in collection {collection_id} has no subscription_type_id malformed subscription entity"
) )
raise MoonstreamHTTPException( raise MoonstreamHTTPException(
status_code=404, status_code=409,
detail="Not valid subscription entity", detail="Not valid subscription entity",
) )
@ -394,13 +454,19 @@ async def update_subscriptions_handler(
raise MoonstreamHTTPException(status_code=500, internal_error=e) raise MoonstreamHTTPException(status_code=500, internal_error=e)
for field in update_required_fields: for field in update_required_fields:
if "color" in field and color is not None: if "color" in field:
field["color"] = color if color is not None:
field["color"] = color
else:
color = field["color"]
if "label" in field and label is not None: if "label" in field:
field["label"] = label if label is not None:
field["label"] = label
else:
label = field["label"]
if abi: if abi is not None:
try: try:
json_abi = json.loads(abi) json_abi = json.loads(abi)
except json.JSONDecodeError: except json.JSONDecodeError:
@ -414,9 +480,19 @@ async def update_subscriptions_handler(
hash = hashlib.md5(abi_string.encode("utf-8")).hexdigest() hash = hashlib.md5(abi_string.encode("utf-8")).hexdigest()
update_secondary_fields["abi_hash"] = hash update_secondary_fields["abi_hash"] = hash
else:
update_secondary_fields = subscription_entity.secondary_fields
if description is not None:
update_secondary_fields["description"] = description
if tags:
allowed_required_fields = [
item
for item in tags
if not any(key in item for key in MOONSTREAM_ENTITIES_RESERVED_TAGS)
]
if allowed_required_fields:
update_required_fields.extend(allowed_required_fields)
try: try:
subscription = ec.update_entity( subscription = ec.update_entity(
token=token, token=token,
@ -441,6 +517,13 @@ async def update_subscriptions_handler(
subscription.address, subscription.address,
) )
normalized_entity_tags = [
f"{key}:{value}"
for tag in subscription.required_fields
for key, value in tag.items()
if key not in MOONSTREAM_ENTITIES_RESERVED_TAGS
]
return data.SubscriptionResourceData( return data.SubscriptionResourceData(
id=str(subscription.entity_id), id=str(subscription.entity_id),
user_id=str(user.id), user_id=str(user.id),
@ -448,6 +531,8 @@ async def update_subscriptions_handler(
color=color, color=color,
label=label, label=label,
abi=subscription.secondary_fields.get("abi"), abi=subscription.secondary_fields.get("abi"),
description=subscription.secondary_fields.get("description"),
tags=normalized_entity_tags,
subscription_type_id=subscription_type_id, subscription_type_id=subscription_type_id,
updated_at=subscription_entity.updated_at, updated_at=subscription_entity.updated_at,
created_at=subscription_entity.created_at, created_at=subscription_entity.created_at,

File diff suppressed because one or more lines are too long

Wyświetl plik

@ -137,6 +137,13 @@ MOONSTREAM_WYRM_WEB3_PROVIDER_URI = os.environ.get(
if MOONSTREAM_WYRM_WEB3_PROVIDER_URI == "": if MOONSTREAM_WYRM_WEB3_PROVIDER_URI == "":
raise Exception("MOONSTREAM_WYRM_WEB3_PROVIDER_URI env variable is not set") raise Exception("MOONSTREAM_WYRM_WEB3_PROVIDER_URI env variable is not set")
MOONSTREAM_ZKSYNC_ERA_TESTNET_WEB3_PROVIDER_URI = os.environ.get(
"MOONSTREAM_ZKSYNC_ERA_TESTNET_WEB3_PROVIDER_URI", ""
)
if MOONSTREAM_ZKSYNC_ERA_TESTNET_WEB3_PROVIDER_URI == "":
raise Exception(
"MOONSTREAM_ZKSYNC_ERA_TESTNET_WEB3_PROVIDER_URI env variable is not set"
)
MOONSTREAM_S3_QUERIES_BUCKET = os.environ.get("MOONSTREAM_S3_QUERIES_BUCKET", "") MOONSTREAM_S3_QUERIES_BUCKET = os.environ.get("MOONSTREAM_S3_QUERIES_BUCKET", "")
if MOONSTREAM_S3_QUERIES_BUCKET == "": if MOONSTREAM_S3_QUERIES_BUCKET == "":
@ -150,6 +157,16 @@ if MOONSTREAM_S3_QUERIES_BUCKET_PREFIX == "":
"MOONSTREAM_S3_QUERIES_BUCKET_PREFIX environment variable must be set" "MOONSTREAM_S3_QUERIES_BUCKET_PREFIX environment variable must be set"
) )
# Entities reserved tags
MOONSTREAM_ENTITIES_RESERVED_TAGS = [
"type",
"subscription_type_id",
"color",
"label",
"user_id",
"address",
"blockchain",
]
## Moonstream resources types ## Moonstream resources types

Wyświetl plik

@ -2,4 +2,4 @@
Moonstream library and API version. Moonstream library and API version.
""" """
MOONSTREAMAPI_VERSION = "0.2.6" MOONSTREAMAPI_VERSION = "0.2.7"

Wyświetl plik

@ -19,6 +19,7 @@ from .settings import (
MOONSTREAM_MUMBAI_WEB3_PROVIDER_URI, MOONSTREAM_MUMBAI_WEB3_PROVIDER_URI,
MOONSTREAM_XDAI_WEB3_PROVIDER_URI, MOONSTREAM_XDAI_WEB3_PROVIDER_URI,
MOONSTREAM_WYRM_WEB3_PROVIDER_URI, MOONSTREAM_WYRM_WEB3_PROVIDER_URI,
MOONSTREAM_ZKSYNC_ERA_TESTNET_WEB3_PROVIDER_URI,
multicall_contracts, multicall_contracts,
multicall_contract_abi, multicall_contract_abi,
) )
@ -69,6 +70,8 @@ def connect(
web3_uri = MOONSTREAM_XDAI_WEB3_PROVIDER_URI web3_uri = MOONSTREAM_XDAI_WEB3_PROVIDER_URI
elif blockchain_type == AvailableBlockchainType.WYRM: elif blockchain_type == AvailableBlockchainType.WYRM:
web3_uri = MOONSTREAM_WYRM_WEB3_PROVIDER_URI web3_uri = MOONSTREAM_WYRM_WEB3_PROVIDER_URI
elif blockchain_type == AvailableBlockchainType.ZKSYNC_ERA_TESTNET:
web3_uri = MOONSTREAM_ZKSYNC_ERA_TESTNET_WEB3_PROVIDER_URI
else: else:
raise Exception("Wrong blockchain type provided for web3 URI") raise Exception("Wrong blockchain type provided for web3 URI")

Wyświetl plik

@ -37,7 +37,7 @@ lru-dict==1.1.8
Mako==1.2.3 Mako==1.2.3
MarkupSafe==2.1.1 MarkupSafe==2.1.1
moonstream-entity==0.0.5 moonstream-entity==0.0.5
moonstreamdb==0.3.3 moonstreamdb==0.3.4
multiaddr==0.0.9 multiaddr==0.0.9
multidict==6.0.2 multidict==6.0.2
netaddr==0.8.0 netaddr==0.8.0

Wyświetl plik

@ -16,7 +16,7 @@ setup(
"bugout>=0.2.9", "bugout>=0.2.9",
"moonstream-entity>=0.0.5", "moonstream-entity>=0.0.5",
"fastapi", "fastapi",
"moonstreamdb>=0.3.3", "moonstreamdb>=0.3.4",
"humbug", "humbug",
"pydantic", "pydantic",
"pyevmasm", "pyevmasm",

Wyświetl plik

@ -0,0 +1,3 @@
[settings]
profile = black
multi_line_output = 3

Wyświetl plik

@ -1,7 +1,6 @@
from logging.config import fileConfig from logging.config import fileConfig
from sqlalchemy import engine_from_config from sqlalchemy import engine_from_config, pool
from sqlalchemy import pool
from alembic import context from alembic import context
@ -26,18 +25,27 @@ target_metadata = MoonstreamBase.metadata
# my_important_option = config.get_main_option("my_important_option") # my_important_option = config.get_main_option("my_important_option")
# ... etc. # ... etc.
from moonstreamdb.models import ( from moonstreamdb.models import (
EthereumBlock,
EthereumTransaction,
EthereumLabel,
PolygonBlock,
PolygonTransaction,
PolygonLabel,
MumbaiBlock,
MumbaiTransaction,
MumbaiLabel,
ESDFunctionSignature,
ESDEventSignature, ESDEventSignature,
ESDFunctionSignature,
EthereumBlock,
EthereumLabel,
EthereumTransaction,
MumbaiBlock,
MumbaiLabel,
MumbaiTransaction,
OpenSeaCrawlingState, OpenSeaCrawlingState,
PolygonBlock,
PolygonLabel,
PolygonTransaction,
WyrmBlock,
WyrmLabel,
WyrmTransaction,
XDaiBlock,
XDaiLabel,
XDaiTransaction,
ZkSyncEraTestnetBlock,
ZkSyncEraTestnetLabel,
ZkSyncEraTestnetTransaction,
) )
@ -55,6 +63,15 @@ def include_symbol(tablename, schema):
ESDFunctionSignature.__tablename__, ESDFunctionSignature.__tablename__,
ESDEventSignature.__tablename__, ESDEventSignature.__tablename__,
OpenSeaCrawlingState.__tablename__, OpenSeaCrawlingState.__tablename__,
WyrmBlock.__tablename__,
WyrmLabel.__tablename__,
WyrmTransaction.__tablename__,
XDaiBlock.__tablename__,
XDaiLabel.__tablename__,
XDaiTransaction.__tablename__,
ZkSyncEraTestnetBlock.__tablename__,
ZkSyncEraTestnetLabel.__tablename__,
ZkSyncEraTestnetTransaction.__tablename__,
} }

Wyświetl plik

@ -0,0 +1,122 @@
"""ZkSync Era model
Revision ID: e4a796c0407d
Revises: c413d5265f76
Create Date: 2023-07-12 12:27:12.814892
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = 'e4a796c0407d'
down_revision = 'c413d5265f76'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('zksync_era_testnet_blocks',
sa.Column('block_number', sa.BigInteger(), nullable=False),
sa.Column('difficulty', sa.BigInteger(), nullable=True),
sa.Column('extra_data', sa.VARCHAR(length=128), nullable=True),
sa.Column('gas_limit', sa.BigInteger(), nullable=True),
sa.Column('gas_used', sa.BigInteger(), nullable=True),
sa.Column('base_fee_per_gas', sa.Numeric(precision=78, scale=0), nullable=True),
sa.Column('hash', sa.VARCHAR(length=256), nullable=True),
sa.Column('logs_bloom', sa.VARCHAR(length=1024), nullable=True),
sa.Column('miner', sa.VARCHAR(length=256), nullable=True),
sa.Column('nonce', sa.VARCHAR(length=256), nullable=True),
sa.Column('parent_hash', sa.VARCHAR(length=256), nullable=True),
sa.Column('receipt_root', sa.VARCHAR(length=256), nullable=True),
sa.Column('uncles', sa.VARCHAR(length=256), nullable=True),
sa.Column('size', sa.Integer(), nullable=True),
sa.Column('state_root', sa.VARCHAR(length=256), nullable=True),
sa.Column('timestamp', sa.BigInteger(), nullable=True),
sa.Column('total_difficulty', sa.VARCHAR(length=256), nullable=True),
sa.Column('transactions_root', sa.VARCHAR(length=256), nullable=True),
sa.Column('indexed_at', sa.DateTime(timezone=True), server_default=sa.text("TIMEZONE('utc', statement_timestamp())"), nullable=False),
sa.Column('mix_hash', sa.VARCHAR(length=256), nullable=True),
sa.Column('sha3_uncles', sa.VARCHAR(length=256), nullable=True),
sa.Column('l1_batch_number', sa.BigInteger(), nullable=True),
sa.Column('l1_batch_timestamp', sa.BigInteger(), nullable=True),
sa.PrimaryKeyConstraint('block_number', name=op.f('pk_zksync_era_testnet_blocks'))
)
op.create_index(op.f('ix_zksync_era_testnet_blocks_block_number'), 'zksync_era_testnet_blocks', ['block_number'], unique=True)
op.create_index(op.f('ix_zksync_era_testnet_blocks_hash'), 'zksync_era_testnet_blocks', ['hash'], unique=False)
op.create_index(op.f('ix_zksync_era_testnet_blocks_timestamp'), 'zksync_era_testnet_blocks', ['timestamp'], unique=False)
op.create_table('zksync_era_testnet_labels',
sa.Column('id', sa.UUID(), nullable=False),
sa.Column('label', sa.VARCHAR(length=256), nullable=False),
sa.Column('block_number', sa.BigInteger(), nullable=True),
sa.Column('address', sa.VARCHAR(length=256), nullable=True),
sa.Column('transaction_hash', sa.VARCHAR(length=256), nullable=True),
sa.Column('label_data', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
sa.Column('block_timestamp', sa.BigInteger(), nullable=True),
sa.Column('log_index', sa.Integer(), 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_zksync_era_testnet_labels')),
sa.UniqueConstraint('id', name=op.f('uq_zksync_era_testnet_labels_id'))
)
op.create_index(op.f('ix_zksync_era_testnet_labels_address'), 'zksync_era_testnet_labels', ['address'], unique=False)
op.create_index('ix_zksync_era_testnet_labels_address_block_number', 'zksync_era_testnet_labels', ['address', 'block_number'], unique=False)
op.create_index('ix_zksync_era_testnet_labels_address_block_timestamp', 'zksync_era_testnet_labels', ['address', 'block_timestamp'], unique=False)
op.create_index(op.f('ix_zksync_era_testnet_labels_block_number'), 'zksync_era_testnet_labels', ['block_number'], unique=False)
op.create_index(op.f('ix_zksync_era_testnet_labels_block_timestamp'), 'zksync_era_testnet_labels', ['block_timestamp'], unique=False)
op.create_index(op.f('ix_zksync_era_testnet_labels_label'), 'zksync_era_testnet_labels', ['label'], unique=False)
op.create_index(op.f('ix_zksync_era_testnet_labels_transaction_hash'), 'zksync_era_testnet_labels', ['transaction_hash'], unique=False)
op.create_table('zksync_era_testnet_transactions',
sa.Column('hash', sa.VARCHAR(length=256), nullable=False),
sa.Column('block_number', sa.BigInteger(), nullable=False),
sa.Column('from_address', sa.VARCHAR(length=256), nullable=True),
sa.Column('to_address', sa.VARCHAR(length=256), nullable=True),
sa.Column('gas', sa.Numeric(precision=78, scale=0), nullable=True),
sa.Column('gas_price', sa.Numeric(precision=78, scale=0), nullable=True),
sa.Column('max_fee_per_gas', sa.Numeric(precision=78, scale=0), nullable=True),
sa.Column('max_priority_fee_per_gas', sa.Numeric(precision=78, scale=0), nullable=True),
sa.Column('input', sa.Text(), nullable=True),
sa.Column('nonce', sa.VARCHAR(length=256), nullable=True),
sa.Column('transaction_index', sa.BigInteger(), nullable=True),
sa.Column('transaction_type', sa.Integer(), nullable=True),
sa.Column('value', sa.Numeric(precision=78, scale=0), nullable=True),
sa.Column('indexed_at', sa.DateTime(timezone=True), server_default=sa.text("TIMEZONE('utc', statement_timestamp())"), nullable=False),
sa.Column('l1_batch_number', sa.BigInteger(), nullable=True),
sa.Column('l1_batch_tx_index', sa.BigInteger(), nullable=True),
sa.ForeignKeyConstraint(['block_number'], ['zksync_era_testnet_blocks.block_number'], name=op.f('fk_zksync_era_testnet_transactions_block_number_zksync_era_testnet_blocks'), ondelete='CASCADE'),
sa.PrimaryKeyConstraint('hash', name=op.f('pk_zksync_era_testnet_transactions'))
)
op.create_index(op.f('ix_zksync_era_testnet_transactions_block_number'), 'zksync_era_testnet_transactions', ['block_number'], unique=False)
op.create_index(op.f('ix_zksync_era_testnet_transactions_from_address'), 'zksync_era_testnet_transactions', ['from_address'], unique=False)
op.create_index(op.f('ix_zksync_era_testnet_transactions_gas'), 'zksync_era_testnet_transactions', ['gas'], unique=False)
op.create_index(op.f('ix_zksync_era_testnet_transactions_gas_price'), 'zksync_era_testnet_transactions', ['gas_price'], unique=False)
op.create_index(op.f('ix_zksync_era_testnet_transactions_hash'), 'zksync_era_testnet_transactions', ['hash'], unique=True)
op.create_index(op.f('ix_zksync_era_testnet_transactions_to_address'), 'zksync_era_testnet_transactions', ['to_address'], unique=False)
op.create_index(op.f('ix_zksync_era_testnet_transactions_value'), 'zksync_era_testnet_transactions', ['value'], unique=False)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index(op.f('ix_zksync_era_testnet_transactions_value'), table_name='zksync_era_testnet_transactions')
op.drop_index(op.f('ix_zksync_era_testnet_transactions_to_address'), table_name='zksync_era_testnet_transactions')
op.drop_index(op.f('ix_zksync_era_testnet_transactions_hash'), table_name='zksync_era_testnet_transactions')
op.drop_index(op.f('ix_zksync_era_testnet_transactions_gas_price'), table_name='zksync_era_testnet_transactions')
op.drop_index(op.f('ix_zksync_era_testnet_transactions_gas'), table_name='zksync_era_testnet_transactions')
op.drop_index(op.f('ix_zksync_era_testnet_transactions_from_address'), table_name='zksync_era_testnet_transactions')
op.drop_index(op.f('ix_zksync_era_testnet_transactions_block_number'), table_name='zksync_era_testnet_transactions')
op.drop_table('zksync_era_testnet_transactions')
op.drop_index(op.f('ix_zksync_era_testnet_labels_transaction_hash'), table_name='zksync_era_testnet_labels')
op.drop_index(op.f('ix_zksync_era_testnet_labels_label'), table_name='zksync_era_testnet_labels')
op.drop_index(op.f('ix_zksync_era_testnet_labels_block_timestamp'), table_name='zksync_era_testnet_labels')
op.drop_index(op.f('ix_zksync_era_testnet_labels_block_number'), table_name='zksync_era_testnet_labels')
op.drop_index('ix_zksync_era_testnet_labels_address_block_timestamp', table_name='zksync_era_testnet_labels')
op.drop_index('ix_zksync_era_testnet_labels_address_block_number', table_name='zksync_era_testnet_labels')
op.drop_index(op.f('ix_zksync_era_testnet_labels_address'), table_name='zksync_era_testnet_labels')
op.drop_table('zksync_era_testnet_labels')
op.drop_index(op.f('ix_zksync_era_testnet_blocks_timestamp'), table_name='zksync_era_testnet_blocks')
op.drop_index(op.f('ix_zksync_era_testnet_blocks_hash'), table_name='zksync_era_testnet_blocks')
op.drop_index(op.f('ix_zksync_era_testnet_blocks_block_number'), table_name='zksync_era_testnet_blocks')
op.drop_table('zksync_era_testnet_blocks')
# ### end Alembic commands ###

Wyświetl plik

@ -1,26 +1,27 @@
from .db import yield_db_session, yield_db_session_ctx from enum import Enum
from typing import Type, Union
from .models import ( from .models import (
EthereumBlock, EthereumBlock,
EthereumLabel, EthereumLabel,
EthereumTransaction, EthereumTransaction,
PolygonBlock,
PolygonLabel,
PolygonTransaction,
MumbaiBlock, MumbaiBlock,
MumbaiLabel, MumbaiLabel,
MumbaiTransaction, MumbaiTransaction,
XDaiBlock, PolygonBlock,
XDaiLabel, PolygonLabel,
XDaiTransaction, PolygonTransaction,
WyrmBlock, WyrmBlock,
WyrmLabel, WyrmLabel,
WyrmTransaction, WyrmTransaction,
XDaiBlock,
XDaiLabel,
XDaiTransaction,
ZkSyncEraTestnetBlock,
ZkSyncEraTestnetLabel,
ZkSyncEraTestnetTransaction,
) )
from enum import Enum
from typing import Type, Union
class AvailableBlockchainType(Enum): class AvailableBlockchainType(Enum):
ETHEREUM = "ethereum" ETHEREUM = "ethereum"
@ -28,17 +29,34 @@ class AvailableBlockchainType(Enum):
MUMBAI = "mumbai" MUMBAI = "mumbai"
XDAI = "xdai" XDAI = "xdai"
WYRM = "wyrm" WYRM = "wyrm"
ZKSYNC_ERA_TESTNET = "zksync_era_testnet"
def get_block_model( def get_block_model(
blockchain_type: AvailableBlockchainType, blockchain_type: AvailableBlockchainType,
) -> Type[Union[EthereumBlock, PolygonBlock, MumbaiBlock, XDaiBlock, WyrmBlock]]: ) -> Type[
Union[
EthereumBlock,
PolygonBlock,
MumbaiBlock,
XDaiBlock,
WyrmBlock,
ZkSyncEraTestnetBlock,
]
]:
""" """
Depends on provided blockchain type: Ethereum, Polygon, Mumbai, XDai, Wyrm Depends on provided blockchain type: Ethereum, Polygon, Mumbai, XDai, Wyrm
set proper blocks model. set proper blocks model.
""" """
block_model: Type[ block_model: Type[
Union[EthereumBlock, PolygonBlock, MumbaiBlock, XDaiBlock, WyrmBlock] Union[
EthereumBlock,
PolygonBlock,
MumbaiBlock,
XDaiBlock,
WyrmBlock,
ZkSyncEraTestnetBlock,
]
] ]
if blockchain_type == AvailableBlockchainType.ETHEREUM: if blockchain_type == AvailableBlockchainType.ETHEREUM:
block_model = EthereumBlock block_model = EthereumBlock
@ -50,6 +68,8 @@ def get_block_model(
block_model = XDaiBlock block_model = XDaiBlock
elif blockchain_type == AvailableBlockchainType.WYRM: elif blockchain_type == AvailableBlockchainType.WYRM:
block_model = WyrmBlock block_model = WyrmBlock
elif blockchain_type == AvailableBlockchainType.ZKSYNC_ERA_TESTNET:
block_model = ZkSyncEraTestnetBlock
else: else:
raise Exception("Unsupported blockchain type provided") raise Exception("Unsupported blockchain type provided")
@ -58,13 +78,29 @@ def get_block_model(
def get_label_model( def get_label_model(
blockchain_type: AvailableBlockchainType, blockchain_type: AvailableBlockchainType,
) -> Type[Union[EthereumLabel, PolygonLabel, MumbaiLabel, XDaiLabel, WyrmLabel]]: ) -> Type[
Union[
EthereumLabel,
PolygonLabel,
MumbaiLabel,
XDaiLabel,
WyrmLabel,
ZkSyncEraTestnetLabel,
]
]:
""" """
Depends on provided blockchain type: Ethereum, Polygon, Mumbai, XDai, Wyrm Depends on provided blockchain type: Ethereum, Polygon, Mumbai, XDai, Wyrm
set proper block label model. set proper block label model.
""" """
label_model: Type[ label_model: Type[
Union[EthereumLabel, PolygonLabel, MumbaiLabel, XDaiLabel, WyrmLabel] Union[
EthereumLabel,
PolygonLabel,
MumbaiLabel,
XDaiLabel,
WyrmLabel,
ZkSyncEraTestnetLabel,
]
] ]
if blockchain_type == AvailableBlockchainType.ETHEREUM: if blockchain_type == AvailableBlockchainType.ETHEREUM:
label_model = EthereumLabel label_model = EthereumLabel
@ -76,6 +112,8 @@ def get_label_model(
label_model = XDaiLabel label_model = XDaiLabel
elif blockchain_type == AvailableBlockchainType.WYRM: elif blockchain_type == AvailableBlockchainType.WYRM:
label_model = WyrmLabel label_model = WyrmLabel
elif blockchain_type == AvailableBlockchainType.ZKSYNC_ERA_TESTNET:
label_model = ZkSyncEraTestnetLabel
else: else:
raise Exception("Unsupported blockchain type provided") raise Exception("Unsupported blockchain type provided")
@ -91,6 +129,7 @@ def get_transaction_model(
MumbaiTransaction, MumbaiTransaction,
XDaiTransaction, XDaiTransaction,
WyrmTransaction, WyrmTransaction,
ZkSyncEraTestnetTransaction,
] ]
]: ]:
""" """
@ -104,6 +143,7 @@ def get_transaction_model(
MumbaiTransaction, MumbaiTransaction,
XDaiTransaction, XDaiTransaction,
WyrmTransaction, WyrmTransaction,
ZkSyncEraTestnetTransaction,
] ]
] ]
if blockchain_type == AvailableBlockchainType.ETHEREUM: if blockchain_type == AvailableBlockchainType.ETHEREUM:
@ -116,6 +156,8 @@ def get_transaction_model(
transaction_model = XDaiTransaction transaction_model = XDaiTransaction
elif blockchain_type == AvailableBlockchainType.WYRM: elif blockchain_type == AvailableBlockchainType.WYRM:
transaction_model = WyrmTransaction transaction_model = WyrmTransaction
elif blockchain_type == AvailableBlockchainType.ZKSYNC_ERA_TESTNET:
transaction_model = ZkSyncEraTestnetTransaction
else: else:
raise Exception("Unsupported blockchain type provided") raise Exception("Unsupported blockchain type provided")

Wyświetl plik

@ -1,12 +1,12 @@
""" """
Moonstream database connection. Moonstream database connection.
""" """
from contextlib import contextmanager
import os import os
from contextlib import contextmanager
from typing import Generator from typing import Generator
from sqlalchemy import create_engine from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, Session from sqlalchemy.orm import Session, sessionmaker
MOONSTREAM_DB_URI = os.environ.get("MOONSTREAM_DB_URI") MOONSTREAM_DB_URI = os.environ.get("MOONSTREAM_DB_URI")
if MOONSTREAM_DB_URI is None: if MOONSTREAM_DB_URI is None:

Wyświetl plik

@ -1,21 +1,21 @@
import uuid import uuid
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import ( from sqlalchemy import (
VARCHAR,
BigInteger, BigInteger,
Column, Column,
DateTime, DateTime,
ForeignKey,
Index, Index,
Integer, Integer,
ForeignKey,
MetaData, MetaData,
Numeric, Numeric,
Text, Text,
VARCHAR,
) )
from sqlalchemy.dialects.postgresql import JSONB, UUID from sqlalchemy.dialects.postgresql import JSONB, UUID
from sqlalchemy.sql import expression
from sqlalchemy.ext.compiler import compiles from sqlalchemy.ext.compiler import compiles
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.sql import expression
""" """
Naming conventions doc Naming conventions doc
@ -614,6 +614,137 @@ class WyrmLabel(Base): # type: ignore
) )
class ZkSyncEraTestnetBlock(Base): # type: ignore
__tablename__ = "zksync_era_testnet_blocks"
block_number = Column(
BigInteger, primary_key=True, unique=True, nullable=False, index=True
)
difficulty = Column(BigInteger)
extra_data = Column(VARCHAR(128))
gas_limit = Column(BigInteger)
gas_used = Column(BigInteger)
base_fee_per_gas = Column(Numeric(precision=78, scale=0), nullable=True)
hash = Column(VARCHAR(256), index=True)
logs_bloom = Column(VARCHAR(1024))
miner = Column(VARCHAR(256))
nonce = Column(VARCHAR(256))
parent_hash = Column(VARCHAR(256))
receipt_root = Column(VARCHAR(256))
uncles = Column(VARCHAR(256))
size = Column(Integer)
state_root = Column(VARCHAR(256))
timestamp = Column(BigInteger, index=True)
total_difficulty = Column(VARCHAR(256))
transactions_root = Column(VARCHAR(256))
indexed_at = Column(
DateTime(timezone=True), server_default=utcnow(), nullable=False
)
mix_hash = Column(VARCHAR(256), nullable=True)
sha3_uncles = Column(VARCHAR(256), nullable=True)
l1_batch_number = Column(BigInteger, nullable=True)
l1_batch_timestamp = Column(BigInteger, nullable=True)
class ZkSyncEraTestnetTransaction(Base): # type: ignore
__tablename__ = "zksync_era_testnet_transactions"
hash = Column(
VARCHAR(256), primary_key=True, unique=True, nullable=False, index=True
)
block_number = Column(
BigInteger,
ForeignKey("zksync_era_testnet_blocks.block_number", ondelete="CASCADE"),
nullable=False,
index=True,
)
from_address = Column(VARCHAR(256), index=True)
to_address = Column(VARCHAR(256), index=True)
gas = Column(Numeric(precision=78, scale=0), index=True)
gas_price = Column(Numeric(precision=78, scale=0), index=True)
max_fee_per_gas = Column(Numeric(precision=78, scale=0), nullable=True)
max_priority_fee_per_gas = Column(Numeric(precision=78, scale=0), nullable=True)
input = Column(Text)
nonce = Column(VARCHAR(256))
transaction_index = Column(BigInteger)
transaction_type = Column(Integer, nullable=True)
value = Column(Numeric(precision=78, scale=0), index=True)
indexed_at = Column(
DateTime(timezone=True), server_default=utcnow(), nullable=False
)
l1_batch_number = Column(BigInteger, nullable=True)
l1_batch_tx_index = Column(BigInteger, nullable=True)
class ZkSyncEraTestnetLabel(Base): # type: ignore
"""
Example of label_data:
{
"label": "ERC20",
"label_data": {
"name": "Uniswap",
"symbol": "UNI"
}
},
{
"label": "Exchange"
"label_data": {...}
}
"""
__tablename__ = "zksync_era_testnet_labels"
__table_args__ = (
Index(
"ix_zksync_era_testnet_labels_address_block_number",
"address",
"block_number",
unique=False,
),
Index(
"ix_zksync_era_testnet_labels_address_block_timestamp",
"address",
"block_timestamp",
unique=False,
),
)
id = Column(
UUID(as_uuid=True),
primary_key=True,
default=uuid.uuid4,
unique=True,
nullable=False,
)
label = Column(VARCHAR(256), nullable=False, index=True)
block_number = Column(
BigInteger,
nullable=True,
index=True,
)
address = Column(
VARCHAR(256),
nullable=True,
index=True,
)
transaction_hash = Column(
VARCHAR(256),
nullable=True,
index=True,
)
label_data = Column(JSONB, nullable=True)
block_timestamp = Column(BigInteger, index=True)
log_index = Column(Integer, nullable=True)
created_at = Column(
DateTime(timezone=True), server_default=utcnow(), nullable=False
)
class ESDFunctionSignature(Base): # type: ignore class ESDFunctionSignature(Base): # type: ignore
""" """
Function signature from blockchain (Ethereum/Polygon) Signature Database. Function signature from blockchain (Ethereum/Polygon) Signature Database.

Wyświetl plik

@ -18,6 +18,9 @@ from .models import (
XDaiBlock, XDaiBlock,
XDaiLabel, XDaiLabel,
XDaiTransaction, XDaiTransaction,
ZkSyncEraTestnetBlock,
ZkSyncEraTestnetLabel,
ZkSyncEraTestnetTransaction,
) )
@ -27,6 +30,7 @@ class Network(Enum):
mumbai = "mumbai" mumbai = "mumbai"
xdai = "xdai" xdai = "xdai"
wyrm = "wyrm" wyrm = "wyrm"
zksync_era_testnet = "zksync_era_testnet"
tx_raw_types = Union[ tx_raw_types = Union[
@ -35,6 +39,7 @@ tx_raw_types = Union[
PolygonTransaction, PolygonTransaction,
WyrmTransaction, WyrmTransaction,
XDaiTransaction, XDaiTransaction,
ZkSyncEraTestnetTransaction,
] ]
MODELS: Dict[Network, Dict[str, Base]] = { MODELS: Dict[Network, Dict[str, Base]] = {
@ -63,4 +68,9 @@ MODELS: Dict[Network, Dict[str, Base]] = {
"labels": WyrmLabel, "labels": WyrmLabel,
"transactions": WyrmTransaction, "transactions": WyrmTransaction,
}, },
Network.zksync_era_testnet: {
"blocks": ZkSyncEraTestnetBlock,
"labels": ZkSyncEraTestnetLabel,
"transactions": ZkSyncEraTestnetTransaction,
},
} }

Wyświetl plik

@ -2,4 +2,4 @@
Moonstream database version. Moonstream database version.
""" """
MOONSTREAMDB_VERSION = "0.3.3" MOONSTREAMDB_VERSION = "0.3.4"

Wyświetl plik

@ -2,7 +2,7 @@
## Installation ## Installation
- Prepare environment variables, according with `sample.env`. - Prepare environment variables, according to `sample.env`.
- Build application - Build application
```bash ```bash
@ -60,14 +60,14 @@ This command will return a list of bugout resources of registered users to acces
] ]
``` ```
`access_id` - token which allow access to nodebalancer, could be specified in both ways: `access_id` - token which allows access to nodebalancer, could be specified in both ways:
- as a header `x-moonstream-access-id` with value `access_id` - as a header `x-moonstream-access-id` with value `access_id`
- as query parameter `access_id=access_id` - as query parameter `access_id=access_id`
`blockchain_access` - boolean which allow you or not to have access to blockchain node, otherwise you will be redirected to database `blockchain_access` - boolean which allows you or not to have access to blockchain node, otherwise you will be redirected to database
`extended_methods` - boolean which allow you to call not whitelisted method to blockchain node, by default for new user this is equal to `false` `extended_methods` - boolean which allows you to call not whitelisted method to blockchain node, by default for new user this is equal to `false`
### server ### server

Wyświetl plik

@ -36,6 +36,27 @@ var (
"net_version": true, "net_version": true,
"web3_clientVersion": true, "web3_clientVersion": true,
// zksync methods
"zks_estimateFee": true,
"zks_estimateGasL1ToL2": true,
"zks_getAllAccountBalances": true,
"zks_getBlockDetails": true,
"zks_getBridgeContracts": true,
"zks_getBytecodeByHash": true,
"zks_getConfirmedTokens": true,
"zks_getL1BatchBlockRange": true,
"zks_getL1BatchDetails": true,
"zks_getL2ToL1LogProof": true,
"zks_getL2ToL1MsgProof": true,
"zks_getMainContract": true,
"zks_getRawBlockTransactions": true,
"zks_getTestnetPaymaster": true,
"zks_getTokenPrice": true,
"zks_getTransactionDetails": true,
"zks_L1BatchNumber": true,
"zks_L1ChainId": true,
} }
) )