88 lines
2.8 KiB
MySQL
88 lines
2.8 KiB
MySQL
|
|
-- TimescaleDB schema for mempool transactions
|
||
|
|
-- This extends the main database with time-series capabilities
|
||
|
|
|
||
|
|
-- Mempool transactions hypertable
|
||
|
|
CREATE TABLE IF NOT EXISTS mempool_transactions (
|
||
|
|
time TIMESTAMPTZ NOT NULL,
|
||
|
|
chain_id INTEGER NOT NULL,
|
||
|
|
hash VARCHAR(66) NOT NULL,
|
||
|
|
from_address VARCHAR(42) NOT NULL,
|
||
|
|
to_address VARCHAR(42),
|
||
|
|
value NUMERIC(78, 0),
|
||
|
|
gas_price BIGINT,
|
||
|
|
max_fee_per_gas BIGINT,
|
||
|
|
max_priority_fee_per_gas BIGINT,
|
||
|
|
gas_limit BIGINT,
|
||
|
|
nonce BIGINT,
|
||
|
|
input_data_length INTEGER,
|
||
|
|
first_seen TIMESTAMPTZ NOT NULL,
|
||
|
|
status VARCHAR(20) DEFAULT 'pending',
|
||
|
|
confirmed_block_number BIGINT,
|
||
|
|
confirmed_at TIMESTAMPTZ,
|
||
|
|
PRIMARY KEY (time, chain_id, hash)
|
||
|
|
);
|
||
|
|
|
||
|
|
-- Convert to hypertable
|
||
|
|
SELECT create_hypertable('mempool_transactions', 'time', if_not_exists => TRUE);
|
||
|
|
|
||
|
|
-- Indexes
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_mempool_chain_hash ON mempool_transactions(chain_id, hash);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_mempool_chain_from ON mempool_transactions(chain_id, from_address);
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_mempool_chain_status ON mempool_transactions(chain_id, status, time);
|
||
|
|
|
||
|
|
-- Network metrics hypertable
|
||
|
|
CREATE TABLE IF NOT EXISTS network_metrics (
|
||
|
|
time TIMESTAMPTZ NOT NULL,
|
||
|
|
chain_id INTEGER NOT NULL,
|
||
|
|
block_number BIGINT,
|
||
|
|
tps DOUBLE PRECISION,
|
||
|
|
gps DOUBLE PRECISION,
|
||
|
|
avg_gas_price BIGINT,
|
||
|
|
pending_transactions INTEGER,
|
||
|
|
block_time_seconds DOUBLE PRECISION,
|
||
|
|
PRIMARY KEY (time, chain_id)
|
||
|
|
);
|
||
|
|
|
||
|
|
SELECT create_hypertable('network_metrics', 'time', if_not_exists => TRUE);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_network_metrics_chain_time ON network_metrics(chain_id, time DESC);
|
||
|
|
|
||
|
|
-- Gas price history hypertable
|
||
|
|
CREATE TABLE IF NOT EXISTS gas_price_history (
|
||
|
|
time TIMESTAMPTZ NOT NULL,
|
||
|
|
chain_id INTEGER NOT NULL,
|
||
|
|
block_number BIGINT,
|
||
|
|
min_gas_price BIGINT,
|
||
|
|
max_gas_price BIGINT,
|
||
|
|
avg_gas_price BIGINT,
|
||
|
|
p25_gas_price BIGINT,
|
||
|
|
p50_gas_price BIGINT,
|
||
|
|
p75_gas_price BIGINT,
|
||
|
|
p95_gas_price BIGINT,
|
||
|
|
p99_gas_price BIGINT,
|
||
|
|
PRIMARY KEY (time, chain_id)
|
||
|
|
);
|
||
|
|
|
||
|
|
SELECT create_hypertable('gas_price_history', 'time', if_not_exists => TRUE);
|
||
|
|
|
||
|
|
-- Continuous aggregate for 1-minute network metrics
|
||
|
|
CREATE MATERIALIZED VIEW IF NOT EXISTS network_metrics_1m
|
||
|
|
WITH (timescaledb.continuous) AS
|
||
|
|
SELECT
|
||
|
|
time_bucket('1 minute', time) AS bucket,
|
||
|
|
chain_id,
|
||
|
|
AVG(tps) AS avg_tps,
|
||
|
|
AVG(gps) AS avg_gps,
|
||
|
|
AVG(avg_gas_price) AS avg_gas_price,
|
||
|
|
AVG(pending_transactions) AS avg_pending_tx
|
||
|
|
FROM network_metrics
|
||
|
|
GROUP BY bucket, chain_id;
|
||
|
|
|
||
|
|
-- Add refresh policy for continuous aggregate
|
||
|
|
SELECT add_continuous_aggregate_policy('network_metrics_1m',
|
||
|
|
start_offset => INTERVAL '1 hour',
|
||
|
|
end_offset => INTERVAL '1 minute',
|
||
|
|
schedule_interval => INTERVAL '1 minute',
|
||
|
|
if_not_exists => TRUE);
|
||
|
|
|