Skip to content
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

LibP2P network backends #278

Merged
merged 18 commits into from
Jun 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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
39 changes: 19 additions & 20 deletions beacon_chain/beacon_node.nim
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import
chronos, chronicles, confutils, serialization/errors,
eth/trie/db, eth/trie/backends/rocksdb_backend, eth/async_utils,
spec/[bitfield, datatypes, digest, crypto, beaconstate, helpers, validator],
conf, time,
state_transition, fork_choice, ssz, beacon_chain_db, validator_pool, extras,
attestation_pool, block_pool, eth2_network, beacon_node_types,
mainchain_monitor, trusted_state_snapshots, version
conf, time, state_transition, fork_choice, ssz, beacon_chain_db,
validator_pool, extras, attestation_pool, block_pool, eth2_network,
beacon_node_types, mainchain_monitor, trusted_state_snapshots, version,
sync_protocol, request_manager

const
topicBeaconBlocks = "ethereum/2.1/beacon_chain/blocks"
Expand All @@ -18,13 +18,7 @@ const
genesisFile = "genesis.json"
testnetsBaseUrl = "https://serenity-testnets.status.im"

# #################################################
# Careful handling of beacon_node <-> sync_protocol
# to avoid recursive dependencies
proc onBeaconBlock*(node: BeaconNode, blck: BeaconBlock) {.gcsafe.}
# Forward decl for sync_protocol
import sync_protocol, request_manager
# #################################################

func localValidatorsDir(conf: BeaconNodeConf): string =
conf.dataDir / "validators"
Expand Down Expand Up @@ -86,13 +80,12 @@ proc saveValidatorKey(keyName, key: string, conf: BeaconNodeConf) =
writeFile(outputFile, key)
info "Imported validator key", file = outputFile

proc persistentNodeId*(conf: BeaconNodeConf): string =
($ensureNetworkKeys(conf).pubKey)[0..5]

proc init*(T: type BeaconNode, conf: BeaconNodeConf): Future[BeaconNode] {.async.} =
new result
result.onBeaconBlock = onBeaconBlock
result.config = conf
result.nickname = if conf.nodename == "auto": persistentNodeId(conf)
result.networkIdentity = getPersistentNetIdentity(conf)
arnetheduck marked this conversation as resolved.
Show resolved Hide resolved
result.nickname = if conf.nodename == "auto": shortForm(result.networkIdentity)
else: conf.nodename

