Skip to content

ngui: QT-based block / beacon node explorer PoC #2304

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: unstable
Choose a base branch
from
Draft
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
7 changes: 7 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,13 @@
path = vendor/nim-toml-serialization
url = https://github.com/status-im/nim-toml-serialization.git
ignore = untracked
[submodule "vendor/DOtherSide"]
path = vendor/DOtherSide
url = https://github.com/filcuc/DOtherSide.git
branch = master
[submodule "vendor/nimqml"]
path = vendor/nimqml
url = https://github.com/status-im/nimqml.git
branch = master
[submodule "vendor/gnosis-chain-configs"]
path = vendor/gnosis-chain-configs
Expand Down
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,10 @@ force_build_alone_tools: | $(FORCE_BUILD_ALONE_TOOLS_DEPS)
# https://www.gnu.org/software/make/manual/html_node/Multiple-Rules.html#Multiple-Rules
# Already defined as a reult
nimbus_beacon_node: force_build_alone_tools
ngui/ngui: | build deps
+ echo -e $(BUILD_MSG) "build/$@" && \
MAKE="$(MAKE)" V="$(V)" $(ENV_SCRIPT) scripts/compile_nim_program.sh $@ "ngui.ngui.nim" $(NIM_PARAMS) && \
echo -e $(BUILD_END_MSG) "ngui/ngui"

GOERLI_TESTNETS_PARAMS := \
--tcp-port=$$(( $(BASE_PORT) + $(NODE_ID) )) \
Expand Down
23 changes: 23 additions & 0 deletions beacon_chain/spec/eth2_apis/rest_validator_calls.nim
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ import

export client, rest_types, eth2_rest_serialization

proc getAttesterDuties*(
epoch: Epoch,
body: seq[ValidatorIndex]
): RestResponse[GetAttesterDutiesResponse] {.
rest, endpoint: "/eth/v1/validator/duties/attester/{epoch}",
meth: MethodPost.}
## https://ethereum.github.io/beacon-APIs/#/Validator/getAttesterDuties

