EH cleanup (#2455)

almost 100% raises in nimbus-eth2 now!

* fix some rare exception-related crashes in json-rpc
This commit is contained in:
Jacek Sieka 2021-03-26 07:52:01 +01:00 committed by GitHub
parent 596cf3d674
commit 2695cfa864
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
47 changed files with 533 additions and 224 deletions

View File

@ -277,11 +277,18 @@ proc snappyEncode(inp: openArray[byte]): seq[byte] =
except CatchableError as err:
raiseAssert err.msg
proc sszEncode(v: auto): seq[byte] =
try:
SSZ.encode(v)
except IOError as err:
# In-memory encode shouldn't fail!
raiseAssert err.msg
proc put(db: BeaconChainDB, key: openArray[byte], v: Eth2Digest) =
db.backend.put(key, v.data).expect("working database (disk broken/full?)")
proc put(db: BeaconChainDB, key: openArray[byte], v: auto) =
db.backend.put(key, snappyEncode(SSZ.encode(v))).expect("working database (disk broken/full?)")
db.backend.put(key, snappyEncode(sszEncode(v))).expect("working database (disk broken/full?)")
proc get(db: BeaconChainDB, key: openArray[byte], T: type Eth2Digest): Opt[T] =
var res: Opt[T]

View File

@ -1,3 +1,10 @@
# beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
@ -98,13 +105,7 @@ func saturate*(d: tuple[inFuture: bool, offset: Duration]): Duration =
if d.inFuture: d.offset else: seconds(0)
proc addTimer*(fromNow: Duration, cb: CallbackFunc, udata: pointer = nil) =
try:
discard setTimer(Moment.now() + fromNow, cb, udata)
except Exception as e:
# TODO https://github.com/status-im/nim-chronos/issues/94
# shouldn't happen because we should have initialized chronos by now
# https://github.com/nim-lang/Nim/issues/10288 - sigh
raiseAssert e.msg
discard setTimer(Moment.now() + fromNow, cb, udata)
func shortLog*(d: Duration): string =
$d

View File

@ -1,10 +1,12 @@
# beacon_chain
# Copyright (c) 2018-2020 Status Research & Development GmbH
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
type
# "state" is already taken by BeaconState
BeaconNodeStatus* = enum

View File

@ -1,3 +1,10 @@
# beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import

View File

@ -1,3 +1,10 @@
# beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import

View File

@ -1,3 +1,12 @@
# beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
os, sequtils, strutils, options, json, terminal,
chronos, chronicles, confutils, stint, json_serialization,
@ -172,6 +181,7 @@ proc sendDeposits*(deposits: seq[LaunchPadDeposit],
await sleepAsync(60.seconds)
web3 = await initWeb3(web3Url, privateKey)
{.pop.} # TODO confutils.nim(775, 17) Error: can raise an unlisted exception: ref IOError
proc main() {.async.} =
var cfg = CliConfig.load()
let rng = keys.newRng()

View File

@ -1,3 +1,12 @@
# beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
std/[deques, hashes, options, strformat, strutils, sequtils, tables,
typetraits, uri],
@ -31,9 +40,6 @@ contract(DepositContract):
amount: Bytes8,
signature: Bytes96,
index: Bytes8) {.event.}
# TODO
# The raises list of this module are still not usable due to general
# Exceptions being reported from Chronos's asyncfutures2.
const
web3Timeouts = 60.seconds
@ -295,7 +301,9 @@ template asBlockHash(x: Eth2Digest): BlockHash =
BlockHash(x.data)
func shortLog*(b: Eth1Block): string =
&"{b.number}:{shortLog b.voteData.block_hash}(deposits = {b.voteData.deposit_count})"
try:
&"{b.number}:{shortLog b.voteData.block_hash}(deposits = {b.voteData.deposit_count})"
except ValueError as exc: raiseAssert exc.msg
template findBlock*(chain: Eth1Chain, eth1Data: Eth1Data): Eth1Block =
getOrDefault(chain.blocksByHash, asBlockHash(eth1Data.block_hash), nil)
@ -386,14 +394,15 @@ proc getBlockByHash*(p: Web3DataProviderRef, hash: BlockHash):
proc getBlockByNumber*(p: Web3DataProviderRef,
number: Eth1BlockNumber): Future[BlockObject] =
return p.web3.provider.eth_getBlockByNumber(&"0x{number:X}", false)
p.web3.provider.eth_getBlockByNumber("0x" & toHex(number), false)
template readJsonField(j: JsonNode, fieldName: string, ValueType: type): untyped =
var res: ValueType
fromJson(j[fieldName], fieldName, res)
res
proc depositEventsToBlocks(depositsList: JsonNode): seq[Eth1Block] =
proc depositEventsToBlocks(depositsList: JsonNode): seq[Eth1Block] {.
raises: [Defect, CatchableError].} =
if depositsList.kind != JArray:
raise newException(CatchableError,
"Web3 provider didn't return a list of deposit events")
@ -499,8 +508,6 @@ proc onBlockHeaders*(p: Web3DataProviderRef,
p.blockHeadersSubscription = awaitWithRetries(
p.web3.subscribeForBlockHeaders(blockHeaderHandler, errorHandler))
{.push raises: [Defect].}
func getDepositsRoot*(m: DepositsMerkleizer): Eth2Digest =
mixInLength(m.getFinalHash, int m.totalChunks)

View File

@ -5,13 +5,13 @@
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/tests/core/pyspec/eth2spec/utils/merkle_minimal.py
# Merkle tree helpers
# ---------------------------------------------------------------
{.push raises: [Defect].}
import
sequtils,
stew/endians2,

View File

@ -1,5 +1,5 @@
# beacon_chain
# Copyright (c) 2018-2020 Status Research & Development GmbH
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).

View File

@ -1,3 +1,12 @@
# beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import chronicles
import stew/io2
export io2

View File

@ -146,12 +146,7 @@ proc blockValidator*(
# sync, we don't lose the gossip blocks, but also don't block the gossip
# propagation of seemingly good blocks
trace "Block validated"
try:
self.verifQueues[].addBlock(SyncBlock(blk: signedBlock))
except Exception as e:
# Chronos can in theory raise an untyped exception in `internalCheckComplete`
# but in practice that's always a Defect not a Catchable exception
raiseAssert e.msg
self.verifQueues[].addBlock(SyncBlock(blk: signedBlock))
ValidationResult.Accept

View File

@ -5,6 +5,8 @@
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
std/math,
stew/results,
@ -76,8 +78,6 @@ type
consensusManager: ref ConsensusManager
## Blockchain DAG, AttestationPool and Quarantine
{.push raises: [Defect].}
# Initialization
# ------------------------------------------------------------------------------
@ -131,9 +131,7 @@ proc complete*(blk: SyncBlock, res: Result[void, BlockError]) =
# Enqueue
# ------------------------------------------------------------------------------
{.pop.}
proc addBlock*(self: var VerifQueueManager, syncBlock: SyncBlock) {.raises: [Exception].} =
proc addBlock*(self: var VerifQueueManager, syncBlock: SyncBlock) =
## Enqueue a Gossip-validated block for consensus verification
# Backpressure:
# If no item can be enqueued because buffer is full,
@ -143,19 +141,8 @@ proc addBlock*(self: var VerifQueueManager, syncBlock: SyncBlock) {.raises: [Exc
# - SyncManager (during sync)
# - RequestManager (missing ancestor blocks)
# TODO: solve the signature requiring raise: [Exception]
# even when push/pop is used
asyncSpawn(
try:
self.blocksQueue.addLast(BlockEntry(v: syncBlock))
except Exception as e:
# Chronos can in theory raise an untyped exception in `internalCheckComplete`
# which asyncSpawn doesn't like.
raiseAssert e.msg
)
{.push raises: [Defect].}
# addLast doesn't fail
asyncSpawn(self.blocksQueue.addLast(BlockEntry(v: syncBlock)))
proc addAttestation*(self: var VerifQueueManager, att: Attestation, att_indices: seq[ValidatorIndex]) =
## Enqueue a Gossip-validated attestation for consensus verification
@ -332,8 +319,6 @@ proc processBlock(self: var VerifQueueManager, entry: BlockEntry) =
if entry.v.resFut != nil:
entry.v.resFut.complete(Result[void, BlockError].err(res.error()))
{.pop.} # Chronos: Error: can raise an unlisted exception: ref Exception
proc runQueueProcessingLoop*(self: ref VerifQueueManager) {.async.} =
# Blocks in eth2 arrive on a schedule for every slot:
#

View File

@ -1,3 +1,10 @@
# beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import

View File

@ -1,3 +1,10 @@
# beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
@ -78,7 +85,7 @@ proc new*(T: type Eth2DiscoveryProtocol,
enrIp: Option[ValidIpAddress], enrTcpPort, enrUdpPort: Option[Port],
pk: PrivateKey,
enrFields: openArray[(string, seq[byte])], rng: ref BrHmacDrbgContext):
T {.raises: [Exception, Defect].} =
T =
# TODO
# Implement more configuration options:
# * for setting up a specific key

View File

@ -1,3 +1,12 @@
# beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
# Std lib
std/[typetraits, sequtils, os, algorithm, math, sets],
@ -162,7 +171,7 @@ type
OnPeerConnectedHandler* = proc(peer: Peer, incoming: bool): Future[void] {.gcsafe.}
OnPeerDisconnectedHandler* = proc(peer: Peer): Future[void] {.gcsafe, raises: [Defect].}
ThunkProc* = LPProtoHandler
MounterProc* = proc(network: Eth2Node) {.gcsafe.}
MounterProc* = proc(network: Eth2Node) {.gcsafe, raises: [Defect, CatchableError].}
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
@ -422,7 +431,8 @@ proc isSeen*(network: ETh2Node, peerId: PeerID): bool =
if peerId notin network.seenTable:
false
else:
let item = network.seenTable[peerId]
let item = try: network.seenTable[peerId]
except KeyError: raiseAssert "checked with notin"
if currentTime >= item.stamp:
# Peer is in SeenTable, but the time period has expired.
network.seenTable.del(peerId)
@ -473,10 +483,12 @@ proc getRequestProtoName(fn: NimNode): NimNode =
let pragmas = fn.pragma
if pragmas.kind == nnkPragma and pragmas.len > 0:
for pragma in pragmas:
if pragma.len > 0 and $pragma[0] == "libp2pProtocol":
let protoName = $(pragma[1])
let protoVer = $(pragma[2].intVal)
return newLit("/eth2/beacon_chain/req/" & protoName & "/" & protoVer & "/")
try:
if pragma.len > 0 and $pragma[0] == "libp2pProtocol":
let protoName = $(pragma[1])
let protoVer = $(pragma[2].intVal)
return newLit("/eth2/beacon_chain/req/" & protoName & "/" & protoVer & "/")
except Exception as exc: raiseAssert exc.msg # TODO https://github.com/nim-lang/Nim/issues/17454
return newLit("")
@ -485,13 +497,18 @@ proc writeChunk*(conn: Connection,
payload: Bytes): Future[void] =
var output = memoryOutput()
if responseCode.isSome:
output.write byte(responseCode.get)
try:
if responseCode.isSome:
output.write byte(responseCode.get)
output.write toBytes(payload.lenu64, Leb128).toOpenArray()
framingFormatCompress(output, payload)
conn.write(output.getOutput)
output.write toBytes(payload.lenu64, Leb128).toOpenArray()
framingFormatCompress(output, payload)
except IOError as exc:
raiseAssert exc.msg # memoryOutput shouldn't raise
try:
conn.write(output.getOutput)
except Exception as exc: # TODO fix libp2p
raiseAssert exc.msg
template errorMsgLit(x: static string): ErrorMsg =
const val = ErrorMsg toBytes(x)
@ -619,7 +636,7 @@ proc setEventHandlers(p: ProtocolInfo,
p.onPeerConnected = onPeerConnected
p.onPeerDisconnected = onPeerDisconnected
proc implementSendProcBody(sendProc: SendProc) =
proc implementSendProcBody(sendProc: SendProc) {.raises: [Exception].} =
let
msg = sendProc.msg
UntypedResponse = bindSym "UntypedResponse"
@ -950,7 +967,7 @@ proc runDiscoveryLoop*(node: Eth2Node) {.async.} =
# when no peers are in the routing table. Don't run it in continuous loop.
await sleepAsync(1.seconds)
proc getPersistentNetMetadata*(config: BeaconNodeConf): Eth2Metadata =
proc getPersistentNetMetadata*(config: BeaconNodeConf): Eth2Metadata {.raises: [Defect, IOError, SerializationError].} =
let metadataPath = config.dataDir / nodeMetadataFilename
if not fileExists(metadataPath):
result = Eth2Metadata()
@ -1098,7 +1115,7 @@ proc onConnEvent(node: Eth2Node, peerId: PeerID, event: ConnEvent) {.async.} =
proc new*(T: type Eth2Node, config: BeaconNodeConf, enrForkId: ENRForkID,
switch: Switch, pubsub: GossipSub, ip: Option[ValidIpAddress],
tcpPort, udpPort: Option[Port], privKey: keys.PrivateKey, discovery: bool,
rng: ref BrHmacDrbgContext): T =
rng: ref BrHmacDrbgContext): T {.raises: [Defect, CatchableError].} =
let
metadata = getPersistentNetMetadata(config)
when not defined(local_testnet):
@ -1141,12 +1158,15 @@ proc new*(T: type Eth2Node, config: BeaconNodeConf, enrForkId: ENRForkID,
if msg.protocolMounter != nil:
msg.protocolMounter node
proc peerHook(peerId: PeerID, event: ConnEvent): Future[void] {.gcsafe.} =
onConnEvent(node, peerId, event)
switch.addConnEventHandler(peerHook, ConnEventKind.Connected)
switch.addConnEventHandler(peerHook, ConnEventKind.Disconnected)
try:
switch.addConnEventHandler(peerHook, ConnEventKind.Connected)
switch.addConnEventHandler(peerHook, ConnEventKind.Disconnected)
except Exception as exc: # TODO fix libp2p, shouldn't happen
raiseAssert exc.msg
node
template publicKey*(node: Eth2Node): keys.PublicKey =
@ -1376,15 +1396,16 @@ proc getPersistentNetKeys*(rng: var BrHmacDrbgContext,
if res.isErr():
fatal "Could not generate random network key file"
quit QuitFailure
let privKey = res.get()
let pubKey = privKey.getKey().tryGet()
let pres = PeerID.init(pubKey)
let
privKey = res.get()
pubKey = privKey.getKey().expect("working public key from random")
pres = PeerID.init(pubKey)
if pres.isErr():
fatal "Could not obtain PeerID from network key"
quit QuitFailure
info "Generating new networking key", network_public_key = pubKey,
network_peer_id = $pres.get()
return NetKeyPair(seckey: privKey, pubkey: privKey.getKey().tryGet())
NetKeyPair(seckey: privKey, pubkey: pubKey)
else:
let keyPath =
if isAbsolute(config.netKeyFile):
@ -1406,11 +1427,12 @@ proc getPersistentNetKeys*(rng: var BrHmacDrbgContext,
if res.isNone():
fatal "Could not load network key file"
quit QuitFailure
let privKey = res.get()
let pubKey = privKey.getKey().tryGet()
let
privKey = res.get()
pubKey = privKey.getKey().expect("working public key from file")
info "Network key storage was successfully unlocked",
key_path = keyPath, network_public_key = pubKey
return NetKeyPair(seckey: privKey, pubkey: pubKey)
NetKeyPair(seckey: privKey, pubkey: pubKey)
else:
info "Network key storage is missing, creating a new one",
key_path = keyPath
@ -1419,8 +1441,9 @@ proc getPersistentNetKeys*(rng: var BrHmacDrbgContext,
fatal "Could not generate random network key file"
quit QuitFailure
let privKey = rres.get()
let pubKey = privKey.getKey().tryGet()
let
privKey = rres.get()
pubKey = privKey.getKey().expect("working public key from random")
# Insecure password used only for automated testing.
let insecurePassword =
@ -1436,7 +1459,7 @@ proc getPersistentNetKeys*(rng: var BrHmacDrbgContext,
info "New network key storage was created", key_path = keyPath,
network_public_key = pubKey
return NetKeyPair(seckey: privKey, pubkey: pubKey)
NetKeyPair(seckey: privKey, pubkey: pubKey)
of createTestnet:
if config.netKeyFile == "random":
@ -1454,8 +1477,9 @@ proc getPersistentNetKeys*(rng: var BrHmacDrbgContext,
fatal "Could not generate random network key file"
quit QuitFailure
let privKey = rres.get()
let pubKey = privKey.getKey().tryGet()
let
privKey = rres.get()
pubKey = privKey.getKey().expect("working public key from random")
# Insecure password used only for automated testing.
let insecurePassword =
@ -1472,15 +1496,17 @@ proc getPersistentNetKeys*(rng: var BrHmacDrbgContext,
info "New network key storage was created", key_path = keyPath,
network_public_key = pubKey
return NetKeyPair(seckey: privKey, pubkey: privkey.getKey().tryGet())
NetKeyPair(seckey: privKey, pubkey: pubKey)
else:
let res = PrivateKey.random(Secp256k1, rng)
if res.isErr():
fatal "Could not generate random network key file"
quit QuitFailure
let privKey = res.get()
return NetKeyPair(seckey: privKey, pubkey: privkey.getKey().tryGet())
let
privKey = res.get()
pubKey = privKey.getKey().expect("working public key from random")
NetKeyPair(seckey: privKey, pubkey: pubKey)
func gossipId(data: openArray[byte], valid: bool): seq[byte] =
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/p2p-interface.md#topics-and-messages
@ -1504,36 +1530,43 @@ func msgIdProvider(m: messages.Message): seq[byte] =
proc newBeaconSwitch*(config: BeaconNodeConf, seckey: PrivateKey,
address: MultiAddress,
rng: ref BrHmacDrbgContext): Switch =
proc createMplex(conn: Connection): Muxer =
Mplex.init(conn, inTimeout = 5.minutes, outTimeout = 5.minutes)
rng: ref BrHmacDrbgContext): Switch {.raises: [Defect, CatchableError].} =
try:
proc createMplex(conn: Connection): Muxer =
Mplex.init(conn, inTimeout = 5.minutes, outTimeout = 5.minutes)
let
peerInfo = PeerInfo.init(seckey, [address])
mplexProvider = newMuxerProvider(createMplex, MplexCodec)
transports = @[Transport(TcpTransport.init({ServerFlags.ReuseAddr}))]
muxers = {MplexCodec: mplexProvider}.toTable
secureManagers = [Secure(newNoise(rng, seckey))]
let
peerInfo = PeerInfo.init(seckey, [address])
mplexProvider = newMuxerProvider(createMplex, MplexCodec)
transports = @[Transport(TcpTransport.init({ServerFlags.ReuseAddr}))]
muxers = {MplexCodec: mplexProvider}.toTable
secureManagers = [Secure(newNoise(rng, seckey))]
peerInfo.agentVersion = config.agentString
peerInfo.agentVersion = config.agentString
let identify = newIdentify(peerInfo)
let identify = newIdentify(peerInfo)
newSwitch(
peerInfo,
transports,
identify,
muxers,
secureManagers,
maxConnections = config.maxPeers)
newSwitch(
peerInfo,
transports,
identify,
muxers,
secureManagers,
maxConnections = config.maxPeers)
except CatchableError as exc: raise exc
except Exception as exc: # TODO fix libp2p
if exc is Defect: raise (ref Defect)exc
raiseAssert exc.msg
proc createEth2Node*(rng: ref BrHmacDrbgContext,
config: BeaconNodeConf,
netKeys: NetKeyPair,
enrForkId: ENRForkID): Eth2Node =
enrForkId: ENRForkID): Eth2Node {.raises: [Defect, CatchableError].} =
var
(extIp, extTcpPort, extUdpPort) = setupAddress(config.nat,
config.listenAddress, config.tcpPort, config.udpPort, clientId)
(extIp, extTcpPort, extUdpPort) = try: setupAddress(
config.nat, config.listenAddress, config.tcpPort, config.udpPort, clientId)
except CatchableError as exc: raise exc
except Exception as exc: raiseAssert exc.msg
hostAddress = tcpEndPoint(config.listenAddress, config.tcpPort)
announcedAddresses = if extIp.isNone() or extTcpPort.isNone(): @[]
else: @[tcpEndPoint(extIp.get(), extTcpPort.get())]
@ -1590,7 +1623,7 @@ proc createEth2Node*(rng: ref BrHmacDrbgContext,
info "Adding priviledged direct peer", peerId, address = maddress
res
)
pubsub = GossipSub.init(
pubsub = try: GossipSub.init(
switch = switch,
msgIdProvider = msgIdProvider,
triggerSelf = true,
@ -1598,7 +1631,8 @@ proc createEth2Node*(rng: ref BrHmacDrbgContext,
verifySignature = false,
anonymize = true,
parameters = params)
except CatchableError as exc: raise exc
except Exception as exc: raiseAssert exc.msg # TODO fix libp2p
switch.mount(pubsub)
Eth2Node.new(config, enrForkId, switch, pubsub,
@ -1614,7 +1648,9 @@ proc announcedENR*(node: Eth2Node): enr.Record =
proc shortForm*(id: NetKeyPair): string =
$PeerID.init(id.pubkey)
proc subscribe*(node: Eth2Node, topic: string, topicParams: TopicParams, enableTopicMetrics: bool = false) =
proc subscribe*(
node: Eth2Node, topic: string, topicParams: TopicParams,
enableTopicMetrics: bool = false) {.raises: [Defect, CatchableError].} =
proc dummyMsgHandler(topic: string, data: seq[byte]) {.async.} =
discard
@ -1625,7 +1661,10 @@ proc subscribe*(node: Eth2Node, topic: string, topicParams: TopicParams, enableT
node.pubsub.knownTopics.incl(topicName)
node.pubsub.topicParams[topicName] = topicParams
node.pubsub.subscribe(topicName, dummyMsgHandler)
try:
node.pubsub.subscribe(topicName, dummyMsgHandler)
except CatchableError as exc: raise exc # TODO fix libp2p
except Exception as exc: raiseAssert exc.msg
proc setValidTopics*(node: Eth2Node, topics: openArray[string]) =
let topicsSnappy = topics.mapIt(it & "_snappy")
@ -1661,10 +1700,15 @@ proc addValidator*[MsgType](node: Eth2Node,
ValidationResult.Ignore
return res
node.pubsub.addValidator(topic & "_snappy", execValidator)
try:
node.pubsub.addValidator(topic & "_snappy", execValidator)
except Exception as exc: raiseAssert exc.msg # TODO fix libp2p
proc unsubscribe*(node: Eth2Node, topic: string) =
node.pubsub.unsubscribeAll(topic & "_snappy")
proc unsubscribe*(node: Eth2Node, topic: string) {.raises: [Defect, CatchableError].} =
try:
node.pubsub.unsubscribeAll(topic & "_snappy")
except CatchableError as exc: raise exc
except Exception as exc: raiseAssert exc.msg # TODO fix libp2p
proc traceMessage(fut: FutureBase, msgId: seq[byte]) =
fut.addCallback do (arg: pointer):
@ -1678,14 +1722,21 @@ proc traceMessage(fut: FutureBase, msgId: seq[byte]) =
msgId = byteutils.toHex(msgId), state = fut.state
proc broadcast*(node: Eth2Node, topic: string, msg: auto) =
let
uncompressed = SSZ.encode(msg)
compressed = snappy.encode(uncompressed)
try:
let
uncompressed = SSZ.encode(msg)
compressed = try: snappy.encode(uncompressed)
except InputTooLarge:
raiseAssert "More than 4gb? not likely.."
# This is only for messages we create. A message this large amounts to an
# internal logic error.
doAssert uncompressed.len <= GOSSIP_MAX_SIZE
inc nbc_gossip_messages_sent
# This is only for messages we create. A message this large amounts to an
# internal logic error.
doAssert uncompressed.len <= GOSSIP_MAX_SIZE
inc nbc_gossip_messages_sent
var futSnappy = node.pubsub.publish(topic & "_snappy", compressed)
traceMessage(futSnappy, gossipId(uncompressed, true))
var futSnappy = try: node.pubsub.publish(topic & "_snappy", compressed)
except Exception as exc:
raiseAssert exc.msg # TODO fix libp2p
traceMessage(futSnappy, gossipId(uncompressed, true))
except IOError as exc:
raiseAssert exc.msg # TODO in-memory compression shouldn't fail

View File

@ -1,23 +1,35 @@
import libp2p/daemon/daemonapi, json_serialization
# beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import libp2p/[peerid, multiaddress], json_serialization
export json_serialization
proc writeValue*(writer: var JsonWriter, value: PeerID) {.inline.} =
proc writeValue*(writer: var JsonWriter, value: PeerID) {.
raises: [Defect, IOError].} =
writer.writeValue $value
proc readValue*(reader: var JsonReader, value: var PeerID) {.inline.} =
proc readValue*(reader: var JsonReader, value: var PeerID) {.
raises: [Defect, IOError, SerializationError].} =
let res = PeerID.init reader.readValue(string)
if res.isOk:
value = res.get()
else:
raiseUnexpectedValue(reader, $res.error)
proc writeValue*(writer: var JsonWriter, value: MultiAddress) {.inline.} =
proc writeValue*(writer: var JsonWriter, value: MultiAddress) {.
raises: [Defect, IOError].} =
writer.writeValue $value
proc readValue*(reader: var JsonReader, value: var MultiAddress) {.inline.} =
proc readValue*(reader: var JsonReader, value: var MultiAddress) {.
raises: [Defect, IOError, SerializationError].} =
let res = MultiAddress.init reader.readValue(string)
if res.isOk:
value = res.value
else:
raiseUnexpectedValue(reader, $res.error)

View File

@ -1,9 +1,12 @@
# Copyright (c) 2020-2021 Status Research & Development GmbH
# beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
tables, strutils, os,
stew/shims/macros, nimcrypto/hash,
@ -23,8 +26,6 @@ import
# TODO(zah):
# We can compress the embedded states with snappy before embedding them here.
{.push raises: [Defect].}
export
ethtypes, conversions, RuntimePreset

View File

@ -1,3 +1,12 @@
# beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import std/[tables, heapqueue]
import chronos
@ -676,12 +685,12 @@ iterator acquiredPeers*[A, B](pool: PeerPool[A, B],
let pindex = sorted.pop().data
yield pool.storage[pindex].data
proc `[]`*[A, B](pool: PeerPool[A, B], key: B): A {.inline.} =
proc `[]`*[A, B](pool: PeerPool[A, B], key: B): A {.inline, raises: [Defect, KeyError].} =
## Retrieve peer with key ``key`` from PeerPool ``pool``.
let pindex = pool.registry[key]
pool.storage[pindex.data]
proc `[]`*[A, B](pool: var PeerPool[A, B], key: B): var A {.inline.} =
proc `[]`*[A, B](pool: var PeerPool[A, B], key: B): var A {.inline, raises: [Defect, KeyError].} =
## Retrieve peer with key ``key`` from PeerPool ``pool``.
let pindex = pool.registry[key]
pool.storage[pindex.data].data

View File

@ -5,6 +5,8 @@
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
# Standard library
std/[math, os, osproc, random, sequtils, strformat, strutils,
@ -31,7 +33,9 @@ import
beacon_clock, version],
./networking/[eth2_discovery, eth2_network, network_metadata],
./gossip_processing/[eth2_processor, gossip_to_consensus, consensus_manager],
./validators/[attestation_aggregation, validator_duties, validator_pool, slashing_protection, keystore_management],
./validators/[
attestation_aggregation, validator_duties, validator_pool,
slashing_protection, keystore_management],
./sync/[sync_manager, sync_protocol, request_manager],
./rpc/[beacon_api, config_api, debug_api, event_api, nimbus_api, node_api,
validator_api],
@ -93,7 +97,8 @@ proc init*(T: type BeaconNode,
depositContractDeployedAt: BlockHashOrNumber,
eth1Network: Option[Eth1Network],
genesisStateContents: string,
genesisDepositsSnapshotContents: string): BeaconNode =
genesisDepositsSnapshotContents: string): BeaconNode {.
raises: [Defect, CatchableError].} =
let
db = BeaconChainDB.init(runtimePreset, config.databaseDir)
@ -212,8 +217,8 @@ proc init*(T: type BeaconNode,
try:
ChainDAGRef.preInit(db, genesisState[], tailState[], tailBlock)
doAssert ChainDAGRef.isInitialized(db), "preInit should have initialized db"
except CatchableError as e:
error "Failed to initialize database", err = e.msg
except CatchableError as exc:
error "Failed to initialize database", err = exc.msg
quit 1
# Doesn't use std/random directly, but dependencies might
@ -298,7 +303,8 @@ proc init*(T: type BeaconNode,
slashingProtectionDB =
case config.slashingDbKind
of SlashingDbKind.v1:
info "Loading slashing protection database", path = config.validatorsDir()
info "Loading slashing protection database",
path = config.validatorsDir()
SlashingProtectionDB.init(
chainDag.headState.data.data.genesis_validators_root,
config.validatorsDir(), "slashing_protection",
@ -306,13 +312,15 @@ proc init*(T: type BeaconNode,
disagreementBehavior = kChooseV1
)
of SlashingDbKind.v2:
info "Loading slashing protection database (v2)", path = config.validatorsDir()
info "Loading slashing protection database (v2)",
path = config.validatorsDir()
SlashingProtectionDB.init(
chainDag.headState.data.data.genesis_validators_root,
config.validatorsDir(), "slashing_protection"
)
of SlashingDbKind.both:
info "Loading slashing protection database (dual DB mode)", path = config.validatorsDir()
info "Loading slashing protection database (dual DB mode)",
path = config.validatorsDir()
SlashingProtectionDB.init(
chainDag.headState.data.data.genesis_validators_root,
config.validatorsDir(), "slashing_protection",
@ -380,7 +388,9 @@ proc init*(T: type BeaconNode,
let cmd = getAppDir() / "nimbus_signing_process".addFileExt(ExeExt)
let args = [$res.config.validatorsDir, $res.config.secretsDir]
let workdir = io2.getCurrentDir().tryGet()
res.vcProcess = startProcess(cmd, workdir, args)
res.vcProcess = try: startProcess(cmd, workdir, args)
except CatchableError as exc: raise exc
except Exception as exc: raiseAssert exc.msg
res.addRemoteValidators()
# This merely configures the BeaconSync
@ -410,7 +420,8 @@ func verifyFinalization(node: BeaconNode, slot: Slot) =
# finalization occurs every slot, to 4 slots vs scheduledSlot.
doAssert finalizedEpoch + 4 >= epoch
proc installAttestationSubnetHandlers(node: BeaconNode, subnets: set[uint8]) =
proc installAttestationSubnetHandlers(node: BeaconNode, subnets: set[uint8]) {.
raises: [Defect, CatchableError].} =
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/p2p-interface.md#attestations-and-aggregation
# nimbus won't score attestation subnets for now, we just rely on block and aggregate which are more stabe and reliable
for subnet in subnets:
@ -651,9 +662,9 @@ proc getInitialAttestationSubnets(node: BeaconNode): Table[uint8, Slot] =
# Nimbus's Nim, use (_, _, subnetIndex, slot).
for (_, ci, subnetIndex, slot) in get_committee_assignments(
node.chainDag.headState.data.data, epoch, validatorIndices, cache):
if subnetIndex in result:
result[subnetIndex] = max(result[subnetIndex], slot + 1)
else:
result.withValue(subnetIndex, v) do:
v[] = max(v[], slot + 1)
do:
result[subnetIndex] = slot + 1
# Either wallEpoch is 0, in which case it might be pre-genesis, but we only
@ -664,7 +675,8 @@ proc getInitialAttestationSubnets(node: BeaconNode): Table[uint8, Slot] =
mergeAttestationSubnets(wallEpoch)
mergeAttestationSubnets(wallEpoch + 1)
proc getAttestationSubnetHandlers(node: BeaconNode) =
proc getAttestationSubnetHandlers(node: BeaconNode) {.
raises: [Defect, CatchableError].} =
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/validator.md#phase-0-attestation-subnet-stability
# TODO:
# We might want to reuse the previous stability subnet if not expired when:
@ -705,7 +717,8 @@ proc getAttestationSubnetHandlers(node: BeaconNode) =
for i in 0'u8 ..< ATTESTATION_SUBNET_COUNT:
if i in initialSubnets:
node.attestationSubnets.subscribedSubnets.incl i
node.attestationSubnets.unsubscribeSlot[i] = initialSubnets[i]
node.attestationSubnets.unsubscribeSlot[i] =
try: initialSubnets[i] except KeyError: raiseAssert "checked with in"
else:
node.attestationSubnets.subscribedSubnets.excl i
node.attestationSubnets.subscribeSlot[i] = FAR_FUTURE_SLOT
@ -719,7 +732,7 @@ proc getAttestationSubnetHandlers(node: BeaconNode) =
node.installAttestationSubnetHandlers(
node.attestationSubnets.subscribedSubnets + initialStabilitySubnets)
proc addMessageHandlers(node: BeaconNode) =
proc addMessageHandlers(node: BeaconNode) {.raises: [Defect, CatchableError].} =
# inspired by lighthouse research here
# https://gist.github.com/blacktemplar/5c1862cb3f0e32a1a7fb0b25e79e6e2c#file-generate-scoring-params-py
const
@ -779,7 +792,7 @@ proc addMessageHandlers(node: BeaconNode) =
func getTopicSubscriptionEnabled(node: BeaconNode): bool =
node.attestationSubnets.enabled
proc removeMessageHandlers(node: BeaconNode) =
proc removeMessageHandlers(node: BeaconNode) {.raises: [Defect, CatchableError].} =
node.attestationSubnets.enabled = false
doAssert not node.getTopicSubscriptionEnabled()
@ -809,7 +822,7 @@ proc setupDoppelgangerDetection(node: BeaconNode, slot: Slot) =
broadcastStartEpoch =
node.processor.doppelgangerDetection.broadcastStartEpoch
proc updateGossipStatus(node: BeaconNode, slot: Slot) =
proc updateGossipStatus(node: BeaconNode, slot: Slot) {.raises: [Defect, CatchableError].} =
# Syncing tends to be ~1 block/s, and allow for an epoch of time for libp2p
# subscribing to spin up. The faster the sync, the more wallSlot - headSlot
# lead time is required
@ -1142,13 +1155,15 @@ func connectedPeersCount(node: BeaconNode): int =
len(node.network.peerPool)
proc installRpcHandlers(rpcServer: RpcServer, node: BeaconNode) =
rpcServer.installBeaconApiHandlers(node)
rpcServer.installConfigApiHandlers(node)
rpcServer.installDebugApiHandlers(node)
rpcServer.installEventApiHandlers(node)
rpcServer.installNimbusApiHandlers(node)
rpcServer.installNodeApiHandlers(node)
rpcServer.installValidatorApiHandlers(node)
try:
rpcServer.installBeaconApiHandlers(node)
rpcServer.installConfigApiHandlers(node)
rpcServer.installDebugApiHandlers(node)
rpcServer.installEventApiHandlers(node)
rpcServer.installNimbusApiHandlers(node)
rpcServer.installNodeApiHandlers(node)
rpcServer.installValidatorApiHandlers(node)
except Exception as exc: raiseAssert exc.msg # TODO fix json-rpc
proc installMessageValidators(node: BeaconNode) =
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/p2p-interface.md#attestations-and-aggregation
@ -1192,13 +1207,20 @@ proc stop*(node: BeaconNode) =
bnStatus = BeaconNodeStatus.Stopping
notice "Graceful shutdown"
if not node.config.inProcessValidators:
node.vcProcess.close()
waitFor node.network.stop()
try:
node.vcProcess.close()
except Exception as exc:
warn "Couldn't close vc process", msg = exc.msg
try:
waitFor node.network.stop()
except CatchableError as exc:
warn "Couldn't stop network", msg = exc.msg
node.attachedValidators.slashingProtection.close()
node.db.close()
notice "Databases closed"
proc run*(node: BeaconNode) =
proc run*(node: BeaconNode) {.raises: [Defect, CatchableError].} =
if bnStatus == BeaconNodeStatus.Starting:
# it might have been set to "Stopping" with Ctrl+C
bnStatus = BeaconNodeStatus.Running
@ -1226,10 +1248,16 @@ proc run*(node: BeaconNode) =
proc controlCHandler() {.noconv.} =
when defined(windows):
# workaround for https://github.com/nim-lang/Nim/issues/4057
setupForeignThreadGc()
try:
setupForeignThreadGc()
except Exception as exc: raiseAssert exc.msg # shouldn't happen
notice "Shutting down after having received SIGINT"
bnStatus = BeaconNodeStatus.Stopping
setControlCHook(controlCHandler)
try:
setControlCHook(controlCHandler)
except Exception as exc: # TODO Exception
warn "Cannot set ctrl-c handler", msg = exc.msg
# equivalent SIGTERM handler
when defined(posix):
proc SIGTERMHandler(signal: cint) {.noconv.} =
@ -1239,16 +1267,13 @@ proc run*(node: BeaconNode) =
# main event loop
while bnStatus == BeaconNodeStatus.Running:
try:
poll()
except CatchableError as e:
debug "Exception in poll()", exc = e.name, err = e.msg
poll() # if poll fails, the network is broken
# time to say goodbye
node.stop()
var gPidFile: string
proc createPidFile(filename: string) =
proc createPidFile(filename: string) {.raises: [Defect, IOError].} =
writeFile filename, $os.getCurrentProcessId()
gPidFile = filename
addQuitProc proc {.noconv.} = discard io2.removeFile(gPidFile)
@ -1266,7 +1291,7 @@ func shouldWeStartWeb3(node: BeaconNode): bool =
(node.config.web3Mode == Web3Mode.enabled) or
(node.config.web3Mode == Web3Mode.auto and node.attachedValidators[].count > 0)
proc start(node: BeaconNode) =
proc start(node: BeaconNode) {.raises: [Defect, CatchableError].} =
let
head = node.chainDag.head
finalizedHead = node.chainDag.finalizedHead
@ -1315,11 +1340,14 @@ func formatGwei(amount: uint64): string =
while result[^1] == '0':
result.setLen(result.len - 1)
proc initStatusBar(node: BeaconNode) =
proc initStatusBar(node: BeaconNode) {.raises: [Defect, ValueError].} =
if not isatty(stdout): return
if not node.config.statusBarEnabled: return
enableTrueColors()
try:
enableTrueColors()
except Exception as exc: # TODO Exception
error "Couldn't enable colors", err = exc.msg
proc dataResolver(expr: string): string {.raises: [Defect].} =
template justified: untyped = node.chainDag.head.atEpochStart(
@ -1595,7 +1623,7 @@ proc handleValidatorExitCommand(config: BeaconNodeConf) {.async.} =
err = err.msg
quit 1
proc loadEth2Network(config: BeaconNodeConf): Eth2NetworkMetadata =
proc loadEth2Network(config: BeaconNodeConf): Eth2NetworkMetadata {.raises: [Defect, IOError].} =
if config.eth2Network.isSome:
getMetadataForNetwork(config.eth2Network.get)
else:
@ -1607,7 +1635,8 @@ proc loadEth2Network(config: BeaconNodeConf): Eth2NetworkMetadata =
echo "Must specify network on non-mainnet node"
quit 1
proc loadBeaconNode(config: var BeaconNodeConf, rng: ref BrHmacDrbgContext): BeaconNode =
proc loadBeaconNode(config: var BeaconNodeConf, rng: ref BrHmacDrbgContext): BeaconNode {.
raises: [Defect, CatchableError].} =
let metadata = config.loadEth2Network()
# Updating the config based on the metadata certainly is not beautiful but it
@ -1625,7 +1654,7 @@ proc loadBeaconNode(config: var BeaconNodeConf, rng: ref BrHmacDrbgContext): Bea
metadata.genesisData,
metadata.genesisDepositsSnapshot)
proc doRunBeaconNode(config: var BeaconNodeConf, rng: ref BrHmacDrbgContext) =
proc doRunBeaconNode(config: var BeaconNodeConf, rng: ref BrHmacDrbgContext) {.raises: [Defect, CatchableError].} =
info "Launching beacon node",
version = fullVersionStr,
bls_backend = $BLS_BACKEND,
@ -1641,7 +1670,10 @@ proc doRunBeaconNode(config: var BeaconNodeConf, rng: ref BrHmacDrbgContext) =
let metricsAddress = config.metricsAddress
notice "Starting metrics HTTP server",
url = "http://" & $metricsAddress & ":" & $config.metricsPort & "/metrics"
startMetricsHttpServer($metricsAddress, config.metricsPort)
try:
startMetricsHttpServer($metricsAddress, config.metricsPort)
except CatchableError as exc: raise exc
except Exception as exc: raiseAssert exc.msg # TODO fix metrics
else:
warn "Metrics support disabled, see https://status-im.github.io/nimbus-eth2/metrics-pretty-pictures.html#simple-metrics"
@ -1663,7 +1695,7 @@ proc doRunBeaconNode(config: var BeaconNodeConf, rng: ref BrHmacDrbgContext) =
else:
node.start()
proc doCreateTestnet(config: BeaconNodeConf, rng: var BrHmacDrbgContext) =
proc doCreateTestnet(config: BeaconNodeConf, rng: var BrHmacDrbgContext) {.raises: [Defect, CatchableError].} =
let launchPadDeposits = try:
Json.loadFile(config.testnetDepositsFile.string, seq[LaunchPadDeposit])
except SerializationError as err:
@ -1716,7 +1748,8 @@ proc doCreateTestnet(config: BeaconNodeConf, rng: var BrHmacDrbgContext) =
writeFile(bootstrapFile, bootstrapEnr.tryGet().toURI)
echo "Wrote ", bootstrapFile
proc doDeposits(config: BeaconNodeConf, rng: var BrHmacDrbgContext) =
proc doDeposits(config: BeaconNodeConf, rng: var BrHmacDrbgContext) {.
raises: [Defect, CatchableError].} =
case config.depositsCmd
#[
of DepositsCmd.create:
@ -1823,7 +1856,8 @@ proc doDeposits(config: BeaconNodeConf, rng: var BrHmacDrbgContext) =
of DepositsCmd.exit:
waitFor handleValidatorExitCommand(config)
proc doWallets(config: BeaconNodeConf, rng: var BrHmacDrbgContext) =
proc doWallets(config: BeaconNodeConf, rng: var BrHmacDrbgContext) {.
raises: [Defect, CatchableError].} =
template findWalletWithoutErrors(name: WalletName): auto =
let res = keystore_management.findWallet(config, name)
if res.isErr:
@ -1864,7 +1898,8 @@ proc doWallets(config: BeaconNodeConf, rng: var BrHmacDrbgContext) =
of WalletsCmd.restore:
restoreWalletInteractively(rng, config)
proc doRecord(config: BeaconNodeConf, rng: var BrHmacDrbgContext) =
proc doRecord(config: BeaconNodeConf, rng: var BrHmacDrbgContext) {.
raises: [Defect, CatchableError].} =
case config.recordCmd:
of RecordCmd.create:
let netKeys = getPersistentNetKeys(rng, config)
@ -1891,13 +1926,14 @@ proc doRecord(config: BeaconNodeConf, rng: var BrHmacDrbgContext) =
of RecordCmd.print:
echo $config.recordPrint
proc doWeb3Cmd(config: BeaconNodeConf) =
proc doWeb3Cmd(config: BeaconNodeConf) {.raises: [Defect, CatchableError].} =
case config.web3Cmd:
of Web3Cmd.test:
let metadata = config.loadEth2Network()
waitFor testWeb3Provider(config.web3TestUrl,
metadata.depositContractAddress)
{.pop.} # TODO moduletests exceptions
programMain:
var
config = makeBannerAndConfig(clientId, BeaconNodeConf)

View File

@ -5,6 +5,8 @@
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
# Common routines for a BeaconNode and a ValidatorClient
import
@ -32,7 +34,7 @@ proc setupStdoutLogging*(logLevel: string) =
except IOError as err:
logLoggingFailure(cstring(msg), err)
proc updateLogLevel*(logLevel: string) =
proc updateLogLevel*(logLevel: string) {.raises: [Defect, ValueError].} =
# Updates log levels (without clearing old ones)
let directives = logLevel.split(";")
try:
@ -58,15 +60,22 @@ proc setupLogging*(logLevel: string, logFile: Option[OutFile]) =
path = logFileDir, err = ioErrorMsg(lres.error)
break openLogFile
if not defaultChroniclesStream.outputs[1].open(logFile):
error "Failed to create log file", logFile
try:
if not defaultChroniclesStream.outputs[1].open(logFile):
error "Failed to create log file", logFile
except CatchableError as exc:
# TODO why is there both exception and bool?
error "Failed to create log file", logFile, msg = exc.msg
else:
warn "The --log-file option is not active in the current build"
try:
updateLogLevel(logLevel)
except ValueError as err:
stderr.write "Invalid value for --log-level. " & err.msg
try:
stderr.write "Invalid value for --log-level. " & err.msg
except IOError as exc:
echo "Invalid value for --log-level. " & err.msg
quit 1
template makeBannerAndConfig*(clientId: string, ConfType: type): untyped =

View File

@ -1,10 +1,12 @@
# beacon_chain
# Copyright (c) 2018-2020 Status Research & Development GmbH
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
# Standard library
os, strutils, tables,
@ -13,6 +15,8 @@ import
./spec/[digest, crypto],
./validators/keystore_management
{.pop.} # TODO moduletests exceptions
programMain:
var validators: Table[ValidatorPubKey, ValidatorPrivKey]
# load and send all public keys so the BN knows for which ones to ping us

View File

@ -5,6 +5,8 @@
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
# Standard library
std/[os, json, random, strutils],
@ -275,6 +277,8 @@ proc onSlotStart(vc: ValidatorClient, lastSlot, scheduledSlot: Slot) {.gcsafe, a
addTimer(nextSlotStart) do (p: pointer):
asyncCheck vc.onSlotStart(slot, nextSlot)
{.pop.} # TODO moduletests exceptions
programMain:
let config = makeBannerAndConfig("Nimbus validator client " & fullVersionStr, ValidatorClientConf)

View File

@ -1,9 +1,12 @@
# Copyright (c) 2018-2020 Status Research & Development GmbH
# beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
std/[parseutils, sequtils, strutils, deques, sets],
stew/results,
@ -35,7 +38,7 @@ type
template unimplemented() =
raise (ref CatchableError)(msg: "Unimplemented")
proc parsePubkey(str: string): ValidatorPubKey =
proc parsePubkey(str: string): ValidatorPubKey {.raises: [Defect, ValueError].} =
const expectedLen = RawPubKeySize * 2 + 2
if str.len != expectedLen: # +2 because of the `0x` prefix
raise newException(ValueError,
@ -43,7 +46,7 @@ proc parsePubkey(str: string): ValidatorPubKey =
$str.len & " provided")
let pubkeyRes = fromHex(ValidatorPubKey, str)
if pubkeyRes.isErr:
raise newException(CatchableError, "Not a valid public key")
raise newException(ValueError, "Not a valid public key")
return pubkeyRes[]
proc createIdQuery(ids: openArray[string]): Result[ValidatorQuery, string] =
@ -71,8 +74,11 @@ proc createIdQuery(ids: openArray[string]): Result[ValidatorQuery, string] =
res.keyset.incl(pubkeyRes.get())
else:
var tmp: uint64
if parseBiggestUInt(item, tmp) != len(item):
return err("Incorrect index value")
try:
if parseBiggestUInt(item, tmp) != len(item):
return err("Incorrect index value")
except ValueError:
return err("Cannot parse index value: " & item)
res.ids.add(tmp)
ok(res)
@ -151,7 +157,7 @@ proc getStatus(validator: Validator,
else:
err("Invalid validator status")
proc getBlockDataFromBlockId(node: BeaconNode, blockId: string): BlockData =
proc getBlockDataFromBlockId(node: BeaconNode, blockId: string): BlockData {.raises: [Defect, CatchableError].} =
result = case blockId:
of "head":
node.chainDag.get(node.chainDag.head)
@ -172,7 +178,8 @@ proc getBlockDataFromBlockId(node: BeaconNode, blockId: string): BlockData =
raise newException(CatchableError, "Block not found")
node.chainDag.get(blockSlot.blck)
proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) =
proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {.
raises: [Exception].} = # TODO fix json-rpc
rpcServer.rpc("get_v1_beacon_genesis") do () -> BeaconGenesisTuple:
return (
genesis_time: node.chainDag.headState.data.data.genesis_time,

View File

@ -1,9 +1,12 @@
# Copyright (c) 2018-2020 Status Research & Development GmbH
# beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
stew/endians2,
json_rpc/[rpcserver, jsonmarshal],
@ -27,7 +30,8 @@ func getDepositAddress(node: BeaconNode): string =
else:
$node.eth1Monitor.depositContractAddress
proc installConfigApiHandlers*(rpcServer: RpcServer, node: BeaconNode) =
proc installConfigApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {.
raises: [Exception].} = # TODO fix json-rpc
rpcServer.rpc("get_v1_config_fork_schedule") do () -> seq[Fork]:
return @[node.chainDag.headState.data.data.fork]

View File

@ -1,3 +1,12 @@
# beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
std/sequtils,
json_rpc/[rpcserver, jsonmarshal],
@ -12,7 +21,8 @@ logScope: topics = "debugapi"
type
RpcServer = RpcHttpServer
proc installDebugApiHandlers*(rpcServer: RpcServer, node: BeaconNode) =
proc installDebugApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {.
raises: [Exception].} = # TODO fix json-rpc
rpcServer.rpc("get_v1_debug_beacon_states_stateId") do (
stateId: string) -> BeaconState:
withStateForStateId(stateId):

View File

@ -1,3 +1,12 @@
# beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
# Standard library
std/[tables, json, typetraits],
@ -14,7 +23,7 @@ proc toJsonHex(data: openArray[byte]): string =
# Per the eth2 API spec, hex arrays are printed with leading 0x
"0x" & toHex(data)
proc fromJson*(n: JsonNode, argName: string, result: var ValidatorPubKey) =
proc fromJson*(n: JsonNode, argName: string, result: var ValidatorPubKey) {.raises: [Defect, ValueError].} =
n.kind.expect(JString, argName)
var tmp = ValidatorPubKey.fromHex(n.getStr()).tryGet()
if not tmp.loadWithCache().isSome():
@ -24,33 +33,33 @@ proc fromJson*(n: JsonNode, argName: string, result: var ValidatorPubKey) =
proc `%`*(pubkey: ValidatorPubKey): JsonNode =
newJString(toJsonHex(toRaw(pubkey)))
proc fromJson*(n: JsonNode, argName: string, result: var List) =
proc fromJson*(n: JsonNode, argName: string, result: var List) {.raises: [Defect, ValueError].} =
fromJson(n, argName, asSeq result)
proc `%`*(list: List): JsonNode = %(asSeq(list))
proc fromJson*(n: JsonNode, argName: string, result: var BitList) =
proc fromJson*(n: JsonNode, argName: string, result: var BitList) {.raises: [Defect, ValueError].} =
n.kind.expect(JString, argName)
result = type(result)(hexToSeqByte(n.getStr()))
proc `%`*(bitlist: BitList): JsonNode =
newJString(toJsonHex(seq[byte](BitSeq(bitlist))))
proc fromJson*(n: JsonNode, argName: string, result: var ValidatorSig) =
proc fromJson*(n: JsonNode, argName: string, result: var ValidatorSig) {.raises: [Defect, ValueError].} =
n.kind.expect(JString, argName)
result = ValidatorSig.fromHex(n.getStr()).tryGet()
proc `%`*(value: ValidatorSig): JsonNode =
newJString(toJsonHex(toRaw(value)))
proc fromJson*(n: JsonNode, argName: string, result: var TrustedSig) =
proc fromJson*(n: JsonNode, argName: string, result: var TrustedSig) {.raises: [Defect, ValueError].} =
n.kind.expect(JString, argName)
hexToByteArray(n.getStr(), result.data)
proc `%`*(value: TrustedSig): JsonNode =
newJString(toJsonHex(toRaw(value)))
proc fromJson*(n: JsonNode, argName: string, result: var Version) =
proc fromJson*(n: JsonNode, argName: string, result: var Version) {.raises: [Defect, ValueError].} =
n.kind.expect(JString, argName)
hexToByteArray(n.getStr(), array[4, byte](result))
@ -58,7 +67,7 @@ proc `%`*(value: Version): JsonNode =
newJString(toJsonHex(distinctBase(value)))
template genFromJsonForIntType(T: untyped) =
proc fromJson*(n: JsonNode, argName: string, result: var T) =
proc fromJson*(n: JsonNode, argName: string, result: var T) {.raises: [Defect, ValueError].} =
n.kind.expect(JInt, argName)
let asInt = n.getBiggestInt()
when T is Epoch:
@ -86,7 +95,7 @@ genFromJsonForIntType(ValidatorIndex)
proc `%`*(value: GraffitiBytes): JsonNode =
newJString(toJsonHex(distinctBase(value)))
proc fromJson*(n: JsonNode, argName: string, value: var GraffitiBytes) =
proc fromJson*(n: JsonNode, argName: string, value: var GraffitiBytes) {.raises: [Defect, ValueError].} =
n.kind.expect(JString, argName)
value = GraffitiBytes.init n.getStr()
@ -99,13 +108,13 @@ proc `%`*(value: ValidatorIndex): JsonNode =
proc `%`*(value: Eth2Digest): JsonNode =
newJString(toJsonHex(value.data))
proc fromJson*(n: JsonNode, argName: string, result: var Eth2Digest) =
proc fromJson*(n: JsonNode, argName: string, result: var Eth2Digest) {.raises: [Defect, ValueError].} =
n.kind.expect(JString, argName)
hexToByteArray(n.getStr(), result.data)
proc `%`*(value: BitSeq): JsonNode =
newJString(toJsonHex(value.bytes))
proc fromJson*(n: JsonNode, argName: string, result: var BitSeq) =
proc fromJson*(n: JsonNode, argName: string, result: var BitSeq) {.raises: [Defect, ValueError].} =
n.kind.expect(JString, argName)
result = BitSeq(hexToSeqByte(n.getStr()))

View File

@ -1,9 +1,12 @@
# Copyright (c) 2018-2020 Status Research & Development GmbH
# beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
json_rpc/[rpcserver, jsonmarshal],
chronicles,
@ -17,6 +20,7 @@ type
template unimplemented() =
raise (ref CatchableError)(msg: "Unimplemented")
proc installEventApiHandlers*(rpcServer: RpcServer, node: BeaconNode) =
proc installEventApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {.
raises: [Exception].} = # TODO fix json-rpc
rpcServer.rpc("get_v1_events") do () -> JsonNode:
unimplemented()

View File

@ -1,9 +1,12 @@
# beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
std/[deques, sequtils, sets],
chronos,
@ -32,7 +35,8 @@ type
line*: int
state*: string
proc installNimbusApiHandlers*(rpcServer: RpcServer, node: BeaconNode) =
proc installNimbusApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {.
raises: [Exception].} = # TODO fix json-rpc
## Install non-standard api handlers - some of these are used by 3rd-parties
## such as eth2stats, pending a full REST api
rpcServer.rpc("getBeaconHead") do () -> Slot:

View File

@ -1,3 +1,12 @@
# beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import std/options,
chronicles,
json_rpc/[rpcserver, jsonmarshal],
@ -142,7 +151,8 @@ proc getP2PAddresses(node: BeaconNode): Option[seq[string]] =
addresses.add($(resa.get()))
return some(addresses)
proc installNodeApiHandlers*(rpcServer: RpcServer, node: BeaconNode) =
proc installNodeApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {.
raises: [Exception].} = # TODO fix json-rpc
rpcServer.rpc("get_v1_node_identity") do () -> NodeIdentityTuple:
let discoveryAddresses =
block:

View File

@ -1,3 +1,12 @@
# beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
std/[strutils, parseutils],
stew/byteutils,
@ -26,16 +35,16 @@ template withStateForStateId*(stateId: string, body: untyped): untyped =
proc toBlockSlot*(blckRef: BlockRef): BlockSlot =
blckRef.atSlot(blckRef.slot)
proc parseRoot*(str: string): Eth2Digest =
return Eth2Digest(data: hexToByteArray[32](str))
proc parseRoot*(str: string): Eth2Digest {.raises: [Defect, ValueError].} =
Eth2Digest(data: hexToByteArray[32](str))
func checkEpochToSlotOverflow*(epoch: Epoch) =
func checkEpochToSlotOverflow*(epoch: Epoch) {.raises: [Defect, ValueError].} =
const maxEpoch = compute_epoch_at_slot(not 0'u64)
if epoch >= maxEpoch:
raise newException(
ValueError, "Requesting epoch for which slot would overflow")
proc doChecksAndGetCurrentHead*(node: BeaconNode, slot: Slot): BlockRef =
proc doChecksAndGetCurrentHead*(node: BeaconNode, slot: Slot): BlockRef {.raises: [Defect, CatchableError].} =
result = node.chainDag.head
if not node.isSynced(result):
raise newException(CatchableError, "Cannot fulfill request until node is synced")
@ -43,11 +52,11 @@ proc doChecksAndGetCurrentHead*(node: BeaconNode, slot: Slot): BlockRef =
if result.slot + uint64(2 * SLOTS_PER_EPOCH) < slot:
raise newException(CatchableError, "Requesting way ahead of the current head")
proc doChecksAndGetCurrentHead*(node: BeaconNode, epoch: Epoch): BlockRef =
proc doChecksAndGetCurrentHead*(node: BeaconNode, epoch: Epoch): BlockRef {.raises: [Defect, CatchableError].} =
checkEpochToSlotOverflow(epoch)
node.doChecksAndGetCurrentHead(epoch.compute_start_slot_at_epoch)
proc getBlockSlotFromString*(node: BeaconNode, slot: string): BlockSlot =
proc getBlockSlotFromString*(node: BeaconNode, slot: string): BlockSlot {.raises: [Defect, CatchableError].} =
if slot.len == 0:
raise newException(ValueError, "Empty slot number not allowed")
var parsed: BiggestUInt
@ -56,7 +65,7 @@ proc getBlockSlotFromString*(node: BeaconNode, slot: string): BlockSlot =
let head = node.doChecksAndGetCurrentHead(parsed.Slot)
return head.atSlot(parsed.Slot)
proc stateIdToBlockSlot*(node: BeaconNode, stateId: string): BlockSlot =
proc stateIdToBlockSlot*(node: BeaconNode, stateId: string): BlockSlot {.raises: [Defect, CatchableError].} =
result = case stateId:
of "head":
node.chainDag.head.toBlockSlot()

View File

@ -5,6 +5,8 @@
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
# Standard library
std/[tables],
@ -29,7 +31,8 @@ logScope: topics = "valapi"
type
RpcServer* = RpcHttpServer
proc installValidatorApiHandlers*(rpcServer: RpcServer, node: BeaconNode) =
proc installValidatorApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {.
raises: [Exception].} = # TODO fix json-rpc
rpcServer.rpc("get_v1_validator_block") do (
slot: Slot, graffiti: GraffitiBytes, randao_reveal: ValidatorSig) -> BeaconBlock:
debug "get_v1_validator_block", slot = slot

View File

@ -1,10 +1,12 @@
# beacon_chain
# Copyright (c) 2018-2020 Status Research & Development GmbH
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
std/[typetraits],
../spec/[crypto, digest]

View File

@ -5,9 +5,7 @@
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
# TODO Cannot override push, even though the function is annotated
# nimbus-eth2/beacon_chain/ssz.nim(212, 18) Error: can raise an unlisted exception: IOError
# {.push raises: [Defect].}
{.push raises: [Defect].}
{.pragma: raisesssz, raises: [Defect, MalformedSszError, SszSizeMismatchError].}
## SSZ serialization for core SSZ types, as specified in:
@ -91,7 +89,7 @@ template supports*(_: type SSZ, T: type): bool =
func init*(T: type SszWriter, stream: OutputStream): T {.raises: [Defect].} =
result.stream = stream
proc writeVarSizeType(w: var SszWriter, value: auto) {.gcsafe.}
proc writeVarSizeType(w: var SszWriter, value: auto) {.gcsafe, raises: [Defect, IOError].}
proc beginRecord*(w: var SszWriter, TT: type): auto {.raises: [Defect].} =
type T = TT

View File

@ -1,3 +1,10 @@
# beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import

View File

@ -1,3 +1,10 @@
# beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import

View File

@ -1,3 +1,12 @@
# beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import options, sequtils, strutils
import chronos, chronicles
import ../spec/[datatypes, digest],
@ -168,4 +177,6 @@ proc fetchAncestorBlocks*(rman: RequestManager, roots: seq[FetchRecord]) =
## Enqueue list missing blocks roots ``roots`` for download by
## Request Manager ``rman``.
for item in roots:
rman.inpQueue.addLastNoWait(item)
try:
rman.inpQueue.addLastNoWait(item)
except AsyncQueueFullError: raiseAssert "unbounded queue"

View File

@ -1,3 +1,12 @@
# beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import chronicles
import options, deques, heapqueue, tables, strutils, sequtils, math, algorithm
import stew/results, chronos, chronicles

View File

@ -1,3 +1,12 @@
# beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
options, tables, sets, macros,
chronicles, chronos, stew/ranges/bitranges, libp2p/switch,
@ -87,6 +96,7 @@ proc handleStatus(peer: Peer,
proc setStatusMsg(peer: Peer, statusMsg: StatusMsg) {.gcsafe.}
{.pop.} # TODO fix p2p macro for raises
p2pProtocol BeaconSync(version = 1,
networkState = BeaconSyncNetworkState,
peerState = BeaconSyncPeerState):

View File

@ -1,3 +1,12 @@
# beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
std/[os, strutils, terminal, wordwrap, unicode],
chronicles, chronos, web3, stint, json_serialization, zxcvbn,
@ -14,7 +23,6 @@ export
when defined(windows):
import stew/[windows/acl]
{.push raises: [Defect].}
{.localPassC: "-fno-lto".} # no LTO for crypto
const

View File

@ -1,10 +1,13 @@
# beacon_chain
# Copyright (c) 2018-2020 Status Research & Development GmbH
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
# TODO doesn't work with concepts (sigh)
# {.push raises: [Defect].}
import
# stdlib
std/os,

View File

@ -1,10 +1,12 @@
# beacon_chain
# Copyright (c) 2018-2020 Status Research & Development GmbH
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
# Stdlib
std/[typetraits, strutils, algorithm],
@ -265,7 +267,7 @@ proc readValue*(r: var JsonReader, a: var (SlotString or EpochString))
proc exportSlashingInterchange*(
db: SlashingProtectionDB_Concept,
path: string, prettify = true) =
path: string, prettify = true) {.raises: [Defect, IOError].} =
## Export a database to the Slashing Protection Database Interchange Format
let spdir = db.toSPDIR()
Json.saveFile(path, spdir, prettify)
@ -273,7 +275,7 @@ proc exportSlashingInterchange*(
proc importSlashingInterchange*(
db: SlashingProtectionDB_Concept,
path: string): SlashingImportStatus =
path: string): SlashingImportStatus {.raises: [Defect, IOError, SerializationError].} =
## Import a Slashing Protection Database Interchange Format
## into a Nimbus DB.
## This adds data to already existing data.

View File

@ -5,6 +5,8 @@
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
# Standard library
std/[tables, os],

View File

@ -5,6 +5,8 @@
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
# Standard library
std/[os, options, typetraits, decls],

View File

@ -5,6 +5,8 @@
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
# Standard library
std/[os, osproc, sequtils, streams, tables],
@ -75,7 +77,7 @@ proc addLocalValidators*(node: BeaconNode) =
for validatorKey in node.config.validatorKeys:
node.addLocalValidator node.chainDag.headState.data.data, validatorKey
proc addRemoteValidators*(node: BeaconNode) =
proc addRemoteValidators*(node: BeaconNode) {.raises: [Defect, OSError, IOError].} =
# load all the validators from the child process - loop until `end`
var line = newStringOfCap(120).TaintedString
while line != "end" and running(node.vcProcess):

View File

@ -1,3 +1,12 @@
# beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
std/[tables, json, streams],
chronos, chronicles, metrics,

View File

@ -1,3 +1,10 @@
# beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import strutils

2
vendor/nim-chronos vendored

@ -1 +1 @@
Subproject commit 4abd7a56450db8eb6578a151af0a5b7ba61bd2bf
Subproject commit e08deb47c2b1a64d771c9f13eb7cfc7d691c436d