Skip to content

Commit 9f39497

Browse files
committed
Block / REST explorer
1 parent 14cb68c commit 9f39497

30 files changed

+1673
-3
lines changed

.gitmodules

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,3 +214,12 @@
214214
url = https://github.com/status-im/nim-ssz-serialization.git
215215
ignore = untracked
216216
branch = master
217+
[submodule "vendor/DOtherSide"]
218+
path = vendor/DOtherSide
219+
url = https://github.com/filcuc/DOtherSide.git
220+
branch = master
221+
[submodule "vendor/nimqml"]
222+
path = vendor/nimqml
223+
url = https://github.com/filcuc/nimqml.git
224+
branch = master
225+

Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,11 @@ $(TOOLS): | build deps
262262
MAKE="$(MAKE)" V="$(V)" $(ENV_SCRIPT) scripts/compile_nim_program.sh $@ "$${TOOL_DIR}/$@.nim" $(NIM_PARAMS) && \
263263
echo -e $(BUILD_END_MSG) "build/$@"
264264

265+
ngui/ngui: | build deps
266+
+ echo -e $(BUILD_MSG) "build/$@" && \
267+
MAKE="$(MAKE)" V="$(V)" $(ENV_SCRIPT) scripts/compile_nim_program.sh $@ "ngui.ngui.nim" $(NIM_PARAMS) && \
268+
echo -e $(BUILD_END_MSG) "ngui/ngui"
269+
265270
clean_eth2_network_simulation_data:
266271
rm -rf tests/simulation/data
267272

beacon_chain/spec/forks.nim

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -331,9 +331,6 @@ template signature*(x: ForkedTrustedSignedBeaconBlock): TrustedSig =
331331
template root*(x: ForkedSignedBeaconBlock | ForkedTrustedSignedBeaconBlock): Eth2Digest =
332332
withBlck(x): blck.root
333333
334-
template slot*(x: ForkedSignedBeaconBlock | ForkedTrustedSignedBeaconBlock): Slot =
335-
withBlck(x): blck.message.slot
336-
337334
template shortLog*(x: ForkedBeaconBlock): auto =
338335
withBlck(x): shortLog(blck)
339336

ngui/attestationlist.nim

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import
2+
std/[sequtils, tables],
3+
NimQml,
4+
../beacon_chain/spec/eth2_apis/rest_beacon_client,
5+
../beacon_chain/spec/[eth2_merkleization, helpers],
6+
./objecttablemodel, ./utils
7+
8+
type
9+
AttestationInfo* = object
10+
slot*: int
11+
index*: int
12+
beacon_block_root*: string
13+
source_epoch*: int
14+
source_root*: string
15+
target_epoch*: int
16+
target_root*: string
17+
aggregation_bits*: string
18+
19+
proc toAttestationInfo*(v: Attestation): AttestationInfo =
20+
AttestationInfo(
21+
slot: v.data.slot.int,
22+
index: v.data.index.int,
23+
beacon_block_root: toBlockLink(v.data.beacon_block_root),
24+
source_epoch: v.data.source.epoch.int,
25+
source_root: toBlockLink(v.data.source.root),
26+
target_epoch: v.data.target.epoch.int,
27+
target_root: toBlockLink(v.data.target.root),
28+
aggregation_bits: $v.aggregation_bits,
29+
)
30+
31+
QtObject:
32+
type AttestationList* = ref object of QAbstractTableModel
33+
# TODO this could be a generic ObjectTableModel, except generics + method don't work..
34+
data: ObjectTableModelImpl[AttestationInfo]
35+
36+
proc setup(self: AttestationList) = self.QAbstractTableModel.setup
37+
38+
proc delete(self: AttestationList) =
39+
self.QAbstractTableModel.delete
40+
41+
proc newAttestationList*(data: seq[Attestation]): AttestationList =
42+
new(result, delete)
43+
result.data = ObjectTableModelImpl[AttestationInfo](items: data.mapIt(it.toAttestationInfo()))
44+
result.setup
45+
46+
method rowCount(self: AttestationList, index: QModelIndex = nil): int =
47+
self.data.rowCount(index)
48+
49+
method columnCount(self: AttestationList, index: QModelIndex = nil): int =
50+
self.data.columnCount(index)
51+
52+
method headerData*(self: AttestationList, section: int, orientation: QtOrientation, role: int): QVariant =
53+
self.data.headerData(section, orientation, role)
54+
55+
method data(self: AttestationList, index: QModelIndex, role: int): QVariant =
56+
self.data.data(index, role)
57+
58+
method roleNames(self: AttestationList): Table[int, string] =
59+
self.data.roleNames()
60+
61+
proc setNewData*(self: AttestationList, v: seq[Attestation]) =
62+
self.data.setNewData(self, v.mapIt(it.toAttestationInfo()))
63+
64+
proc sort*(self: AttestationList, section: int) {.slot.} =
65+
self.data.sort(self, section)

