global: fixes

This commit is contained in:
nym21
2026-05-04 16:57:21 +02:00
parent 4663d13194
commit dc32bd480f
121 changed files with 2996 additions and 2165 deletions
+43 -36
View File
@@ -65,8 +65,9 @@ Height = int
Timestamp = int
# Block hash
BlockHash = str
# Transaction index within a block (0 = coinbase)
TxIndex = int
# Position of a transaction within a single block (0 = coinbase).
# Distinct from `TxIndex`, which is the chain-wide global tx index.
BlockTxIndex = int
# Unsigned cents (u64) - for values that should never be negative.
# Used for invested capital, realized cap, etc.
Cents = int
@@ -105,6 +106,13 @@ UrpdAggregation = Literal["raw", "lin200", "lin500", "lin1000", "log10", "log50"
# Position of a transaction inside a `CpfpCluster.txs` array. Cluster-local,
# has no meaning outside the enclosing cluster.
CpfpClusterTxIndex = int
# BIP-141 sigop cost. The block-level budget is 80,000, so a `u32`
# fits a single tx's count with room to spare.
#
# Witness sigops count as 1; legacy and P2SH-redeem sigops count as 4.
# Five vbytes per sigop is the policy adjustment Core applies in
# `nSigOpCost` to discourage sigop-heavy txs (`max(weight/4, sigops*5)`).
SigOps = int
# Virtual size in vbytes (weight / 4, rounded up). Max block vsize is ~1,000,000 vB.
VSize = int
# Date in YYYYMMDD format stored as u32
@@ -221,6 +229,9 @@ Vout = int
# and matching brk's `script_sig: ScriptBuf` (bytes internally, hex
# on the wire).
Witness = List[str]
# Chain-wide transaction index (0 = the genesis coinbase). For an
# in-block position, use `BlockTxIndex` instead.
TxIndex = int
# Raw transaction version (i32) from Bitcoin protocol.
# Unlike TxVersion (u8, indexed), this preserves non-standard values
# used in coinbase txs for miner signaling/branding.
@@ -481,7 +492,7 @@ class BlockHashStartIndex(TypedDict):
start_index: Starting transaction index within the block (0-based)
"""
hash: BlockHash
start_index: TxIndex
start_index: BlockTxIndex
class BlockHashTxIndex(TypedDict):
"""
@@ -492,7 +503,7 @@ class BlockHashTxIndex(TypedDict):
index: Transaction index within the block (0-based)
"""
hash: BlockHash
index: TxIndex
index: BlockTxIndex
class BlockInfo(TypedDict):
"""
@@ -655,11 +666,9 @@ class CostBasisQuery(TypedDict):
class CpfpClusterChunk(TypedDict):
"""
One SFL chunk inside a `CpfpCluster`.
Attributes:
txs: Txs in this chunk.
feerate: Combined feerate of the chunk (sat/vB).
One SFL chunk inside a `CpfpCluster`. `txs` is in topological order
(matches `CpfpCluster.txs` ordering); the chunk's `feerate` is the
per-chunk SFL feerate and is the same for every tx in this chunk.
"""
txs: List[CpfpClusterTxIndex]
feerate: FeeRate
@@ -672,14 +681,14 @@ class CpfpClusterTx(TypedDict):
parents: In-cluster parents of this tx.
"""
txid: Txid
fee: Sats
weight: Weight
fee: Sats
parents: List[CpfpClusterTxIndex]
class CpfpCluster(TypedDict):
"""
CPFP cluster output for an unconfirmed tx: the connected component
the seed belongs to, plus its SFL linearization.
CPFP cluster: the connected component the seed belongs to, plus its
SFL linearization.
Attributes:
txs: All txs in the cluster, in topological order (parents before children).
@@ -692,12 +701,7 @@ class CpfpCluster(TypedDict):
class CpfpEntry(TypedDict):
"""
A transaction in a CPFP relationship
Attributes:
txid: Transaction ID
weight: Transaction weight
fee: Transaction fee (sats)
A transaction in a CPFP relationship.
"""
txid: Txid
weight: Weight
@@ -705,27 +709,30 @@ class CpfpEntry(TypedDict):
class CpfpInfo(TypedDict):
"""
CPFP (Child Pays For Parent) information for a transaction
CPFP (Child Pays For Parent) information for a transaction.
Attributes:
ancestors: Ancestor transactions in the CPFP chain
bestDescendant: Best (highest fee rate) descendant, if any
descendants: Descendant transactions in the CPFP chain
effectiveFeePerVsize: Effective fee rate considering CPFP relationships (sat/vB)
sigops: Total signature operation count for the seed tx
fee: Transaction fee (sats)
adjustedVsize: Adjusted virtual size (accounting for sigops)
cluster: Mempool cluster the seed belongs to: full tx list, SFL-linearized
chunks, and the seed's chunk index. Only set for unconfirmed txs.
ancestors: Ancestor transactions in the CPFP chain.
bestDescendant: Best (highest fee rate) descendant, if any.
descendants: Descendant transactions in the CPFP chain.
effectiveFeePerVsize: Effective fee rate considering CPFP relationships (sat/vB).
sigops: BIP-141 sigop cost for the seed tx (witness sigops count as 1,
legacy and P2SH-redeem sigops count as 4).
fee: Transaction fee (sats).
vsize: Virtual size of the seed tx (vbytes).
adjustedVsize: Policy-adjusted virtual size: `max(vsize, sigops * 5)`.
cluster: Cluster the seed belongs to: full tx list, SFL-linearized chunks,
and the seed's chunk index.
"""
ancestors: List[CpfpEntry]
bestDescendant: Union[CpfpEntry, None]
descendants: List[CpfpEntry]
effectiveFeePerVsize: Union[FeeRate, None]
sigops: Optional[int]
fee: Union[Sats, None]
adjustedVsize: Union[VSize, None]
cluster: Union[CpfpCluster, None]
effectiveFeePerVsize: FeeRate
sigops: SigOps
fee: Sats
vsize: VSize
adjustedVsize: VSize
cluster: CpfpCluster
class DataRangeFormat(TypedDict):
"""
@@ -1589,7 +1596,7 @@ class Transaction(TypedDict):
vout: List[TxOut]
size: int
weight: Weight
sigops: int
sigops: SigOps
fee: Sats
status: TxStatus
@@ -7935,7 +7942,7 @@ class BrkClient(BrkClientBase):
Endpoint: `GET /api/block/{hash}/status`"""
return self.get_json(f'/api/block/{hash}/status')
def get_block_txid(self, hash: BlockHash, index: TxIndex) -> Txid:
def get_block_txid(self, hash: BlockHash, index: BlockTxIndex) -> Txid:
"""Transaction ID at index.
Retrieve a single transaction ID at a specific index within a block. Returns plain text txid.
@@ -7965,7 +7972,7 @@ class BrkClient(BrkClientBase):
Endpoint: `GET /api/block/{hash}/txs`"""
return self.get_json(f'/api/block/{hash}/txs')
def get_block_txs_from_index(self, hash: BlockHash, start_index: TxIndex) -> List[Transaction]:
def get_block_txs_from_index(self, hash: BlockHash, start_index: BlockTxIndex) -> List[Transaction]:
"""Block transactions (paginated).
Retrieve transactions in a block by block hash, starting from the specified index. Returns up to 25 transactions at a time.
@@ -38,15 +38,15 @@ def test_cpfp_invariants(brk, live):
assert int(c["adjustedVsize"]) > 0
def test_cpfp_unknown_tx_returns_empty(brk, mempool):
"""Both servers return {ancestors: []} for any 64-char hex (no 404)."""
def test_cpfp_unknown_txid(brk, mempool):
"""mempool.space returns 200 with {ancestors: []}; brk distinguishes
'unknown txid' from 'tx with no neighbors' and returns an error."""
bad = "0" * 64
path = f"/api/v1/cpfp/{bad}"
b = brk.get_cpfp(bad)
m = mempool.get_json(path)
show("GET", path, b, m)
assert b.get("ancestors") == []
assert m.get("ancestors") == []
with pytest.raises(BrkError):
brk.get_cpfp(bad)
@pytest.mark.parametrize("bad", ["abc", "deadbeef"])