Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/api/v1/serializers/blocks.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import List, Self
from typing import List, Optional, Self

from core.models import NbeSchema
from core.types import HexBytes
Expand All @@ -16,6 +16,8 @@ class BlockRead(NbeSchema):
fork: int
block_root: HexBytes
proof_of_leadership: ProofOfLeadership
lib: Optional[HexBytes] = None
tip: Optional[HexBytes] = None
transactions: List[Transaction]

@classmethod
Expand All @@ -29,5 +31,7 @@ def from_block(cls, block: Block) -> Self:
fork=block.fork,
block_root=block.block_root,
proof_of_leadership=block.proof_of_leadership,
lib=block.lib,
tip=block.tip,
transactions=block.transactions,
)
4 changes: 3 additions & 1 deletion src/models/block.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import logging
from typing import TYPE_CHECKING, List, Self
from typing import TYPE_CHECKING, List, Optional, Self

from sqlalchemy import Column
from sqlmodel import Field, Relationship
Expand Down Expand Up @@ -30,6 +30,8 @@ class Block(TimestampedModel, table=True):
proof_of_leadership: ProofOfLeadership = Field(
sa_column=Column(PydanticJsonColumn(ProofOfLeadership), nullable=False)
)
lib: Optional[HexBytes] = Field(default=None, nullable=True)
tip: Optional[HexBytes] = Field(default=None, nullable=True)

# --- Relationships --- #

Expand Down
2 changes: 2 additions & 0 deletions src/node/api/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ async def get_blocks_stream(self) -> AsyncIterator[BlockSerializer]:
try:
event = json.loads(line)
block = BlockSerializer.model_validate(event["block"])
block.lib = event.get("lib")
block.tip = event.get("tip")
except (ValidationError, KeyError, json.JSONDecodeError) as error:
logger.exception(error)
continue
Expand Down
6 changes: 5 additions & 1 deletion src/node/api/serializers/block.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging
from os import getenv
from random import randint
from typing import List, Self
from typing import List, Optional, Self

from rusty_results import Empty, Option

Expand All @@ -28,6 +28,8 @@ def _get_random_transactions() -> List[SignedTransactionSerializer]:
class BlockSerializer(NbeSerializer, FromRandom):
header: HeaderSerializer
transactions: List[SignedTransactionSerializer]
lib: Optional[str] = None
tip: Optional[str] = None

@classmethod
def model_validate_json(cls, *args, **kwargs) -> Self:
Expand All @@ -46,6 +48,8 @@ def into_block(self) -> Block:
"slot": self.header.slot,
"block_root": self.header.block_root,
"proof_of_leadership": self.header.proof_of_leadership.into_proof_of_leadership(),
"lib": bytes.fromhex(self.lib) if self.lib else None,
"tip": bytes.fromhex(self.tip) if self.tip else None,
}
).with_transactions(transactions)

Expand Down
12 changes: 12 additions & 0 deletions static/components/BlocksTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ const normalize = (raw) => {
hash: raw.hash ?? header?.hash ?? '',
parent: raw.parent_block_hash ?? header?.parent_block ?? raw.parent_block ?? '',
root: raw.block_root ?? header?.block_root ?? '',
lib: raw.lib ?? '',
tip: raw.tip ?? '',
transactionCount: txLen,
};
};
Expand Down Expand Up @@ -179,6 +181,10 @@ export default function BlocksTable({ live, onDisableLive }) {
h('td', null, h('span', { class: 'mono', title: b.root }, shortenHex(b.root))),
// Transactions
h('td', null, h('span', { class: 'mono' }, String(b.transactionCount))),
// LIB
h('td', null, h('span', { class: 'mono', title: b.lib }, b.lib ? shortenHex(b.lib) : '—')),
// Tip
h('td', null, h('span', { class: 'mono', title: b.tip }, b.tip ? shortenHex(b.tip) : '—')),
);
};

Expand All @@ -192,6 +198,8 @@ export default function BlocksTable({ live, onDisableLive }) {
h('td', null, '\u00A0'),
h('td', null, '\u00A0'),
h('td', null, '\u00A0'),
h('td', null, '\u00A0'),
h('td', null, '\u00A0'),
);
};

Expand Down Expand Up @@ -227,6 +235,8 @@ export default function BlocksTable({ live, onDisableLive }) {
h('col', { style: 'width:200px' }), // Parent
h('col', { style: 'width:200px' }), // Block Root
h('col', { style: 'width:100px' }), // Transactions
h('col', { style: 'width:160px' }), // LIB
h('col', { style: 'width:160px' }), // Tip
),
h(
'thead',
Expand All @@ -240,6 +250,8 @@ export default function BlocksTable({ live, onDisableLive }) {
h('th', null, 'Parent'),
h('th', null, 'Block Root'),
h('th', null, 'Transactions'),
h('th', null, 'LIB'),
h('th', null, 'Tip'),
),
),
h('tbody', null, ...rows),
Expand Down
56 changes: 56 additions & 0 deletions static/pages/BlockDetail.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ export default function BlockDetailPage({ parameters }) {
const blockRoot = block?.block_root ?? header?.block_root ?? '';
const currentBlockHash = block?.hash ?? header?.hash ?? '';
const parentHash = block?.parent_block_hash ?? header?.parent_block ?? '';
const lib = block?.lib ?? '';
const tip = block?.tip ?? '';

return h(
'main',
Expand Down Expand Up @@ -255,6 +257,60 @@ export default function BlockDetailPage({ parameters }) {
),
h(CopyPill, { text: parentHash }),
),

// LIB
h('div', null, h('b', null, 'LIB:')),
h(
'div',
{ style: 'display:flex; gap:8px; flex-wrap:wrap; align-items:flex-start;' },
lib
? h(
'a',
{
class: 'pill mono linkish',
href: PAGE.BLOCK_DETAIL(lib),
title: String(lib),
style: 'max-width:100%; overflow-wrap:anywhere; word-break:break-word;',
},
shortenHex(lib),
)
: h(
'span',
{
class: 'pill mono',
style: 'max-width:100%; overflow-wrap:anywhere; word-break:break-word;',
},
'—',
),
lib && h(CopyPill, { text: lib }),
),

// Tip
h('div', null, h('b', null, 'Tip:')),
h(
'div',
{ style: 'display:flex; gap:8px; flex-wrap:wrap; align-items:flex-start;' },
tip
? h(
'a',
{
class: 'pill mono linkish',
href: PAGE.BLOCK_DETAIL(tip),
title: String(tip),
style: 'max-width:100%; overflow-wrap:anywhere; word-break:break-word;',
},
shortenHex(tip),
)
: h(
'span',
{
class: 'pill mono',
style: 'max-width:100%; overflow-wrap:anywhere; word-break:break-word;',
},
'—',
),
tip && h(CopyPill, { text: tip }),
),
),
),

Expand Down