ngui/attesterslashinglist.nim

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import
2+
std/[sequtils, tables],
3+
NimQml,
4+
../beacon_chain/spec/eth2_apis/rest_beacon_client,
5+
../beacon_chain/spec/[helpers],
6+
./objecttablemodel, ./utils
7+
8+
type
9+
AttesterSlashingInfo* = object
10+
info*: string
11+
12+
proc toAttesterSlashingInfo*(v: AttesterSlashing): AttesterSlashingInfo =
13+
AttesterSlashingInfo(
14+
info: $v
15+
)
16+
17+
QtObject:
18+
type AttesterSlashingList* = ref object of QAbstractTableModel
19+
# TODO this could be a generic ObjectTableModel, except generics + method don't work..
20+
data: ObjectTableModelImpl[AttesterSlashingInfo]
21+
22+
proc setup(self: AttesterSlashingList) = self.QAbstractTableModel.setup
23+
24+
proc delete(self: AttesterSlashingList) =
25+
self.QAbstractTableModel.delete
26+
27+
proc newAttesterSlashingList*(data: openArray[AttesterSlashing]): AttesterSlashingList =
28+
new(result, delete)
29+
result.data = ObjectTableModelImpl[AttesterSlashingInfo](items: data.mapIt(it.toAttesterSlashingInfo()))
30+
result.setup
31+
32+
method rowCount(self: AttesterSlashingList, index: QModelIndex = nil): int =
33+
self.data.rowCount(index)
34+
35+
method columnCount(self: AttesterSlashingList, index: QModelIndex = nil): int =
36+
self.data.columnCount(index)
37+
38+
method headerData*(self: AttesterSlashingList, section: int, orientation: QtOrientation, role: int): QVariant =
39+
self.data.headerData(section, orientation, role)
40+
41+
method data(self: AttesterSlashingList, index: QModelIndex, role: int): QVariant =
42+
self.data.data(index, role)
43+
44+
method roleNames(self: AttesterSlashingList): Table[int, string] =
45+
self.data.roleNames()
46+
47+
proc setNewData*(self: AttesterSlashingList, v: openArray[AttesterSlashing]) =
48+
self.data.setNewData(self, v.mapIt(it.toAttesterSlashingInfo()))
49+
50+
proc sort*(self: AttesterSlashingList, section: int) {.slot.} =
51+
self.data.sort(self, section)

