global: fixes

This commit is contained in:
nym21
2026-04-29 16:51:01 +02:00
parent a7e41df1c6
commit 43f3be4924
101 changed files with 3074 additions and 2869 deletions

View File

@@ -0,0 +1,17 @@
"""Mining-specific fixtures shared by every mining test in this folder."""
import pytest
@pytest.fixture(scope="module")
def pool_slugs(mempool):
"""Top 3 active pool slugs from the last week."""
data = mempool.get_json("/api/v1/mining/pools/1w")
pools = data.get("pools", []) if isinstance(data, dict) else []
slugs = [p["slug"] for p in pools if p.get("blockCount", 0) > 0][:3]
return slugs or ["foundryusa"]
@pytest.fixture(scope="module")
def pool_slug(pool_slugs):
return pool_slugs[0]

View File

@@ -0,0 +1,15 @@
"""GET /api/v1/mining/blocks/fee-rates/{time_period}"""
import pytest
from _lib import assert_same_structure, show, summary
@pytest.mark.parametrize("period", ["24h", "3d", "1w", "1m", "3m", "6m", "1y"])
def test_mining_blocks_fee_rates(brk, mempool, period):
"""Block fee-rate percentiles must have the same element structure."""
path = f"/api/v1/mining/blocks/fee-rates/{period}"
b = brk.get_json(path)
m = mempool.get_json(path)
show("GET", path, summary(b), summary(m))
assert_same_structure(b, m)

View File

@@ -0,0 +1,15 @@
"""GET /api/v1/mining/blocks/fees/{time_period}"""
import pytest
from _lib import assert_same_structure, show, summary
@pytest.mark.parametrize("period", ["24h", "3d", "1w", "1m", "3m", "6m", "1y"])
def test_mining_blocks_fees(brk, mempool, period):
"""Average block fees must have the same element structure."""
path = f"/api/v1/mining/blocks/fees/{period}"
b = brk.get_json(path)
m = mempool.get_json(path)
show("GET", path, summary(b), summary(m))
assert_same_structure(b, m)

View File

@@ -0,0 +1,15 @@
"""GET /api/v1/mining/blocks/rewards/{time_period}"""
import pytest
from _lib import assert_same_structure, show, summary
@pytest.mark.parametrize("period", ["24h", "3d", "1w", "1m", "3m", "6m", "1y"])
def test_mining_blocks_rewards(brk, mempool, period):
"""Average block rewards must have the same element structure."""
path = f"/api/v1/mining/blocks/rewards/{period}"
b = brk.get_json(path)
m = mempool.get_json(path)
show("GET", path, summary(b), summary(m))
assert_same_structure(b, m)

View File

@@ -0,0 +1,15 @@
"""GET /api/v1/mining/blocks/sizes-weights/{time_period}"""
import pytest
from _lib import assert_same_structure, show, summary
@pytest.mark.parametrize("period", ["24h", "3d", "1w", "1m", "3m", "6m", "1y"])
def test_mining_blocks_sizes_weights(brk, mempool, period):
"""Block sizes and weights must have the same structure."""
path = f"/api/v1/mining/blocks/sizes-weights/{period}"
b = brk.get_json(path)
m = mempool.get_json(path)
show("GET", path, summary(b), summary(m))
assert_same_structure(b, m)

View File

@@ -0,0 +1,15 @@
"""GET /api/v1/mining/blocks/timestamp/{timestamp}"""
from _lib import assert_same_structure, show
def test_mining_blocks_timestamp(brk, mempool, live):
"""Block lookup by timestamp must have the same structure for various eras."""
for block in live.blocks:
info = brk.get_json(f"/api/block/{block.hash}")
ts = info["timestamp"]
path = f"/api/v1/mining/blocks/timestamp/{ts}"
b = brk.get_json(path)
m = mempool.get_json(path)
show("GET", path, b, m)
assert_same_structure(b, m)

View File

@@ -0,0 +1,15 @@
"""GET /api/v1/mining/difficulty-adjustments/{time_period}"""
import pytest
from _lib import assert_same_structure, show, summary
@pytest.mark.parametrize("period", ["24h", "3d", "1w", "1m", "3m", "6m", "1y", "2y", "3y"])
def test_mining_difficulty_adjustments(brk, mempool, period):
"""Historical difficulty adjustments must have the same structure."""
path = f"/api/v1/mining/difficulty-adjustments/{period}"
b = brk.get_json(path)
m = mempool.get_json(path)
show("GET", path, summary(b), summary(m))
assert_same_structure(b, m)

View File

@@ -0,0 +1,15 @@
"""GET /api/v1/mining/hashrate/{time_period}"""
import pytest
from _lib import assert_same_structure, show, summary
@pytest.mark.parametrize("period", ["24h", "3d", "1w", "1m", "3m", "6m", "1y", "2y", "3y"])
def test_mining_hashrate(brk, mempool, period):
"""Network hashrate + difficulty must have the same structure."""
path = f"/api/v1/mining/hashrate/{period}"
b = brk.get_json(path)
m = mempool.get_json(path)
show("GET", path, summary(b), summary(m))
assert_same_structure(b, m)

View File

