kopia lustrzana https://github.com/bugout-dev/moonstream
				
				
				
			added sync functionality
							rodzic
							
								
									c134d4f6ac
								
							
						
					
					
						commit
						42f6d893cc
					
				|  | @ -13,7 +13,7 @@ from typing import Any, cast, Dict, Optional | |||
| 
 | ||||
| 
 | ||||
| from moonstreamdb.db import yield_db_session_ctx | ||||
| from moonstreamdb.models import EthereumBlock | ||||
| from moonstreamdb.models import EthereumBlock, EthereumTransaction, EthereumLabel | ||||
| from sqlalchemy.orm.session import Session | ||||
| from web3 import Web3 | ||||
| 
 | ||||
|  | @ -21,6 +21,8 @@ from ..ethereum import connect | |||
| from .ethereum import ( | ||||
|     summary as ethereum_summary, | ||||
|     add_labels, | ||||
|     MINT_LABEL, | ||||
|     TRANSFER_LABEL, | ||||
|     SUMMARY_KEY_ARGS, | ||||
|     SUMMARY_KEY_ID, | ||||
|     SUMMARY_KEY_NUM_BLOCKS, | ||||
|  | @ -61,53 +63,45 @@ def get_latest_block_from_db(db_session: Session): | |||
| 
 | ||||
| 
 | ||||
| def get_latest_summary_block() -> Optional[int]: | ||||
|     pass | ||||
|     return None | ||||
| 
 | ||||
| 
 | ||||
| def get_latest_nft_event_date() -> Optional[datetime]: | ||||
|     pass | ||||
| def get_latest_nft_labeled_block(db_session: Session) -> Optional[int]: | ||||
| 
 | ||||
|     query = ( | ||||
|         db_session.query( | ||||
|             EthereumLabel.label, | ||||
|             EthereumTransaction.hash, | ||||
|             EthereumBlock.block_number, | ||||
|         ) | ||||
|         .join( | ||||
|             EthereumTransaction, | ||||
|             EthereumLabel.transaction_hash == EthereumTransaction.hash, | ||||
|         ) | ||||
|         .join( | ||||
|             EthereumBlock, | ||||
|             EthereumTransaction.block_number == EthereumBlock.block_number, | ||||
|         ) | ||||
|         .filter(EthereumLabel.label.in_([MINT_LABEL, TRANSFER_LABEL])) | ||||
|         .order_by(EthereumBlock.block_number.desc()) | ||||
|         .limit(1) | ||||
|     ) | ||||
| 
 | ||||
|     return query.one_or_none().block_number | ||||
| 
 | ||||
| 
 | ||||
| def sync_labels( | ||||
|     db_session: Session, web3_client: Web3, start: Optional[int] | ||||
| ) -> EthereumBlock: | ||||
| def sync_labels(db_session: Session, web3_client: Web3, start: Optional[int]) -> int: | ||||
|     if start is None: | ||||
|         logger.info( | ||||
|             "Syncing start block is not given, getting it from latest nft label in db" | ||||
|         ) | ||||
|         start_date = get_latest_nft_event_date() | ||||
|         if start_date is None: | ||||
|         start = get_latest_nft_labeled_block(db_session) | ||||
|         if start is None: | ||||
|             logger.warning( | ||||
|                 "Didn't find any nft labels in db, starting sync from 3 month before now" | ||||
|             ) | ||||
|             time_now = datetime.now(timezone.utc) | ||||
|             start_date = time_now - relativedelta(months=3) | ||||
| 
 | ||||
|         start = ( | ||||
|             db_session.query(EthereumBlock) | ||||
|             .filter(EthereumBlock.timestamp >= start_date.timestamp()) | ||||
|             .order_by(EthereumBlock.timestamp.asc()) | ||||
|             .limit(1) | ||||
|             .one() | ||||
|         ).block_number | ||||
|     logger.info(f"Start block: {start}, date: {start_date}") | ||||
|     latest_block = get_latest_block_from_db(db_session) | ||||
|     end = latest_block.block_number | ||||
|     assert start <= end, f"Start block {start} is greater than latest_block {end} in db" | ||||
|     logger.info(f"Labeling blocks {start}-{end}") | ||||
|     add_labels(web3_client, db_session, start, end) | ||||
|     return latest_block | ||||
| 
 | ||||
| 
 | ||||
| def sync_summaries(db_session: Session, end: int, start: Optional[int]): | ||||
|     if start is None: | ||||
|         logger.info( | ||||
|             "Syncing start time is not given, getting it from latest nft label in db" | ||||
|         ) | ||||
|         start = get_latest_summary_block() | ||||
|         if start is None: | ||||
|             time_now = datetime.now(timezone.utc) | ||||
|             start_date = time_now - relativedelta(months=3) | ||||
|             start = ( | ||||
|                 db_session.query(EthereumBlock) | ||||
|                 .filter(EthereumBlock.timestamp >= start_date.timestamp()) | ||||
|  | @ -115,20 +109,60 @@ def sync_summaries(db_session: Session, end: int, start: Optional[int]): | |||
|                 .limit(1) | ||||
|                 .one() | ||||
|             ).block_number | ||||
|         start += 1 | ||||
|     logger.info(f"Syncing labels, start block: {start}") | ||||
|     latest_block = get_latest_block_from_db(db_session) | ||||
|     end = latest_block.block_number | ||||
|     if start > end: | ||||
|         logger.warn(f"Start block {start} is greater than latest_block {end} in db") | ||||
|         logger.warn("Maybe ethcrawler is not syncing or nft sync is up to date") | ||||
|         return start - 1 | ||||
|     logger.info(f"Labeling blocks {start}-{end}") | ||||
|     add_labels(web3_client, db_session, start, end) | ||||
|     return latest_block.block_number | ||||
| 
 | ||||
|     while start < end: | ||||
|         current_end = start + BLOCKS_PER_SUMMARY - 1 | ||||
|         current_end_time = ( | ||||
|             db_session.query(EthereumBlock) | ||||
|             .filter(EthereumBlock.block_number <= current_end) | ||||
|             .order_by(EthereumBlock.block_number.desc()) | ||||
|             .limit(1) | ||||
|             .one() | ||||
|         ).timestamp | ||||
|         summary_result = ethereum_summary( | ||||
|             db_session, datetime.fromtimestamp(current_end_time, timezone.utc) | ||||
| 
 | ||||
| def sync_summaries( | ||||
|     db_session: Session, | ||||
|     start: Optional[int], | ||||
|     end: int, | ||||
|     humbug_token: str, | ||||
| ) -> int: | ||||
|     if start is None: | ||||
|         logger.info( | ||||
|             "Syncing start time is not given, getting it from latest nft label in db" | ||||
|         ) | ||||
|         start = get_latest_summary_block() | ||||
|         if start is not None: | ||||
|             start += 1 | ||||
|         else: | ||||
|             logger.info( | ||||
|                 "There is no entry in humbug, starting to create summaries from 3 month ago" | ||||
|             ) | ||||
|             time_now = datetime.now(timezone.utc) | ||||
|             start_date = time_now - relativedelta(months=3) | ||||
|             start = ( | ||||
|                 db_session.query(EthereumBlock) | ||||
|                 .filter(EthereumBlock.timestamp >= start_date.timestamp()) | ||||
|                 .order_by(EthereumBlock.timestamp.asc()) | ||||
|                 .limit(1) | ||||
|                 .one() | ||||
|             ).block_number | ||||
| 
 | ||||
|     logger.info(f"Syncing summaries start_block: {start}") | ||||
|     batch_end = start + BLOCKS_PER_SUMMARY - 1 | ||||
|     if batch_end > end: | ||||
|         logger.warn("Syncing summaries is not required") | ||||
|     while batch_end <= end: | ||||
|         summary_result = ethereum_summary(db_session, start, batch_end) | ||||
|         push_summary(summary_result, humbug_token) | ||||
|         logger.info(f"Pushed summary of blocks : {start}-{batch_end}") | ||||
|         start = batch_end + 1 | ||||
|         batch_end += BLOCKS_PER_SUMMARY | ||||
| 
 | ||||
|     if start == end: | ||||
|         return end | ||||
|     else: | ||||
|         return start - 1 | ||||
| 
 | ||||
| 
 | ||||
| def ethereum_sync_handler(args: argparse.Namespace) -> None: | ||||
|  | @ -139,20 +173,22 @@ def ethereum_sync_handler(args: argparse.Namespace) -> None: | |||
|         raise ValueError("MOONSTREAM_HUMBUG_TOKEN env variable is not set") | ||||
| 
 | ||||
|     with yield_db_session_ctx() as db_session: | ||||
|         logger.info("Initial labeling:") | ||||
|         last_labeled = sync_labels(db_session, web3_client, args.start) | ||||
|         logger.info("Initial summary creation:") | ||||
|         last_summary_created = sync_summaries( | ||||
|             db_session, args.start, last_labeled, humbug_token | ||||
|         ) | ||||
|         while True: | ||||
|             end_time = datetime.fromtimestamp(latest_block.timestamp, timezone.utc) | ||||
|             print(f"Creating summary with endtime={end_time}") | ||||
|             result = ethereum_summary(db_session, end_time) | ||||
|             push_summary(result, end, humbug_token) | ||||
| 
 | ||||
|             sleep_time = 60 * 60 | ||||
|             print(f"Going to sleep for:{sleep_time}s") | ||||
|             logger.info("Syncing") | ||||
|             last_labeled = sync_labels(db_session, web3_client, last_labeled + 1) | ||||
|             last_summary_created = sync_summaries( | ||||
|                 db_session, last_summary_created + 1, last_labeled, humbug_token | ||||
|             ) | ||||
|             sleep_time = 20 * 60 | ||||
|             logger.info(f"Going to sleep for {sleep_time}s") | ||||
|             time.sleep(sleep_time) | ||||
| 
 | ||||
|             start = end + 1 | ||||
|             latest_block = get_latest_block_from_db(db_session) | ||||
|             end = latest_block.block_number | ||||
| 
 | ||||
| 
 | ||||
| def ethereum_label_handler(args: argparse.Namespace) -> None: | ||||
|     web3_client = web3_client_from_cli_or_env(args) | ||||
|  | @ -310,6 +346,11 @@ def main() -> None: | |||
|         required=False, | ||||
|         help="Starting block number (inclusive if block available)", | ||||
|     ) | ||||
|     parser_ethereum_sync.add_argument( | ||||
|         "--humbug", | ||||
|         default=None, | ||||
|         help=("Humbug token to publish summary reports"), | ||||
|     ) | ||||
|     parser_ethereum_sync.set_defaults(func=ethereum_sync_handler) | ||||
| 
 | ||||
|     args = parser.parse_args() | ||||
|  |  | |||
		Ładowanie…
	
		Reference in New Issue
	
	 yhtiyar
						yhtiyar