ngui/blockmodel.nim

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import NimQml
2+
3+
import
4+
std/[sequtils, times],
5+
NimQml,
6+
../beacon_chain/spec/eth2_apis/rest_beacon_client,
7+
../beacon_chain/spec/datatypes/[phase0, altair],
8+
"."/[
9+
attestationlist, depositlist, attesterslashinglist, proposerslashinglist,
10+
voluntaryexitlist, utils]
11+
12+
QtObject:
13+
type
14+
BlockModel* = ref object of QObject
15+
blck: phase0.SignedBeaconBlock
16+
attestationsx: AttestationList
17+
depositsx: DepositList
18+
attester_slashingsx: AttesterSlashingList
19+
proposer_slashingsx: ProposerSlashingList
20+
voluntary_exitsx: VoluntaryExitList
21+
genesis_time*: uint64
22+
23+
proc delete*(self: BlockModel) =
24+
self.QObject.delete
25+
26+
proc setup*(self: BlockModel) =
27+
self.QObject.setup
28+
29+
proc newBlockModel*(blck: phase0.SignedBeaconBlock, genesis_time: uint64): BlockModel =
30+
let res = BlockModel(
31+
blck: blck,
32+
attestationsx: newAttestationList(blck.message.body.attestations.asSeq()),
33+
depositsx: newDepositList(blck.message.body.deposits.mapIt(it.toDepositInfo())),
34+
attester_slashingsx: newAttesterSlashingList(blck.message.body.attester_slashings.asSeq()),
35+
proposer_slashingsx: newProposerSlashingList(blck.message.body.proposer_slashings.asSeq()),
36+
voluntary_exitsx: newVoluntaryExitList(blck.message.body.voluntary_exits.asSeq()),
37+
genesis_time: genesis_time,
38+
)
39+
res.setup()
40+
res
41+
42+
proc `blck=`*(self: BlockModel, blck: phase0.SignedBeaconBlock) =
43+
self.blck = blck
44+
self.attestationsx.setNewData(blck.message.body.attestations.asSeq())
45+
self.depositsx.setNewData(blck.message.body.deposits.mapIt(it.toDepositInfo()))
46+
self.attester_slashingsx.setNewData(blck.message.body.attester_slashings.asSeq())
47+
self.proposer_slashingsx.setNewData(blck.message.body.proposer_slashings.asSeq())
48+
self.voluntary_exitsx.setNewData(blck.message.body.voluntary_exits.asSeq())
49+
50+
proc slot*(self: BlockModel): int {.slot.} = self.blck.message.slot.int
51+
QtProperty[int] slot: read = slot
52+
53+
proc time*(self: BlockModel): string {.slot.} =
54+
let t = self.genesis_time + self.blck.message.slot * SECONDS_PER_SLOT
55+
$fromUnix(t.int64).utc
56+
QtProperty[string] time: read = time
57+
58+
proc root*(self: BlockModel): string {.slot.} = toDisplayHex(self.blck.root.data)
59+
QtProperty[string] root: read = root
60+
61+
proc proposer_index*(self: BlockModel): int {.slot.} = self.blck.message.proposer_index.int
62+
QtProperty[int] proposer_index: read = proposer_index
63+
64+
proc parent_root*(self: BlockModel): string {.slot.} = toBlockLink(self.blck.message.parent_root)
65+
QtProperty[string] parent_root: read = parent_root
66+
67+
proc state_root*(self: BlockModel): string {.slot.} = toDisplayHex(self.blck.message.state_root.data)
68+
QtProperty[string] state_root: read = state_root
69+
70+
proc randao_reveal*(self: BlockModel): string {.slot.} = toDisplayHex(self.blck.message.body.randao_reveal)
71+
QtProperty[string] randao_reveal: read = randao_reveal
72+
73+
proc eth1_data*(self: BlockModel): string {.slot.} = RestJson.encode(self.blck.message.body.eth1_data, pretty=true)
74+
QtProperty[string] eth1_data: read = eth1_data
75+
76+
proc graffiti*(self: BlockModel): string {.slot.} = $self.blck.message.body.graffiti
77+
QtProperty[string] graffiti: read = graffiti
78+
79+
proc proposer_slashings*(self: BlockModel): QVariant {.slot.} = newQVariant(self.proposer_slashingsx)
80+
QtProperty[QVariant] proposer_slashings: read = proposer_slashings
81+
82+
proc attester_slashings*(self: BlockModel): QVariant {.slot.} = newQVariant(self.attester_slashingsx)
83+
QtProperty[QVariant] attester_slashings: read = attester_slashings
84+
85+
proc attestations*(self: BlockModel): QVariant {.slot.} = newQVariant(self.attestationsx)
86+
QtProperty[QVariant] attestations: read = attestations
87+
88+
proc deposits*(self: BlockModel): QVariant {.slot.} = newQVariant(self.depositsx)
89+
QtProperty[QVariant] deposits: read = deposits
90+
91+
proc voluntary_exits*(self: BlockModel): QVariant {.slot.} = newQVariant(self.voluntary_exitsx)
92+
QtProperty[QVariant] voluntary_exits: read = voluntary_exits
93+
94+
proc signature*(self: BlockModel): string {.slot.} = toDisplayHex(self.blck.signature)
95+
QtProperty[string] signature: read = signature

