moonstream/moonstreamapi/moonstreamapi/admin/migrations/checksum_address.py

103 wiersze
3.5 KiB
Python
Czysty Zwykły widok Historia

2021-10-28 14:57:52 +00:00
"""
Convert all addresses in user subscriptions
and ethereum_labels column to checksum address.
2021-10-28 14:57:52 +00:00
"""
import logging
from typing import List
2021-10-28 14:57:52 +00:00
from bugout.data import BugoutResources
from bugout.exceptions import BugoutResponseException
from moonstreamdb.models import EthereumLabel
from sqlalchemy import func
2021-10-28 16:02:35 +00:00
from sqlalchemy.orm.session import Session
2021-10-28 14:57:52 +00:00
from web3 import Web3
from ...settings import BUGOUT_REQUEST_TIMEOUT_SECONDS, MOONSTREAM_ADMIN_ACCESS_TOKEN
from ...settings import bugout_client as bc
logger = logging.getLogger(__name__)
2021-10-28 14:57:52 +00:00
def checksum_all_subscription_addresses(web3: Web3) -> None:
"""
Parse all existing subscriptions at Brood resource
and replace address with checksum.
"""
2021-10-28 14:57:52 +00:00
resources: BugoutResources = bc.list_resources(
token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
params={"type": "subscription"},
timeout=BUGOUT_REQUEST_TIMEOUT_SECONDS,
)
for resource in resources.resources:
resource_data = resource.resource_data
try:
address = resource_data["address"]
resource_data["address"] = web3.toChecksumAddress(address)
updated_resource = bc.update_resource(
token=MOONSTREAM_ADMIN_ACCESS_TOKEN,
resource_id=resource.id,
resource_data={"update": resource_data},
timeout=BUGOUT_REQUEST_TIMEOUT_SECONDS,
)
logger.info(f"Resource id: {updated_resource.id} updated")
2021-10-28 14:57:52 +00:00
except ValueError as e:
logger.info(
2021-10-28 14:57:52 +00:00
f"Not valid checksum address: {address}, probably "
"txpool or whalewatch subscription"
)
continue
except BugoutResponseException as e:
logger.info(f"Bugout error: {e.status_code} with details: {e.detail}")
2021-10-28 14:57:52 +00:00
except Exception as e:
logger.info(f"Unexpected error: {repr(e)}")
2021-10-28 14:57:52 +00:00
continue
2021-10-28 16:02:35 +00:00
def checksum_all_labels_addresses(db_session: Session, web3: Web3) -> None:
"""
Convert all address to checksum in ethereum_labels column at database.
Docs for SQLAlchemy mapping:
https://docs.sqlalchemy.org/en/14/orm/session_api.html#sqlalchemy.orm.Session.bulk_update_mappings
"""
query_limit = 500
2021-11-03 13:42:24 +00:00
query_index = 0
malformed_addresses: List[str] = []
while True:
query = (
db_session.query(EthereumLabel.id, EthereumLabel.address)
.filter(EthereumLabel.address == func.lower(EthereumLabel.address))
.filter(EthereumLabel.address.not_in(malformed_addresses))
2021-11-03 13:42:24 +00:00
.order_by(EthereumLabel.address)
.limit(query_limit)
2021-11-03 13:42:24 +00:00
.offset(query_index * query_limit)
)
address_list = query.all()
address_list_len = len(address_list)
if address_list_len == 0:
break
logger.info(f"Updating next {address_list_len} rows")
# Build map of id and updated address checksum
mappings = []
for address in address_list:
2021-11-03 12:14:36 +00:00
try:
checksum_address = web3.toChecksumAddress(address[1])
mappings.append({"id": address[0], "address": checksum_address})
except Exception as e:
logger.warn(
f"Unable checksum address: {address[1]}, added to malformed list"
)
malformed_addresses.append(address[1])
db_session.bulk_update_mappings(EthereumLabel, mappings)
db_session.commit()
mappings[:] = []
2021-11-03 13:42:24 +00:00
query_index += 1
2021-11-03 12:14:36 +00:00
logger.warn(f"List of malformed addresses: {malformed_addresses}")