From 8b76ceed524ee9a4b505af5f8a1b7ab883fddef4 Mon Sep 17 00:00:00 2001 From: Jacek Sieka Date: Wed, 24 Mar 2021 17:20:55 +0100 Subject: [PATCH] Fix minor exception effect issues (#2448) Makes code compatible with https://github.com/status-im/nim-chronos/pull/166 without requiring it. --- beacon_chain/beacon_chain_db.nim | 2 +- .../block_pools_types.nim | 3 +- beacon_chain/eth1/deposit_contract.nim | 2 +- beacon_chain/eth1/eth1_monitor.nim | 2 +- beacon_chain/networking/eth2_network.nim | 10 +-- beacon_chain/networking/peer_pool.nim | 11 +-- beacon_chain/nimbus_beacon_node.nim | 8 +- beacon_chain/spec/state_transition.nim | 2 +- beacon_chain/statusbar.nim | 76 ++++++++++++------- beacon_chain/sync/sync_protocol.nim | 2 +- .../validators/keystore_management.nim | 2 +- vendor/nim-chronos | 2 +- vendor/nim-eth | 2 +- vendor/nim-libp2p | 2 +- 14 files changed, 73 insertions(+), 53 deletions(-) diff --git a/beacon_chain/beacon_chain_db.nim b/beacon_chain/beacon_chain_db.nim index 05334f9bb..78d8b97c5 100644 --- a/beacon_chain/beacon_chain_db.nim +++ b/beacon_chain/beacon_chain_db.nim @@ -59,7 +59,7 @@ type immutableValidators*: ImmutableValidatorsSeq immutableValidatorsMem*: seq[ImmutableValidatorData] - checkpoint*: proc() {.gcsafe.} + checkpoint*: proc() {.gcsafe, raises: [Defect].} Keyspaces* = enum defaultKeyspace = "kvstore" diff --git a/beacon_chain/consensus_object_pools/block_pools_types.nim b/beacon_chain/consensus_object_pools/block_pools_types.nim index 1834c5797..5e814c543 100644 --- a/beacon_chain/consensus_object_pools/block_pools_types.nim +++ b/beacon_chain/consensus_object_pools/block_pools_types.nim @@ -215,8 +215,7 @@ type OnBlockAdded* = proc( blckRef: BlockRef, blck: TrustedSignedBeaconBlock, - epochRef: EpochRef, state: HashedBeaconState) {.raises: [Defect], gcsafe.} - # The `{.gcsafe.}` annotation is needed to shut up the compiler. + epochRef: EpochRef, state: HashedBeaconState) {.gcsafe, raises: [Defect].} template validator_keys*(e: EpochRef): untyped = e.validator_key_store[1][] diff --git a/beacon_chain/eth1/deposit_contract.nim b/beacon_chain/eth1/deposit_contract.nim index 290b84af8..1ea679617 100644 --- a/beacon_chain/eth1/deposit_contract.nim +++ b/beacon_chain/eth1/deposit_contract.nim @@ -122,7 +122,7 @@ proc sendEth(web3: Web3, to: Eth1Address, valueEth: int): Future[TxHash] = web3.send(tr) type - DelayGenerator* = proc(): chronos.Duration {.closure, gcsafe.} + DelayGenerator* = proc(): chronos.Duration {.gcsafe, raises: [Defect].} proc ethToWei(eth: UInt256): UInt256 = eth * 1000000000000000000.u256 diff --git a/beacon_chain/eth1/eth1_monitor.nim b/beacon_chain/eth1/eth1_monitor.nim index 1351dfffe..982ef8895 100644 --- a/beacon_chain/eth1/eth1_monitor.nim +++ b/beacon_chain/eth1/eth1_monitor.nim @@ -112,7 +112,7 @@ type pubkey: Bytes48, withdrawalCredentials: Bytes32, amount: Bytes8, - signature: Bytes96, merkleTreeIndex: Bytes8, j: JsonNode) {.raises: [Defect], gcsafe.} + signature: Bytes96, merkleTreeIndex: Bytes8, j: JsonNode) {.gcsafe, raises: [Defect].} BlockProposalEth1Data* = object vote*: Eth1Data diff --git a/beacon_chain/networking/eth2_network.nim b/beacon_chain/networking/eth2_network.nim index 9e03956b6..e1e3e724c 100644 --- a/beacon_chain/networking/eth2_network.nim +++ b/beacon_chain/networking/eth2_network.nim @@ -157,13 +157,13 @@ type InvalidRequest ServerError - PeerStateInitializer* = proc(peer: Peer): RootRef {.gcsafe.} - NetworkStateInitializer* = proc(network: EthereumNode): RootRef {.gcsafe.} + PeerStateInitializer* = proc(peer: Peer): RootRef {.gcsafe, raises: [Defect].} + NetworkStateInitializer* = proc(network: EthereumNode): RootRef {.gcsafe, raises: [Defect].} OnPeerConnectedHandler* = proc(peer: Peer, incoming: bool): Future[void] {.gcsafe.} - OnPeerDisconnectedHandler* = proc(peer: Peer): Future[void] {.gcsafe.} + OnPeerDisconnectedHandler* = proc(peer: Peer): Future[void] {.gcsafe, raises: [Defect].} ThunkProc* = LPProtoHandler MounterProc* = proc(network: Eth2Node) {.gcsafe.} - MessageContentPrinter* = proc(msg: pointer): string {.gcsafe.} + MessageContentPrinter* = proc(msg: pointer): string {.gcsafe, raises: [Defect].} # https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/p2p-interface.md#goodbye DisconnectionReason* = enum @@ -1638,7 +1638,7 @@ proc setValidTopics*(node: Eth2Node, topics: openArray[string]) = proc addValidator*[MsgType](node: Eth2Node, topic: string, msgValidator: proc(msg: MsgType): - ValidationResult {.gcsafe.} ) = + ValidationResult {.gcsafe, raises: [Defect].} ) = # Validate messages as soon as subscribed proc execValidator( topic: string, message: GossipMsg): Future[ValidationResult] {.async.} = diff --git a/beacon_chain/networking/peer_pool.nim b/beacon_chain/networking/peer_pool.nim index 0ebb15781..4f2029734 100644 --- a/beacon_chain/networking/peer_pool.nim +++ b/beacon_chain/networking/peer_pool.nim @@ -28,13 +28,13 @@ type PeerIndex = object data: int - cmp: proc(a, b: PeerIndex): bool {.closure, gcsafe.} + cmp: proc(a, b: PeerIndex): bool {.gcsafe, raises: [Defect].} PeerScoreCheckCallback*[T] = proc(peer: T): bool {.gcsafe, raises: [Defect].} PeerCounterCallback* = proc() {.gcsafe, raises: [Defect].} - PeerOnDeleteCallback*[T] = proc(peer: T) {.gcsafe.} + PeerOnDeleteCallback*[T] = proc(peer: T) {.gcsafe, raises: [Defect].} PeerPool*[A, B] = ref object incNotEmptyEvent*: AsyncEvent @@ -45,7 +45,7 @@ type outQueue: HeapQueue[PeerIndex] registry: Table[B, PeerIndex] storage: seq[PeerItem[A]] - cmp: proc(a, b: PeerIndex): bool {.closure, gcsafe.} + cmp: proc(a, b: PeerIndex): bool {.gcsafe, raises: [Defect].} scoreCheck: PeerScoreCheckCallback[A] onDeletePeer: PeerOnDeleteCallback[A] peerCounter: PeerCounterCallback @@ -288,7 +288,8 @@ proc deletePeer*[A, B](pool: PeerPool[A, B], peer: A, force = false): bool = mixin getKey let key = getKey(peer) if pool.registry.hasKey(key): - let pindex = pool.registry[key].data + let pindex = try: pool.registry[key].data + except KeyError: raiseAssert "checked with hasKey" var item = addr(pool.storage[pindex]) if (PeerFlags.Acquired in item[].flags): if not(force): @@ -339,7 +340,7 @@ proc deletePeer*[A, B](pool: PeerPool[A, B], peer: A, force = false): bool = proc addPeerImpl[A, B](pool: PeerPool[A, B], peer: A, peerKey: B, peerType: PeerType) = - proc onPeerClosed(udata: pointer) {.gcsafe.} = + proc onPeerClosed(udata: pointer) {.gcsafe, raises: [Defect].} = discard pool.deletePeer(peer) let item = PeerItem[A](data: peer, peerType: peerType, diff --git a/beacon_chain/nimbus_beacon_node.nim b/beacon_chain/nimbus_beacon_node.nim index caf65aa35..75998c688 100644 --- a/beacon_chain/nimbus_beacon_node.nim +++ b/beacon_chain/nimbus_beacon_node.nim @@ -1120,12 +1120,14 @@ proc startSyncManager(node: BeaconNode) = debug "Peer was removed from PeerPool due to low score", peer = peer, peer_score = peer.score, score_low_limit = PeerScoreLowLimit, score_high_limit = PeerScoreHighLimit - asyncSpawn peer.disconnect(PeerScoreLow) + asyncSpawn(try: peer.disconnect(PeerScoreLow) + except Exception as exc: raiseAssert exc.msg) # Shouldn't actually happen! else: debug "Peer was removed from PeerPool", peer = peer, peer_score = peer.score, score_low_limit = PeerScoreLowLimit, score_high_limit = PeerScoreHighLimit - asyncSpawn peer.disconnect(FaultOrError) + asyncSpawn(try: peer.disconnect(FaultOrError) + except Exception as exc: raiseAssert exc.msg) # Shouldn't actually happen! node.network.peerPool.setScoreCheck(scoreCheck) node.network.peerPool.setOnDeletePeer(onDeletePeer) @@ -1319,7 +1321,7 @@ proc initStatusBar(node: BeaconNode) = enableTrueColors() - proc dataResolver(expr: string): string = + proc dataResolver(expr: string): string {.raises: [Defect].} = template justified: untyped = node.chainDag.head.atEpochStart( node.chainDag.headState.data.data.current_justified_checkpoint.epoch) # TODO: diff --git a/beacon_chain/spec/state_transition.nim b/beacon_chain/spec/state_transition.nim index b01351438..3c6895082 100644 --- a/beacon_chain/spec/state_transition.nim +++ b/beacon_chain/spec/state_transition.nim @@ -91,7 +91,7 @@ proc noRollback*(state: var BeaconState) = trace "Skipping rollback of broken state" type - RollbackHashedProc* = proc(state: var HashedBeaconState) {.gcsafe.} + RollbackHashedProc* = proc(state: var HashedBeaconState) {.gcsafe, raises: [Defect].} # Hashed-state transition functions # --------------------------------------------------------------- diff --git a/beacon_chain/statusbar.nim b/beacon_chain/statusbar.nim index d9a77c0ee..58b06a767 100644 --- a/beacon_chain/statusbar.nim +++ b/beacon_chain/statusbar.nim @@ -1,5 +1,7 @@ +{.push raises: [Defect].} + import - tables, strutils, parseutils, sequtils, terminal, colors + std/[strutils, parseutils, sequtils, terminal, colors] type ContentFragments = seq[tuple[kind: InterpolatedKind, value: string]] @@ -12,7 +14,8 @@ type cellsLeft: seq[StatusBarCell] cellsRight: seq[StatusBarCell] - DataItemResolver* = proc (dataItem: string): string + DataItemResolver* = proc (dataItem: string): string {. + gcsafe, raises: [Defect].} StatusBarView* = object model: DataItemResolver @@ -29,10 +32,12 @@ const backgroundColor = rgb(36, 36, 36) foregroundColor = colWhiteSmoke -func loadFragmentsLayout(contentLayout: string): ContentFragments = +func loadFragmentsLayout(contentLayout: string): ContentFragments {. + raises: [Defect, ValueError].} = result = toSeq(interpolatedFragments(strip contentLayout)) -func loadCellsLayout(cellsLayout: string): seq[StatusBarCell] = +func loadCellsLayout(cellsLayout: string): seq[StatusBarCell] {. + raises: [Defect, ValueError].} = var cells = cellsLayout.split(';') for cell in cells: var columns = cell.split(':', maxSplit = 1) @@ -49,7 +54,7 @@ func loadLayout(layout: string): Layout {.raises: [Defect, ValueError].} = result.cellsLeft = loadCellsLayout(sections[0]) if sections.len == 2: result.cellsRight = loadCellsLayout(sections[1]) -func updateContent(cell: var StatusBarCell, model: DataItemResolver) = +proc updateContent(cell: var StatusBarCell, model: DataItemResolver) = cell.content.setLen 0 for fragment in cell.contentFragments: case fragment[0] @@ -58,11 +63,11 @@ func updateContent(cell: var StatusBarCell, model: DataItemResolver) = of ikExpr, ikVar: cell.content.add model(fragment[1]) -func updateCells(cells: var seq[StatusBarCell], model: DataItemResolver) = +proc updateCells(cells: var seq[StatusBarCell], model: DataItemResolver) = for cell in mitems(cells): cell.updateContent(model) -func update*(s: var StatusBarView) = +proc update*(s: var StatusBarView) = updateCells s.layout.cellsLeft, s.model updateCells s.layout.cellsRight, s.model @@ -73,18 +78,29 @@ func width(cells: seq[StatusBarCell]): int = result = max(0, cells.len - 1) # the number of separators for cell in cells: result += cell.width +var complained = false +template ignoreException(body: untyped) = + try: + body + except Exception as exc: + if not complained: + # TODO terminal.nim exception leak + echo "Unable to update status bar: ", exc.msg + complained = true + proc renderCells(cells: seq[StatusBarCell], sep: string) = for i, cell in cells: - stdout.setBackgroundColor backgroundColor - stdout.setForegroundColor foregroundColor - stdout.setStyle {styleDim} - if i > 0: stdout.write sep - stdout.write " ", cell.label, ": " - stdout.setStyle {styleBright} - stdout.write cell.content, " " - stdout.resetAttributes() + ignoreException: + stdout.setBackgroundColor backgroundColor + stdout.setForegroundColor foregroundColor + stdout.setStyle {styleDim} + if i > 0: stdout.write sep + stdout.write " ", cell.label, ": " + stdout.setStyle {styleBright} + stdout.write cell.content, " " + stdout.resetAttributes() -proc render*(s: var StatusBarView) = +proc render*(s: var StatusBarView) {.raises: [Defect, ValueError].} = doAssert s.consumedLines == 0 let @@ -92,21 +108,23 @@ proc render*(s: var StatusBarView) = allCellsWidth = s.layout.cellsLeft.width + s.layout.cellsRight.width if allCellsWidth > 0: - renderCells(s.layout.cellsLeft, sepLeft) - stdout.setBackgroundColor backgroundColor - if termWidth > allCellsWidth: - stdout.write spaces(termWidth - allCellsWidth) - s.consumedLines = 1 - else: - stdout.write spaces(max(0, termWidth - s.layout.cellsLeft.width)), "\p" - s.consumedLines = 2 - renderCells(s.layout.cellsRight, sepRight) - stdout.flushFile + ignoreException: + renderCells(s.layout.cellsLeft, sepLeft) + stdout.setBackgroundColor backgroundColor + if termWidth > allCellsWidth: + stdout.write spaces(termWidth - allCellsWidth) + s.consumedLines = 1 + else: + stdout.write spaces(max(0, termWidth - s.layout.cellsLeft.width)), "\p" + s.consumedLines = 2 + renderCells(s.layout.cellsRight, sepRight) + stdout.flushFile proc erase*(s: var StatusBarView) = - for i in 1 ..< s.consumedLines: cursorUp() - for i in 0 ..< s.consumedLines: eraseLine() - s.consumedLines = 0 + ignoreException: + for i in 1 ..< s.consumedLines: cursorUp() + for i in 0 ..< s.consumedLines: eraseLine() + s.consumedLines = 0 func init*(T: type StatusBarView, layout: string, diff --git a/beacon_chain/sync/sync_protocol.nim b/beacon_chain/sync/sync_protocol.nim index 20a626ce6..595b65ff7 100644 --- a/beacon_chain/sync/sync_protocol.nim +++ b/beacon_chain/sync/sync_protocol.nim @@ -35,7 +35,7 @@ type else: index: uint32 - BeaconBlockCallback* = proc(signedBlock: SignedBeaconBlock) {.gcsafe.} + BeaconBlockCallback* = proc(signedBlock: SignedBeaconBlock) {.gcsafe, raises: [Defect].} BeaconSyncNetworkState* = ref object chainDag*: ChainDAGRef diff --git a/beacon_chain/validators/keystore_management.nim b/beacon_chain/validators/keystore_management.nim index 9edc3fbeb..e36e95dd5 100644 --- a/beacon_chain/validators/keystore_management.nim +++ b/beacon_chain/validators/keystore_management.nim @@ -193,7 +193,7 @@ proc keyboardCreatePassword(prompt: string, return ok(password) proc keyboardGetPassword[T](prompt: string, attempts: int, - pred: proc(p: string): KsResult[T] {.closure.}): KsResult[T] = + pred: proc(p: string): KsResult[T] {.gcsafe, raises: [Defect].}): KsResult[T] = var remainingAttempts = attempts counter = 1 diff --git a/vendor/nim-chronos b/vendor/nim-chronos index c8eefb938..4abd7a564 160000 --- a/vendor/nim-chronos +++ b/vendor/nim-chronos @@ -1 +1 @@ -Subproject commit c8eefb9382a786993fc703386b0bd446ecf9c037 +Subproject commit 4abd7a56450db8eb6578a151af0a5b7ba61bd2bf diff --git a/vendor/nim-eth b/vendor/nim-eth index be5e088b2..16802c0e5 160000 --- a/vendor/nim-eth +++ b/vendor/nim-eth @@ -1 +1 @@ -Subproject commit be5e088b21e06a85cac4826454412db8459ed4f1 +Subproject commit 16802c0e5218cce405cd623a554ce95549dd5181 diff --git a/vendor/nim-libp2p b/vendor/nim-libp2p index a54e1cc69..54031c9e9 160000 --- a/vendor/nim-libp2p +++ b/vendor/nim-libp2p @@ -1 +1 @@ -Subproject commit a54e1cc699f036f3a8eeff33c3d9f893b8a284e9 +Subproject commit 54031c9e9bc9882a2e8c2d5937031731ed63ab5e