@@ -0,0 +1,15 @@
"""GET /api/v1/mining/hashrate/pools/{time_period}"""
import pytest
from _lib import assert_same_structure, show, summary
@pytest.mark.parametrize("period", ["24h", "3d", "1w", "1m", "3m", "1y"])
def test_mining_hashrate_pools(brk, mempool, period):
"""Per-pool hashrate must have the same structure."""
path = f"/api/v1/mining/hashrate/pools/{period}"
b = brk.get_json(path)
m = mempool.get_json(path)
show("GET", path, summary(b), summary(m))
assert_same_structure(b, m)

View File

@@ -0,0 +1,13 @@
"""GET /api/v1/mining/pool/{slug}"""
from _lib import assert_same_structure, show, summary
def test_mining_pool_detail(brk, mempool, pool_slugs):
"""Pool detail must have the same structure for top pools."""
for slug in pool_slugs:
path = f"/api/v1/mining/pool/{slug}"
b = brk.get_json(path)
m = mempool.get_json(path)
show("GET", path, summary(b), summary(m))
assert_same_structure(b, m)

View File

@@ -0,0 +1,15 @@
"""GET /api/v1/mining/pool/{slug}/blocks"""
from _lib import assert_same_structure, show
def test_mining_pool_blocks(brk, mempool, pool_slugs):
"""Recent blocks by pool must have the same element structure."""
for slug in pool_slugs:
path = f"/api/v1/mining/pool/{slug}/blocks"
b = brk.get_json(path)
m = mempool.get_json(path)
show("GET", path, f"({len(b)} blocks)", f"({len(m)} blocks)")
assert isinstance(b, list) and isinstance(m, list)
if b and m:
assert_same_structure(b[0], m[0])

View File

@@ -0,0 +1,15 @@
"""GET /api/v1/mining/pool/{slug}/blocks/{height}"""
from _lib import assert_same_structure, show
def test_mining_pool_blocks_at_height(brk, mempool, pool_slug, live):
"""Pool blocks before various heights must have the same element structure."""
for block in live.blocks[::2]: # every other block, to keep run-time bounded
path = f"/api/v1/mining/pool/{pool_slug}/blocks/{block.height}"
b = brk.get_json(path)
m = mempool.get_json(path)
show("GET", path, f"({len(b)} blocks)", f"({len(m)} blocks)")
assert isinstance(b, list) and isinstance(m, list)
if b and m:
assert_same_structure(b[0], m[0])

View File

@@ -0,0 +1,13 @@
"""GET /api/v1/mining/pool/{slug}/hashrate"""
from _lib import assert_same_structure, show, summary
def test_mining_pool_hashrate(brk, mempool, pool_slugs):
"""Pool hashrate history must have the same structure for top pools."""
for slug in pool_slugs:
path = f"/api/v1/mining/pool/{slug}/hashrate"
b = brk.get_json(path)
m = mempool.get_json(path)
show("GET", path, summary(b), summary(m))
assert_same_structure(b, m)

View File

@@ -0,0 +1,45 @@
"""GET /api/v1/mining/pools"""
from _lib import assert_same_structure, show
def test_mining_pools_list_structure(brk, mempool):
"""Pool list must have the same element structure."""
path = "/api/v1/mining/pools"
b = brk.get_json(path)
m = mempool.get_json(path)
show(
"GET", path,
b[:3] if isinstance(b, list) else b,
m[:3] if isinstance(m, list) else m,
)
assert_same_structure(b, m)
def _pools(data):
"""`pools` may live at the root or inside an envelope across versions."""
if isinstance(data, list):
return data
return data.get("pools", []) if isinstance(data, dict) else []
def test_mining_pools_list_fields(brk):
"""Each pool entry must carry slug and name (period-less endpoint omits stats)."""
b = _pools(brk.get_json("/api/v1/mining/pools"))
show("GET", "/api/v1/mining/pools", f"({len(b)} pools)", "")
assert b, "no pools in brk's response"
required = {"slug", "name"}
for p in b[:5]:
missing = required - set(p.keys())
assert not missing, f"pool {p.get('slug', '?')} missing fields: {missing}"
assert isinstance(p["name"], str) and p["name"]
def test_mining_pools_slugs_unique(brk):
"""Pool slugs must be unique across the response."""
b = _pools(brk.get_json("/api/v1/mining/pools"))
slugs = [p["slug"] for p in b]
show("GET", "/api/v1/mining/pools", f"({len(slugs)} slugs)", "")
assert len(slugs) == len(set(slugs)), (
f"duplicate slugs: {len(slugs) - len(set(slugs))}"
)

View File

@@ -0,0 +1,15 @@
"""GET /api/v1/mining/pools/{time_period}"""
import pytest
from _lib import assert_same_structure, show, summary
@pytest.mark.parametrize("period", ["24h", "3d", "1w", "1m", "3m", "6m", "1y", "2y", "3y", "all"])
def test_mining_pools_by_period(brk, mempool, period):
"""Pool stats for a time period must have the same structure."""
path = f"/api/v1/mining/pools/{period}"
b = brk.get_json(path)
m = mempool.get_json(path)
show("GET", path, summary(b), summary(m))
assert_same_structure(b, m)

View File

@@ -0,0 +1,15 @@
"""GET /api/v1/mining/reward-stats/{block_count}"""
import pytest
from _lib import assert_same_structure, show
@pytest.mark.parametrize("block_count", [10, 100, 500])
def test_mining_reward_stats(brk, mempool, block_count):
"""Reward stats must have the same structure."""
path = f"/api/v1/mining/reward-stats/{block_count}"
b = brk.get_json(path)
m = mempool.get_json(path)
show("GET", path, b, m)
assert_same_structure(b, m)