diff --git a/models/external/beacon_api_eth_v1_events_execution_payload.sql b/models/external/beacon_api_eth_v1_events_execution_payload.sql new file mode 100644 index 00000000..afc1c8af --- /dev/null +++ b/models/external/beacon_api_eth_v1_events_execution_payload.sql @@ -0,0 +1,32 @@ +--- +table: beacon_api_eth_v1_events_execution_payload +cache: + incremental_scan_interval: 5s + full_scan_interval: 24h +interval: + type: slot +lag: 12 +--- +SELECT + {{ if .cache.is_incremental_scan }} + '{{ .cache.previous_min }}' as min, + {{ else }} + toUnixTimestamp(min(slot_start_date_time)) as min, + {{ end }} + toUnixTimestamp(max(slot_start_date_time)) as max +FROM {{ .self.helpers.from }} +WHERE + meta_network_name = '{{ .env.NETWORK }}' + + -- previous_max if incremental scan and is set, otherwise default/env + {{- $ts := default "0" .env.EXTERNAL_MODEL_MIN_TIMESTAMP -}} + {{- if .cache.is_incremental_scan -}} + {{- if .cache.previous_max -}} + {{- $ts = .cache.previous_max -}} + {{- end -}} + {{- end }} + AND slot_start_date_time >= fromUnixTimestamp({{ $ts }}) + {{- if .cache.is_incremental_scan }} + AND slot_start_date_time <= fromUnixTimestamp({{ $ts }}) + {{ default "100000" .env.EXTERNAL_MODEL_SCAN_SIZE_TIMESTAMP }} + {{- end }} + diff --git a/models/transformations/fct_block_head.sql b/models/transformations/fct_block_head.sql index 644a79be..3825b90e 100644 --- a/models/transformations/fct_block_head.sql +++ b/models/transformations/fct_block_head.sql @@ -14,16 +14,36 @@ tags: - head dependencies: - "{{external}}.beacon_api_eth_v2_beacon_block" + # Gloas payload-hash source. OR-grouped with the beacon block table so + # networks where the execution_payload events table is empty or absent + # schedule unaffected. + - - "{{external}}.beacon_api_eth_v1_events_execution_payload" + - "{{external}}.beacon_api_eth_v2_beacon_block" --- INSERT INTO `{{ .self.database }}`.`{{ .self.table }}` +WITH +-- Gloas (ePBS): the beacon block no longer embeds the execution payload, so +-- its execution_payload_block_hash is empty in the block table. The +-- execution_payload SSE events map each revealed payload's block hash to its +-- beacon block root. Empty on pre-gloas networks, where it contributes nothing. +payload_events AS ( + SELECT + block_root, + any(block_hash) AS payload_block_hash + FROM {{ index .dep "{{external}}" "beacon_api_eth_v1_events_execution_payload" "helpers" "from" }} + WHERE meta_network_name = '{{ .env.NETWORK }}' + AND slot_start_date_time BETWEEN fromUnixTimestamp({{ .bounds.start }}) AND fromUnixTimestamp({{ .bounds.end }}) + AND block_hash != '' + GROUP BY block_root +) SELECT fromUnixTimestamp({{ .task.start }}) as updated_date_time, argMax(slot, updated_date_time) AS slot, slot_start_date_time, argMax(epoch, updated_date_time) AS epoch, argMax(epoch_start_date_time, updated_date_time) AS epoch_start_date_time, - block_root, + bb.block_root AS block_root, argMax(block_version, updated_date_time) AS block_version, argMax(block_total_bytes, updated_date_time) AS block_total_bytes, argMax(block_total_bytes_compressed, updated_date_time) AS block_total_bytes_compressed, @@ -32,7 +52,9 @@ SELECT argMax(proposer_index, updated_date_time) AS proposer_index, argMax(eth1_data_block_hash, updated_date_time) AS eth1_data_block_hash, argMax(eth1_data_deposit_root, updated_date_time) AS eth1_data_deposit_root, - argMax(execution_payload_block_hash, updated_date_time) AS execution_payload_block_hash, + -- Pre-gloas blocks carry their payload hash. Gloas blocks fall back to + -- the payload observed for their block root on the SSE layer + coalesce(nullif(argMax(execution_payload_block_hash, updated_date_time), ''), any(pe.payload_block_hash), '') AS execution_payload_block_hash, argMax(execution_payload_block_number, updated_date_time) AS execution_payload_block_number, argMax(execution_payload_fee_recipient, updated_date_time) AS execution_payload_fee_recipient, argMax(execution_payload_base_fee_per_gas, updated_date_time) AS execution_payload_base_fee_per_gas, @@ -45,7 +67,8 @@ SELECT argMax(execution_payload_transactions_count, updated_date_time) AS execution_payload_transactions_count, argMax(execution_payload_transactions_total_bytes, updated_date_time) AS execution_payload_transactions_total_bytes, argMax(execution_payload_transactions_total_bytes_compressed, updated_date_time) AS execution_payload_transactions_total_bytes_compressed -FROM {{ index .dep "{{external}}" "beacon_api_eth_v2_beacon_block" "helpers" "from" }} FINAL +FROM {{ index .dep "{{external}}" "beacon_api_eth_v2_beacon_block" "helpers" "from" }} AS bb FINAL +GLOBAL LEFT JOIN payload_events pe ON bb.block_root = pe.block_root WHERE slot_start_date_time BETWEEN fromUnixTimestamp({{ .bounds.start }}) AND fromUnixTimestamp({{ .bounds.end }}) AND meta_network_name = '{{ .env.NETWORK }}' GROUP BY slot_start_date_time, block_root