Ivan FB 3b03ca29b1
refactor: introduce proper logos_delivery layers folder structure (#3935)
Co-authored-by: NagyZoltanPeter <113987313+NagyZoltanPeter@users.noreply.github.com>
2026-06-08 13:37:53 +02:00

86 lines
2.5 KiB
Nim

{.push raises: [].}
import
std/[options, net],
results,
eth/keys as eth_keys,
eth/p2p/discoveryv5/enr,
libp2p/crypto/crypto as libp2p_crypto
import ./typed_record
## Builder
type EnrBuilder* = object
seqNumber: uint64
privateKey: eth_keys.PrivateKey
ipAddress: Opt[IpAddress]
tcpPort: Opt[Port]
udpPort: Opt[Port]
fields: seq[FieldPair]
proc init*(T: type EnrBuilder, key: eth_keys.PrivateKey, seqNum: uint64 = 1): T =
EnrBuilder(
seqNumber: seqNum,
privateKey: key,
ipAddress: Opt.none(IpAddress),
tcpPort: Opt.none(Port),
udpPort: Opt.none(Port),
fields: newSeq[FieldPair](),
)
proc init*(T: type EnrBuilder, key: libp2p_crypto.PrivateKey, seqNum: uint64 = 1): T =
# TODO: Inconvenient runtime assertion. Move this assertion to compile time
if key.scheme != PKScheme.Secp256k1:
raise newException(Defect, "invalid private key scheme")
let
bytes = key.getRawBytes().expect("Private key is valid")
privateKey =
eth_keys.PrivateKey.fromRaw(bytes).expect("Raw private key is of valid length")
EnrBuilder.init(key = privateKey, seqNum = seqNum)
proc addFieldPair*(builder: var EnrBuilder, pair: FieldPair) =
builder.fields.add(pair)
proc addFieldPair*[V](builder: var EnrBuilder, key: string, value: V) =
builder.addFieldPair(toFieldPair(key, value))
proc build*(builder: EnrBuilder): EnrResult[enr.Record] =
# Note that nim-eth's `Record.init` does not deduplicate the field pairs.
# See: https://github.com/status-im/nim-eth/blob/4b22fcd/eth/p2p/discoveryv5/enr.nim#L143-L144
enr.Record.init(
seqNum = builder.seqNumber,
pk = builder.privateKey,
ip = builder.ipAddress,
tcpPort = builder.tcpPort,
udpPort = builder.udpPort,
extraFields = builder.fields,
)
## Builder extension: IP address and TCP/UDP ports
proc addAddressAndPorts(
builder: var EnrBuilder, ip: IpAddress, tcpPort, udpPort: Option[Port]
) =
builder.ipAddress = Opt.some(ip)
builder.tcpPort = tcpPort.toOpt()
builder.udpPort = udpPort.toOpt()
proc addPorts(builder: var EnrBuilder, tcp, udp: Option[Port]) =
# Based on: https://github.com/status-im/nim-eth/blob/4b22fcd/eth/p2p/discoveryv5/enr.nim#L166
builder.tcpPort = tcp.toOpt()
builder.udpPort = udp.toOpt()
proc withIpAddressAndPorts*(
builder: var EnrBuilder,
ipAddr = none(IpAddress),
tcpPort = none(Port),
udpPort = none(Port),
) =
if ipAddr.isSome():
addAddressAndPorts(builder, ipAddr.get(), tcpPort, udpPort)
else:
addPorts(builder, tcpPort, udpPort)