template fail(args: varargs[untyped]) =
Expand Down Expand Up @@ -182,6 +175,7 @@ proc init*(T: type BeaconNode, conf: BeaconNodeConf): Future[BeaconNode] {.async
# TODO sync is called when a remote peer is connected - is that the right
# time to do so?
let sync = result.network.protocolState(BeaconSync)
sync.chainId = 0 # TODO specify chainId
sync.networkId = result.networkMetadata.networkId
sync.node = result
sync.db = result.db
Expand Down Expand Up @@ -210,11 +204,10 @@ template withState(
body

proc connectToNetwork(node: BeaconNode) {.async.} =
let localKeys = ensureNetworkKeys(node.config)
var bootstrapNodes = newSeq[BootstrapAddr]()

for bootNode in node.networkMetadata.bootstrapNodes:
if bootNode.pubkey == localKeys.pubKey:
if bootNode.isSameNode(node.networkIdentity):
node.isBootstrapNode = true
else:
bootstrapNodes.add bootNode
Expand Down Expand Up @@ -278,7 +271,7 @@ proc updateHead(node: BeaconNode, slot: Slot): BlockRef =
# TODO move all of this logic to BlockPool
debug "Preparing for fork choice",
stateRoot = shortLog(root),
connectedPeers = node.network.connectedPeers,
connectedPeers = node.network.peersCount,
stateSlot = humaneSlotNum(state.slot),
stateEpoch = humaneEpochNum(state.slot.slotToEpoch)

Expand Down Expand Up @@ -656,15 +649,15 @@ proc onSecond(node: BeaconNode, moment: Moment) {.async.} =
if missingBlocks.len > 0:
info "Requesting detected missing blocks", missingBlocks
node.requestManager.fetchAncestorBlocks(missingBlocks) do (b: BeaconBlock):
node.onBeaconBlock(b)
onBeaconBlock(node ,b)

let nextSecond = max(Moment.now(), moment + chronos.seconds(1))
addTimer(nextSecond) do (p: pointer):
asyncCheck node.onSecond(nextSecond)

proc run*(node: BeaconNode) =
waitFor node.network.subscribe(topicBeaconBlocks) do (blck: BeaconBlock):
node.onBeaconBlock(blck)
onBeaconBlock(node, blck)

waitFor node.network.subscribe(topicAttestations) do (attestation: Attestation):
node.onAttestation(attestation)
Expand Down Expand Up @@ -729,7 +722,13 @@ when isMainModule:
for i in config.firstValidator.int ..< config.totalValidators.int:
let depositFile = config.validatorsDir /
validatorFileBaseName(i) & ".deposit.json"
deposits.add Json.loadFile(depositFile, Deposit)
try:
deposits.add Json.loadFile(depositFile, Deposit)
except SerializationError as err:
stderr.write "Error while loading a deposit file:\n"
stderr.write err.formatMsg(depositFile), "\n"
stderr.write "Please regenerate the deposit files by running validator_keygen again\n"
quit 1

let initialState = get_genesis_beacon_state(
deposits,
Expand Down
30 changes: 9 additions & 21 deletions beacon_chain/beacon_node_types.nim
Original file line number Diff line number Diff line change
@@ -1,21 +1,8 @@
import # Beacon Node
eth/[p2p, keys],
spec/[bitfield, digest],
beacon_chain_db, conf, mainchain_monitor, eth2_network,
./time

import # Attestation Pool
import
sets, deques, tables,
eth/keys,
spec/[bitfield, datatypes, crypto, digest],
deques, tables
# block_pool

import # Block Pool
spec/[datatypes, digest],
beacon_chain_db,
tables

import # Validator Pool
spec/crypto, tables
beacon_chain_db, conf, mainchain_monitor, eth2_network, time

type

Expand All @@ -26,18 +13,19 @@ type
# #############################################
BeaconNode* = ref object
nickname*: string
network*: EthereumNode
network*: Eth2Node
networkIdentity*: Eth2NodeIdentity
networkMetadata*: NetworkMetadata
requestManager*: RequestManager
isBootstrapNode*: bool
db*: BeaconChainDB
config*: BeaconNodeConf
keys*: KeyPair
attachedValidators*: ValidatorPool
blockPool*: BlockPool
attestationPool*: AttestationPool
mainchainMonitor*: MainchainMonitor
beaconClock*: BeaconClock
onBeaconBlock*: proc (node: BeaconNode, blck: BeaconBlock) {.gcsafe.}

stateCache*: StateData ##\
## State cache object that's used as a scratch pad
Expand Down Expand Up @@ -258,10 +246,10 @@ type
validators*: Table[ValidatorPubKey, AttachedValidator]

RequestManager* = object
network*: EthereumNode
network*: Eth2Node

NetworkMetadata* = object
networkId*: uint64
networkId*: uint8
networkGeneration*: uint64
genesisRoot*: Eth2Digest
bootstrapNodes*: seq[BootstrapAddr]
Expand Down
4 changes: 2 additions & 2 deletions beacon_chain/conf.nim
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import
spec/[crypto, datatypes], time, version

export
defs
defs, enabledLogLevel

const
DEFAULT_NETWORK* {.strdefine.} = "testnet0"
Expand Down Expand Up @@ -79,7 +79,7 @@ type

of createTestnet:
networkId* {.
desc: "An unique numeric identifier for the network".}: uint64
desc: "An unique numeric identifier for the network".}: uint8
arnetheduck marked this conversation as resolved.
Show resolved Hide resolved

validatorsDir* {.
desc: "Directory containing validator descriptors named vXXXXXXX.deposit.json"
Expand Down
Loading