ngui/depositlist.nim

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import
2+
std/[tables],
3+
NimQml,
4+
../beacon_chain/spec/datatypes/base,
5+
./objecttablemodel, ./utils
6+
7+
type
8+
DepositInfo* = object
9+
pubkey*: string
10+
withdrawal_credentials*: string
11+
amount*: uint64
12+
signature*: string
13+
14+
proc toDepositInfo*(v: Deposit): DepositInfo =
15+
DepositInfo(
16+
pubkey: toDisplayHex(v.data.pubkey.toRaw()),
17+
withdrawal_credentials: toDisplayHex(v.data.withdrawal_credentials),
18+
amount: v.data.amount,
19+
signature: toDisplayHex(v.data.signature),
20+
)
21+
22+
QtObject:
23+
type DepositList* = ref object of QAbstractTableModel
24+
# TODO this could be a generic ObjectTableModel, except generics + method don't work..
25+
data: ObjectTableModelImpl[DepositInfo]
26+
27+
proc setup(self: DepositList) = self.QAbstractTableModel.setup
28+
29+
proc delete(self: DepositList) =
30+
self.QAbstractTableModel.delete
31+
32+
proc newDepositList*(data: seq[DepositInfo]): DepositList =
33+
new(result, delete)
34+
result.data = ObjectTableModelImpl[DepositInfo](items: data)
35+
result.setup
36+
37+
method rowCount(self: DepositList, index: QModelIndex = nil): int =
38+
self.data.rowCount(index)
39+
40+
method columnCount(self: DepositList, index: QModelIndex = nil): int =
41+
self.data.columnCount(index)
42+
43+
method headerData*(self: DepositList, section: int, orientation: QtOrientation, role: int): QVariant =
44+
self.data.headerData(section, orientation, role)
45+
46+
method data(self: DepositList, index: QModelIndex, role: int): QVariant =
47+
self.data.data(index, role)
48+
49+
method roleNames(self: DepositList): Table[int, string] =
50+
self.data.roleNames()
51+
52+
proc setNewData*(self: DepositList, v: seq[DepositInfo]) =
53+
self.data.setNewData(self, v)
54+
55+
proc sort*(self: DepositList, section: int) {.slot.} =
56+
self.data.sort(self, section)

ngui/epochmodel.nim

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import NimQml
2+
3+
import
4+
../beacon_chain/spec/eth2_apis/rest_beacon_client,
5+
./slotlist
6+
7+
QtObject:
8+
type
9+
EpochModel* = ref object of QObject
10+
client: RestClientRef
11+
epoch: int
12+
slotList: SlotList
13+
14+
proc delete*(self: EpochModel) =
15+
self.QObject.delete
16+
17+
proc setup*(self: EpochModel) =
18+
self.QObject.setup
19+
20+
proc newEpochModel*(client: RestClientRef, epoch: int): EpochModel =
21+
let data = client.loadSlots(epoch.Epoch)
22+
let res = EpochModel(client: client, epoch: epoch, slotList: newSlotList(data))
23+
res.setup()
24+
res
25+
26+
proc epoch*(self: EpochModel): int {.slot.} = self.epoch
27+
proc epochChanged*(self: EpochModel, v: int) {.signal.}
28+
QtProperty[int] epoch:
29+
read = epoch
30+
notify = epochChanged
31+
32+
proc getSlotList*(self: EpochModel): QVariant {.slot.} = newQVariant(self.slotList)
33+
QtProperty[QVariant] slotList: read = getSlotList
34+
35+
proc setNewData*(self: EpochModel, epoch: int, data: seq[SlotInfo]) =
36+
self.epoch = epoch
37+
self.epochChanged(epoch)
38+
39+
self.slotList.setNewData(data)
40+
41+
proc reload(self: EpochModel) {.slot.} =
42+
self.slotList.setNewData(self.client.loadSlots(self.epoch.Epoch))
43+
44+
proc next(self: EpochModel) {.slot.} =
45+
self.epoch = self.epoch + 1
46+
self.epochChanged(self.epoch)
47+
self.reload() # TODO listen to epochchanged
48+
49+
proc prev(self: EpochModel) {.slot.} =
50+
self.epoch = self.epoch - 1
51+
self.epochChanged(self.epoch)
52+
self.reload() # TODO listen to epochchanged

0 commit comments

Comments
 (0)