proc getAttesterDutiesPlain*(
epoch: Epoch,
body: seq[ValidatorIndex]
Expand All @@ -21,13 +29,28 @@ proc getAttesterDutiesPlain*(
meth: MethodPost.}
## https://ethereum.github.io/beacon-APIs/#/Validator/getAttesterDuties

proc getProposerDuties*(
epoch: Epoch
): RestResponse[GetProposerDutiesResponse] {.
rest, endpoint: "/eth/v1/validator/duties/proposer/{epoch}",
meth: MethodGet.}
## https://ethereum.github.io/beacon-APIs/#/Validator/getProposerDuties

proc getProposerDutiesPlain*(
epoch: Epoch
): RestPlainResponse {.
rest, endpoint: "/eth/v1/validator/duties/proposer/{epoch}",
meth: MethodGet.}
## https://ethereum.github.io/beacon-APIs/#/Validator/getProposerDuties

proc getSyncCommitteeDuties*(
epoch: Epoch,
body: seq[ValidatorIndex]
): RestResponse[GetSyncCommitteeDutiesResponse] {.
rest, endpoint: "/eth/v1/validator/duties/sync/{epoch}",
meth: MethodPost.}
## https://ethereum.github.io/beacon-APIs/#/Validator/getSyncCommitteeDuties

proc getSyncCommitteeDutiesPlain*(
epoch: Epoch,
body: seq[ValidatorIndex]
Expand Down
31 changes: 25 additions & 6 deletions beacon_chain/spec/forks.nim
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,10 @@ type
phase0.Attestation |
electra.SingleAttestation

ForkyAttesterSlashing* =
phase0.AttesterSlashing |
electra.AttesterSlashing

ForkedAttestation* = object
case kind*: ConsensusFork
of ConsensusFork.Phase0: phase0Data*: phase0.Attestation
Expand Down Expand Up @@ -1252,28 +1256,43 @@ template getForkedBlockField*(
of ConsensusFork.Electra: unsafeAddr x.electraData.message.y
of ConsensusFork.Fulu: unsafeAddr x.fuluData.message.y)[]

template signature*(x: ForkedSignedBeaconBlock |
template getForkedBodyField*(
x: ForkedSignedBeaconBlock |
ForkedMsgTrustedSignedBeaconBlock |
ForkedTrustedSignedBeaconBlock,
y: untyped): untyped =
# unsafeAddr avoids a copy of the field in some cases
(case x.kind
of ConsensusFork.Phase0: unsafeAddr x.phase0Data.message.body.y
of ConsensusFork.Altair: unsafeAddr x.altairData.message.body.y
of ConsensusFork.Bellatrix: unsafeAddr x.bellatrixData.message.body.y
of ConsensusFork.Capella: unsafeAddr x.capellaData.message.body.y
of ConsensusFork.Deneb: unsafeAddr x.denebData.message.body.y
of ConsensusFork.Electra: unsafeAddr x.electraData.message.body.y
of ConsensusFork.Fulu: unsafeAddr x.fuluData.message.body.y)[]

func signature*(x: ForkedSignedBeaconBlock |
ForkedMsgTrustedSignedBeaconBlock |
ForkedSignedBlindedBeaconBlock): ValidatorSig =
withBlck(x): forkyBlck.signature

template signature*(x: ForkedTrustedSignedBeaconBlock): TrustedSig =
func signature*(x: ForkedTrustedSignedBeaconBlock): TrustedSig =
withBlck(x): forkyBlck.signature

template root*(x: ForkedSignedBeaconBlock |
func root*(x: ForkedSignedBeaconBlock |
ForkedMsgTrustedSignedBeaconBlock |
ForkedTrustedSignedBeaconBlock): Eth2Digest =
withBlck(x): forkyBlck.root

template slot*(x: ForkedSignedBeaconBlock |
func slot*(x: ForkedSignedBeaconBlock |
ForkedMsgTrustedSignedBeaconBlock |
ForkedTrustedSignedBeaconBlock): Slot =
withBlck(x): forkyBlck.message.slot

template shortLog*(x: ForkedBeaconBlock | ForkedBlindedBeaconBlock): auto =
func shortLog*(x: ForkedBeaconBlock | ForkedBlindedBeaconBlock): auto =
withBlck(x): shortLog(forkyBlck)

template shortLog*(x: ForkedSignedBeaconBlock |
func shortLog*(x: ForkedSignedBeaconBlock |
ForkedMsgTrustedSignedBeaconBlock |
ForkedTrustedSignedBeaconBlock |
ForkedSignedBlindedBeaconBlock): auto =
Expand Down
1 change: 1 addition & 0 deletions beacon_chain/spec/helpers.nim
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import
# Status libraries
std/times,
stew/[byteutils, endians2, objects],
nimcrypto/sha2,
chronicles,
Expand Down
1 change: 1 addition & 0 deletions ngui/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
resources.cpp
80 changes: 80 additions & 0 deletions ngui/attestationlist.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import
std/[sequtils, tables],
NimQml,
../beacon_chain/spec/eth2_apis/rest_beacon_client,
../beacon_chain/spec/[eth2_merkleization, helpers],
./objecttablemodel,
./utils

type AttestationInfo* = object
slot*: int
index*: int
beacon_block_root*: string
source_epoch*: int
source_root*: string
target_epoch*: int
target_root*: string
aggregation_bits*: string

proc toAttestationInfo*(v: phase0.Attestation): AttestationInfo =
AttestationInfo(
slot: v.data.slot.int,
index: v.data.index.int,
beacon_block_root: toBlockLink(v.data.beacon_block_root),
source_epoch: v.data.source.epoch.int,
source_root: toBlockLink(v.data.source.root),
target_epoch: v.data.target.epoch.int,
target_root: toBlockLink(v.data.target.root),
aggregation_bits: $v.aggregation_bits,
)

proc toAttestationInfo*(v: electra.Attestation): AttestationInfo =
AttestationInfo(
slot: v.data.slot.int,
index: 0.int,
beacon_block_root: toBlockLink(v.data.beacon_block_root),
source_epoch: v.data.source.epoch.int,
source_root: toBlockLink(v.data.source.root),
target_epoch: v.data.target.epoch.int,
target_root: toBlockLink(v.data.target.root),
aggregation_bits: $v.aggregation_bits,
)

QtObject:
type AttestationList* = ref object of QAbstractTableModel
# TODO this could be a generic ObjectTableModel, except generics + method don't work..
data: ObjectTableModelImpl[AttestationInfo]

proc setup(self: AttestationList) =
self.QAbstractTableModel.setup

proc delete(self: AttestationList) =
self.QAbstractTableModel.delete

proc newAttestationList*(data: seq[AttestationInfo]): AttestationList =
new(result, delete)
result.data = ObjectTableModelImpl[AttestationInfo](items: data)
result.setup

method rowCount(self: AttestationList, index: QModelIndex = nil): int =
self.data.rowCount(index)

method columnCount(self: AttestationList, index: QModelIndex = nil): int =
self.data.columnCount(index)

method headerData*(
self: AttestationList, section: int, orientation: QtOrientation, role: int
): QVariant =
self.data.headerData(section, orientation, role)

method data(self: AttestationList, index: QModelIndex, role: int): QVariant =
self.data.data(index, role)

method roleNames(self: AttestationList): Table[int, string] =
self.data.roleNames()

proc setNewData*(self: AttestationList, v: seq[AttestationInfo]) =
self.data.setNewData(self, v)

proc sort*(self: AttestationList, section: int) {.slot.} =
self.data.sort(self, section)
56 changes: 56 additions & 0 deletions ngui/attesterslashinglist.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import
std/[sequtils, tables],
NimQml,
../beacon_chain/spec/eth2_apis/rest_beacon_client,
../beacon_chain/spec/[helpers],
./objecttablemodel,
./utils

type AttesterSlashingInfo* = object
info*: string

proc toAttesterSlashingInfo*(v: ForkyAttesterSlashing): AttesterSlashingInfo =
AttesterSlashingInfo(info: $v)

QtObject:
type AttesterSlashingList* = ref object of QAbstractTableModel
# TODO this could be a generic ObjectTableModel, except generics + method don't work..
data: ObjectTableModelImpl[AttesterSlashingInfo]

proc setup(self: AttesterSlashingList) =
self.QAbstractTableModel.setup

proc delete(self: AttesterSlashingList) =
self.QAbstractTableModel.delete

proc newAttesterSlashingList*(
data: openArray[ForkyAttesterSlashing]
): AttesterSlashingList =
new(result, delete)
result.data = ObjectTableModelImpl[AttesterSlashingInfo](
items: data.mapIt(it.toAttesterSlashingInfo())
)
result.setup

method rowCount(self: AttesterSlashingList, index: QModelIndex = nil): int =
self.data.rowCount(index)

method columnCount(self: AttesterSlashingList, index: QModelIndex = nil): int =
self.data.columnCount(index)

method headerData*(
self: AttesterSlashingList, section: int, orientation: QtOrientation, role: int
): QVariant =
self.data.headerData(section, orientation, role)

method data(self: AttesterSlashingList, index: QModelIndex, role: int): QVariant =
self.data.data(index, role)

method roleNames(self: AttesterSlashingList): Table[int, string] =
self.data.roleNames()

proc setNewData*(self: AttesterSlashingList, v: openArray[ForkyAttesterSlashing]) =
self.data.setNewData(self, v.mapIt(it.toAttesterSlashingInfo()))

proc sort*(self: AttesterSlashingList, section: int) {.slot.} =
self.data.sort(self, section)
Loading
Loading