diff --git a/models/airswap/ethereum/airswap_ethereum_sources.yml b/models/airswap/ethereum/airswap_ethereum_sources.yml index c5226cbdd3a..6ac67507c51 100644 --- a/models/airswap/ethereum/airswap_ethereum_sources.yml +++ b/models/airswap/ethereum/airswap_ethereum_sources.yml @@ -4,6 +4,9 @@ sources: - name: airswap_ethereum description: > Decoded tables related to Airswap dex trades. + freshness: # default freshness + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: Light_evt_Swap description: > diff --git a/models/babyswap/bnb/babyswap_bnb_sources.yml b/models/babyswap/bnb/babyswap_bnb_sources.yml index fa255f41a95..21fe510b9d3 100644 --- a/models/babyswap/bnb/babyswap_bnb_sources.yml +++ b/models/babyswap/bnb/babyswap_bnb_sources.yml @@ -3,6 +3,9 @@ version: 2 sources: - name: babyswap_bnb description: "Binance Smart Chain (bnb) decoded tables related to BabySwap contract" + freshness: # default freshness + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: BabyPair_evt_Swap loaded_at_field: evt_block_time diff --git a/models/bancor/ethereum/bancor_ethereum_sources.yml b/models/bancor/ethereum/bancor_ethereum_sources.yml index 13686085479..1a2958d06ef 100644 --- a/models/bancor/ethereum/bancor_ethereum_sources.yml +++ b/models/bancor/ethereum/bancor_ethereum_sources.yml @@ -3,6 +3,9 @@ version: 2 sources: - name: bancornetwork_ethereum description: "Ethereum decoded tables related to Bancor Network contract" + freshness: # default freshness + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: BancorNetwork_v6_evt_Conversion freshness: diff --git a/models/base_sources/ethereum_base_sources.yml b/models/base_sources/ethereum_base_sources.yml index ad3f2b2a4d6..36f3e7b9079 100644 --- a/models/base_sources/ethereum_base_sources.yml +++ b/models/base_sources/ethereum_base_sources.yml @@ -223,6 +223,9 @@ sources: - name: erc1155_ethereum description: "Transfers events for ERC1155 tokens on Ethereum." + freshness: + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: evt_transfersingle loaded_at_field: evt_block_time @@ -264,6 +267,9 @@ sources: - name: erc721_ethereum description: "Transfers events for ERC721 tokens on Ethereum." + freshness: + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: evt_transfer loaded_at_field: evt_block_time diff --git a/models/biswap/bnb/biswap_bnb_sources.yml b/models/biswap/bnb/biswap_bnb_sources.yml index 07556b13bd5..a4a66a475ba 100644 --- a/models/biswap/bnb/biswap_bnb_sources.yml +++ b/models/biswap/bnb/biswap_bnb_sources.yml @@ -3,6 +3,9 @@ version: 2 sources: - name: biswap_bnb description: "Binance Smart Chain (bsc) decoded tables related to Biswap contract" + freshness: # default freshness + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: BiswapPair_evt_Swap loaded_at_field: evt_block_time diff --git a/models/clipper/ethereum/clipper_ethereum_sources.yml b/models/clipper/ethereum/clipper_ethereum_sources.yml index 60772b8cce4..6fd1fd27b60 100644 --- a/models/clipper/ethereum/clipper_ethereum_sources.yml +++ b/models/clipper/ethereum/clipper_ethereum_sources.yml @@ -3,7 +3,13 @@ version: 2 sources: - name: clipper_ethereum description: "Ethereum decoded tables related to Clipper DEX" + freshness: # default freshness + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: ClipperExchangeInterface_evt_Swapped + loaded_at_field: evt_block_time - name: ClipperCaravelExchange_evt_Swapped + loaded_at_field: evt_block_time - name: ClipperVerifiedCaravelExchange_evt_Swapped + loaded_at_field: evt_block_time diff --git a/models/curvefi/avalanche_c/curvefi_avalanche_c_sources.yml b/models/curvefi/avalanche_c/curvefi_avalanche_c_sources.yml index 4231d803294..3e96ed8d4b5 100644 --- a/models/curvefi/avalanche_c/curvefi_avalanche_c_sources.yml +++ b/models/curvefi/avalanche_c/curvefi_avalanche_c_sources.yml @@ -3,6 +3,9 @@ version: 2 sources: - name: curvefi_avalanche_c description: "decoded events for curve.fi on avalanche" + freshness: # default freshness + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: 3pool_evt_TokenExchange loaded_at_field: evt_block_time diff --git a/models/curvefi/ethereum/curvefi_ethereum_sources.yml b/models/curvefi/ethereum/curvefi_ethereum_sources.yml index f102155a0cd..f756fb1d895 100644 --- a/models/curvefi/ethereum/curvefi_ethereum_sources.yml +++ b/models/curvefi/ethereum/curvefi_ethereum_sources.yml @@ -3,6 +3,9 @@ version: 2 sources: - name: curvefi_ethereum description: "decoded events and function calls for curve.fi on ethereum" + freshness: # default freshness + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: CurveFactory_call_deploy_plain_pool loaded_at_field: call_block_time diff --git a/models/defiswap/ethereum/defiswap_ethereum_sources.yml b/models/defiswap/ethereum/defiswap_ethereum_sources.yml index bd0150a38b4..e6971c3babd 100644 --- a/models/defiswap/ethereum/defiswap_ethereum_sources.yml +++ b/models/defiswap/ethereum/defiswap_ethereum_sources.yml @@ -4,6 +4,9 @@ sources: - name: defiswap_ethereum description: > Decoded tables related to defiswap dex swap. + freshness: # default freshness + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: CroDefiSwapPair_evt_Swap description: > @@ -42,6 +45,9 @@ sources: - name: crodefi_ethereum description: > Decoded tables related to defiswap dex pair creation. + freshness: # default freshness + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: CroDefiSwapFactory_evt_PairCreated description: > diff --git a/models/dodo/ethereum/dodo_ethereum_sources.yml b/models/dodo/ethereum/dodo_ethereum_sources.yml index 6df1bbb5581..995dd0b73f1 100644 --- a/models/dodo/ethereum/dodo_ethereum_sources.yml +++ b/models/dodo/ethereum/dodo_ethereum_sources.yml @@ -4,6 +4,9 @@ sources: - name: dodo_ethereum description: > Decoded tables related to Dodo dex trades. + freshness: # default freshness + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: DODO_evt_SellBaseToken description: > diff --git a/models/element/avalanche_c/element_avalanche_c_sources.yml b/models/element/avalanche_c/element_avalanche_c_sources.yml index 2105ff269a5..10547b88582 100644 --- a/models/element/avalanche_c/element_avalanche_c_sources.yml +++ b/models/element/avalanche_c/element_avalanche_c_sources.yml @@ -2,6 +2,9 @@ version: 2 sources: - name: element_ex_avalanche_c + freshness: + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: OrdersFeature_evt_ERC721SellOrderFilled loaded_at_field: evt_block_time diff --git a/models/element/bnb/element_bnb_sources.yml b/models/element/bnb/element_bnb_sources.yml index deafca35b65..ee171203746 100644 --- a/models/element/bnb/element_bnb_sources.yml +++ b/models/element/bnb/element_bnb_sources.yml @@ -2,6 +2,9 @@ version: 2 sources: - name: element_ex_bnb + freshness: + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: OrdersFeature_evt_ERC721SellOrderFilled loaded_at_field: evt_block_time diff --git a/models/element/ethereum/element_ethereum_sources.yml b/models/element/ethereum/element_ethereum_sources.yml index 4ca50f74d53..d08c9dcfc92 100644 --- a/models/element/ethereum/element_ethereum_sources.yml +++ b/models/element/ethereum/element_ethereum_sources.yml @@ -2,6 +2,9 @@ version: 2 sources: - name: element_ex_ethereum + freshness: + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: OrdersFeature_evt_ERC721SellOrderFilled loaded_at_field: evt_block_time diff --git a/models/fraxswap/avalanche_c/fraxswap_avalanche_c_sources.yml b/models/fraxswap/avalanche_c/fraxswap_avalanche_c_sources.yml index 300c34abeb3..3419b2db908 100644 --- a/models/fraxswap/avalanche_c/fraxswap_avalanche_c_sources.yml +++ b/models/fraxswap/avalanche_c/fraxswap_avalanche_c_sources.yml @@ -3,6 +3,11 @@ version: 2 sources: - name: fraxswap_avalanche_c description: "Avalanche (C-Chain) decoded tables related to Fraxswap contract" + freshness: # default freshness + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: FraxswapFactory_evt_PairCreated + loaded_at_field: evt_block_time - name: FraxswapPair_evt_Swap + loaded_at_field: evt_block_time diff --git a/models/fraxswap/bnb/fraxswap_bnb_sources.yml b/models/fraxswap/bnb/fraxswap_bnb_sources.yml index b6ce90746b4..ed606baf8d2 100644 --- a/models/fraxswap/bnb/fraxswap_bnb_sources.yml +++ b/models/fraxswap/bnb/fraxswap_bnb_sources.yml @@ -3,6 +3,11 @@ version: 2 sources: - name: fraxswap_bnb description: "BNB Chain decoded tables related to Fraxswap contract" + freshness: # default freshness + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: FraxswapFactory_evt_PairCreated + loaded_at_field: evt_block_time - name: FraxswapPair_evt_Swap + loaded_at_field: evt_block_time diff --git a/models/fraxswap/ethereum/fraxswap_ethereum_sources.yml b/models/fraxswap/ethereum/fraxswap_ethereum_sources.yml index a03efb5639a..5ad0a9bd44d 100644 --- a/models/fraxswap/ethereum/fraxswap_ethereum_sources.yml +++ b/models/fraxswap/ethereum/fraxswap_ethereum_sources.yml @@ -3,6 +3,11 @@ version: 2 sources: - name: fraxswap_ethereum description: "Ethereum Chain decoded tables related to Fraxswap contract" + freshness: # default freshness + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: FraxswapFactory_evt_PairCreated + loaded_at_field: evt_block_time - name: FraxswapPair_evt_Swap + loaded_at_field: evt_block_time diff --git a/models/fraxswap/polygon/fraxswap_polygon_sources.yml b/models/fraxswap/polygon/fraxswap_polygon_sources.yml index a8351f39eaf..f2543958a88 100644 --- a/models/fraxswap/polygon/fraxswap_polygon_sources.yml +++ b/models/fraxswap/polygon/fraxswap_polygon_sources.yml @@ -3,6 +3,11 @@ version: 2 sources: - name: fraxswap_polygon description: "Polygon Chain decoded tables related to Fraxswap contract" + freshness: # default freshness + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: FraxswapFactory_evt_PairCreated + loaded_at_field: evt_block_time - name: FraxswapPair_evt_Swap + loaded_at_field: evt_block_time diff --git a/models/hashflow/ethereum/hashflow_ethereum_sources.yml b/models/hashflow/ethereum/hashflow_ethereum_sources.yml index 99e05eb8ed3..bb26e8d3e33 100644 --- a/models/hashflow/ethereum/hashflow_ethereum_sources.yml +++ b/models/hashflow/ethereum/hashflow_ethereum_sources.yml @@ -3,6 +3,9 @@ version: 2 sources: - name: hashflow_ethereum description: "Hashflow non-decoded tables related to hashflow contracts" + freshness: # default freshness + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: pool_evt_trade freshness: diff --git a/models/kyberswap/avalanche_c/kyberswap_avalanche_c_sources.yml b/models/kyberswap/avalanche_c/kyberswap_avalanche_c_sources.yml index a903feacd3c..0356a511a54 100644 --- a/models/kyberswap/avalanche_c/kyberswap_avalanche_c_sources.yml +++ b/models/kyberswap/avalanche_c/kyberswap_avalanche_c_sources.yml @@ -3,10 +3,19 @@ version: 2 sources: - name: kyber_avalanche_c description: "Avalanche (C-Chain) decoded tables related to Kyberswap contract" + freshness: # default freshness + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: DMMPool_evt_Swap + loaded_at_field: evt_block_time - name: DMMFactory_evt_PoolCreated + loaded_at_field: evt_block_time - name: Elastic_Pool_evt_swap + loaded_at_field: evt_block_time - name: Elastic_Factory_evt_PoolCreated + loaded_at_field: evt_block_time - name: AggregationRouter_evt_Swapped + loaded_at_field: evt_block_time - name: MetaAggregationRouter_evt_Swapped + loaded_at_field: evt_block_time diff --git a/models/mstable/ethereum/mstable_ethereum_sources.yml b/models/mstable/ethereum/mstable_ethereum_sources.yml index 8cb4ab61aa7..ec982e883d9 100644 --- a/models/mstable/ethereum/mstable_ethereum_sources.yml +++ b/models/mstable/ethereum/mstable_ethereum_sources.yml @@ -4,6 +4,9 @@ sources: - name: mstable_ethereum description: > Decoded tables related to mStable dex trades. + freshness: # default freshness + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: Masset_evt_Swapped description: > diff --git a/models/nomiswap/bnb/nomiswap_bnb_sources.yml b/models/nomiswap/bnb/nomiswap_bnb_sources.yml index b7eee475fc2..3073d6c8b1d 100644 --- a/models/nomiswap/bnb/nomiswap_bnb_sources.yml +++ b/models/nomiswap/bnb/nomiswap_bnb_sources.yml @@ -3,6 +3,9 @@ version: 2 sources: - name: nomiswap_bnb description: "BNB Chain decoded tables related to SushiSwap contract" + freshness: # default freshness + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: NomiswapPair_evt_Swap loaded_at_field: evt_block_time diff --git a/models/opensea/ethereum/opensea_ethereum_sources.yml b/models/opensea/ethereum/opensea_ethereum_sources.yml index e09fd47d488..da55d60c900 100644 --- a/models/opensea/ethereum/opensea_ethereum_sources.yml +++ b/models/opensea/ethereum/opensea_ethereum_sources.yml @@ -2,6 +2,9 @@ version: 2 sources: - name: opensea_ethereum + freshness: + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: wyvernexchange_call_atomicmatch_ loaded_at_field: call_block_time diff --git a/models/shibaswap/ethereum/shibaswap_ethereum_sources.yml b/models/shibaswap/ethereum/shibaswap_ethereum_sources.yml index a1322baa23a..485fb24bb86 100644 --- a/models/shibaswap/ethereum/shibaswap_ethereum_sources.yml +++ b/models/shibaswap/ethereum/shibaswap_ethereum_sources.yml @@ -3,6 +3,11 @@ version: 2 sources: - name: shibaswap_ethereum description: "Ethereum decoded tables related to Shibaswap DEX trades" + freshness: # default freshness + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: UniswapV2Pair_evt_Swap + loaded_at_field: evt_block_time - name: UniswapV2Factory_evt_PairCreated + loaded_at_field: evt_block_time diff --git a/models/sudoswap/ethereum/sudoswap_ethereum_sources.yml b/models/sudoswap/ethereum/sudoswap_ethereum_sources.yml index d2ee97204c3..819393e4e8d 100644 --- a/models/sudoswap/ethereum/sudoswap_ethereum_sources.yml +++ b/models/sudoswap/ethereum/sudoswap_ethereum_sources.yml @@ -2,6 +2,9 @@ version: 2 sources: - name: sudo_amm_ethereum + freshness: + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: LSSVMPairFactory_call_createPairETH freshness: diff --git a/models/sushiswap/avalanche_c/sushiswap_avalanche_c_sources.yml b/models/sushiswap/avalanche_c/sushiswap_avalanche_c_sources.yml index cc253fbe584..4a8258639a4 100644 --- a/models/sushiswap/avalanche_c/sushiswap_avalanche_c_sources.yml +++ b/models/sushiswap/avalanche_c/sushiswap_avalanche_c_sources.yml @@ -3,6 +3,9 @@ version: 2 sources: - name: sushiswap_v2_avalanche_c description: "Avalanche (C-Chain) decoded tables related to SushiSwap contract" + freshness: # default freshness + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: Pair_evt_Swap loaded_at_field: evt_block_time diff --git a/models/swapr/ethereum/swapr_ethereum_sources.yml b/models/swapr/ethereum/swapr_ethereum_sources.yml index 3856d2a5fed..75cb3b46968 100644 --- a/models/swapr/ethereum/swapr_ethereum_sources.yml +++ b/models/swapr/ethereum/swapr_ethereum_sources.yml @@ -4,6 +4,9 @@ sources: - name: swapr_ethereum description: > Decoded tables related to Swapr dex. + freshness: # default freshness + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: DXswapPair_evt_Swap description: > diff --git a/models/uniswap/ethereum/uniswap_ethereum_sources.yml b/models/uniswap/ethereum/uniswap_ethereum_sources.yml index c99c5c8af7a..29b51041fbb 100644 --- a/models/uniswap/ethereum/uniswap_ethereum_sources.yml +++ b/models/uniswap/ethereum/uniswap_ethereum_sources.yml @@ -3,6 +3,9 @@ version: 2 sources: - name: uniswap_ethereum description: "Ethereum decoded tables related to Uniswap v1 contract" + freshness: # default freshness + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: Exchange_evt_TokenPurchase freshness: @@ -38,6 +41,8 @@ sources: description: "Raw amount of tokens bought during transaction with the contract" - name: Factory_evt_NewExchange loaded_at_field: evt_block_time + freshness: # default freshness + warn_after: { count: 84, period: hour } description: "" # to-do columns: - name: contract_address # appears to be used differently here than the exchange event tables in uniswap v1 diff --git a/models/woofi/avalanche_c/woofi_avalanche_c_sources.yml b/models/woofi/avalanche_c/woofi_avalanche_c_sources.yml index 78e0bdd65dc..0b37d300f6b 100644 --- a/models/woofi/avalanche_c/woofi_avalanche_c_sources.yml +++ b/models/woofi/avalanche_c/woofi_avalanche_c_sources.yml @@ -4,6 +4,9 @@ sources: - name: woofi_avalanche_c description: > Decoded tables related to woofi dex trades. + freshness: # default freshness + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: WooPP_evt_WooSwap description: > diff --git a/models/woofi/bnb/woofi_bnb_sources.yml b/models/woofi/bnb/woofi_bnb_sources.yml index 4135110af6d..5d5f4a86639 100644 --- a/models/woofi/bnb/woofi_bnb_sources.yml +++ b/models/woofi/bnb/woofi_bnb_sources.yml @@ -4,6 +4,9 @@ sources: - name: woofi_bnb description: > Decoded tables related to woofi dex trades. + freshness: # default freshness + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: WooPP_evt_WooSwap description: > diff --git a/models/zeroex/optimism/zeroex_api_optimism_sources.yml b/models/zeroex/optimism/zeroex_api_optimism_sources.yml index 3b29fb932b4..324293b0023 100644 --- a/models/zeroex/optimism/zeroex_api_optimism_sources.yml +++ b/models/zeroex/optimism/zeroex_api_optimism_sources.yml @@ -17,9 +17,6 @@ sources: # for native orders on v3 - name: zeroex_v3_optimism description: "Optimism decoded tables related to 0x v3 Exchange Contract" - freshness: - warn_after: { count: 12, period: hour } loaded_at_field: evt_block_time - tables: - name: Exchange_evt_Fill \ No newline at end of file diff --git a/models/zora/ethereum/zora_ethereum_sources.yml b/models/zora/ethereum/zora_ethereum_sources.yml index 3673cc074dd..116b5537b58 100644 --- a/models/zora/ethereum/zora_ethereum_sources.yml +++ b/models/zora/ethereum/zora_ethereum_sources.yml @@ -2,6 +2,9 @@ version: 2 sources: - name: zora_v3_ethereum + freshness: # default freshness + warn_after: { count: 12, period: hour } + error_after: { count: 24, period: hour } tables: - name: OffersV1_evt_ExchangeExecuted loaded_at_field: evt_block_time diff --git a/scripts/test_token_checker.py b/scripts/test_token_checker.py index c51a3b8772f..db4eb617da2 100644 --- a/scripts/test_token_checker.py +++ b/scripts/test_token_checker.py @@ -47,4 +47,4 @@ def test_valid_token5(): def test_valid_token6(): test_token_checker = TokenChecker(new_line='("bets-betswirl", "polygon", "BETS", "0x9246a5f10a79a5a939b0c2a75a3ad196aafdb43b", 18),') - test_token_checker.validate_token() \ No newline at end of file + test_token_checker.validate_token() diff --git a/scripts/validate_source_freshness_checks.py b/scripts/validate_source_freshness_checks.py new file mode 100644 index 00000000000..8ddb17e1881 --- /dev/null +++ b/scripts/validate_source_freshness_checks.py @@ -0,0 +1,57 @@ +import argparse +import json +import logging +import sys +from pathlib import Path + +from ruamel.yaml import YAML + +logging.basicConfig(stream=sys.stdout, level=logging.WARN) + +parser = argparse.ArgumentParser() +parser.add_argument('--model') +args = parser.parse_args() + +class SourceSelector(object): + def __init__(self, method, value): + self.method = method + self.value = value + + +class Sources: + def __init__(self, model, manifest): + self.model = model + self.manifest = manifest + self.node_dependencies = self.manifest['nodes'][self.model]['depends_on'].get('nodes') + self.model_dependencies = [model for model in self.node_dependencies if 'model' in model] + self.source_node_dependencies = [model for model in self.node_dependencies if 'source' in model] + if self.model_dependencies != []: + self.subjects = [Sources(model=subject_model, manifest=manifest) for subject_model in + self.model_dependencies] + for subject in self.subjects: + self.source_node_dependencies.extend(subject.source_node_dependencies) + else: + return + +def missing_freshness_checks(sources, manifest, check_type='warn'): + sources = list(set(sources)) + source_defintions = {source: manifest['sources'][source] for source in sources} + empty_checks = [key for key, value in source_defintions.items() if + value['freshness'][f'{check_type}_after']['count'] is None] + return empty_checks + + +class MissingSourceFreshnessChecks(Exception): + def __init__(self, sources_missing_checks): + self.sources_missing_checks = sources_missing_checks + self.message = "Sources Missing Freshness Checks: \n" + "\n".join(sources_missing_checks) + super().__init__(self.message) + + +with open('../target/manifest.json') as json_file: + manifest = json.load(json_file) + +sources_cls = Sources(model=f'model.spellbook.{args.model}', manifest=manifest) +sources = sources_cls.source_node_dependencies +sources_missing_checks = missing_freshness_checks(sources, manifest) +assert len(sources_missing_checks) == 0, MissingSourceFreshnessChecks(sources_missing_checks)