mirror of
https://github.com/FlipsideCrypto/flow-models.git
synced 2026-02-06 09:37:27 +00:00
An 5719/flow rework (#396)
* core models * tests * decoder / abis * history process * workflows * end points * workflow
This commit is contained in:
parent
ecbf09726c
commit
e119e85c07
2
.github/workflows/dbt_run_evm.yml
vendored
2
.github/workflows/dbt_run_evm.yml
vendored
@ -43,4 +43,4 @@ jobs:
|
||||
|
||||
- name: Update evm tables
|
||||
run: |
|
||||
dbt run -s tag:evm
|
||||
dbt run --vars '{"STREAMLINE_INVOKE_STREAMS":True}' -s tag:evm tag:streamline_decoded_logs_realtime tag:streamline_decoded_logs_complete
|
||||
|
||||
46
.github/workflows/dbt_run_evm_decoded_logs.yml
vendored
Normal file
46
.github/workflows/dbt_run_evm_decoded_logs.yml
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
name: dbt_run_evm_decoded_logs
|
||||
run-name: dbt_run_evm_decoded_logs
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
# Every hour on minute 45(see https://crontab.guru)
|
||||
- cron: "45 * * * *"
|
||||
|
||||
env:
|
||||
USE_VARS: "${{ vars.USE_VARS }}"
|
||||
DBT_PROFILES_DIR: "${{ vars.DBT_PROFILES_DIR }}"
|
||||
ACCOUNT: "${{ vars.ACCOUNT }}"
|
||||
ROLE: "${{ vars.ROLE }}"
|
||||
USER: "${{ vars.USER }}"
|
||||
PASSWORD: "${{ secrets.PASSWORD }}"
|
||||
REGION: "${{ vars.REGION }}"
|
||||
DATABASE: "${{ vars.DATABASE }}"
|
||||
WAREHOUSE: "${{ vars.WAREHOUSE }}"
|
||||
SCHEMA: "${{ vars.SCHEMA }}"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}
|
||||
|
||||
jobs:
|
||||
run_dbt_jobs:
|
||||
runs-on: ubuntu-latest
|
||||
environment:
|
||||
name: workflow_prod
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.10"
|
||||
cache: "pip"
|
||||
|
||||
- name: install dependencies
|
||||
run: |
|
||||
pip install -r requirements.txt
|
||||
dbt deps
|
||||
|
||||
- name: Update decoded tables
|
||||
run: |
|
||||
dbt run -s tag:evm_decoded_logs
|
||||
50
.github/workflows/dbt_run_scheduled_abis.yml
vendored
Normal file
50
.github/workflows/dbt_run_scheduled_abis.yml
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
name: dbt_run_scheduled_abis
|
||||
run-name: dbt_run_scheduled_abis
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
# Run at 23:27 UTC every day
|
||||
- cron: "27 23 * * *"
|
||||
|
||||
env:
|
||||
DBT_PROFILES_DIR: ./
|
||||
|
||||
ACCOUNT: "${{ vars.ACCOUNT }}"
|
||||
ROLE: "${{ vars.ROLE }}"
|
||||
USER: "${{ vars.USER }}"
|
||||
PASSWORD: "${{ secrets.PASSWORD }}"
|
||||
REGION: "${{ vars.REGION }}"
|
||||
DATABASE: "${{ vars.DATABASE }}"
|
||||
WAREHOUSE: "${{ vars.WAREHOUSE }}"
|
||||
SCHEMA: "${{ vars.SCHEMA }}"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}
|
||||
|
||||
jobs:
|
||||
run_dbt_jobs:
|
||||
runs-on: ubuntu-latest
|
||||
environment:
|
||||
name: workflow_prod
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.10"
|
||||
cache: "pip"
|
||||
|
||||
- name: install dependencies
|
||||
run: |
|
||||
pip install -r requirements.txt
|
||||
dbt deps
|
||||
|
||||
- name: Run ABI Models
|
||||
run: |
|
||||
dbt run -m models/evm/silver/abis
|
||||
|
||||
- name: Kick off decoded logs history, if there are new ABIs from users
|
||||
run: |
|
||||
dbt run-operation run_decoded_logs_history
|
||||
50
.github/workflows/dbt_run_streamline_decoded_logs_history.yml
vendored
Normal file
50
.github/workflows/dbt_run_streamline_decoded_logs_history.yml
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
name: dbt_run_streamline_decoded_logs_history
|
||||
run-name: dbt_run_streamline_decoded_logs_history
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
# Run at 22:43 UTC every Saturday
|
||||
- cron: "43 22 * * 6"
|
||||
|
||||
env:
|
||||
DBT_PROFILES_DIR: ./
|
||||
|
||||
ACCOUNT: "${{ vars.ACCOUNT }}"
|
||||
ROLE: "${{ vars.ROLE }}"
|
||||
USER: "${{ vars.USER }}"
|
||||
PASSWORD: "${{ secrets.PASSWORD }}"
|
||||
REGION: "${{ vars.REGION }}"
|
||||
DATABASE: "${{ vars.DATABASE }}"
|
||||
WAREHOUSE: "${{ vars.WAREHOUSE }}"
|
||||
SCHEMA: "${{ vars.SCHEMA }}"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}
|
||||
|
||||
jobs:
|
||||
run_dbt_jobs:
|
||||
runs-on: ubuntu-latest
|
||||
environment:
|
||||
name: workflow_prod
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.10"
|
||||
cache: "pip"
|
||||
|
||||
- name: install dependencies
|
||||
run: |
|
||||
pip install -r requirements.txt
|
||||
dbt deps
|
||||
|
||||
- name: Update complete table
|
||||
run: |
|
||||
dbt run -m models/evm/streamline/decoder/streamline__decoded_logs_complete.sql
|
||||
|
||||
- name: Decode historical logs
|
||||
run: |
|
||||
dbt run-operation decoded_logs_history --vars '{"STREAMLINE_INVOKE_STREAMS":True}'
|
||||
2
.github/workflows/dbt_test.yml
vendored
2
.github/workflows/dbt_test.yml
vendored
@ -45,7 +45,7 @@ jobs:
|
||||
|
||||
- name: Run DBT Jobs
|
||||
run: |
|
||||
dbt test -s "flow_models,models/gold" tag:observability tag:evm tag:evm_gap_test --vars '{"TEST_RANGE": True, "START_HEIGHT": ${{ vars.STREAMLINE_START_BLOCK }}, "END_HEIGHT": 100000000}'
|
||||
dbt test -s "flow_models,models/gold" tag:observability tag:evm_gap_test --vars '{"TEST_RANGE": True, "START_HEIGHT": ${{ vars.STREAMLINE_START_BLOCK }}, "END_HEIGHT": 100000000}'
|
||||
continue-on-error: true
|
||||
|
||||
- name: Log test results
|
||||
|
||||
50
.github/workflows/dbt_test_recent_evm.yml
vendored
Normal file
50
.github/workflows/dbt_test_recent_evm.yml
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
name: dbt_test_recent_evm
|
||||
run-name: dbt_test_recent_evm
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
# Run at 0500 UTC daily (see https://crontab.guru)
|
||||
- cron: "0 5 * * *"
|
||||
|
||||
env:
|
||||
DBT_PROFILES_DIR: ./
|
||||
|
||||
ACCOUNT: "${{ vars.ACCOUNT }}"
|
||||
ROLE: "${{ vars.ROLE }}"
|
||||
USER: "${{ vars.USER }}"
|
||||
PASSWORD: "${{ secrets.PASSWORD }}"
|
||||
REGION: "${{ vars.REGION }}"
|
||||
DATABASE: "${{ vars.DATABASE }}"
|
||||
WAREHOUSE: "${{ vars.WAREHOUSE }}"
|
||||
SCHEMA: "${{ vars.SCHEMA }}"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}
|
||||
|
||||
jobs:
|
||||
run_dbt_jobs:
|
||||
runs-on: ubuntu-latest
|
||||
environment:
|
||||
name: workflow_prod
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.10"
|
||||
cache: "pip"
|
||||
|
||||
- name: install dependencies
|
||||
run: |
|
||||
pip install -r requirements.txt
|
||||
dbt deps
|
||||
|
||||
- name: Build Recent Testing Views
|
||||
run: |
|
||||
dbt run -m "flow_models,tag:recent_evm_test"
|
||||
|
||||
- name: Run Recent Tests
|
||||
run: |
|
||||
dbt test -m "flow_models,tag:recent_evm_test"
|
||||
129
macros/evm/decoded_logs_history.sql
Normal file
129
macros/evm/decoded_logs_history.sql
Normal file
@ -0,0 +1,129 @@
|
||||
{% macro decoded_logs_history(backfill_mode=false) %}
|
||||
|
||||
{%- set params = {
|
||||
"sql_limit": var("DECODED_LOGS_HISTORY_SQL_LIMIT", 8000000),
|
||||
"producer_batch_size": var("DECODED_LOGS_HISTORY_PRODUCER_BATCH_SIZE", 400000),
|
||||
"worker_batch_size": var("DECODED_LOGS_HISTORY_WORKER_BATCH_SIZE", 100000)
|
||||
} -%}
|
||||
|
||||
{% set wait_time = var("DECODED_LOGS_HISTORY_WAIT_TIME", 60) %}
|
||||
|
||||
{% set find_months_query %}
|
||||
SELECT
|
||||
DISTINCT date_trunc('month', block_timestamp)::date as month
|
||||
FROM {{ ref('core_evm__fact_blocks') }}
|
||||
ORDER BY month ASC
|
||||
{% endset %}
|
||||
|
||||
{% set results = run_query(find_months_query) %}
|
||||
|
||||
{% if execute %}
|
||||
{% set months = results.columns[0].values() %}
|
||||
|
||||
{% for month in months %}
|
||||
{% set view_name = 'decoded_logs_history_' ~ month.strftime('%Y_%m') %}
|
||||
|
||||
{% set create_view_query %}
|
||||
create or replace view streamline.{{view_name}} as (
|
||||
WITH target_blocks AS (
|
||||
SELECT
|
||||
block_number
|
||||
FROM {{ ref('core_evm__fact_blocks') }}
|
||||
WHERE date_trunc('month', block_timestamp) = '{{month}}'::timestamp
|
||||
),
|
||||
new_abis AS (
|
||||
SELECT
|
||||
abi,
|
||||
parent_contract_address,
|
||||
event_signature,
|
||||
start_block,
|
||||
end_block
|
||||
FROM {{ ref('silver_evm__complete_event_abis') }}
|
||||
{% if not backfill_mode %}
|
||||
WHERE inserted_timestamp > dateadd('day', -30, sysdate())
|
||||
{% endif %}
|
||||
),
|
||||
existing_logs_to_exclude AS (
|
||||
SELECT _log_id
|
||||
FROM {{ ref('streamline__decoded_logs_complete') }} l
|
||||
INNER JOIN target_blocks b using (block_number)
|
||||
),
|
||||
candidate_logs AS (
|
||||
SELECT
|
||||
l.block_number,
|
||||
l.tx_hash,
|
||||
l.event_index,
|
||||
l.contract_address,
|
||||
l.topics,
|
||||
l.data,
|
||||
concat(l.tx_hash::string, '-', l.event_index::string) as _log_id
|
||||
FROM target_blocks b
|
||||
INNER JOIN {{ ref('core_evm__fact_event_logs') }} l using (block_number)
|
||||
WHERE l.tx_succeeded and date_trunc('month', l.block_timestamp) = '{{month}}'::timestamp
|
||||
)
|
||||
SELECT
|
||||
l.block_number,
|
||||
l._log_id,
|
||||
A.abi,
|
||||
OBJECT_CONSTRUCT(
|
||||
'topics', l.topics,
|
||||
'data', l.data,
|
||||
'address', l.contract_address
|
||||
) AS data
|
||||
FROM candidate_logs l
|
||||
INNER JOIN new_abis A
|
||||
ON A.parent_contract_address = l.contract_address
|
||||
AND A.event_signature = l.topics[0]::STRING
|
||||
AND l.block_number BETWEEN A.start_block AND A.end_block
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM existing_logs_to_exclude e
|
||||
WHERE e._log_id = l._log_id
|
||||
)
|
||||
LIMIT {{ params.sql_limit }}
|
||||
)
|
||||
{% endset %}
|
||||
|
||||
{# Create the view #}
|
||||
{% do run_query(create_view_query) %}
|
||||
{{ log("Created view for month " ~ month.strftime('%Y-%m'), info=True) }}
|
||||
|
||||
{% if var("STREAMLINE_INVOKE_STREAMS", false) %}
|
||||
{# Check if rows exist first #}
|
||||
{% set check_rows_query %}
|
||||
SELECT EXISTS(SELECT 1 FROM streamline.{{view_name}} LIMIT 1)
|
||||
{% endset %}
|
||||
|
||||
{% set results = run_query(check_rows_query) %}
|
||||
{% set has_rows = results.columns[0].values()[0] %}
|
||||
|
||||
{% if has_rows %}
|
||||
{# Invoke streamline, if rows exist to decode #}
|
||||
{% set decode_query %}
|
||||
SELECT
|
||||
streamline.udf_bulk_decode_logs_v2(
|
||||
PARSE_JSON(
|
||||
$${ "external_table": "decoded_logs",
|
||||
"producer_batch_size": {{ params.producer_batch_size }},
|
||||
"sql_limit": {{ params.sql_limit }},
|
||||
"sql_source": "{{view_name}}",
|
||||
"worker_batch_size": {{ params.worker_batch_size }} }$$
|
||||
)
|
||||
);
|
||||
{% endset %}
|
||||
|
||||
{% do run_query(decode_query) %}
|
||||
{{ log("Triggered decoding for month " ~ month.strftime('%Y-%m'), info=True) }}
|
||||
|
||||
{# Call wait since we actually did some decoding #}
|
||||
{% do run_query("call system$wait(" ~ wait_time ~ ")") %}
|
||||
{{ log("Completed wait after decoding for month " ~ month.strftime('%Y-%m'), info=True) }}
|
||||
{% else %}
|
||||
{{ log("No rows to decode for month " ~ month.strftime('%Y-%m'), info=True) }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% endmacro %}
|
||||
31
macros/evm/run_decoded_logs_history.sql
Normal file
31
macros/evm/run_decoded_logs_history.sql
Normal file
@ -0,0 +1,31 @@
|
||||
{% macro run_decoded_logs_history() %}
|
||||
|
||||
{% set blockchain = var('GLOBAL_PROD_DB_NAME','').lower() %}
|
||||
|
||||
{% set check_for_new_user_abis_query %}
|
||||
select 1
|
||||
from {{ ref('silver_evm__user_verified_abis') }}
|
||||
where _inserted_timestamp::date = sysdate()::date
|
||||
and dayname(sysdate()) <> 'Sat'
|
||||
{% endset %}
|
||||
|
||||
{% set results = run_query(check_for_new_user_abis_query) %}
|
||||
|
||||
{% if execute %}
|
||||
{% set new_user_abis = results.columns[0].values()[0] %}
|
||||
|
||||
{% if new_user_abis %}
|
||||
{% set invoke_workflow_query %}
|
||||
SELECT
|
||||
github_actions.workflow_dispatches(
|
||||
'FlipsideCrypto',
|
||||
'flow-models',
|
||||
'dbt_run_streamline_decoded_logs_history.yml',
|
||||
NULL
|
||||
)
|
||||
{% endset %}
|
||||
|
||||
{% do run_query(invoke_workflow_query) %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
@ -94,11 +94,11 @@
|
||||
|
||||
{% macro create_udf_bulk_decode_logs() %}
|
||||
CREATE
|
||||
OR REPLACE EXTERNAL FUNCTION streamline.udf_bulk_decode_logs(
|
||||
OR REPLACE EXTERNAL FUNCTION streamline.udf_bulk_decode_logs_v2(
|
||||
json OBJECT
|
||||
) returns ARRAY api_integration = {% if target.name == "prod" %}
|
||||
aws_flow_evm_api_prod AS 'https://rajpkbgko9.execute-api.us-east-1.amazonaws.com/prod/bulk_decode_logs'
|
||||
AWS_FLOW_EVM_API_PROD AS 'https://rajpkbgko9.execute-api.us-east-1.amazonaws.com/prod/bulk_decode_logs'
|
||||
{% else %}
|
||||
aws_flow_evm_api_dev AS'https://pfv9lhg3kg.execute-api.us-east-1.amazonaws.com/stg/bulk_decode_logs'
|
||||
AWS_FLOW_EVM_API_DEV AS'https://pfv9lhg3kg.execute-api.us-east-1.amazonaws.com/stg/bulk_decode_logs'
|
||||
{%- endif %};
|
||||
{% endmacro %}
|
||||
35
macros/tests/evm/events_match_txs.sql
Normal file
35
macros/tests/evm/events_match_txs.sql
Normal file
@ -0,0 +1,35 @@
|
||||
{% test events_match_txs(
|
||||
model,
|
||||
transactions_model
|
||||
) %}
|
||||
WITH logs AS (
|
||||
SELECT
|
||||
DISTINCT block_number,
|
||||
tx_hash,
|
||||
tx_position
|
||||
FROM
|
||||
{{ model }}
|
||||
),
|
||||
missing_transactions AS (
|
||||
SELECT
|
||||
logs.block_number,
|
||||
logs.tx_hash,
|
||||
logs.tx_position
|
||||
FROM
|
||||
logs
|
||||
LEFT JOIN {{ transactions_model }}
|
||||
txs USING (
|
||||
block_number,
|
||||
tx_hash,
|
||||
tx_position
|
||||
)
|
||||
WHERE
|
||||
txs.tx_hash IS NULL
|
||||
OR txs.tx_position IS NULL
|
||||
OR txs.block_number IS NULL
|
||||
)
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
missing_transactions
|
||||
{% endtest %}
|
||||
15
macros/tests/evm/find_missing_decoded_logs.sql
Normal file
15
macros/tests/evm/find_missing_decoded_logs.sql
Normal file
@ -0,0 +1,15 @@
|
||||
{% test find_missing_decoded_logs(model, fact_logs_model, wrapped_asset_address) %}
|
||||
SELECT
|
||||
l.block_number,
|
||||
l.fact_event_logs_id
|
||||
FROM
|
||||
{{ fact_logs_model }}
|
||||
l
|
||||
LEFT JOIN {{ model }}
|
||||
d
|
||||
ON d.ez_decoded_event_logs_id = l.fact_event_logs_id
|
||||
WHERE
|
||||
l.contract_address = '{{ wrapped_asset_address }}'
|
||||
AND l.topics [0] :: STRING = '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef' -- Transfer
|
||||
AND d.ez_decoded_event_logs_id IS NULL
|
||||
{% endtest %}
|
||||
31
macros/tests/evm/txs_match_blocks.sql
Normal file
31
macros/tests/evm/txs_match_blocks.sql
Normal file
@ -0,0 +1,31 @@
|
||||
{% test txs_match_blocks(
|
||||
model,
|
||||
blocks_model
|
||||
) %}
|
||||
WITH count_txs AS (
|
||||
SELECT
|
||||
block_number,
|
||||
COUNT(*) AS record_count
|
||||
FROM
|
||||
{{ model }}
|
||||
GROUP BY
|
||||
ALL
|
||||
),
|
||||
block_txs AS (
|
||||
SELECT
|
||||
block_number,
|
||||
tx_count AS expected_count
|
||||
FROM
|
||||
{{ blocks_model }}
|
||||
)
|
||||
SELECT
|
||||
block_number,
|
||||
record_count AS actual_count,
|
||||
expected_count
|
||||
FROM
|
||||
block_txs
|
||||
LEFT JOIN count_txs USING (block_number)
|
||||
WHERE
|
||||
record_count != expected_count
|
||||
OR expected_count IS NULL
|
||||
{% endtest %}
|
||||
45
models/evm/bronze/bronze__decoded_logs.sql
Normal file
45
models/evm/bronze/bronze__decoded_logs.sql
Normal file
@ -0,0 +1,45 @@
|
||||
{{ config (
|
||||
materialized = 'view',
|
||||
tags = ['evm']
|
||||
) }}
|
||||
|
||||
WITH meta AS (
|
||||
SELECT
|
||||
job_created_time AS _inserted_timestamp,
|
||||
file_name,
|
||||
CAST(SPLIT_PART(SPLIT_PART(file_name, '/', 6), '_', 1) AS INTEGER) AS _partition_by_block_number,
|
||||
TO_DATE(
|
||||
concat_ws('-', SPLIT_PART(file_name, '/', 3), SPLIT_PART(file_name, '/', 4), SPLIT_PART(file_name, '/', 5))
|
||||
) AS _partition_by_created_date
|
||||
FROM
|
||||
TABLE(
|
||||
information_schema.external_table_file_registration_history(
|
||||
start_time => DATEADD('day', -3, CURRENT_TIMESTAMP()),
|
||||
table_name => '{{ source( "bronze_streamline", "evm_decoded_logs") }}')
|
||||
) A
|
||||
)
|
||||
SELECT
|
||||
block_number,
|
||||
id :: STRING AS id,
|
||||
DATA,
|
||||
metadata,
|
||||
b.file_name,
|
||||
_inserted_timestamp,
|
||||
s._partition_by_block_number AS _partition_by_block_number,
|
||||
s._partition_by_created_date AS _partition_by_created_date
|
||||
FROM
|
||||
{{ source(
|
||||
"bronze_streamline",
|
||||
"evm_decoded_logs"
|
||||
) }}
|
||||
s
|
||||
JOIN meta b
|
||||
ON b.file_name = metadata$filename
|
||||
AND b._partition_by_block_number = s._partition_by_block_number
|
||||
AND b._partition_by_created_date = s._partition_by_created_date
|
||||
WHERE
|
||||
b._partition_by_block_number = s._partition_by_block_number
|
||||
AND b._partition_by_created_date = s._partition_by_created_date
|
||||
AND s._partition_by_created_date >= DATEADD('day', -2, CURRENT_TIMESTAMP())
|
||||
AND DATA :error IS NULL
|
||||
AND DATA IS NOT NULL
|
||||
44
models/evm/bronze/bronze__decoded_logs_fr.sql
Normal file
44
models/evm/bronze/bronze__decoded_logs_fr.sql
Normal file
@ -0,0 +1,44 @@
|
||||
{{ config (
|
||||
materialized = 'view',
|
||||
tags = ['evm']
|
||||
) }}
|
||||
|
||||
WITH meta AS (
|
||||
SELECT
|
||||
registered_on AS _inserted_timestamp,
|
||||
file_name,
|
||||
CAST(SPLIT_PART(SPLIT_PART(file_name, '/', 6), '_', 1) AS INTEGER) AS _partition_by_block_number,
|
||||
TO_DATE(
|
||||
concat_ws('-', SPLIT_PART(file_name, '/', 3), SPLIT_PART(file_name, '/', 4), SPLIT_PART(file_name, '/', 5))
|
||||
) AS _partition_by_created_date
|
||||
FROM
|
||||
TABLE(
|
||||
information_schema.external_table_files(
|
||||
table_name => '{{ source( "bronze_streamline", "evm_decoded_logs") }}'
|
||||
)
|
||||
) A
|
||||
)
|
||||
SELECT
|
||||
block_number,
|
||||
id :: STRING AS id,
|
||||
DATA,
|
||||
metadata,
|
||||
b.file_name,
|
||||
_inserted_timestamp,
|
||||
s._partition_by_block_number AS _partition_by_block_number,
|
||||
s._partition_by_created_date AS _partition_by_created_date
|
||||
FROM
|
||||
{{ source(
|
||||
"bronze_streamline",
|
||||
"evm_decoded_logs"
|
||||
) }}
|
||||
s
|
||||
JOIN meta b
|
||||
ON b.file_name = metadata$filename
|
||||
AND b._partition_by_block_number = s._partition_by_block_number
|
||||
AND b._partition_by_created_date = s._partition_by_created_date
|
||||
WHERE
|
||||
b._partition_by_block_number = s._partition_by_block_number
|
||||
AND b._partition_by_created_date = s._partition_by_created_date
|
||||
AND DATA :error IS NULL
|
||||
AND DATA IS NOT NULL
|
||||
110
models/evm/bronze/bronze_evm_api__token_reads.sql
Normal file
110
models/evm/bronze/bronze_evm_api__token_reads.sql
Normal file
@ -0,0 +1,110 @@
|
||||
{{ config(
|
||||
materialized = 'incremental',
|
||||
unique_key = "contract_address",
|
||||
full_refresh = false,
|
||||
tags = ['evm']
|
||||
) }}
|
||||
|
||||
WITH base AS (
|
||||
|
||||
SELECT
|
||||
contract_address,
|
||||
latest_event_block AS latest_block
|
||||
FROM
|
||||
{{ ref('silver_evm__relevant_contracts') }}
|
||||
WHERE
|
||||
total_event_count >= 25
|
||||
|
||||
{% if is_incremental() %}
|
||||
AND contract_address NOT IN (
|
||||
SELECT
|
||||
contract_address
|
||||
FROM
|
||||
{{ this }}
|
||||
)
|
||||
{% endif %}
|
||||
ORDER BY
|
||||
total_event_count DESC
|
||||
LIMIT
|
||||
200
|
||||
), function_sigs AS (
|
||||
SELECT
|
||||
'0x313ce567' AS function_sig,
|
||||
'decimals' AS function_name
|
||||
UNION
|
||||
SELECT
|
||||
'0x06fdde03',
|
||||
'name'
|
||||
UNION
|
||||
SELECT
|
||||
'0x95d89b41',
|
||||
'symbol'
|
||||
),
|
||||
all_reads AS (
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
base
|
||||
JOIN function_sigs
|
||||
ON 1 = 1
|
||||
),
|
||||
ready_reads AS (
|
||||
SELECT
|
||||
contract_address,
|
||||
latest_block,
|
||||
function_sig,
|
||||
RPAD(
|
||||
function_sig,
|
||||
64,
|
||||
'0'
|
||||
) AS input,
|
||||
utils.udf_json_rpc_call(
|
||||
'eth_call',
|
||||
[{'to': contract_address, 'from': null, 'data': input}, utils.udf_int_to_hex(latest_block)],
|
||||
concat_ws(
|
||||
'-',
|
||||
contract_address,
|
||||
input,
|
||||
latest_block
|
||||
)
|
||||
) AS rpc_request
|
||||
FROM
|
||||
all_reads
|
||||
),
|
||||
node_call AS (
|
||||
SELECT
|
||||
contract_address,
|
||||
latest_block,
|
||||
function_sig,
|
||||
input,
|
||||
live.udf_api(
|
||||
'POST',
|
||||
'{Service}',
|
||||
OBJECT_CONSTRUCT(
|
||||
'Content-Type',
|
||||
'application/json'
|
||||
),
|
||||
rpc_request,
|
||||
'Vault/prod/flow/evm/mainnet'
|
||||
) AS response
|
||||
FROM
|
||||
ready_reads
|
||||
WHERE
|
||||
EXISTS (
|
||||
SELECT
|
||||
1
|
||||
FROM
|
||||
ready_reads
|
||||
LIMIT
|
||||
1
|
||||
)
|
||||
)
|
||||
SELECT
|
||||
contract_address,
|
||||
latest_block AS block_number,
|
||||
function_sig,
|
||||
NULL AS function_input,
|
||||
response,
|
||||
SYSDATE() :: TIMESTAMP AS _inserted_timestamp
|
||||
FROM
|
||||
node_call
|
||||
15
models/evm/bronze/bronze_evm_api__token_reads.yml
Normal file
15
models/evm/bronze/bronze_evm_api__token_reads.yml
Normal file
@ -0,0 +1,15 @@
|
||||
version: 2
|
||||
models:
|
||||
- name: bronze_evm_api__token_reads
|
||||
|
||||
columns:
|
||||
- name: _INSERTED_TIMESTAMP
|
||||
tests:
|
||||
- not_null
|
||||
- dbt_expectations.expect_row_values_to_have_recent_data:
|
||||
datepart: day
|
||||
interval: 1
|
||||
- dbt_expectations.expect_column_values_to_be_in_type_list:
|
||||
column_type_list:
|
||||
- TIMESTAMP_LTZ
|
||||
- TIMESTAMP_NTZ
|
||||
182
models/evm/descriptions/blocks.md
Normal file
182
models/evm/descriptions/blocks.md
Normal file
@ -0,0 +1,182 @@
|
||||
{% docs evm_blocks_table_doc %}
|
||||
|
||||
This table contains block level data for this EVM blockchain. This table can be used to analyze trends at a block level, for example gas fees vs. total transactions over time. For more information, please see [Etherscan Resources](https://etherscan.io/directory/Learning_Resources/Ethereum) or [The Ethereum Organization](https://ethereum.org/en/developers/docs/blocks/)
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_block_header_json %}
|
||||
|
||||
This JSON column contains the block header details.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_blockchain %}
|
||||
|
||||
The blockchain on which transactions are being confirmed.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_blocks_hash %}
|
||||
|
||||
The hash of the block header for a given block.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_blocks_nonce %}
|
||||
|
||||
Block nonce is a value used during mining to demonstrate proof of work for a given block.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_difficulty %}
|
||||
|
||||
The effort required to mine the block.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_extra_data %}
|
||||
|
||||
Any data included by the miner for a given block.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_gas_limit %}
|
||||
|
||||
Total gas limit provided by all transactions in the block.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_gas_used %}
|
||||
|
||||
Total gas used in the block.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_network %}
|
||||
|
||||
The network on the blockchain used by a transaction.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_parent_hash %}
|
||||
|
||||
The hash of the block from which a given block is generated. Also known as the parent block.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_receipts_root %}
|
||||
|
||||
The root of the state trie.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_sha3_uncles %}
|
||||
|
||||
The mechanism which Ethereum Javascript RLP encodes an empty string.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_size %}
|
||||
|
||||
Block size, which is determined by a given block's gas limit.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_total_difficulty %}
|
||||
|
||||
Total difficulty of the chain at a given block.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_tx_count %}
|
||||
|
||||
Total number of transactions within a block.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_uncle_blocks %}
|
||||
|
||||
Uncle blocks occur when two blocks are mined and broadcasted at the same time, with the same block number. The block validated across the most nodes will be added to the primary chain, and the other one becomes an uncle block. Miners do receive rewards for uncle blocks.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_miner %}
|
||||
|
||||
The address of the beneficiary to whom the mining rewards were given
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_state_root %}
|
||||
|
||||
The root of the final state trie of the block
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_transactions_root %}
|
||||
|
||||
The root of the transaction trie of the block
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_logs_bloom %}
|
||||
|
||||
The bloom filter for the logs of the block.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_mix_hash %}
|
||||
|
||||
A string of a 256-bit hash encoded as a hexadecimal
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_base_fee_per_gas %}
|
||||
|
||||
A string of the base fee encoded in hexadecimal format. Please note that this response field will not be included in a block requested before the EIP-1559 upgrade
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_blob_gas_used %}
|
||||
|
||||
The amount of gas used for blob transactions in the block.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_excess_blob_gas %}
|
||||
|
||||
The amount of excess blob gas in the block.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_parent_beacon_block_root %}
|
||||
|
||||
The root of the parent beacon block.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_withdrawals %}
|
||||
|
||||
The withdrawals for the block.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_withdrawals_root %}
|
||||
|
||||
The root of the withdrawals for the block.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_base_fee_per_gas %}
|
||||
|
||||
A string of the base fee encoded in hexadecimal format, converted to integer.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_block_header_json %}
|
||||
|
||||
This JSON column contains the block header details.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_blockchain %}
|
||||
|
||||
The blockchain on which transactions are being confirmed.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_blocks_hash %}
|
||||
|
||||
The hash of the block header for a given block.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_blocks_nonce %}
|
||||
|
||||
Block nonce is a value used during mining to demonstrate proof of work for a given block.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_blocks_table_doc %}
|
||||
|
||||
This table contains block level data for the flowEVM Blockchain. This table can be used to analyze trends at a block level, for example gas fees vs. total transactions over time. For more information on EVM transactions, please see [Etherscan Resources](https://etherscan.io/directory/Learning_Resources/Ethereum) or [The Ethereum Organization](https://ethereum.org/en/developers/docs/blocks/)
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_difficulty %}
|
||||
|
||||
The effort required to mine the block.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_extra_data %}
|
||||
|
||||
Any data included by the validator for a given block.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_gas_limit %}
|
||||
|
||||
Total gas limit provided by all transactions in the block.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_gas_used %}
|
||||
|
||||
Total gas used in the block.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_logs_bloom %}
|
||||
|
||||
The bloom filter for the logs of the block. null if pending
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_miner %}
|
||||
|
||||
Miner who successfully added a given block to the blockchain.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_mix_hash %}
|
||||
|
||||
A string of a 256-bit hash encoded as a hexadecimal
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_network %}
|
||||
|
||||
The network on the blockchain used by a transaction.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_nonce %}
|
||||
|
||||
The hash of the generated proof-of-work. null if pending
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_parent_hash %}
|
||||
|
||||
The hash of the block from which a given block is generated. Also known as the parent block.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_receipts_root %}
|
||||
|
||||
The root of the state trie.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_sha3_uncles %}
|
||||
|
||||
The mechanism which Ethereum Javascript RLP encodes an empty string.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_size %}
|
||||
|
||||
Block size, which is determined by a given block's gas limit.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_state_root %}
|
||||
|
||||
The root of the final state trie of the block
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_total_difficulty %}
|
||||
|
||||
Total difficulty of the chain at a given block.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_transactions %}
|
||||
|
||||
An array containing transaction response data.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_transactions_root %}
|
||||
|
||||
The root of the transaction trie of the block
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_tx_count %}
|
||||
|
||||
Total number of transactions within a block.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_uncle_blocks %}
|
||||
|
||||
Uncle blocks occur when two blocks are mined and broadcasted at the same time, with the same block number. The block validated across the most nodes will be added to the primary chain, and the other one becomes an uncle block. Miners do receive rewards for uncle blocks.
|
||||
|
||||
{% enddocs %}
|
||||
95
models/evm/descriptions/event_logs.md
Normal file
95
models/evm/descriptions/event_logs.md
Normal file
@ -0,0 +1,95 @@
|
||||
{% docs evm_logs_table_doc %}
|
||||
|
||||
This table contains flattened event logs from transactions on this EVM blockchain. Transactions may have multiple events, which are denoted by the event index for a transaction hash. Therefore, this table is unique on the combination of transaction hash and event index. Please see `fact_decoded_event_logs` or `ez_decoded_event_logs` for the decoded event logs.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_event_index %}
|
||||
|
||||
Event number within a transaction.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_event_inputs %}
|
||||
|
||||
The decoded event inputs for a given event.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_event_removed %}
|
||||
|
||||
Whether the event has been removed from the transaction.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_log_id_events %}
|
||||
|
||||
This is the primary key for this table. This is a concatenation of the transaction hash and the event index at which the event occurred. This field can be used within other event based tables such as ```fact_transfers``` & ```ez_token_transfers```.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_logs_contract_address %}
|
||||
|
||||
The address interacted with for a given event.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_logs_contract_name %}
|
||||
|
||||
The name of the contract or token, where possible.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_logs_data %}
|
||||
|
||||
The un-decoded event data.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_logs_tx_hash %}
|
||||
|
||||
Transaction hash is a unique 66-character identifier that is generated when a transaction is executed. This field will not be unique in this table, as a given transaction can include multiple events.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_topics %}
|
||||
|
||||
The un-decoded event input topics.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_topic_0 %}
|
||||
|
||||
The first topic of the event, which is a unique identifier for the event.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_topic_1 %}
|
||||
|
||||
The second topic of the event, if applicable.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_topic_2 %}
|
||||
|
||||
The third topic of the event, if applicable.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_topic_3 %}
|
||||
|
||||
The fourth topic of the event, if applicable.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_event_index %}
|
||||
|
||||
Event number within a transaction.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_event_inputs %}
|
||||
|
||||
The decoded event inputs for a given event.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_event_name %}
|
||||
|
||||
The decoded event name for a given event.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_event_removed %}
|
||||
|
||||
Whether the event has been removed from the transaction.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_origin_sig %}
|
||||
|
||||
The function signature of this transaction.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_log_id_events %}
|
||||
|
||||
This is the primary key for this table. This is a concatenation of the transaction hash and the event index at which the event occurred.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_logs_contract_address %}
|
||||
|
||||
The address interacted with for a given event.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_logs_contract_name %}
|
||||
|
||||
The name of the contract or token, where possible.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_logs_data %}
|
||||
|
||||
The un-decoded event data.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_logs_table_doc %}
|
||||
|
||||
This table contains flattened event logs from transactions on the flowEVM Blockchain. Transactions may have multiple events, which are denoted by the event index for a transaction hash. Therefore, this table is unique on the combination of transaction hash and event index.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_logs_tx_hash %}
|
||||
|
||||
Transaction hash is a unique 66-character identifier that is generated when a transaction is executed. This field will not be unique in this table, as a given transaction can include multiple events.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_origin_from %}
|
||||
|
||||
The from address of this transaction.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_origin_to %}
|
||||
|
||||
The to address of this transaction.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_topics %}
|
||||
|
||||
The un-decoded event input topics.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_block_number %}
|
||||
|
||||
Also known as block height. The block number, which indicates the length of the blockchain, increases after the addition of each new block.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_block_timestamp %}
|
||||
|
||||
The date and time at which the block was produced.
|
||||
|
||||
{% enddocs %}
|
||||
89
models/evm/descriptions/general/complete_general.md
Normal file
89
models/evm/descriptions/general/complete_general.md
Normal file
@ -0,0 +1,89 @@
|
||||
{% docs evm_internal_column %}
|
||||
|
||||
Deprecated. This column is no longer used. Please remove from your query by Jan. 10 2024.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_amount_deprecation %}
|
||||
|
||||
This column is being deprecated for standardization purposes on Jan. 10 2024. Please use the equivalent column without the native asset prefix. For example, use `amount` instead of `avax_amount`.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_block_number %}
|
||||
|
||||
Also known as block height. The block number, which indicates the length of the blockchain, increases after the addition of each new block.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_block_timestamp %}
|
||||
|
||||
The date and time at which the block was produced.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_from_address %}
|
||||
|
||||
The sending address of this transaction.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_ingested_at %}
|
||||
|
||||
Internal column.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_to_address %}
|
||||
|
||||
The receiving address of this transaction. This can be a contract address.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_pk %}
|
||||
|
||||
The unique identifier for each row in the table.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_inserted_timestamp %}
|
||||
|
||||
The UTC timestamp at which the row was inserted into the table.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_modified_timestamp %}
|
||||
|
||||
The UTC timestamp at which the row was last modified.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_precise_amount_unadjusted %}
|
||||
|
||||
The precise, unadjusted amount of the transaction. This is returned as a string to avoid precision loss.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_precise_amount_adjusted %}
|
||||
|
||||
The precise, adjusted amount of the transaction. This is returned as a string to avoid precision loss.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_value_hex %}
|
||||
|
||||
The value of the transaction in hexadecimal format.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_column_deprecation_notice %}
|
||||
|
||||
This column is being deprecated for standardization purposes.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_table_deprecation_notice %}
|
||||
|
||||
This table is being deprecated for standardization purposes.
|
||||
|
||||
{% enddocs %}
|
||||
69
models/evm/descriptions/general/complete_labels.md
Normal file
69
models/evm/descriptions/general/complete_labels.md
Normal file
@ -0,0 +1,69 @@
|
||||
{% docs evm_labels_table %}
|
||||
|
||||
This table contains labels for addresses on this EVM blockchain.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_table_dim_labels %}
|
||||
|
||||
The labels table is a store of one-to-one address identifiers, or an address name. Labels are broken out into a "type" (such as cex, dex, dapp, games, etc.) and a "subtype" (ex: contract_deployer, hot_wallet, token_contract, etc.) in order to help classify each address name into similar groups. Our labels are sourced from many different places, but can primarily be grouped into two categories: automatic and manual. Automatic labels are continuously labeled based on certain criteria, such as a known contract deploying another contract, behavior-based algorithms for finding deposit wallets, and consistent data pulls of custom protocol APIs. Manual labels are done periodically to find addresses that cannot be found programmatically such as finding new protocol addresses, centralized exchange hot wallets, or trending addresses. Labels can also be added by our community by using our add-a-label tool (https://science.flipsidecrypto.xyz/add-a-label/) or on-chain with near (https://near.social/lord1.near/widget/Form) and are reviewed by our labels team. A label can be removed by our labels team if it is found to be incorrect or no longer relevant; this generally will only happen for mislabeled deposit wallets.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_project_name %}
|
||||
|
||||
The name of the project for this address.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_label %}
|
||||
|
||||
The label for this address.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_label_address %}
|
||||
|
||||
Address that the label is for. This is the field that should be used to join other tables with labels.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_label_address_name %}
|
||||
|
||||
The most granular label for this address.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_label_blockchain %}
|
||||
|
||||
The name of the blockchain.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_label_creator %}
|
||||
|
||||
The name of the creator of the label.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_label_subtype %}
|
||||
|
||||
A sub-category nested within label type providing further detail.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_label_type %}
|
||||
|
||||
A high-level category describing the address's main function or ownership.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_decimals %}
|
||||
|
||||
The number of decimal places this contract needs adjusted where token values exist. For example, use the decimal field to correctly transform raw amounts in ```fact_token_transfers```.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,11 +0,0 @@
|
||||
{% docs internal_column %}
|
||||
|
||||
Deprecated. This column is no longer used. Please remove from your query by Jan. 31 2024.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs amount_deprecation %}
|
||||
|
||||
This column is being deprecated for standardization purposes on Jan. 31 2024. Please use the equivalent column without the native asset prefix. For example, use `amount` instead of `eth_amount`.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_from_address %}
|
||||
|
||||
The sending address of this transaction.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_ingested_at %}
|
||||
|
||||
Internal column.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs is_pending %}
|
||||
|
||||
A boolean flag indicating if the record is pending or complete.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,17 +0,0 @@
|
||||
{% docs precise_amount_unadjusted %}
|
||||
|
||||
The precise, unadjusted amount of the transaction. This is returned as a string to avoid precision loss.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs precise_amount_adjusted %}
|
||||
|
||||
The precise, adjusted amount of the transaction. This is returned as a string to avoid precision loss.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs tx_fee_precise %}
|
||||
|
||||
The precise amount of the transaction fee. This is returned as a string to avoid precision loss.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_symbol %}
|
||||
|
||||
The symbol belonging to the address of the token
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_to_address %}
|
||||
|
||||
The receiving address of this transaction. This can be a contract address.
|
||||
|
||||
{% enddocs %}
|
||||
136
models/evm/descriptions/traces.md
Normal file
136
models/evm/descriptions/traces.md
Normal file
@ -0,0 +1,136 @@
|
||||
{% docs evm_traces_table_doc %}
|
||||
|
||||
This table contains flattened trace data for internal contract calls. User-defined functions (UDFs) are available to decode hex encoded fields, including `utils.udf_hex_to_int()`.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_traces_block_no %}
|
||||
|
||||
The block number of this transaction.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_traces_blocktime %}
|
||||
|
||||
The block timestamp of this transaction.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_traces_call_data %}
|
||||
|
||||
The raw JSON data for this trace.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_traces_value %}
|
||||
|
||||
The amount of the native asset transferred in this trace.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_traces_from %}
|
||||
|
||||
The sending address of this trace. This is not necessarily the from address of the transaction.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_traces_gas %}
|
||||
|
||||
The gas supplied for this trace.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_traces_gas_used %}
|
||||
|
||||
The gas used for this trace.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_traces_identifier %}
|
||||
|
||||
This field represents the position and type of the trace within the transaction.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_trace_index %}
|
||||
|
||||
The index of the trace within the transaction.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_traces_input %}
|
||||
|
||||
The input data for this trace.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_traces_output %}
|
||||
|
||||
The output data for this trace.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_sub_traces %}
|
||||
|
||||
The amount of nested sub traces for this trace.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_traces_to %}
|
||||
|
||||
The receiving address of this trace. This is not necessarily the to address of the transaction.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_traces_tx_hash %}
|
||||
|
||||
The transaction hash for the trace. Please note, this is not necessarily unique in this table as transactions frequently have multiple traces.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_traces_type %}
|
||||
|
||||
The type of internal transaction. Common trace types are `CALL`, `DELEGATECALL`, and `STATICCALL`.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_trace_succeeded %}
|
||||
|
||||
The boolean value representing if the trace succeeded.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_trace_error_reason %}
|
||||
|
||||
The reason for the trace failure, if any.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_trace_address %}
|
||||
|
||||
The trace address for this trace.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_revert_reason %}
|
||||
|
||||
The reason for the revert, if available.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
249
models/evm/descriptions/transactions.md
Normal file
249
models/evm/descriptions/transactions.md
Normal file
@ -0,0 +1,249 @@
|
||||
{% docs evm_tx_table_doc %}
|
||||
|
||||
This table contains transaction level data for this EVM blockchain. Each transaction will have a unique transaction hash, along with transaction fees and a value transferred in the native asset when applicable. Transactions may be native asset transfers or interactions with contract addresses. For more information, please see [The Ethereum Organization - Transactions](https://ethereum.org/en/developers/docs/transactions/)
|
||||
|
||||
Below are the specific native tokens that correspond to each EVM chain:
|
||||
|
||||
| Status | Description |
|
||||
|------------|-------------|
|
||||
| ETHEREUM | ETH |
|
||||
| BINANCE | BNB |
|
||||
| POLYGON | POL |
|
||||
| AVALANCHE | AVAX |
|
||||
| ARBITRUM | ETH |
|
||||
| OPTIMISM | ETH |
|
||||
| GNOSIS | xDAI |
|
||||
| KAIA | KLAY |
|
||||
| SEI | SEI |
|
||||
| CORE | CORE |
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_cumulative_gas_used %}
|
||||
|
||||
The total amount of gas used when this transaction was executed in the block.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_tx_block_hash %}
|
||||
|
||||
Block hash is a unique 66-character identifier that is generated when a block is produced.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_tx_fee %}
|
||||
|
||||
Amount paid to validate the transaction in the native asset.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_tx_gas_limit %}
|
||||
|
||||
Maximum amount of gas allocated for the transaction.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_tx_gas_price %}
|
||||
|
||||
Cost per unit of gas in Gwei.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_tx_gas_used %}
|
||||
|
||||
Gas used by the transaction.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_tx_hash %}
|
||||
|
||||
Transaction hash is a unique 66-character identifier that is generated when a transaction is executed.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_tx_input_data %}
|
||||
|
||||
This column contains additional data for this transaction, and is commonly used as part of a contract interaction or as a message to the recipient.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_tx_json %}
|
||||
|
||||
This JSON column contains the transaction details, including event logs.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_tx_nonce %}
|
||||
|
||||
The number of transactions sent from a given address.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_tx_origin_sig %}
|
||||
|
||||
The function signature of the call that triggered this transaction.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_origin_sig %}
|
||||
|
||||
The function signature of the contract call that triggered this transaction.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_tx_position %}
|
||||
|
||||
The position of the transaction within the block.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_tx_status %}
|
||||
|
||||
Status of the transaction.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_value %}
|
||||
|
||||
The value transacted in the native asset.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_effective_gas_price %}
|
||||
|
||||
The total base charge plus tip paid for each unit of gas, in Gwei.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_max_fee_per_gas %}
|
||||
|
||||
The maximum fee per gas of the transaction, in Gwei.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_max_priority_fee_per_gas %}
|
||||
|
||||
The maximum priority fee per gas of the transaction, in Gwei.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_r %}
|
||||
|
||||
The r value of the transaction signature.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_s %}
|
||||
|
||||
The s value of the transaction signature.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
|
||||
{% docs evm_v %}
|
||||
|
||||
The v value of the transaction signature.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_tx_succeeded %}
|
||||
|
||||
Whether the transaction was successful, returned as a boolean.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_tx_fee_precise %}
|
||||
|
||||
The precise amount of the transaction fee. This is returned as a string to avoid precision loss.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_tx_type %}
|
||||
|
||||
The type of transaction.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_mint %}
|
||||
|
||||
The minting event associated with the transaction
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_source_hash %}
|
||||
|
||||
The hash of the source transaction that created this transaction
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_eth_value %}
|
||||
|
||||
The eth value for the transaction
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_chain_id %}
|
||||
|
||||
The unique identifier for the chain the transaction was executed on.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_l1_fee_precise_raw %}
|
||||
|
||||
The raw l1 fee for the transaction, in Gwei.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_l1_fee_precise %}
|
||||
|
||||
The precise l1 fee for the transaction, in Gwei.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_y_parity %}
|
||||
|
||||
The y parity for the transaction.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_access_list %}
|
||||
|
||||
The access list for the transaction.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_l1_base_fee_scalar %}
|
||||
|
||||
The scalar l1 base fee for the transaction.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_l1_blob_base_fee %}
|
||||
|
||||
The blob base fee for the transaction.
|
||||
|
||||
{% enddocs %}
|
||||
|
||||
{% docs evm_l1_blob_base_fee_scalar %}
|
||||
|
||||
The scalar blob base fee for the transaction.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_block_hash %}
|
||||
|
||||
Block hash is a unique 66-character identifier that is generate when a block is produced.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_chain_id %}
|
||||
|
||||
The chain id returned by the node.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_cumulative_gas_used %}
|
||||
|
||||
The total amount of gas used when this transaction was executed in the block.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_receipt_type %}
|
||||
|
||||
The transaction type as returned by the receipt body.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_tx_fee %}
|
||||
|
||||
Amount paid to validate the transaction in ETH.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_tx_gas_limit %}
|
||||
|
||||
Maximum amount of gas allocated for the transaction.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_tx_gas_price %}
|
||||
|
||||
Cost per unit of gas in Gwei.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_tx_gas_used %}
|
||||
|
||||
Gas used by transaction.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_tx_hash %}
|
||||
|
||||
Transaction hash is a unique 66-character identifier that is generated when a transaction is executed.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_tx_input_data %}
|
||||
|
||||
This column contains additional data for this transaction, and is commonly used as part of a contract interaction or as a message to the recipient.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_tx_json %}
|
||||
|
||||
This JSON column contains the transaction details, including event logs.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_tx_nonce %}
|
||||
|
||||
The number of transactions sent from a given address.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_tx_origin_sig %}
|
||||
|
||||
The function signature of the contract call.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_tx_position %}
|
||||
|
||||
The position of the transaction within the block.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_tx_status %}
|
||||
|
||||
Status of the transaction.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_tx_table_doc %}
|
||||
|
||||
This table contains transaction level data for the flowEVM Blockchain. Each transaction will have a unique transaction hash, along with transactions fees and a ETH value transferred when applicable. Transactions may be native ETH transfers or interactions with contract addresses. For more information, please see [The Ethereum Organization - Transactions](https://ethereum.org/en/developers/docs/transactions/)
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_tx_type %}
|
||||
|
||||
Transaction Type as returned by the transaction body.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,5 +0,0 @@
|
||||
{% docs flowevm_value %}
|
||||
|
||||
The value transacted in ETH.
|
||||
|
||||
{% enddocs %}
|
||||
@ -1,83 +1,64 @@
|
||||
{{ config(
|
||||
materialized = 'incremental',
|
||||
unique_key = "fact_blocks_id",
|
||||
incremental_strategy = 'merge',
|
||||
merge_exclude_columns = ["inserted_timestamp"],
|
||||
cluster_by = ['inserted_timestamp :: DATE', 'ROUND(block_number, -3)'],
|
||||
persist_docs ={ "relation": true,
|
||||
"columns": true },
|
||||
{{ config (
|
||||
materialized = "incremental",
|
||||
incremental_strategy = 'delete+insert',
|
||||
unique_key = "block_number",
|
||||
cluster_by = ['block_timestamp::DATE'],
|
||||
tags = ['evm']
|
||||
) }}
|
||||
|
||||
SELECT
|
||||
block_number,
|
||||
block_timestamp,
|
||||
block_json :hash :: STRING AS block_hash,
|
||||
utils.udf_hex_to_int(
|
||||
block_json :timestamp :: STRING
|
||||
) :: TIMESTAMP AS block_timestamp,
|
||||
'mainnet' AS network,
|
||||
'flow' AS blockchain,
|
||||
transaction_count AS tx_count,
|
||||
difficulty,
|
||||
total_difficulty,
|
||||
extra_data,
|
||||
gas_limit,
|
||||
gas_used,
|
||||
block_hash AS HASH,
|
||||
parent_hash,
|
||||
receipts_root,
|
||||
sha3_uncles,
|
||||
SIZE,
|
||||
uncles AS uncle_blocks,
|
||||
OBJECT_CONSTRUCT(
|
||||
'baseFeePerGas',
|
||||
base_fee_per_gas,
|
||||
'difficulty',
|
||||
difficulty,
|
||||
'extraData',
|
||||
extra_data,
|
||||
'gasLimit',
|
||||
gas_limit,
|
||||
'gasUsed',
|
||||
gas_used,
|
||||
'hash',
|
||||
block_hash,
|
||||
'logsBloom',
|
||||
logs_bloom,
|
||||
'miner',
|
||||
miner,
|
||||
'nonce',
|
||||
nonce,
|
||||
'number',
|
||||
block_number,
|
||||
'parentHash',
|
||||
parent_hash,
|
||||
'receiptsRoot',
|
||||
receipts_root,
|
||||
'sha3Uncles',
|
||||
sha3_uncles,
|
||||
'size',
|
||||
SIZE,
|
||||
'stateRoot',
|
||||
state_root,
|
||||
'timestamp',
|
||||
block_timestamp,
|
||||
'totalDifficulty',
|
||||
total_difficulty,
|
||||
'transactionsRoot',
|
||||
transactions_root,
|
||||
'uncles',
|
||||
uncles
|
||||
) AS block_header_json,
|
||||
evm_blocks_id AS fact_blocks_id,
|
||||
inserted_timestamp,
|
||||
modified_timestamp
|
||||
ARRAY_SIZE(
|
||||
block_json :transactions
|
||||
) AS tx_count,
|
||||
utils.udf_hex_to_int(
|
||||
block_json :size :: STRING
|
||||
) :: bigint AS SIZE,
|
||||
block_json :miner :: STRING AS miner,
|
||||
block_json :mixHash :: STRING AS mix_hash,
|
||||
block_json :extraData :: STRING AS extra_data,
|
||||
block_json :parentHash :: STRING AS parent_hash,
|
||||
utils.udf_hex_to_int(
|
||||
block_json :gasUsed :: STRING
|
||||
) :: bigint AS gas_used,
|
||||
utils.udf_hex_to_int(
|
||||
block_json :gasLimit :: STRING
|
||||
) :: bigint AS gas_limit,
|
||||
utils.udf_hex_to_int(
|
||||
block_json :baseFeePerGas :: STRING
|
||||
) :: bigint AS base_fee_per_gas,
|
||||
utils.udf_hex_to_int(
|
||||
block_json :difficulty :: STRING
|
||||
) :: bigint AS difficulty,
|
||||
utils.udf_hex_to_int(
|
||||
block_json :totalDifficulty :: STRING
|
||||
) :: bigint AS total_difficulty,
|
||||
block_json :sha3Uncles :: STRING AS sha3_uncles,
|
||||
block_json :uncles AS uncle_blocks,
|
||||
utils.udf_hex_to_int(
|
||||
block_json :nonce :: STRING
|
||||
) :: bigint AS nonce,
|
||||
block_json :receiptsRoot :: STRING AS receipts_root,
|
||||
block_json :stateRoot :: STRING AS state_root,
|
||||
block_json :transactionsRoot :: STRING AS transactions_root,
|
||||
block_json :logsBloom :: STRING AS logs_bloom,
|
||||
{{ dbt_utils.generate_surrogate_key(['block_number']) }} AS fact_blocks_id,
|
||||
SYSDATE() AS inserted_timestamp,
|
||||
SYSDATE() AS modified_timestamp
|
||||
FROM
|
||||
{{ ref('silver_evm__blocks') }}
|
||||
WHERE 1=1
|
||||
|
||||
{% if is_incremental() %}
|
||||
WHERE
|
||||
modified_timestamp >= (
|
||||
SELECT
|
||||
MAX(modified_timestamp)
|
||||
FROM
|
||||
{{ this }}
|
||||
AND modified_timestamp > (
|
||||
SELECT
|
||||
COALESCE(MAX(modified_timestamp), '1970-01-01' :: TIMESTAMP) AS modified_timestamp
|
||||
FROM
|
||||
{{ this }}
|
||||
)
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
@ -1,51 +1,56 @@
|
||||
version: 2
|
||||
models:
|
||||
- name: core_evm__fact_blocks
|
||||
description: '{{ doc("flowevm_blocks_table_doc") }}'
|
||||
tests:
|
||||
- dbt_utils.recency:
|
||||
datepart: hour
|
||||
field: block_timestamp
|
||||
interval: 2
|
||||
|
||||
description: '{{ doc("evm_blocks_table_doc") }}'
|
||||
|
||||
columns:
|
||||
- name: BLOCK_NUMBER
|
||||
description: '{{ doc("flowevm_block_number") }}'
|
||||
description: '{{ doc("evm_block_number") }}'
|
||||
- name: BLOCK_HASH
|
||||
description: '{{ doc("evm_blocks_hash") }}'
|
||||
- name: BLOCK_TIMESTAMP
|
||||
description: '{{ doc("flowevm_block_timestamp") }}'
|
||||
description: '{{ doc("evm_block_timestamp") }}'
|
||||
- name: NETWORK
|
||||
description: '{{ doc("flowevm_network") }}'
|
||||
- name: BLOCKCHAIN
|
||||
description: '{{ doc("flowevm_blockchain") }}'
|
||||
description: '{{ doc("evm_network") }}'
|
||||
- name: TX_COUNT
|
||||
description: '{{ doc("flowevm_tx_count") }}'
|
||||
- name: DIFFICULTY
|
||||
description: '{{ doc("flowevm_difficulty") }}'
|
||||
- name: TOTAL_DIFFICULTY
|
||||
description: '{{ doc("flowevm_total_difficulty") }}'
|
||||
- name: EXTRA_DATA
|
||||
description: '{{ doc("flowevm_extra_data") }}'
|
||||
- name: GAS_LIMIT
|
||||
description: '{{ doc("flowevm_gas_limit") }}'
|
||||
- name: GAS_USED
|
||||
description: '{{ doc("flowevm_gas_used") }}'
|
||||
- name: HASH
|
||||
description: '{{ doc("flowevm_blocks_hash") }}'
|
||||
- name: PARENT_HASH
|
||||
description: '{{ doc("flowevm_parent_hash") }}'
|
||||
- name: RECEIPTS_ROOT
|
||||
description: '{{ doc("flowevm_receipts_root") }}'
|
||||
- name: SHA3_UNCLES
|
||||
description: '{{ doc("flowevm_sha3_uncles") }}'
|
||||
description: '{{ doc("evm_tx_count") }}'
|
||||
- name: SIZE
|
||||
description: '{{ doc("flowevm_size") }}'
|
||||
description: '{{ doc("evm_size") }}'
|
||||
- name: MINER
|
||||
description: '{{ doc("evm_miner") }}'
|
||||
- name: BASE_FEE_PER_GAS
|
||||
description: '{{ doc("evm_base_fee_per_gas") }}'
|
||||
- name: MIX_HASH
|
||||
description: '{{ doc("evm_mix_hash") }}'
|
||||
- name: EXTRA_DATA
|
||||
description: '{{ doc("evm_extra_data") }}'
|
||||
- name: PARENT_HASH
|
||||
description: '{{ doc("evm_parent_hash") }}'
|
||||
- name: GAS_USED
|
||||
description: '{{ doc("evm_gas_used") }}'
|
||||
- name: GAS_LIMIT
|
||||
description: '{{ doc("evm_gas_limit") }}'
|
||||
- name: DIFFICULTY
|
||||
description: '{{ doc("evm_difficulty") }}'
|
||||
- name: TOTAL_DIFFICULTY
|
||||
description: '{{ doc("evm_total_difficulty") }}'
|
||||
- name: SHA3_UNCLES
|
||||
description: '{{ doc("evm_sha3_uncles") }}'
|
||||
- name: UNCLE_BLOCKS
|
||||
description: '{{ doc("flowevm_uncle_blocks") }}'
|
||||
- name: BLOCK_HEADER_JSON
|
||||
description: '{{ doc("flowevm_block_header_json") }}'
|
||||
description: '{{ doc("evm_uncle_blocks") }}'
|
||||
- name: NONCE
|
||||
description: '{{ doc("evm_blocks_nonce") }}'
|
||||
- name: RECEIPTS_ROOT
|
||||
description: '{{ doc("evm_receipts_root") }}'
|
||||
- name: STATE_ROOT
|
||||
description: '{{ doc("evm_state_root") }}'
|
||||
- name: TRANSACTIONS_ROOT
|
||||
description: '{{ doc("evm_transactions_root") }}'
|
||||
- name: LOGS_BLOOM
|
||||
description: '{{ doc("evm_logs_bloom") }}'
|
||||
- name: FACT_BLOCKS_ID
|
||||
description: '{{ doc("pk_id") }}'
|
||||
description: '{{ doc("evm_pk") }}'
|
||||
- name: INSERTED_TIMESTAMP
|
||||
description: '{{ doc("inserted_timestamp") }}'
|
||||
description: '{{ doc("evm_inserted_timestamp") }}'
|
||||
- name: MODIFIED_TIMESTAMP
|
||||
description: '{{ doc("modified_timestamp") }}'
|
||||
description: '{{ doc("evm_modified_timestamp") }}'
|
||||
@ -1,40 +1,223 @@
|
||||
{{ config(
|
||||
materialized = 'incremental',
|
||||
unique_key = "fact_event_logs_id",
|
||||
incremental_strategy = 'merge',
|
||||
merge_exclude_columns = ["inserted_timestamp"],
|
||||
cluster_by = ['inserted_timestamp :: DATE', 'ROUND(block_number, -3)'],
|
||||
persist_docs ={ "relation": true,
|
||||
"columns": true },
|
||||
{{ config (
|
||||
materialized = "incremental",
|
||||
incremental_strategy = 'delete+insert',
|
||||
unique_key = "block_number",
|
||||
cluster_by = ['block_timestamp::DATE'],
|
||||
tags = ['evm']
|
||||
) }}
|
||||
|
||||
WITH base AS (
|
||||
|
||||
SELECT
|
||||
block_number,
|
||||
{% if uses_receipts_by_hash %}
|
||||
tx_hash,
|
||||
{% else %}
|
||||
receipts_json :transactionHash :: STRING AS tx_hash,
|
||||
{% endif %}
|
||||
receipts_json,
|
||||
receipts_json :logs AS full_logs
|
||||
FROM
|
||||
{{ ref('silver_evm__receipts') }}
|
||||
WHERE
|
||||
1 = 1
|
||||
AND ARRAY_SIZE(receipts_json :logs) > 0
|
||||
|
||||
{% if is_incremental() %}
|
||||
AND modified_timestamp > (
|
||||
SELECT
|
||||
COALESCE(MAX(modified_timestamp), '1970-01-01' :: TIMESTAMP) AS modified_timestamp
|
||||
FROM
|
||||
{{ this }})
|
||||
{% endif %}
|
||||
),
|
||||
flattened_logs AS (
|
||||
SELECT
|
||||
block_number,
|
||||
tx_hash,
|
||||
lower(receipts_json :from :: STRING) AS origin_from_address,
|
||||
lower(receipts_json :to :: STRING) AS origin_to_address,
|
||||
CASE
|
||||
WHEN receipts_json :status :: STRING = '0x1' THEN TRUE
|
||||
WHEN receipts_json :status :: STRING = '1' THEN TRUE
|
||||
WHEN receipts_json :status :: STRING = '0x0' THEN FALSE
|
||||
WHEN receipts_json :status :: STRING = '0' THEN FALSE
|
||||
ELSE NULL
|
||||
END AS tx_succeeded,
|
||||
VALUE :address :: STRING AS contract_address,
|
||||
VALUE :blockHash :: STRING AS block_hash,
|
||||
VALUE :blockNumber :: STRING AS block_number_hex,
|
||||
VALUE :data :: STRING AS DATA,
|
||||
utils.udf_hex_to_int(
|
||||
VALUE :logIndex :: STRING
|
||||
) :: INT AS event_index,
|
||||
VALUE :removed :: BOOLEAN AS event_removed,
|
||||
VALUE :topics AS topics,
|
||||
VALUE :transactionHash :: STRING AS transaction_hash,
|
||||
utils.udf_hex_to_int(
|
||||
VALUE :transactionIndex :: STRING
|
||||
) :: INT AS transaction_index
|
||||
FROM
|
||||
base,
|
||||
LATERAL FLATTEN (
|
||||
input => full_logs
|
||||
)
|
||||
),
|
||||
new_logs AS (
|
||||
SELECT
|
||||
l.block_number,
|
||||
b.block_timestamp,
|
||||
l.tx_hash,
|
||||
l.transaction_index AS tx_position,
|
||||
l.event_index,
|
||||
l.contract_address,
|
||||
l.topics,
|
||||
l.topics [0] :: STRING AS topic_0,
|
||||
l.topics [1] :: STRING AS topic_1,
|
||||
l.topics [2] :: STRING AS topic_2,
|
||||
l.topics [3] :: STRING AS topic_3,
|
||||
l.data,
|
||||
l.event_removed,
|
||||
txs.from_address AS origin_from_address,
|
||||
txs.to_address AS origin_to_address,
|
||||
txs.origin_function_signature,
|
||||
l.tx_succeeded
|
||||
FROM
|
||||
flattened_logs l
|
||||
LEFT JOIN {{ ref('core_evm__fact_blocks') }}
|
||||
b
|
||||
ON l.block_number = b.block_number
|
||||
|
||||
{% if is_incremental() %}
|
||||
AND b.modified_timestamp >= (
|
||||
SELECT
|
||||
MAX(modified_timestamp) :: DATE - 1
|
||||
FROM
|
||||
{{ this }}
|
||||
)
|
||||
{% endif %}
|
||||
LEFT JOIN {{ ref('core_evm__fact_transactions') }}
|
||||
txs
|
||||
ON l.tx_hash = txs.tx_hash
|
||||
AND l.block_number = txs.block_number
|
||||
|
||||
{% if is_incremental() %}
|
||||
AND txs.modified_timestamp >= (
|
||||
SELECT
|
||||
MAX(modified_timestamp) :: DATE - 1
|
||||
FROM
|
||||
{{ this }}
|
||||
)
|
||||
{% endif %}
|
||||
)
|
||||
|
||||
{% if is_incremental() %},
|
||||
missing_data AS (
|
||||
SELECT
|
||||
t.block_number,
|
||||
b.block_timestamp AS block_timestamp_heal,
|
||||
t.tx_hash,
|
||||
t.tx_position,
|
||||
t.event_index,
|
||||
t.contract_address,
|
||||
t.topics,
|
||||
t.topic_0,
|
||||
t.topic_1,
|
||||
t.topic_2,
|
||||
t.topic_3,
|
||||
t.data,
|
||||
t.event_removed,
|
||||
txs.from_address AS origin_from_address_heal,
|
||||
txs.to_address AS origin_to_address_heal,
|
||||
txs.origin_function_signature AS origin_function_signature_heal,
|
||||
t.tx_succeeded
|
||||
FROM
|
||||
{{ this }}
|
||||
t
|
||||
LEFT JOIN {{ ref('core_evm__fact_transactions') }}
|
||||
txs
|
||||
ON t.tx_hash = txs.tx_hash
|
||||
AND t.block_number = txs.block_number
|
||||
LEFT JOIN {{ ref('core_evm__fact_blocks') }}
|
||||
b
|
||||
ON t.block_number = b.block_number
|
||||
WHERE
|
||||
t.block_timestamp IS NULL
|
||||
OR t.origin_function_signature IS NULL
|
||||
)
|
||||
{% endif %},
|
||||
all_logs AS (
|
||||
SELECT
|
||||
block_number,
|
||||
block_timestamp,
|
||||
tx_hash,
|
||||
tx_position,
|
||||
event_index,
|
||||
contract_address,
|
||||
topics,
|
||||
topic_0,
|
||||
topic_1,
|
||||
topic_2,
|
||||
topic_3,
|
||||
DATA,
|
||||
event_removed,
|
||||
origin_from_address,
|
||||
origin_to_address,
|
||||
origin_function_signature,
|
||||
tx_succeeded
|
||||
FROM
|
||||
new_logs
|
||||
|
||||
{% if is_incremental() %}
|
||||
UNION ALL
|
||||
SELECT
|
||||
block_number,
|
||||
block_timestamp_heal AS block_timestamp,
|
||||
tx_hash,
|
||||
tx_position,
|
||||
event_index,
|
||||
contract_address,
|
||||
topics,
|
||||
topic_0,
|
||||
topic_1,
|
||||
topic_2,
|
||||
topic_3,
|
||||
DATA,
|
||||
event_removed,
|
||||
origin_from_address_heal AS origin_from_address,
|
||||
origin_to_address_heal AS origin_to_address,
|
||||
origin_function_signature_heal AS origin_function_signature,
|
||||
tx_succeeded
|
||||
FROM
|
||||
missing_data
|
||||
{% endif %}
|
||||
)
|
||||
SELECT
|
||||
block_number,
|
||||
block_timestamp,
|
||||
tx_hash,
|
||||
origin_function_signature,
|
||||
origin_from_address,
|
||||
origin_to_address,
|
||||
tx_position,
|
||||
event_index,
|
||||
contract_address,
|
||||
topics,
|
||||
topic_0,
|
||||
topic_1,
|
||||
topic_2,
|
||||
topic_3,
|
||||
DATA,
|
||||
event_removed,
|
||||
tx_status,
|
||||
_log_id,
|
||||
evm_logs_id AS fact_event_logs_id,
|
||||
inserted_timestamp,
|
||||
modified_timestamp
|
||||
origin_from_address,
|
||||
origin_to_address,
|
||||
origin_function_signature,
|
||||
tx_succeeded,
|
||||
{{ dbt_utils.generate_surrogate_key(['tx_hash','event_index']) }} AS fact_event_logs_id,
|
||||
SYSDATE() AS inserted_timestamp,
|
||||
SYSDATE() AS modified_timestamp
|
||||
FROM
|
||||
{{ ref('silver_evm__logs') }}
|
||||
|
||||
{% if is_incremental() %}
|
||||
WHERE
|
||||
modified_timestamp >= (
|
||||
SELECT
|
||||
MAX(modified_timestamp)
|
||||
FROM
|
||||
{{ this }}
|
||||
)
|
||||
{% endif %}
|
||||
all_logs qualify ROW_NUMBER() over (
|
||||
PARTITION BY fact_event_logs_id
|
||||
ORDER BY
|
||||
block_number DESC,
|
||||
block_timestamp DESC nulls last,
|
||||
origin_function_signature DESC nulls last
|
||||
) = 1
|
||||
@ -1,43 +1,46 @@
|
||||
version: 2
|
||||
models:
|
||||
- name: core_evm__fact_event_logs
|
||||
description: '{{ doc("flowevm_logs_table_doc") }}'
|
||||
tests:
|
||||
- dbt_utils.recency:
|
||||
datepart: hour
|
||||
field: block_timestamp
|
||||
interval: 2
|
||||
|
||||
description: '{{ doc("evm_logs_table_doc") }}'
|
||||
|
||||
columns:
|
||||
- name: BLOCK_NUMBER
|
||||
description: '{{ doc("flowevm_block_number") }}'
|
||||
description: '{{ doc("evm_block_number") }}'
|
||||
- name: BLOCK_TIMESTAMP
|
||||
description: '{{ doc("flowevm_block_timestamp") }}'
|
||||
description: '{{ doc("evm_block_timestamp") }}'
|
||||
- name: TX_HASH
|
||||
description: '{{ doc("flowevm_logs_tx_hash") }}'
|
||||
description: '{{ doc("evm_tx_hash") }}'
|
||||
- name: TX_POSITION
|
||||
description: '{{ doc("evm_tx_position") }}'
|
||||
- name: EVENT_INDEX
|
||||
description: '{{ doc("flowevm_event_index") }}'
|
||||
description: '{{ doc("evm_event_index") }}'
|
||||
- name: CONTRACT_ADDRESS
|
||||
description: '{{ doc("flowevm_logs_contract_address") }}'
|
||||
description: '{{ doc("evm_logs_contract_address") }}'
|
||||
- name: TOPICS
|
||||
description: '{{ doc("flowevm_topics") }}'
|
||||
description: '{{ doc("evm_topics") }}'
|
||||
- name: TOPIC_0
|
||||
description: '{{ doc("evm_topic_0") }}'
|
||||
- name: TOPIC_1
|
||||
description: '{{ doc("evm_topic_1") }}'
|
||||
- name: TOPIC_2
|
||||
description: '{{ doc("evm_topic_2") }}'
|
||||
- name: TOPIC_3
|
||||
description: '{{ doc("evm_topic_3") }}'
|
||||
- name: DATA
|
||||
description: '{{ doc("flowevm_logs_data") }}'
|
||||
description: '{{ doc("evm_logs_data") }}'
|
||||
- name: EVENT_REMOVED
|
||||
description: '{{ doc("flowevm_event_removed") }}'
|
||||
- name: _LOG_ID
|
||||
description: '{{ doc("internal_column") }}'
|
||||
- name: TX_STATUS
|
||||
description: '{{ doc("flowevm_tx_status") }}'
|
||||
- name: ORIGIN_FUNCTION_SIGNATURE
|
||||
description: '{{ doc("flowevm_origin_sig") }}'
|
||||
description: '{{ doc("evm_event_removed") }}'
|
||||
- name: ORIGIN_FROM_ADDRESS
|
||||
description: '{{ doc("flowevm_origin_from") }}'
|
||||
description: '{{ doc("evm_from_address") }}'
|
||||
- name: ORIGIN_TO_ADDRESS
|
||||
description: '{{ doc("flowevm_origin_to") }}'
|
||||
description: '{{ doc("evm_to_address") }}'
|
||||
- name: ORIGIN_FUNCTION_SIGNATURE
|
||||
description: '{{ doc("evm_origin_sig") }}'
|
||||
- name: TX_SUCCEEDED
|
||||
description: '{{ doc("evm_tx_succeeded") }}'
|
||||
- name: FACT_EVENT_LOGS_ID
|
||||
description: '{{ doc("pk_id") }}'
|
||||
description: '{{ doc("evm_pk") }}'
|
||||
- name: INSERTED_TIMESTAMP
|
||||
description: '{{ doc("inserted_timestamp") }}'
|
||||
description: '{{ doc("evm_inserted_timestamp") }}'
|
||||
- name: MODIFIED_TIMESTAMP
|
||||
description: '{{ doc("modified_timestamp") }}'
|
||||
description: '{{ doc("evm_modified_timestamp") }}'
|
||||
379
models/evm/gold/core/core_evm__fact_traces.sql
Normal file
379
models/evm/gold/core/core_evm__fact_traces.sql
Normal file
@ -0,0 +1,379 @@
|
||||
{{ config(
|
||||
materialized = "incremental",
|
||||
incremental_strategy = 'delete+insert',
|
||||
unique_key = "block_number",
|
||||
cluster_by = ['block_timestamp::DATE'],
|
||||
tags = ['evm']
|
||||
) }}
|
||||
|
||||
WITH silver_traces AS (
|
||||
SELECT
|
||||
block_number,
|
||||
tx_position,
|
||||
trace_address,
|
||||
parent_trace_address,
|
||||
trace_address_array,
|
||||
trace_json,
|
||||
traces_id,
|
||||
'regular' AS source
|
||||
FROM {{ ref('silver_evm__traces') }}
|
||||
WHERE 1 = 1
|
||||
{% if is_incremental() %}
|
||||
AND modified_timestamp > (
|
||||
SELECT COALESCE(MAX(modified_timestamp), '1970-01-01'::TIMESTAMP) AS modified_timestamp
|
||||
FROM {{ this }}
|
||||
)
|
||||
{% endif %}
|
||||
),
|
||||
|
||||
sub_traces AS (
|
||||
SELECT
|
||||
block_number,
|
||||
tx_position,
|
||||
parent_trace_address,
|
||||
COUNT(*) AS sub_traces
|
||||
FROM silver_traces
|
||||
GROUP BY
|
||||
block_number,
|
||||
tx_position,
|
||||
parent_trace_address
|
||||
),
|
||||
|
||||
trace_index_array AS (
|
||||
SELECT
|
||||
block_number,
|
||||
tx_position,
|
||||
trace_address,
|
||||
ARRAY_AGG(flat_value) AS number_array
|
||||
FROM (
|
||||
SELECT
|
||||
block_number,
|
||||
tx_position,
|
||||
trace_address,
|
||||
IFF(VALUE::STRING = 'ORIGIN', -1, VALUE::INT) AS flat_value
|
||||
FROM silver_traces,
|
||||
LATERAL FLATTEN(input => trace_address_array)
|
||||
)
|
||||
GROUP BY
|
||||
block_number,
|
||||
tx_position,
|
||||
trace_address
|
||||
),
|
||||
|
||||
trace_index_sub_traces AS (
|
||||
SELECT
|
||||
b.block_number,
|
||||
b.tx_position,
|
||||
b.trace_address,
|
||||
IFNULL(sub_traces, 0) AS sub_traces,
|
||||
number_array,
|
||||
ROW_NUMBER() OVER (
|
||||
PARTITION BY b.block_number, b.tx_position
|
||||
ORDER BY number_array ASC
|
||||
) - 1 AS trace_index,
|
||||
b.trace_json,
|
||||
b.traces_id,
|
||||
b.source
|
||||
FROM silver_traces b
|
||||
LEFT JOIN sub_traces s
|
||||
ON b.block_number = s.block_number
|
||||
AND b.tx_position = s.tx_position
|
||||
AND b.trace_address = s.parent_trace_address
|
||||
JOIN trace_index_array n
|
||||
ON b.block_number = n.block_number
|
||||
AND b.tx_position = n.tx_position
|
||||
AND b.trace_address = n.trace_address
|
||||
),
|
||||
|
||||
errored_traces AS (
|
||||
SELECT
|
||||
block_number,
|
||||
tx_position,
|
||||
trace_address,
|
||||
trace_json
|
||||
FROM trace_index_sub_traces
|
||||
WHERE trace_json:error::STRING IS NOT NULL
|
||||
),
|
||||
|
||||
error_logic AS (
|
||||
SELECT
|
||||
b0.block_number,
|
||||
b0.tx_position,
|
||||
b0.trace_address,
|
||||
b0.trace_json:error::STRING AS error,
|
||||
b1.trace_json:error::STRING AS any_error,
|
||||
b2.trace_json:error::STRING AS origin_error
|
||||
FROM trace_index_sub_traces b0
|
||||
LEFT JOIN errored_traces b1
|
||||
ON b0.block_number = b1.block_number
|
||||
AND b0.tx_position = b1.tx_position
|
||||
AND b0.trace_address RLIKE CONCAT('^', b1.trace_address, '(_[0-9]+)*$')
|
||||
LEFT JOIN errored_traces b2
|
||||
ON b0.block_number = b2.block_number
|
||||
AND b0.tx_position = b2.tx_position
|
||||
AND b2.trace_address = 'ORIGIN'
|
||||
),
|
||||
|
||||
aggregated_errors AS (
|
||||
SELECT
|
||||
block_number,
|
||||
tx_position,
|
||||
trace_address,
|
||||
error,
|
||||
IFF(
|
||||
MAX(any_error) IS NULL AND error IS NULL AND origin_error IS NULL,
|
||||
TRUE,
|
||||
FALSE
|
||||
) AS trace_succeeded
|
||||
FROM error_logic
|
||||
GROUP BY
|
||||
block_number,
|
||||
tx_position,
|
||||
trace_address,
|
||||
error,
|
||||
origin_error
|
||||
),
|
||||
|
||||
json_traces AS (
|
||||
SELECT
|
||||
block_number,
|
||||
tx_position,
|
||||
trace_address,
|
||||
sub_traces,
|
||||
number_array,
|
||||
trace_index,
|
||||
trace_succeeded,
|
||||
trace_json:error::STRING AS error_reason,
|
||||
trace_json:revertReason::STRING AS revert_reason,
|
||||
lower(trace_json:from::STRING) AS from_address,
|
||||
lower(trace_json:to::STRING) AS to_address,
|
||||
IFNULL(trace_json:value::STRING, '0x0') AS value_hex,
|
||||
IFNULL(utils.udf_hex_to_int(trace_json:value::STRING), '0') AS value_precise_raw,
|
||||
utils.udf_decimal_adjust(value_precise_raw, 18) AS value_precise,
|
||||
value_precise::FLOAT AS value,
|
||||
utils.udf_hex_to_int(trace_json:gas::STRING)::INT AS gas,
|
||||
utils.udf_hex_to_int(trace_json:gasUsed::STRING)::INT AS gas_used,
|
||||
trace_json:input::STRING AS input,
|
||||
trace_json:output::STRING AS output,
|
||||
trace_json:type::STRING AS type,
|
||||
traces_id
|
||||
FROM trace_index_sub_traces
|
||||
JOIN aggregated_errors USING (
|
||||
block_number,
|
||||
tx_position,
|
||||
trace_address
|
||||
)
|
||||
),
|
||||
|
||||
incremental_traces AS (
|
||||
SELECT
|
||||
f.block_number,
|
||||
t.tx_hash,
|
||||
t.block_timestamp,
|
||||
t.origin_function_signature,
|
||||
t.from_address AS origin_from_address,
|
||||
t.to_address AS origin_to_address,
|
||||
t.tx_position,
|
||||
f.trace_index,
|
||||
f.from_address AS from_address,
|
||||
f.to_address AS to_address,
|
||||
f.value_hex,
|
||||
f.value_precise_raw,
|
||||
f.value_precise,
|
||||
f.value,
|
||||
f.gas,
|
||||
f.gas_used,
|
||||
f.input,
|
||||
f.output,
|
||||
f.type,
|
||||
f.sub_traces,
|
||||
f.error_reason,
|
||||
f.revert_reason,
|
||||
f.traces_id,
|
||||
f.trace_succeeded,
|
||||
f.trace_address,
|
||||
t.tx_succeeded
|
||||
FROM json_traces f
|
||||
LEFT OUTER JOIN {{ ref('core_evm__fact_transactions') }} t
|
||||
ON f.tx_position = t.tx_position
|
||||
AND f.block_number = t.block_number
|
||||
{% if is_incremental() %}
|
||||
AND t.modified_timestamp >= (
|
||||
SELECT DATEADD('hour', -24, MAX(modified_timestamp))
|
||||
FROM {{ this }}
|
||||
)
|
||||
{% endif %}
|
||||
)
|
||||
{% if is_incremental() %},
|
||||
overflow_blocks AS (
|
||||
SELECT DISTINCT block_number
|
||||
FROM silver_traces
|
||||
WHERE source = 'overflow'
|
||||
),
|
||||
|
||||
heal_missing_data AS (
|
||||
SELECT
|
||||
t.block_number,
|
||||
txs.tx_hash,
|
||||
txs.block_timestamp AS block_timestamp_heal,
|
||||
txs.origin_function_signature AS origin_function_signature_heal,
|
||||
txs.from_address AS origin_from_address_heal,
|
||||
txs.to_address AS origin_to_address_heal,
|
||||
txs.tx_position,
|
||||
t.trace_index,
|
||||
t.from_address,
|
||||
t.to_address,
|
||||
t.value_hex,
|
||||
t.value_precise_raw,
|
||||
t.value_precise,
|
||||
t.value,
|
||||
t.gas,
|
||||
t.gas_used,
|
||||
t.input,
|
||||
t.output,
|
||||
t.type,
|
||||
t.sub_traces,
|
||||
t.error_reason,
|
||||
t.revert_reason,
|
||||
t.fact_traces_id AS traces_id,
|
||||
t.trace_succeeded,
|
||||
t.trace_address,
|
||||
txs.tx_succeeded AS tx_succeeded_heal
|
||||
FROM {{ this }} t
|
||||
JOIN {{ ref('core_evm__fact_transactions') }} txs
|
||||
ON t.tx_position = txs.tx_position
|
||||
AND t.block_number = txs.block_number
|
||||
WHERE t.tx_position IS NULL
|
||||
OR t.block_timestamp IS NULL
|
||||
OR t.tx_succeeded IS NULL
|
||||
|
||||
)
|
||||
{% endif %},
|
||||
all_traces AS (
|
||||
SELECT
|
||||
block_number,
|
||||
tx_hash,
|
||||
block_timestamp,
|
||||
origin_function_signature,
|
||||
origin_from_address,
|
||||
origin_to_address,
|
||||
tx_position,
|
||||
trace_index,
|
||||
from_address,
|
||||
to_address,
|
||||
value_hex,
|
||||
value_precise_raw,
|
||||
value_precise,
|
||||
value,
|
||||
gas,
|
||||
gas_used,
|
||||
input,
|
||||
output,
|
||||
type,
|
||||
sub_traces,
|
||||
error_reason,
|
||||
revert_reason,
|
||||
trace_succeeded,
|
||||
trace_address,
|
||||
tx_succeeded
|
||||
FROM incremental_traces
|
||||
|
||||
{% if is_incremental() %}
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT
|
||||
block_number,
|
||||
tx_hash,
|
||||
block_timestamp_heal AS block_timestamp,
|
||||
origin_function_signature_heal AS origin_function_signature,
|
||||
origin_from_address_heal AS origin_from_address,
|
||||
origin_to_address_heal AS origin_to_address,
|
||||
tx_position,
|
||||
trace_index,
|
||||
from_address,
|
||||
to_address,
|
||||
value_hex,
|
||||
value_precise_raw,
|
||||
value_precise,
|
||||
value,
|
||||
gas,
|
||||
gas_used,
|
||||
input,
|
||||
output,
|
||||
type,
|
||||
sub_traces,
|
||||
error_reason,
|
||||
revert_reason,
|
||||
trace_succeeded,
|
||||
trace_address,
|
||||
tx_succeeded_heal AS tx_succeeded
|
||||
FROM heal_missing_data
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT
|
||||
block_number,
|
||||
tx_hash,
|
||||
block_timestamp,
|
||||
origin_function_signature,
|
||||
origin_from_address,
|
||||
origin_to_address,
|
||||
tx_position,
|
||||
trace_index,
|
||||
from_address,
|
||||
to_address,
|
||||
value_hex,
|
||||
value_precise_raw,
|
||||
value_precise,
|
||||
value,
|
||||
gas,
|
||||
gas_used,
|
||||
input,
|
||||
output,
|
||||
type,
|
||||
sub_traces,
|
||||
error_reason,
|
||||
revert_reason,
|
||||
trace_succeeded,
|
||||
trace_address,
|
||||
tx_succeeded
|
||||
FROM {{ this }}
|
||||
JOIN overflow_blocks USING (block_number)
|
||||
{% endif %}
|
||||
)
|
||||
|
||||
SELECT
|
||||
block_number,
|
||||
block_timestamp,
|
||||
tx_hash,
|
||||
tx_position,
|
||||
trace_index,
|
||||
from_address,
|
||||
to_address,
|
||||
input,
|
||||
output,
|
||||
type,
|
||||
trace_address,
|
||||
sub_traces,
|
||||
value,
|
||||
value_precise_raw,
|
||||
value_precise,
|
||||
value_hex,
|
||||
gas,
|
||||
gas_used,
|
||||
origin_from_address,
|
||||
origin_to_address,
|
||||
origin_function_signature,
|
||||
trace_succeeded,
|
||||
error_reason,
|
||||
revert_reason,
|
||||
tx_succeeded,
|
||||
{{ dbt_utils.generate_surrogate_key(['tx_hash', 'trace_index']) }} AS fact_traces_id,
|
||||
SYSDATE() AS inserted_timestamp,
|
||||
SYSDATE() AS modified_timestamp
|
||||
FROM all_traces
|
||||
QUALIFY (ROW_NUMBER() OVER (
|
||||
PARTITION BY block_number, tx_position, trace_index
|
||||
ORDER BY modified_timestamp DESC, block_timestamp DESC NULLS LAST
|
||||
)) = 1
|
||||
62
models/evm/gold/core/core_evm__fact_traces.yml
Normal file
62
models/evm/gold/core/core_evm__fact_traces.yml
Normal file
@ -0,0 +1,62 @@
|
||||
version: 2
|
||||
models:
|
||||
- name: core_evm__fact_traces
|
||||
description: '{{ doc("evm_traces_table_doc") }}'
|
||||
|
||||
columns:
|
||||
- name: BLOCK_NUMBER
|
||||
description: '{{ doc("evm_block_number") }}'
|
||||
- name: BLOCK_TIMESTAMP
|
||||
description: '{{ doc("evm_block_timestamp") }}'
|
||||
- name: TX_HASH
|
||||
description: '{{ doc("evm_tx_hash") }}'
|
||||
- name: TX_POSITION
|
||||
description: '{{ doc("evm_tx_position") }}'
|
||||
- name: TRACE_INDEX
|
||||
description: '{{ doc("evm_trace_index") }}'
|
||||
- name: FROM_ADDRESS
|
||||
description: '{{ doc("evm_from_address") }}'
|
||||
- name: TO_ADDRESS
|
||||
description: '{{ doc("evm_to_address") }}'
|
||||
- name: INPUT
|
||||
description: '{{ doc("evm_traces_input") }}'
|
||||
- name: OUTPUT
|
||||
description: '{{ doc("evm_traces_output") }}'
|
||||
- name: TYPE
|
||||
description: '{{ doc("evm_traces_type") }}'
|
||||
- name: TRACE_ADDRESS
|
||||
description: '{{ doc("evm_trace_address") }}'
|
||||
- name: SUB_TRACES
|
||||
description: '{{ doc("evm_sub_traces") }}'
|
||||
- name: VALUE
|
||||
description: '{{ doc("evm_value") }}'
|
||||
- name: VALUE_PRECISE_RAW
|
||||
description: '{{ doc("evm_precise_amount_unadjusted") }}'
|
||||
- name: VALUE_PRECISE
|
||||
description: '{{ doc("evm_precise_amount_adjusted") }}'
|
||||
- name: VALUE_HEX
|
||||
description: '{{ doc("evm_value_hex") }}'
|
||||
- name: GAS
|
||||
description: '{{ doc("evm_traces_gas") }}'
|
||||
- name: GAS_USED
|
||||
description: '{{ doc("evm_traces_gas_used") }}'
|
||||
- name: ORIGIN_FROM_ADDRESS
|
||||
description: '{{ doc("evm_traces_from") }}'
|
||||
- name: ORIGIN_TO_ADDRESS
|
||||
description: '{{ doc("evm_traces_to") }}'
|
||||
- name: ORIGIN_FUNCTION_SIGNATURE
|
||||
description: '{{ doc("evm_origin_sig") }}'
|
||||
- name: TRACE_SUCCEEDED
|
||||
description: '{{ doc("evm_trace_succeeded") }}'
|
||||
- name: ERROR_REASON
|
||||
description: '{{ doc("evm_trace_error_reason") }}'
|
||||
- name: REVERT_REASON
|
||||
description: '{{ doc("evm_revert_reason") }}'
|
||||
- name: TX_SUCCEEDED
|
||||
description: '{{ doc("evm_tx_succeeded") }}'
|
||||
- name: FACT_TRACES_ID
|
||||
description: '{{ doc("evm_pk") }}'
|
||||
- name: INSERTED_TIMESTAMP
|
||||
description: '{{ doc("evm_inserted_timestamp") }}'
|
||||
- name: MODIFIED_TIMESTAMP
|
||||
description: '{{ doc("evm_modified_timestamp") }}'
|
||||
@ -1,50 +1,348 @@
|
||||
{{ config(
|
||||
materialized = 'incremental',
|
||||
unique_key = "fact_transactions_id",
|
||||
{{ config (
|
||||
materialized = "incremental",
|
||||
incremental_strategy = 'delete+insert',
|
||||
cluster_by = ['inserted_timestamp :: DATE', 'ROUND(block_number, -3)'],
|
||||
persist_docs ={ "relation": true,
|
||||
"columns": true },
|
||||
unique_key = "block_number",
|
||||
cluster_by = ['block_timestamp::DATE'],
|
||||
tags = ['evm']
|
||||
) }}
|
||||
SELECT
|
||||
block_number,
|
||||
block_timestamp,
|
||||
block_hash,
|
||||
tx_hash,
|
||||
nonce,
|
||||
POSITION,
|
||||
origin_function_signature,
|
||||
from_address,
|
||||
to_address,
|
||||
VALUE,
|
||||
value_precise_unadj AS value_precise_raw,
|
||||
value_precise_adj AS value_precise,
|
||||
tx_fee,
|
||||
tx_fee_precise,
|
||||
gas_price_adj AS gas_price,
|
||||
effective_gas_price,
|
||||
gas AS gas_limit,
|
||||
gas_used,
|
||||
cumulative_gas_used,
|
||||
input_data,
|
||||
tx_status AS status,
|
||||
tx_succeeded,
|
||||
r,
|
||||
s,
|
||||
v,
|
||||
evm_txs_id AS fact_transactions_id,
|
||||
inserted_timestamp,
|
||||
modified_timestamp
|
||||
FROM
|
||||
{{ ref('silver_evm__transactions') }}
|
||||
|
||||
WITH base AS (
|
||||
|
||||
SELECT
|
||||
block_number,
|
||||
tx_position,
|
||||
transaction_json
|
||||
FROM
|
||||
{{ ref('silver_evm__transactions') }}
|
||||
|
||||
{% if is_incremental() %}
|
||||
WHERE
|
||||
modified_timestamp >= (
|
||||
modified_timestamp > (
|
||||
SELECT
|
||||
MAX(modified_timestamp)
|
||||
COALESCE(MAX(modified_timestamp), '1970-01-01' :: TIMESTAMP) AS modified_timestamp
|
||||
FROM
|
||||
{{ this }}
|
||||
)
|
||||
{{ this }})
|
||||
{% endif %}
|
||||
),
|
||||
transactions_fields AS (
|
||||
SELECT
|
||||
block_number,
|
||||
tx_position,
|
||||
transaction_json :blockHash :: STRING AS block_hash,
|
||||
transaction_json :blockNumber :: STRING AS block_number_hex,
|
||||
lower(transaction_json :from :: STRING) AS from_address,
|
||||
utils.udf_hex_to_int(
|
||||
transaction_json :gas :: STRING
|
||||
) :: bigint AS gas_limit,
|
||||
utils.udf_hex_to_int(
|
||||
transaction_json :gasPrice :: STRING
|
||||
) :: bigint AS gas_price,
|
||||
transaction_json :hash :: STRING AS tx_hash,
|
||||
transaction_json :input :: STRING AS input_data,
|
||||
LEFT(
|
||||
input_data,
|
||||
10
|
||||
) AS origin_function_signature,
|
||||
utils.udf_hex_to_int(
|
||||
transaction_json :nonce :: STRING
|
||||
) :: bigint AS nonce,
|
||||
transaction_json :r :: STRING AS r,
|
||||
transaction_json :s :: STRING AS s,
|
||||
lower(transaction_json :to :: STRING) AS to_address1,
|
||||
CASE
|
||||
WHEN to_address1 = '' THEN NULL
|
||||
ELSE to_address1
|
||||
END AS to_address,
|
||||
utils.udf_hex_to_int(
|
||||
transaction_json :transactionIndex :: STRING
|
||||
) :: bigint AS transaction_index,
|
||||
utils.udf_hex_to_int(
|
||||
transaction_json :type :: STRING
|
||||
) :: bigint AS tx_type,
|
||||
utils.udf_hex_to_int(
|
||||
transaction_json :v :: STRING
|
||||
) :: bigint AS v,
|
||||
TRY_TO_NUMBER(
|
||||
utils.udf_hex_to_int(
|
||||
transaction_json :maxFeePerGas :: STRING
|
||||
)
|
||||
) / pow(
|
||||
10,
|
||||
9
|
||||
) AS max_fee_per_gas,
|
||||
TRY_TO_NUMBER(
|
||||
utils.udf_hex_to_int(
|
||||
transaction_json :maxPriorityFeePerGas :: STRING
|
||||
)
|
||||
) / pow(
|
||||
10,
|
||||
9
|
||||
) AS max_priority_fee_per_gas,
|
||||
utils.udf_hex_to_int(
|
||||
transaction_json :value :: STRING
|
||||
) AS value_precise_raw,
|
||||
utils.udf_decimal_adjust(
|
||||
value_precise_raw,
|
||||
18
|
||||
) AS value_precise,
|
||||
value_precise :: FLOAT AS VALUE,
|
||||
utils.udf_hex_to_int(transaction_json :yParity :: STRING):: bigint AS y_parity,
|
||||
transaction_json :accessList AS access_list,
|
||||
FROM
|
||||
base
|
||||
),
|
||||
new_transactions AS (
|
||||
SELECT
|
||||
txs.block_number,
|
||||
txs.block_hash,
|
||||
b.block_timestamp,
|
||||
txs.tx_hash,
|
||||
txs.from_address,
|
||||
txs.to_address,
|
||||
txs.origin_function_signature,
|
||||
txs.value,
|
||||
txs.value_precise_raw,
|
||||
txs.value_precise,
|
||||
txs.max_fee_per_gas,
|
||||
txs.max_priority_fee_per_gas,
|
||||
txs.y_parity,
|
||||
txs.access_list,
|
||||
utils.udf_decimal_adjust(
|
||||
txs.gas_price * utils.udf_hex_to_int(
|
||||
r.receipts_json :gasUsed :: STRING
|
||||
) :: bigint,
|
||||
18
|
||||
) AS tx_fee_precise,
|
||||
COALESCE(
|
||||
tx_fee_precise :: FLOAT,
|
||||
0
|
||||
) AS tx_fee,
|
||||
CASE
|
||||
WHEN r.receipts_json :status :: STRING = '0x1' THEN TRUE
|
||||
WHEN r.receipts_json :status :: STRING = '1' THEN TRUE
|
||||
WHEN r.receipts_json :status :: STRING = '0x0' THEN FALSE
|
||||
WHEN r.receipts_json :status :: STRING = '0' THEN FALSE
|
||||
ELSE NULL
|
||||
END AS tx_succeeded,
|
||||
txs.tx_type,
|
||||
txs.nonce,
|
||||
txs.tx_position,
|
||||
txs.input_data,
|
||||
txs.gas_price / pow(
|
||||
10,
|
||||
9
|
||||
) AS gas_price,
|
||||
utils.udf_hex_to_int(
|
||||
r.receipts_json :gasUsed :: STRING
|
||||
) :: bigint AS gas_used,
|
||||
txs.gas_limit,
|
||||
utils.udf_hex_to_int(
|
||||
r.receipts_json :cumulativeGasUsed :: STRING
|
||||
) :: bigint AS cumulative_gas_used,
|
||||
utils.udf_hex_to_int(
|
||||
r.receipts_json :effectiveGasPrice :: STRING
|
||||
) :: bigint AS effective_gas_price,
|
||||
txs.r,
|
||||
txs.s,
|
||||
txs.v
|
||||
FROM
|
||||
transactions_fields txs
|
||||
LEFT JOIN {{ ref('core_evm__fact_blocks') }}
|
||||
b
|
||||
ON txs.block_number = b.block_number
|
||||
|
||||
{% if is_incremental() %}
|
||||
AND b.modified_timestamp >= (
|
||||
SELECT
|
||||
MAX(modified_timestamp) :: DATE - 1
|
||||
FROM
|
||||
{{ this }}
|
||||
)
|
||||
{% endif %}
|
||||
LEFT JOIN {{ ref('silver_evm__receipts') }}
|
||||
r
|
||||
ON txs.block_number = r.block_number
|
||||
AND txs.tx_hash = r.receipts_json :transactionHash :: STRING
|
||||
|
||||
{% if is_incremental() %}
|
||||
AND r.modified_timestamp >= (
|
||||
SELECT
|
||||
MAX(modified_timestamp) :: DATE - 1
|
||||
FROM
|
||||
{{ this }}
|
||||
)
|
||||
{% endif %}
|
||||
)
|
||||
|
||||
{% if is_incremental() %},
|
||||
missing_data AS (
|
||||
SELECT
|
||||
t.block_number,
|
||||
b.block_timestamp AS block_timestamp_heal,
|
||||
t.tx_hash,
|
||||
t.from_address,
|
||||
t.to_address,
|
||||
t.origin_function_signature,
|
||||
t.value,
|
||||
t.value_precise_raw,
|
||||
t.value_precise,
|
||||
t.max_fee_per_gas,
|
||||
t.max_priority_fee_per_gas,
|
||||
t.y_parity,
|
||||
t.access_list,
|
||||
utils.udf_decimal_adjust(
|
||||
t.gas_price * utils.udf_hex_to_int(
|
||||
r.receipts_json :gasUsed :: STRING
|
||||
) :: bigint,
|
||||
9
|
||||
) AS tx_fee_precise_heal,
|
||||
COALESCE(
|
||||
tx_fee_precise_heal :: FLOAT,
|
||||
0
|
||||
) AS tx_fee_heal,
|
||||
CASE
|
||||
WHEN r.receipts_json :status :: STRING = '0x1' THEN TRUE
|
||||
WHEN r.receipts_json :status :: STRING = '0x0' THEN FALSE
|
||||
ELSE NULL
|
||||
END AS tx_succeeded_heal,
|
||||
t.tx_type,
|
||||
t.nonce,
|
||||
t.tx_position,
|
||||
t.input_data,
|
||||
t.gas_price,
|
||||
utils.udf_hex_to_int(
|
||||
r.receipts_json :gasUsed :: STRING
|
||||
) :: bigint AS gas_used_heal,
|
||||
t.gas_limit,
|
||||
utils.udf_hex_to_int(
|
||||
r.receipts_json :cumulativeGasUsed :: STRING
|
||||
) :: bigint AS cumulative_gas_used_heal,
|
||||
utils.udf_hex_to_int(
|
||||
r.receipts_json :effectiveGasPrice :: STRING
|
||||
) :: bigint AS effective_gas_price_heal,
|
||||
t.r,
|
||||
t.s,
|
||||
t.v
|
||||
FROM
|
||||
{{ this }}
|
||||
t
|
||||
LEFT JOIN {{ ref('core_evm__fact_blocks') }}
|
||||
b
|
||||
ON t.block_number = b.block_number
|
||||
LEFT JOIN {{ ref('silver_evm__receipts') }}
|
||||
r
|
||||
ON t.block_number = r.block_number
|
||||
AND t.tx_hash = r.receipts_json :transactionHash :: STRING
|
||||
WHERE
|
||||
t.block_timestamp IS NULL
|
||||
OR t.tx_succeeded IS NULL
|
||||
)
|
||||
{% endif %},
|
||||
all_transactions AS (
|
||||
SELECT
|
||||
block_number,
|
||||
block_timestamp,
|
||||
tx_hash,
|
||||
from_address,
|
||||
to_address,
|
||||
origin_function_signature,
|
||||
VALUE,
|
||||
value_precise_raw,
|
||||
value_precise,
|
||||
max_fee_per_gas,
|
||||
max_priority_fee_per_gas,
|
||||
y_parity,
|
||||
access_list,
|
||||
tx_fee,
|
||||
tx_fee_precise,
|
||||
tx_succeeded,
|
||||
tx_type,
|
||||
nonce,
|
||||
tx_position,
|
||||
input_data,
|
||||
gas_price,
|
||||
gas_used,
|
||||
gas_limit,
|
||||
cumulative_gas_used,
|
||||
effective_gas_price,
|
||||
r,
|
||||
s,
|
||||
v
|
||||
FROM
|
||||
new_transactions
|
||||
|
||||
{% if is_incremental() %}
|
||||
UNION ALL
|
||||
SELECT
|
||||
block_number,
|
||||
block_timestamp_heal AS block_timestamp,
|
||||
tx_hash,
|
||||
from_address,
|
||||
to_address,
|
||||
origin_function_signature,
|
||||
VALUE,
|
||||
value_precise_raw,
|
||||
value_precise,
|
||||
max_fee_per_gas,
|
||||
max_priority_fee_per_gas,
|
||||
y_parity,
|
||||
access_list,
|
||||
tx_fee_heal AS tx_fee,
|
||||
tx_fee_precise_heal AS tx_fee_precise,
|
||||
tx_succeeded_heal AS tx_succeeded,
|
||||
tx_type,
|
||||
nonce,
|
||||
tx_position,
|
||||
input_data,
|
||||
gas_price,
|
||||
gas_used_heal AS gas_used,
|
||||
gas_limit,
|
||||
cumulative_gas_used_heal AS cumulative_gas_used,
|
||||
effective_gas_price_heal AS effective_gas_price,
|
||||
r,
|
||||
s,
|
||||
v
|
||||
FROM
|
||||
missing_data
|
||||
{% endif %}
|
||||
)
|
||||
SELECT
|
||||
block_number,
|
||||
block_timestamp,
|
||||
tx_hash,
|
||||
from_address,
|
||||
to_address,
|
||||
origin_function_signature,
|
||||
VALUE,
|
||||
value_precise_raw,
|
||||
value_precise,
|
||||
tx_fee,
|
||||
tx_fee_precise,
|
||||
tx_succeeded,
|
||||
tx_type,
|
||||
nonce,
|
||||
tx_position,
|
||||
input_data,
|
||||
gas_price,
|
||||
gas_used,
|
||||
gas_limit,
|
||||
cumulative_gas_used,
|
||||
effective_gas_price,
|
||||
max_fee_per_gas,
|
||||
max_priority_fee_per_gas,
|
||||
y_parity,
|
||||
access_list,
|
||||
r,
|
||||
s,
|
||||
v,
|
||||
{{ dbt_utils.generate_surrogate_key(['tx_hash']) }} AS fact_transactions_id,
|
||||
SYSDATE() AS inserted_timestamp,
|
||||
SYSDATE() AS modified_timestamp
|
||||
FROM
|
||||
all_transactions qualify ROW_NUMBER() over (
|
||||
PARTITION BY fact_transactions_id
|
||||
ORDER BY
|
||||
block_number DESC,
|
||||
block_timestamp DESC nulls last,
|
||||
tx_succeeded DESC nulls last
|
||||
) = 1
|
||||
@ -1,67 +1,68 @@
|
||||
version: 2
|
||||
models:
|
||||
- name: core_evm__fact_transactions
|
||||
description: '{{ doc("flowevm_tx_table_doc") }}'
|
||||
tests:
|
||||
- dbt_utils.recency:
|
||||
datepart: hour
|
||||
field: block_timestamp
|
||||
interval: 2
|
||||
|
||||
description: '{{ doc("evm_tx_table_doc") }}'
|
||||
|
||||
columns:
|
||||
- name: BLOCK_NUMBER
|
||||
description: '{{ doc("flowevm_block_number") }}'
|
||||
description: '{{ doc("evm_block_number") }}'
|
||||
- name: BLOCK_TIMESTAMP
|
||||
description: '{{ doc("flowevm_block_timestamp") }}'
|
||||
- name: BLOCK_HASH
|
||||
description: '{{ doc("flowevm_block_hash") }}'
|
||||
description: '{{ doc("evm_block_timestamp") }}'
|
||||
- name: TX_HASH
|
||||
description: '{{ doc("flowevm_tx_hash") }}'
|
||||
- name: NONCE
|
||||
description: '{{ doc("flowevm_tx_nonce") }}'
|
||||
- name: POSITION
|
||||
description: '{{ doc("flowevm_tx_position") }}'
|
||||
description: '{{ doc("evm_tx_hash") }}'
|
||||
- name: FROM_ADDRESS
|
||||
description: '{{ doc("flowevm_from_address") }}'
|
||||
description: '{{ doc("evm_from_address") }}'
|
||||
- name: TO_ADDRESS
|
||||
description: '{{ doc("flowevm_to_address") }}'
|
||||
description: '{{ doc("evm_to_address") }}'
|
||||
- name: ORIGIN_FUNCTION_SIGNATURE
|
||||
description: '{{ doc("evm_tx_origin_sig") }}'
|
||||
- name: VALUE
|
||||
description: '{{ doc("flowevm_value") }}'
|
||||
description: '{{ doc("evm_value") }}'
|
||||
- name: VALUE_PRECISE_RAW
|
||||
description: '{{ doc("precise_amount_unadjusted") }}'
|
||||
description: '{{ doc("evm_precise_amount_unadjusted") }}'
|
||||
- name: VALUE_PRECISE
|
||||
description: '{{ doc("precise_amount_adjusted") }}'
|
||||
description: '{{ doc("evm_precise_amount_adjusted") }}'
|
||||
- name: TX_FEE
|
||||
description: '{{ doc("flowevm_tx_fee") }}'
|
||||
description: '{{ doc("evm_tx_fee") }}'
|
||||
- name: TX_FEE_PRECISE
|
||||
description: '{{ doc("tx_fee_precise") }}'
|
||||
- name: GAS_PRICE
|
||||
description: '{{ doc("flowevm_tx_gas_price") }}'
|
||||
- name: EFFECTIVE_GAS_PRICE
|
||||
description: The total base charge plus tip paid for each unit of gas, in Gwei.
|
||||
- name: GAS_LIMIT
|
||||
description: '{{ doc("flowevm_tx_gas_limit") }}'
|
||||
- name: GAS_USED
|
||||
description: '{{ doc("flowevm_tx_gas_used") }}'
|
||||
- name: CUMULATIVE_GAS_USED
|
||||
description: '{{ doc("flowevm_cumulative_gas_used") }}'
|
||||
- name: STATUS
|
||||
description: '{{ doc("flowevm_tx_status") }}'
|
||||
description: '{{ doc("evm_tx_fee_precise") }}'
|
||||
- name: TX_SUCCEEDED
|
||||
description: '{{ doc("tx_succeeded") }}'
|
||||
description: '{{ doc("evm_tx_succeeded") }}'
|
||||
- name: TX_TYPE
|
||||
description: '{{ doc("evm_tx_type") }}'
|
||||
- name: NONCE
|
||||
description: '{{ doc("evm_tx_nonce") }}'
|
||||
- name: TX_POSITION
|
||||
description: '{{ doc("evm_tx_position") }}'
|
||||
- name: INPUT_DATA
|
||||
description: '{{ doc("flowevm_tx_input_data") }}'
|
||||
- name: ORIGIN_FUNCTION_SIGNATURE
|
||||
description: '{{ doc("flowevm_tx_origin_sig") }}'
|
||||
description: '{{ doc("evm_tx_input_data") }}'
|
||||
- name: GAS_PRICE
|
||||
description: '{{ doc("evm_tx_gas_price") }}'
|
||||
- name: GAS_USED
|
||||
description: '{{ doc("evm_tx_gas_used") }}'
|
||||
- name: GAS_LIMIT
|
||||
description: '{{ doc("evm_tx_gas_limit") }}'
|
||||
- name: CUMULATIVE_GAS_USED
|
||||
description: '{{ doc("evm_cumulative_gas_used") }}'
|
||||
- name: EFFECTIVE_GAS_PRICE
|
||||
description: '{{ doc("evm_effective_gas_price") }}'
|
||||
- name: R
|
||||
description: The r value of the transaction signature.
|
||||
description: '{{ doc("evm_r") }}'
|
||||
- name: S
|
||||
description: The s value of the transaction signature.
|
||||
description: '{{ doc("evm_s") }}'
|
||||
- name: V
|
||||
description: The v value of the transaction signature.
|
||||
description: '{{ doc("evm_v") }}'
|
||||
- name: MAX_FEE_PER_GAS
|
||||
description: '{{ doc("evm_max_fee_per_gas") }}'
|
||||
- name: MAX_PRIORITY_FEE_PER_GAS
|
||||
description: '{{ doc("evm_max_priority_fee_per_gas") }}'
|
||||
- name: Y_PARITY
|
||||
description: '{{ doc("evm_y_parity") }}'
|
||||
- name: ACCESS_LIST
|
||||
description: '{{ doc("evm_access_list") }}'
|
||||
- name: FACT_TRANSACTIONS_ID
|
||||
description: '{{ doc("pk_id") }}'
|
||||
description: '{{ doc("evm_pk") }}'
|
||||
- name: INSERTED_TIMESTAMP
|
||||
description: '{{ doc("inserted_timestamp") }}'
|
||||
description: '{{ doc("evm_inserted_timestamp") }}'
|
||||
- name: MODIFIED_TIMESTAMP
|
||||
description: '{{ doc("modified_timestamp") }}'
|
||||
description: '{{ doc("evm_modified_timestamp") }}'
|
||||
@ -0,0 +1,9 @@
|
||||
{{ config (
|
||||
materialized = "view",
|
||||
tags = ['full_evm_test']
|
||||
) }}
|
||||
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
{{ ref('core_evm__fact_blocks') }}
|
||||
145
models/evm/gold/tests/blocks/test_gold_evm__fact_blocks_full.yml
Normal file
145
models/evm/gold/tests/blocks/test_gold_evm__fact_blocks_full.yml
Normal file
@ -0,0 +1,145 @@
|
||||
version: 2
|
||||
models:
|
||||
- name: test_gold_evm__fact_blocks_full
|
||||
description: "This is a view used to test all of the gold fact blocks model."
|
||||
tests:
|
||||
- dbt_utils.unique_combination_of_columns:
|
||||
combination_of_columns:
|
||||
- BLOCK_NUMBER
|
||||
- sequence_gaps:
|
||||
column_name: BLOCK_NUMBER
|
||||
where: BLOCK_TIMESTAMP < CURRENT_DATE - 1
|
||||
|
||||
columns:
|
||||
- name: BLOCK_NUMBER
|
||||
tests:
|
||||
- not_null
|
||||
- dbt_expectations.expect_column_values_to_be_in_type_list:
|
||||
column_type_list:
|
||||
- NUMBER
|
||||
- FLOAT
|
||||
- name: BLOCK_HASH
|
||||
tests:
|
||||
- not_null
|
||||
- dbt_expectations.expect_column_values_to_match_regex:
|
||||
regex: 0[xX][0-9a-fA-F]+
|
||||
- name: BLOCK_TIMESTAMP
|
||||
tests:
|
||||
- not_null
|
||||
- dbt_expectations.expect_column_values_to_be_in_type_list:
|
||||
column_type_list:
|
||||
- TIMESTAMP_LTZ
|
||||
- TIMESTAMP_NTZ
|
||||
- dbt_expectations.expect_row_values_to_have_recent_data:
|
||||
datepart: hour
|
||||
interval: 2
|
||||
- name: NETWORK
|
||||
tests:
|
||||
- not_null
|
||||
- dbt_expectations.expect_column_values_to_match_regex:
|
||||
regex: ^[a-zA-Z0-9_]+$
|
||||
- name: TX_COUNT
|
||||
tests:
|
||||
- not_null
|
||||
- dbt_expectations.expect_column_values_to_be_in_type_list:
|
||||
column_type_list:
|
||||
- NUMBER
|
||||
- FLOAT
|
||||
- name: SIZE
|
||||
tests:
|
||||
- not_null
|
||||
- dbt_expectations.expect_column_values_to_be_in_type_list:
|
||||
column_type_list:
|
||||
- NUMBER
|
||||
- FLOAT
|
||||
- name: MINER
|
||||
tests:
|
||||
- not_null
|
||||
- dbt_expectations.expect_column_values_to_match_regex:
|
||||
regex: 0[xX][0-9a-fA-F]+
|
||||
- name: EXTRA_DATA
|
||||
tests:
|
||||
- not_null
|
||||
- name: PARENT_HASH
|
||||
tests:
|
||||
- not_null
|
||||
- dbt_expectations.expect_column_values_to_match_regex:
|
||||
regex: 0[xX][0-9a-fA-F]+
|
||||
- name: GAS_USED
|
||||
tests:
|
||||
- not_null
|
||||
- dbt_expectations.expect_column_values_to_be_in_type_list:
|
||||
column_type_list:
|
||||
- NUMBER
|
||||
- FLOAT
|
||||
- name: GAS_LIMIT
|
||||
tests:
|
||||
- not_null
|
||||
- dbt_expectations.expect_column_values_to_be_in_type_list:
|
||||
column_type_list:
|
||||
- NUMBER
|
||||
- FLOAT
|
||||
- name: DIFFICULTY
|
||||
tests:
|
||||
- not_null
|
||||
- dbt_expectations.expect_column_values_to_be_in_type_list:
|
||||
column_type_list:
|
||||
- NUMBER
|
||||
- FLOAT
|
||||
- name: SHA3_UNCLES
|
||||
tests:
|
||||
- not_null
|
||||
- name: UNCLE_BLOCKS
|
||||
tests:
|
||||
- not_null
|
||||
- name: NONCE
|
||||
tests:
|
||||
- not_null
|
||||
- dbt_expectations.expect_column_values_to_be_in_type_list:
|
||||
column_type_list:
|
||||
- NUMBER
|
||||
- FLOAT
|
||||
- name: RECEIPTS_ROOT
|
||||
tests:
|
||||
- not_null
|
||||
- dbt_expectations.expect_column_values_to_match_regex:
|
||||
regex: 0[xX][0-9a-fA-F]+
|
||||
- name: STATE_ROOT
|
||||
tests:
|
||||
- not_null
|
||||
- dbt_expectations.expect_column_values_to_match_regex:
|
||||
regex: 0[xX][0-9a-fA-F]+
|
||||
- name: TRANSACTIONS_ROOT
|
||||
tests:
|
||||
- not_null
|
||||
- dbt_expectations.expect_column_values_to_match_regex:
|
||||
regex: 0[xX][0-9a-fA-F]+
|
||||
- name: LOGS_BLOOM
|
||||
tests:
|
||||
- not_null
|
||||
- dbt_expectations.expect_column_values_to_match_regex:
|
||||
regex: 0[xX][0-9a-fA-F]+
|
||||
- name: FACT_BLOCKS_ID
|
||||
tests:
|
||||
- not_null
|
||||
- dbt_expectations.expect_column_values_to_be_unique
|
||||
- name: INSERTED_TIMESTAMP
|
||||
tests:
|
||||
- not_null
|
||||
- dbt_expectations.expect_row_values_to_have_recent_data:
|
||||
datepart: hour
|
||||
interval: 2
|
||||
- dbt_expectations.expect_column_values_to_be_in_type_list:
|
||||
column_type_list:
|
||||
- TIMESTAMP_LTZ
|
||||
- TIMESTAMP_NTZ
|
||||
- name: MODIFIED_TIMESTAMP
|
||||
tests:
|
||||
- not_null
|
||||
- dbt_expectations.expect_row_values_to_have_recent_data:
|
||||
datepart: hour
|
||||
interval: 2
|
||||
- dbt_expectations.expect_column_values_to_be_in_type_list:
|
||||
column_type_list:
|
||||
- TIMESTAMP_LTZ
|
||||
- TIMESTAMP_NTZ
|
||||
@ -0,0 +1,16 @@
|
||||
{{ config (
|
||||
materialized = "view",
|
||||
tags = ['recent_evm_test']
|
||||
) }}
|
||||
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
{{ ref('core_evm__fact_blocks') }}
|
||||
WHERE
|
||||
block_number > (
|
||||
SELECT
|
||||
block_number
|
||||
FROM
|
||||
{{ ref('_evm_block_lookback') }}
|
||||
)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user