mirror of
https://github.com/logos-blockchain/logos-blockchain-block-explorer-template.git
synced 2026-04-03 01:13:12 +00:00
Merge 259e3bfea12ce77954b5349e1e64b5c37c8c1771 into db76ad97f8497d73038c8038e0647eaedb65351c
This commit is contained in:
commit
e0a566df36
@ -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
|
||||
@ -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
|
||||
@ -29,5 +31,7 @@ class BlockRead(NbeSchema):
|
||||
fork=block.fork,
|
||||
block_root=block.block_root,
|
||||
proof_of_leadership=block.proof_of_leadership,
|
||||
lib=block.lib,
|
||||
tip=block.tip,
|
||||
transactions=block.transactions,
|
||||
)
|
||||
|
||||
@ -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
|
||||
@ -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 --- #
|
||||
|
||||
|
||||
@ -113,6 +113,8 @@ class HttpNodeApi(NodeApi):
|
||||
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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -28,6 +28,8 @@ logger = logging.getLogger(__name__)
|
||||
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:
|
||||
@ -46,6 +48,8 @@ class BlockSerializer(NbeSerializer, FromRandom):
|
||||
"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)
|
||||
|
||||
|
||||
@ -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,
|
||||
};
|
||||
};
|
||||
@ -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) : '—')),
|
||||
);
|
||||
};
|
||||
|
||||
@ -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'),
|
||||
);
|
||||
};
|
||||
|
||||
@ -232,6 +240,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',
|
||||
@ -245,6 +255,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),
|
||||
|
||||
@ -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',
|
||||
@ -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 }),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user