mirror of https://github.com/status-im/nim-eth.git
remove remaining `int` holdouts in rlp (#737)
these were never well defined
This commit is contained in:
parent
b49df0a71a
commit
119c910a4e
|
@ -35,7 +35,7 @@ type
|
||||||
msgResponse
|
msgResponse
|
||||||
|
|
||||||
Message* = ref object
|
Message* = ref object
|
||||||
id*: Opt[uint]
|
id*: Opt[uint64]
|
||||||
ident*: NimNode
|
ident*: NimNode
|
||||||
kind*: MessageKind
|
kind*: MessageKind
|
||||||
procDef*: NimNode
|
procDef*: NimNode
|
||||||
|
@ -83,7 +83,7 @@ type
|
||||||
P2PProtocol* = ref object
|
P2PProtocol* = ref object
|
||||||
# Settings
|
# Settings
|
||||||
name*: string
|
name*: string
|
||||||
version*: int
|
version*: uint64
|
||||||
timeouts*: int64
|
timeouts*: int64
|
||||||
useRequestIds*: bool
|
useRequestIds*: bool
|
||||||
useSingleRecordInlining*: bool
|
useSingleRecordInlining*: bool
|
||||||
|
@ -148,8 +148,7 @@ const
|
||||||
let
|
let
|
||||||
# Variable names affecting the public interface of the library:
|
# Variable names affecting the public interface of the library:
|
||||||
reqIdVar* {.compileTime.} = ident "reqId"
|
reqIdVar* {.compileTime.} = ident "reqId"
|
||||||
# XXX: Binding the int type causes instantiation failure for some reason
|
ReqIdType* {.compileTime.} = ident "uint64"
|
||||||
ReqIdType* {.compileTime.} = ident "uint"
|
|
||||||
peerVar* {.compileTime.} = ident "peer"
|
peerVar* {.compileTime.} = ident "peer"
|
||||||
responseVar* {.compileTime.} = ident "response"
|
responseVar* {.compileTime.} = ident "response"
|
||||||
streamVar* {.compileTime.} = ident "stream"
|
streamVar* {.compileTime.} = ident "stream"
|
||||||
|
@ -313,7 +312,7 @@ proc verifyStateType(t: NimNode): NimNode =
|
||||||
proc processProtocolBody*(p: P2PProtocol, protocolBody: NimNode)
|
proc processProtocolBody*(p: P2PProtocol, protocolBody: NimNode)
|
||||||
|
|
||||||
proc init*(T: type P2PProtocol, backendFactory: BackendFactory,
|
proc init*(T: type P2PProtocol, backendFactory: BackendFactory,
|
||||||
name: string, version: int, body: NimNode,
|
name: string, version: uint64, body: NimNode,
|
||||||
timeouts: int64, useRequestIds: bool, rlpxName: string,
|
timeouts: int64, useRequestIds: bool, rlpxName: string,
|
||||||
outgoingRequestDecorator: NimNode,
|
outgoingRequestDecorator: NimNode,
|
||||||
incomingRequestDecorator: NimNode,
|
incomingRequestDecorator: NimNode,
|
||||||
|
@ -345,14 +344,14 @@ proc init*(T: type P2PProtocol, backendFactory: BackendFactory,
|
||||||
assert(not result.backend.implementProtocolInit.isNil)
|
assert(not result.backend.implementProtocolInit.isNil)
|
||||||
|
|
||||||
if result.backend.ReqIdType.isNil:
|
if result.backend.ReqIdType.isNil:
|
||||||
result.backend.ReqIdType = ident "uint"
|
result.backend.ReqIdType = ident "uint64"
|
||||||
|
|
||||||
result.processProtocolBody body
|
result.processProtocolBody body
|
||||||
|
|
||||||
if not result.backend.afterProtocolInit.isNil:
|
if not result.backend.afterProtocolInit.isNil:
|
||||||
result.backend.afterProtocolInit(result)
|
result.backend.afterProtocolInit(result)
|
||||||
|
|
||||||
proc augmentUserHandler(p: P2PProtocol, userHandlerProc: NimNode, msgId = Opt.none(uint)) =
|
proc augmentUserHandler(p: P2PProtocol, userHandlerProc: NimNode, msgId = Opt.none(uint64)) =
|
||||||
## This procs adds a set of common helpers available in all messages handlers
|
## This procs adds a set of common helpers available in all messages handlers
|
||||||
## (e.g. `perProtocolMsgId`, `peer.state`, etc).
|
## (e.g. `perProtocolMsgId`, `peer.state`, etc).
|
||||||
|
|
||||||
|
@ -446,7 +445,7 @@ proc ResponderType(msg: Message): NimNode =
|
||||||
proc needsSingleParamInlining(msg: Message): bool =
|
proc needsSingleParamInlining(msg: Message): bool =
|
||||||
msg.recBody.kind == nnkDistinctTy
|
msg.recBody.kind == nnkDistinctTy
|
||||||
|
|
||||||
proc newMsg(protocol: P2PProtocol, kind: MessageKind, msgId: uint,
|
proc newMsg(protocol: P2PProtocol, kind: MessageKind, msgId: uint64,
|
||||||
procDef: NimNode, response: Message = nil): Message =
|
procDef: NimNode, response: Message = nil): Message =
|
||||||
|
|
||||||
if procDef[0].kind == nnkPostfix:
|
if procDef[0].kind == nnkPostfix:
|
||||||
|
@ -528,7 +527,7 @@ proc newMsg(protocol: P2PProtocol, kind: MessageKind, msgId: uint,
|
||||||
proc isVoid(t: NimNode): bool =
|
proc isVoid(t: NimNode): bool =
|
||||||
t.kind == nnkEmpty or eqIdent(t, "void")
|
t.kind == nnkEmpty or eqIdent(t, "void")
|
||||||
|
|
||||||
proc addMsg(p: P2PProtocol, msgId: uint, procDef: NimNode) =
|
proc addMsg(p: P2PProtocol, msgId: uint64, procDef: NimNode) =
|
||||||
var
|
var
|
||||||
returnType = procDef.params[0]
|
returnType = procDef.params[0]
|
||||||
hasReturnValue = not isVoid(returnType)
|
hasReturnValue = not isVoid(returnType)
|
||||||
|
@ -544,7 +543,7 @@ proc addMsg(p: P2PProtocol, msgId: uint, procDef: NimNode) =
|
||||||
let
|
let
|
||||||
responseIdent = ident($procDef.name & "Response")
|
responseIdent = ident($procDef.name & "Response")
|
||||||
response = Message(protocol: p,
|
response = Message(protocol: p,
|
||||||
id: Opt.none(uint),
|
id: Opt.none(uint64),
|
||||||
ident: responseIdent,
|
ident: responseIdent,
|
||||||
kind: msgResponse,
|
kind: msgResponse,
|
||||||
recName: returnType,
|
recName: returnType,
|
||||||
|
@ -871,7 +870,7 @@ proc processProtocolBody*(p: P2PProtocol, protocolBody: NimNode) =
|
||||||
##
|
##
|
||||||
## All messages will have properly computed numeric IDs
|
## All messages will have properly computed numeric IDs
|
||||||
##
|
##
|
||||||
var nextId = 0u
|
var nextId = 0u64
|
||||||
|
|
||||||
for n in protocolBody:
|
for n in protocolBody:
|
||||||
case n.kind
|
case n.kind
|
||||||
|
@ -880,7 +879,7 @@ proc processProtocolBody*(p: P2PProtocol, protocolBody: NimNode) =
|
||||||
# By default message IDs are assigned in increasing order
|
# By default message IDs are assigned in increasing order
|
||||||
# `nextID` can be used to skip some of the numeric slots
|
# `nextID` can be used to skip some of the numeric slots
|
||||||
if n.len == 2 and n[1].kind == nnkIntLit:
|
if n.len == 2 and n[1].kind == nnkIntLit:
|
||||||
nextId = n[1].intVal.uint
|
nextId = n[1].intVal.uint64
|
||||||
else:
|
else:
|
||||||
error("nextID expects a single int value", n)
|
error("nextID expects a single int value", n)
|
||||||
|
|
||||||
|
@ -895,10 +894,10 @@ proc processProtocolBody*(p: P2PProtocol, protocolBody: NimNode) =
|
||||||
error "requestResponse expects a block with at least two proc definitions"
|
error "requestResponse expects a block with at least two proc definitions"
|
||||||
|
|
||||||
var queries = newSeq[Message]()
|
var queries = newSeq[Message]()
|
||||||
let responseMsg = p.newMsg(msgResponse, nextId + procs.len.uint - 1, procs[^1])
|
let responseMsg = p.newMsg(msgResponse, nextId + procs.len.uint64 - 1, procs[^1])
|
||||||
|
|
||||||
for i in 0 .. procs.len - 2:
|
for i in 0 .. procs.len - 2:
|
||||||
queries.add p.newMsg(msgRequest, nextId + i.uint, procs[i], response = responseMsg)
|
queries.add p.newMsg(msgRequest, nextId + i.uint64, procs[i], response = responseMsg)
|
||||||
|
|
||||||
p.requests.add Request(queries: queries, response: responseMsg)
|
p.requests.add Request(queries: queries, response: responseMsg)
|
||||||
|
|
||||||
|
@ -991,7 +990,7 @@ proc genTypeSection*(p: P2PProtocol): NimNode =
|
||||||
|
|
||||||
if p.isRlpx:
|
if p.isRlpx:
|
||||||
result.add quote do:
|
result.add quote do:
|
||||||
template msgId*(`MSG`: type `msgStrongRecName`): uint = `msgId`
|
template msgId*(`MSG`: type `msgStrongRecName`): uint64 = `msgId`
|
||||||
|
|
||||||
proc genCode*(p: P2PProtocol): NimNode =
|
proc genCode*(p: P2PProtocol): NimNode =
|
||||||
for msg in p.messages:
|
for msg in p.messages:
|
||||||
|
@ -1027,7 +1026,7 @@ proc genCode*(p: P2PProtocol): NimNode =
|
||||||
|
|
||||||
macro emitForSingleBackend(
|
macro emitForSingleBackend(
|
||||||
name: static[string],
|
name: static[string],
|
||||||
version: static[int],
|
version: static[uint64],
|
||||||
backend: static[BackendFactory],
|
backend: static[BackendFactory],
|
||||||
body: untyped,
|
body: untyped,
|
||||||
# TODO Nim can't handle a proper duration parameter here
|
# TODO Nim can't handle a proper duration parameter here
|
||||||
|
|
|
@ -40,7 +40,7 @@ type
|
||||||
protocolStates*: seq[RootRef]
|
protocolStates*: seq[RootRef]
|
||||||
discovery*: DiscoveryProtocol
|
discovery*: DiscoveryProtocol
|
||||||
when useSnappy:
|
when useSnappy:
|
||||||
protocolVersion*: uint
|
protocolVersion*: uint64
|
||||||
rng*: ref HmacDrbgContext
|
rng*: ref HmacDrbgContext
|
||||||
|
|
||||||
Peer* = ref object
|
Peer* = ref object
|
||||||
|
@ -50,7 +50,7 @@ type
|
||||||
# Private fields:
|
# Private fields:
|
||||||
transport*: StreamTransport
|
transport*: StreamTransport
|
||||||
dispatcher*: Dispatcher
|
dispatcher*: Dispatcher
|
||||||
lastReqId*: Opt[uint]
|
lastReqId*: Opt[uint64]
|
||||||
secretsState*: SecretState
|
secretsState*: SecretState
|
||||||
connectionState*: ConnectionState
|
connectionState*: ConnectionState
|
||||||
protocolStates*: seq[RootRef]
|
protocolStates*: seq[RootRef]
|
||||||
|
@ -86,7 +86,7 @@ type
|
||||||
|
|
||||||
Capability* = object
|
Capability* = object
|
||||||
name*: string
|
name*: string
|
||||||
version*: int
|
version*: uint64
|
||||||
|
|
||||||
EthP2PError* = object of CatchableError
|
EthP2PError* = object of CatchableError
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ type
|
||||||
|
|
||||||
ProtocolInfo* = ref object
|
ProtocolInfo* = ref object
|
||||||
name*: string
|
name*: string
|
||||||
version*: int
|
version*: uint64
|
||||||
messages*: seq[MessageInfo]
|
messages*: seq[MessageInfo]
|
||||||
index*: int # the position of the protocol in the
|
index*: int # the position of the protocol in the
|
||||||
# ordered list of supported protocols
|
# ordered list of supported protocols
|
||||||
|
@ -124,7 +124,7 @@ type
|
||||||
disconnectHandler*: DisconnectionHandler
|
disconnectHandler*: DisconnectionHandler
|
||||||
|
|
||||||
MessageInfo* = ref object
|
MessageInfo* = ref object
|
||||||
id*: uint # this is a `msgId` (as opposed to a `reqId`)
|
id*: uint64 # this is a `msgId` (as opposed to a `reqId`)
|
||||||
name*: string
|
name*: string
|
||||||
|
|
||||||
# Private fields:
|
# Private fields:
|
||||||
|
@ -142,11 +142,11 @@ type
|
||||||
# protocol. If the other peer also supports the protocol, the stored
|
# protocol. If the other peer also supports the protocol, the stored
|
||||||
# offset indicates the numeric value of the first message of the protocol
|
# offset indicates the numeric value of the first message of the protocol
|
||||||
# (for this particular connection). If the other peer doesn't support the
|
# (for this particular connection). If the other peer doesn't support the
|
||||||
# particular protocol, the stored offset is `Opt.none(uint)`.
|
# particular protocol, the stored offset is `Opt.none(uint64)`.
|
||||||
#
|
#
|
||||||
# `messages` holds a mapping from valid message IDs to their handler procs.
|
# `messages` holds a mapping from valid message IDs to their handler procs.
|
||||||
#
|
#
|
||||||
protocolOffsets*: seq[Opt[uint]]
|
protocolOffsets*: seq[Opt[uint64]]
|
||||||
messages*: seq[MessageInfo] # per `msgId` table (se above)
|
messages*: seq[MessageInfo] # per `msgId` table (se above)
|
||||||
activeProtocols*: seq[ProtocolInfo]
|
activeProtocols*: seq[ProtocolInfo]
|
||||||
|
|
||||||
|
@ -155,14 +155,14 @@ type
|
||||||
##
|
##
|
||||||
|
|
||||||
OutstandingRequest* = object
|
OutstandingRequest* = object
|
||||||
id*: uint # a `reqId` that may be used for response
|
id*: uint64 # a `reqId` that may be used for response
|
||||||
future*: FutureBase
|
future*: FutureBase
|
||||||
timeoutAt*: Moment
|
timeoutAt*: Moment
|
||||||
|
|
||||||
# Private types:
|
# Private types:
|
||||||
MessageHandlerDecorator* = proc(msgId: uint, n: NimNode): NimNode
|
MessageHandlerDecorator* = proc(msgId: uint64, n: NimNode): NimNode
|
||||||
|
|
||||||
ThunkProc* = proc(x: Peer, msgId: uint, data: Rlp): Future[void]
|
ThunkProc* = proc(x: Peer, msgId: uint64, data: Rlp): Future[void]
|
||||||
{.gcsafe, async: (raises: [RlpError, EthP2PError]).}
|
{.gcsafe, async: (raises: [RlpError, EthP2PError]).}
|
||||||
|
|
||||||
MessageContentPrinter* = proc(msg: pointer): string
|
MessageContentPrinter* = proc(msg: pointer): string
|
||||||
|
|
|
@ -64,7 +64,7 @@ logScope:
|
||||||
type
|
type
|
||||||
ResponderWithId*[MsgType] = object
|
ResponderWithId*[MsgType] = object
|
||||||
peer*: Peer
|
peer*: Peer
|
||||||
reqId*: uint
|
reqId*: uint64
|
||||||
|
|
||||||
ResponderWithoutId*[MsgType] = distinct Peer
|
ResponderWithoutId*[MsgType] = distinct Peer
|
||||||
|
|
||||||
|
@ -126,14 +126,14 @@ when tracingEnabled:
|
||||||
init, writeValue, getOutput
|
init, writeValue, getOutput
|
||||||
|
|
||||||
proc init*[MsgName](T: type ResponderWithId[MsgName],
|
proc init*[MsgName](T: type ResponderWithId[MsgName],
|
||||||
peer: Peer, reqId: uint): T =
|
peer: Peer, reqId: uint64): T =
|
||||||
T(peer: peer, reqId: reqId)
|
T(peer: peer, reqId: reqId)
|
||||||
|
|
||||||
proc init*[MsgName](T: type ResponderWithoutId[MsgName], peer: Peer): T =
|
proc init*[MsgName](T: type ResponderWithoutId[MsgName], peer: Peer): T =
|
||||||
T(peer)
|
T(peer)
|
||||||
|
|
||||||
chronicles.formatIt(Peer): $(it.remote)
|
chronicles.formatIt(Peer): $(it.remote)
|
||||||
chronicles.formatIt(Opt[uint]): (if it.isSome(): $it.value else: "-1")
|
chronicles.formatIt(Opt[uint64]): (if it.isSome(): $it.value else: "-1")
|
||||||
|
|
||||||
include p2p_backends_helpers
|
include p2p_backends_helpers
|
||||||
|
|
||||||
|
@ -247,9 +247,9 @@ proc getDispatcher(node: EthereumNode,
|
||||||
|
|
||||||
new result
|
new result
|
||||||
newSeq(result.protocolOffsets, protocolCount())
|
newSeq(result.protocolOffsets, protocolCount())
|
||||||
result.protocolOffsets.fill Opt.none(uint)
|
result.protocolOffsets.fill Opt.none(uint64)
|
||||||
|
|
||||||
var nextUserMsgId = 0x10u
|
var nextUserMsgId = 0x10u64
|
||||||
|
|
||||||
for localProtocol in node.protocols:
|
for localProtocol in node.protocols:
|
||||||
let idx = localProtocol.index
|
let idx = localProtocol.index
|
||||||
|
@ -258,7 +258,7 @@ proc getDispatcher(node: EthereumNode,
|
||||||
if localProtocol.name == remoteCapability.name and
|
if localProtocol.name == remoteCapability.name and
|
||||||
localProtocol.version == remoteCapability.version:
|
localProtocol.version == remoteCapability.version:
|
||||||
result.protocolOffsets[idx] = Opt.some(nextUserMsgId)
|
result.protocolOffsets[idx] = Opt.some(nextUserMsgId)
|
||||||
nextUserMsgId += localProtocol.messages.len.uint
|
nextUserMsgId += localProtocol.messages.len.uint64
|
||||||
break findMatchingProtocol
|
break findMatchingProtocol
|
||||||
|
|
||||||
template copyTo(src, dest; index: int) =
|
template copyTo(src, dest; index: int) =
|
||||||
|
@ -275,9 +275,9 @@ proc getDispatcher(node: EthereumNode,
|
||||||
localProtocol.messages.copyTo(result.messages,
|
localProtocol.messages.copyTo(result.messages,
|
||||||
result.protocolOffsets[idx].value.int)
|
result.protocolOffsets[idx].value.int)
|
||||||
|
|
||||||
proc getMsgName*(peer: Peer, msgId: uint): string =
|
proc getMsgName*(peer: Peer, msgId: uint64): string =
|
||||||
if not peer.dispatcher.isNil and
|
if not peer.dispatcher.isNil and
|
||||||
msgId < peer.dispatcher.messages.len.uint and
|
msgId < peer.dispatcher.messages.len.uint64 and
|
||||||
not peer.dispatcher.messages[msgId].isNil:
|
not peer.dispatcher.messages[msgId].isNil:
|
||||||
return peer.dispatcher.messages[msgId].name
|
return peer.dispatcher.messages[msgId].name
|
||||||
else:
|
else:
|
||||||
|
@ -288,14 +288,14 @@ proc getMsgName*(peer: Peer, msgId: uint): string =
|
||||||
of 3: "pong"
|
of 3: "pong"
|
||||||
else: $msgId
|
else: $msgId
|
||||||
|
|
||||||
proc getMsgMetadata*(peer: Peer, msgId: uint): (ProtocolInfo, MessageInfo) =
|
proc getMsgMetadata*(peer: Peer, msgId: uint64): (ProtocolInfo, MessageInfo) =
|
||||||
doAssert msgId >= 0
|
doAssert msgId >= 0
|
||||||
|
|
||||||
let dpInfo = devp2pInfo()
|
let dpInfo = devp2pInfo()
|
||||||
if msgId <= dpInfo.messages[^1].id:
|
if msgId <= dpInfo.messages[^1].id:
|
||||||
return (dpInfo, dpInfo.messages[msgId])
|
return (dpInfo, dpInfo.messages[msgId])
|
||||||
|
|
||||||
if msgId < peer.dispatcher.messages.len.uint:
|
if msgId < peer.dispatcher.messages.len.uint64:
|
||||||
let numProtocol = protocolCount()
|
let numProtocol = protocolCount()
|
||||||
for i in 0 ..< numProtocol:
|
for i in 0 ..< numProtocol:
|
||||||
let protocol = getProtocol(i)
|
let protocol = getProtocol(i)
|
||||||
|
@ -307,7 +307,7 @@ proc getMsgMetadata*(peer: Peer, msgId: uint): (ProtocolInfo, MessageInfo) =
|
||||||
# Protocol info objects
|
# Protocol info objects
|
||||||
#
|
#
|
||||||
|
|
||||||
proc initProtocol(name: string, version: int,
|
proc initProtocol(name: string, version: uint64,
|
||||||
peerInit: PeerStateInitializer,
|
peerInit: PeerStateInitializer,
|
||||||
networkInit: NetworkStateInitializer): ProtocolInfo =
|
networkInit: NetworkStateInitializer): ProtocolInfo =
|
||||||
ProtocolInfo(
|
ProtocolInfo(
|
||||||
|
@ -338,13 +338,13 @@ proc nextMsgResolver[MsgType](msgData: Rlp, future: FutureBase)
|
||||||
MsgType.rlpFieldsCount > 1)
|
MsgType.rlpFieldsCount > 1)
|
||||||
|
|
||||||
proc registerMsg(protocol: ProtocolInfo,
|
proc registerMsg(protocol: ProtocolInfo,
|
||||||
msgId: uint,
|
msgId: uint64,
|
||||||
name: string,
|
name: string,
|
||||||
thunk: ThunkProc,
|
thunk: ThunkProc,
|
||||||
printer: MessageContentPrinter,
|
printer: MessageContentPrinter,
|
||||||
requestResolver: RequestResolver,
|
requestResolver: RequestResolver,
|
||||||
nextMsgResolver: NextMsgResolver) =
|
nextMsgResolver: NextMsgResolver) =
|
||||||
if protocol.messages.len.uint <= msgId:
|
if protocol.messages.len.uint64 <= msgId:
|
||||||
protocol.messages.setLen(msgId + 1)
|
protocol.messages.setLen(msgId + 1)
|
||||||
protocol.messages[msgId] = MessageInfo(
|
protocol.messages[msgId] = MessageInfo(
|
||||||
id: msgId,
|
id: msgId,
|
||||||
|
@ -357,7 +357,7 @@ proc registerMsg(protocol: ProtocolInfo,
|
||||||
# Message composition and encryption
|
# Message composition and encryption
|
||||||
#
|
#
|
||||||
|
|
||||||
proc perPeerMsgIdImpl(peer: Peer, proto: ProtocolInfo, msgId: uint): uint =
|
proc perPeerMsgIdImpl(peer: Peer, proto: ProtocolInfo, msgId: uint64): uint64 =
|
||||||
result = msgId
|
result = msgId
|
||||||
if not peer.dispatcher.isNil:
|
if not peer.dispatcher.isNil:
|
||||||
result += peer.dispatcher.protocolOffsets[proto.index].value
|
result += peer.dispatcher.protocolOffsets[proto.index].value
|
||||||
|
@ -373,10 +373,10 @@ proc supports*(peer: Peer, Protocol: type): bool =
|
||||||
## Checks whether a Peer supports a particular protocol
|
## Checks whether a Peer supports a particular protocol
|
||||||
peer.supports(Protocol.protocolInfo)
|
peer.supports(Protocol.protocolInfo)
|
||||||
|
|
||||||
template perPeerMsgId(peer: Peer, MsgType: type): uint =
|
template perPeerMsgId(peer: Peer, MsgType: type): uint64 =
|
||||||
perPeerMsgIdImpl(peer, MsgType.msgProtocol.protocolInfo, MsgType.msgId)
|
perPeerMsgIdImpl(peer, MsgType.msgProtocol.protocolInfo, MsgType.msgId)
|
||||||
|
|
||||||
proc invokeThunk*(peer: Peer, msgId: uint, msgData: Rlp): Future[void]
|
proc invokeThunk*(peer: Peer, msgId: uint64, msgData: Rlp): Future[void]
|
||||||
{.async: (raises: [rlp.RlpError, EthP2PError]).} =
|
{.async: (raises: [rlp.RlpError, EthP2PError]).} =
|
||||||
template invalidIdError: untyped =
|
template invalidIdError: untyped =
|
||||||
raise newException(UnsupportedMessageError,
|
raise newException(UnsupportedMessageError,
|
||||||
|
@ -384,7 +384,7 @@ proc invokeThunk*(peer: Peer, msgId: uint, msgData: Rlp): Future[void]
|
||||||
" on a connection supporting " & peer.dispatcher.describeProtocols)
|
" on a connection supporting " & peer.dispatcher.describeProtocols)
|
||||||
|
|
||||||
# msgId can be negative as it has int as type and gets decoded from rlp
|
# msgId can be negative as it has int as type and gets decoded from rlp
|
||||||
if msgId >= peer.dispatcher.messages.len.uint: invalidIdError()
|
if msgId >= peer.dispatcher.messages.len.uint64: invalidIdError()
|
||||||
if peer.dispatcher.messages[msgId].isNil: invalidIdError()
|
if peer.dispatcher.messages[msgId].isNil: invalidIdError()
|
||||||
|
|
||||||
let thunk = peer.dispatcher.messages[msgId].thunk
|
let thunk = peer.dispatcher.messages[msgId].thunk
|
||||||
|
@ -423,8 +423,8 @@ proc send*[Msg](peer: Peer, msg: Msg): Future[void] =
|
||||||
proc registerRequest(peer: Peer,
|
proc registerRequest(peer: Peer,
|
||||||
timeout: Duration,
|
timeout: Duration,
|
||||||
responseFuture: FutureBase,
|
responseFuture: FutureBase,
|
||||||
responseMsgId: uint): uint =
|
responseMsgId: uint64): uint64 =
|
||||||
result = if peer.lastReqId.isNone: 0u else: peer.lastReqId.value + 1u
|
result = if peer.lastReqId.isNone: 0u64 else: peer.lastReqId.value + 1u64
|
||||||
peer.lastReqId = Opt.some(result)
|
peer.lastReqId = Opt.some(result)
|
||||||
|
|
||||||
let timeoutAt = Moment.fromNow(timeout)
|
let timeoutAt = Moment.fromNow(timeout)
|
||||||
|
@ -440,7 +440,7 @@ proc registerRequest(peer: Peer,
|
||||||
|
|
||||||
discard setTimer(timeoutAt, timeoutExpired, nil)
|
discard setTimer(timeoutAt, timeoutExpired, nil)
|
||||||
|
|
||||||
proc resolveResponseFuture(peer: Peer, msgId: uint, msg: pointer) =
|
proc resolveResponseFuture(peer: Peer, msgId: uint64, msg: pointer) =
|
||||||
## This function is a split off from the previously combined version with
|
## This function is a split off from the previously combined version with
|
||||||
## the same name using optional request ID arguments. This here is the
|
## the same name using optional request ID arguments. This here is the
|
||||||
## version without a request ID (there is the other part below.).
|
## version without a request ID (there is the other part below.).
|
||||||
|
@ -485,7 +485,7 @@ proc resolveResponseFuture(peer: Peer, msgId: uint, msg: pointer) =
|
||||||
else:
|
else:
|
||||||
trace "late or dup RPLx reply ignored", msgId
|
trace "late or dup RPLx reply ignored", msgId
|
||||||
|
|
||||||
proc resolveResponseFuture(peer: Peer, msgId: uint, msg: pointer, reqId: uint) =
|
proc resolveResponseFuture(peer: Peer, msgId: uint64, msg: pointer, reqId: uint64) =
|
||||||
## Variant of `resolveResponseFuture()` for request ID argument.
|
## Variant of `resolveResponseFuture()` for request ID argument.
|
||||||
logScope:
|
logScope:
|
||||||
msg = peer.dispatcher.messages[msgId].name
|
msg = peer.dispatcher.messages[msgId].name
|
||||||
|
@ -544,7 +544,7 @@ proc resolveResponseFuture(peer: Peer, msgId: uint, msg: pointer, reqId: uint) =
|
||||||
trace "late or dup RPLx reply ignored"
|
trace "late or dup RPLx reply ignored"
|
||||||
|
|
||||||
|
|
||||||
proc recvMsg*(peer: Peer): Future[tuple[msgId: uint, msgData: Rlp]] {.async.} =
|
proc recvMsg*(peer: Peer): Future[tuple[msgId: uint64, msgData: Rlp]] {.async.} =
|
||||||
## This procs awaits the next complete RLPx message in the TCP stream
|
## This procs awaits the next complete RLPx message in the TCP stream
|
||||||
|
|
||||||
var headerBytes: array[32, byte]
|
var headerBytes: array[32, byte]
|
||||||
|
@ -610,7 +610,7 @@ proc recvMsg*(peer: Peer): Future[tuple[msgId: uint, msgData: Rlp]] {.async.} =
|
||||||
try:
|
try:
|
||||||
# uint32 as this seems more than big enough for the amount of msgIds
|
# uint32 as this seems more than big enough for the amount of msgIds
|
||||||
msgId = rlp.read(uint32)
|
msgId = rlp.read(uint32)
|
||||||
result = (msgId.uint, rlp)
|
result = (msgId.uint64, rlp)
|
||||||
except RlpError:
|
except RlpError:
|
||||||
await peer.disconnectAndRaise(BreachOfProtocol,
|
await peer.disconnectAndRaise(BreachOfProtocol,
|
||||||
"Cannot read RLPx message id")
|
"Cannot read RLPx message id")
|
||||||
|
@ -680,7 +680,7 @@ proc nextMsg*(peer: Peer, MsgType: type): Future[MsgType] =
|
||||||
# message handler code as the TODO mentions already.
|
# message handler code as the TODO mentions already.
|
||||||
proc dispatchMessages*(peer: Peer) {.async.} =
|
proc dispatchMessages*(peer: Peer) {.async.} =
|
||||||
while peer.connectionState notin {Disconnecting, Disconnected}:
|
while peer.connectionState notin {Disconnecting, Disconnected}:
|
||||||
var msgId: uint
|
var msgId: uint64
|
||||||
var msgData: Rlp
|
var msgData: Rlp
|
||||||
try:
|
try:
|
||||||
(msgId, msgData) = await peer.recvMsg()
|
(msgId, msgData) = await peer.recvMsg()
|
||||||
|
@ -721,7 +721,7 @@ proc dispatchMessages*(peer: Peer) {.async.} =
|
||||||
# The documentation will need to be updated, explaining the fact that
|
# The documentation will need to be updated, explaining the fact that
|
||||||
# nextMsg will be resolved only if the message handler has executed
|
# nextMsg will be resolved only if the message handler has executed
|
||||||
# successfully.
|
# successfully.
|
||||||
if msgId < peer.awaitedMessages.len.uint and
|
if msgId < peer.awaitedMessages.len.uint64 and
|
||||||
peer.awaitedMessages[msgId] != nil:
|
peer.awaitedMessages[msgId] != nil:
|
||||||
let msgInfo = peer.dispatcher.messages[msgId]
|
let msgInfo = peer.dispatcher.messages[msgId]
|
||||||
try:
|
try:
|
||||||
|
@ -791,7 +791,7 @@ proc p2pProtocolBackendImpl*(protocol: P2PProtocol): Backend =
|
||||||
msgIdent = msg.ident
|
msgIdent = msg.ident
|
||||||
msgName = $msgIdent
|
msgName = $msgIdent
|
||||||
msgRecName = msg.recName
|
msgRecName = msg.recName
|
||||||
responseMsgId = if msg.response.isNil: Opt.none(uint) else: msg.response.id
|
responseMsgId = if msg.response.isNil: Opt.none(uint64) else: msg.response.id
|
||||||
hasReqId = msg.hasReqId
|
hasReqId = msg.hasReqId
|
||||||
protocol = msg.protocol
|
protocol = msg.protocol
|
||||||
|
|
||||||
|
@ -812,7 +812,7 @@ proc p2pProtocolBackendImpl*(protocol: P2PProtocol): Backend =
|
||||||
if hasReqId:
|
if hasReqId:
|
||||||
# Messages using request Ids
|
# Messages using request Ids
|
||||||
readParams.add quote do:
|
readParams.add quote do:
|
||||||
let `reqIdVar` = `read`(`receivedRlp`, uint)
|
let `reqIdVar` = `read`(`receivedRlp`, uint64)
|
||||||
|
|
||||||
case msg.kind
|
case msg.kind
|
||||||
of msgRequest:
|
of msgRequest:
|
||||||
|
@ -887,7 +887,7 @@ proc p2pProtocolBackendImpl*(protocol: P2PProtocol): Backend =
|
||||||
thunkName = ident(msgName & "Thunk")
|
thunkName = ident(msgName & "Thunk")
|
||||||
|
|
||||||
msg.defineThunk quote do:
|
msg.defineThunk quote do:
|
||||||
proc `thunkName`(`peerVar`: `Peer`, _: uint, data: Rlp)
|
proc `thunkName`(`peerVar`: `Peer`, _: uint64, data: Rlp)
|
||||||
# Fun error if you just use `RlpError` instead of `rlp.RlpError`:
|
# Fun error if you just use `RlpError` instead of `rlp.RlpError`:
|
||||||
# "Error: type expected, but got symbol 'RlpError' of kind 'EnumField'"
|
# "Error: type expected, but got symbol 'RlpError' of kind 'EnumField'"
|
||||||
{.async: (raises: [rlp.RlpError, EthP2PError]).} =
|
{.async: (raises: [rlp.RlpError, EthP2PError]).} =
|
||||||
|
@ -973,7 +973,7 @@ proc p2pProtocolBackendImpl*(protocol: P2PProtocol): Backend =
|
||||||
|
|
||||||
p2pProtocol DevP2P(version = 5, rlpxName = "p2p"):
|
p2pProtocol DevP2P(version = 5, rlpxName = "p2p"):
|
||||||
proc hello(peer: Peer,
|
proc hello(peer: Peer,
|
||||||
version: uint,
|
version: uint64,
|
||||||
clientId: string,
|
clientId: string,
|
||||||
capabilities: seq[Capability],
|
capabilities: seq[Capability],
|
||||||
listenPort: uint,
|
listenPort: uint,
|
||||||
|
@ -1082,7 +1082,7 @@ proc initPeerState*(peer: Peer, capabilities: openArray[Capability])
|
||||||
# Similarly, we need a bit of book-keeping data to keep track
|
# Similarly, we need a bit of book-keeping data to keep track
|
||||||
# of the potentially concurrent calls to `nextMsg`.
|
# of the potentially concurrent calls to `nextMsg`.
|
||||||
peer.awaitedMessages.newSeq(peer.dispatcher.messages.len)
|
peer.awaitedMessages.newSeq(peer.dispatcher.messages.len)
|
||||||
peer.lastReqId = Opt.some(0u)
|
peer.lastReqId = Opt.some(0u64)
|
||||||
peer.initProtocolStates peer.dispatcher.activeProtocols
|
peer.initProtocolStates peer.dispatcher.activeProtocols
|
||||||
|
|
||||||
proc postHelloSteps(peer: Peer, h: DevP2P.hello) {.async.} =
|
proc postHelloSteps(peer: Peer, h: DevP2P.hello) {.async.} =
|
||||||
|
@ -1145,10 +1145,10 @@ proc initSecretState(p: Peer, hs: Handshake, authMsg, ackMsg: openArray[byte]) =
|
||||||
|
|
||||||
template setSnappySupport(peer: Peer, node: EthereumNode, handshake: Handshake) =
|
template setSnappySupport(peer: Peer, node: EthereumNode, handshake: Handshake) =
|
||||||
when useSnappy:
|
when useSnappy:
|
||||||
peer.snappyEnabled = node.protocolVersion >= devp2pSnappyVersion.uint and
|
peer.snappyEnabled = node.protocolVersion >= devp2pSnappyVersion.uint64 and
|
||||||
handshake.version >= devp2pSnappyVersion.uint
|
handshake.version >= devp2pSnappyVersion.uint64
|
||||||
|
|
||||||
template getVersion(handshake: Handshake): uint =
|
template getVersion(handshake: Handshake): uint64 =
|
||||||
when useSnappy:
|
when useSnappy:
|
||||||
handshake.version
|
handshake.version
|
||||||
else:
|
else:
|
||||||
|
@ -1160,7 +1160,7 @@ template baseProtocolVersion(node: EthereumNode): untyped =
|
||||||
else:
|
else:
|
||||||
devp2pVersion
|
devp2pVersion
|
||||||
|
|
||||||
template baseProtocolVersion(peer: Peer): uint =
|
template baseProtocolVersion(peer: Peer): uint64 =
|
||||||
when useSnappy:
|
when useSnappy:
|
||||||
if peer.snappyEnabled: devp2pSnappyVersion
|
if peer.snappyEnabled: devp2pSnappyVersion
|
||||||
else: devp2pVersion
|
else: devp2pVersion
|
||||||
|
@ -1473,10 +1473,10 @@ when isMainModule:
|
||||||
# are considered GcSafe. The short answer is that they aren't, because
|
# are considered GcSafe. The short answer is that they aren't, because
|
||||||
# they dispatch into user code that might use the GC.
|
# they dispatch into user code that might use the GC.
|
||||||
type
|
type
|
||||||
GcSafeDispatchMsg = proc (peer: Peer, msgId: uint, msgData: var Rlp)
|
GcSafeDispatchMsg = proc (peer: Peer, msgId: uint64, msgData: var Rlp)
|
||||||
|
|
||||||
GcSafeRecvMsg = proc (peer: Peer):
|
GcSafeRecvMsg = proc (peer: Peer):
|
||||||
Future[tuple[msgId: uint, msgData: Rlp]] {.gcsafe.}
|
Future[tuple[msgId: uint64, msgData: Rlp]] {.gcsafe.}
|
||||||
|
|
||||||
GcSafeAccept = proc (transport: StreamTransport, myKeys: KeyPair):
|
GcSafeAccept = proc (transport: StreamTransport, myKeys: KeyPair):
|
||||||
Future[Peer] {.gcsafe.}
|
Future[Peer] {.gcsafe.}
|
||||||
|
|
|
@ -502,10 +502,7 @@ func validate*(self: Rlp) =
|
||||||
# score in order to facilitate easier overloading with user types:
|
# score in order to facilitate easier overloading with user types:
|
||||||
template read*(rlp: var Rlp, T: type): auto =
|
template read*(rlp: var Rlp, T: type): auto =
|
||||||
when T is SomeSignedInt:
|
when T is SomeSignedInt:
|
||||||
let value = readImpl(rlp, uint64)
|
{.error "Signed integer encoding is not defined for rlp".}
|
||||||
if value > uint64(T.high()):
|
|
||||||
raiseIntOutOfBounds()
|
|
||||||
T value
|
|
||||||
else:
|
else:
|
||||||
readImpl(rlp, T)
|
readImpl(rlp, T)
|
||||||
|
|
||||||
|
|
|
@ -301,15 +301,15 @@ proc appendImpl(self: var RlpWriter, data: tuple) {.inline.} =
|
||||||
# We define a single `append` template with a pretty low specificity
|
# We define a single `append` template with a pretty low specificity
|
||||||
# score in order to facilitate easier overloading with user types:
|
# score in order to facilitate easier overloading with user types:
|
||||||
template append*[T](w: var RlpWriter; data: T) =
|
template append*[T](w: var RlpWriter; data: T) =
|
||||||
when data is (SomeSignedInt|enum|bool):
|
when data is (enum|bool):
|
||||||
when data is SomeSignedInt:
|
# TODO detect negative enum values at compile time?
|
||||||
# TODO potentially remove signed integer support - we should never make it
|
|
||||||
# this far!
|
|
||||||
{.warning: "Signed integers cannot reliably be encoded using RLP".}
|
|
||||||
appendImpl(w, uint64(data))
|
appendImpl(w, uint64(data))
|
||||||
else:
|
else:
|
||||||
appendImpl(w, data)
|
appendImpl(w, data)
|
||||||
|
|
||||||
|
template append*(w: var RlpWriter; data: SomeSignedInt) =
|
||||||
|
{.error: "Signed integer encoding is not defined for rlp".}
|
||||||
|
|
||||||
proc initRlpList*(listSize: int): RlpWriter =
|
proc initRlpList*(listSize: int): RlpWriter =
|
||||||
result = initRlpWriter()
|
result = initRlpWriter()
|
||||||
startList(result, listSize)
|
startList(result, listSize)
|
||||||
|
|
|
@ -20,7 +20,7 @@ proc generate() =
|
||||||
|
|
||||||
# valid data for a Ping packet
|
# valid data for a Ping packet
|
||||||
block:
|
block:
|
||||||
let payload = rlp.encode((4, fromAddr, toAddr, expiration()))
|
let payload = rlp.encode((uint64 4, fromAddr, toAddr, expiration()))
|
||||||
let encodedData = @[1.byte] & payload
|
let encodedData = @[1.byte] & payload
|
||||||
debug "Ping", data=byteutils.toHex(encodedData)
|
debug "Ping", data=byteutils.toHex(encodedData)
|
||||||
|
|
||||||
|
|
|
@ -23,9 +23,8 @@ test:
|
||||||
testDecode(payload, uint16)
|
testDecode(payload, uint16)
|
||||||
testDecode(payload, uint32)
|
testDecode(payload, uint32)
|
||||||
testDecode(payload, uint64)
|
testDecode(payload, uint64)
|
||||||
testDecode(payload, int)
|
|
||||||
testDecode(payload, bool)
|
testDecode(payload, bool)
|
||||||
testDecode(payload, seq[byte])
|
testDecode(payload, seq[byte])
|
||||||
testDecode(payload, (string, int32))
|
testDecode(payload, (string, uint32))
|
||||||
testDecode(payload, TestEnum)
|
testDecode(payload, TestEnum)
|
||||||
testDecode(payload, TestObject)
|
testDecode(payload, TestObject)
|
||||||
|
|
|
@ -64,16 +64,24 @@ suite "test api usage":
|
||||||
|
|
||||||
MyObj = object
|
MyObj = object
|
||||||
a: array[3, char]
|
a: array[3, char]
|
||||||
b: int
|
b: uint64
|
||||||
c: MyEnum
|
c: MyEnum
|
||||||
|
|
||||||
|
IntObj = object
|
||||||
|
v: int
|
||||||
|
|
||||||
var input: MyObj
|
var input: MyObj
|
||||||
input.a = ['e', 't', 'h']
|
input.a = ['e', 't', 'h']
|
||||||
input.b = 63
|
input.b = 63
|
||||||
input.c = bar
|
input.c = bar
|
||||||
|
|
||||||
|
|
||||||
var writer = initRlpWriter()
|
var writer = initRlpWriter()
|
||||||
writer.append(input)
|
writer.append(input)
|
||||||
|
|
||||||
|
check:
|
||||||
|
not compiles(writer.append(default(IntObj)))
|
||||||
|
|
||||||
let bytes = writer.finish()
|
let bytes = writer.finish()
|
||||||
var rlp = rlpFromBytes(bytes)
|
var rlp = rlpFromBytes(bytes)
|
||||||
|
|
||||||
|
@ -85,7 +93,7 @@ suite "test api usage":
|
||||||
var writer = initRlpList(3)
|
var writer = initRlpList(3)
|
||||||
writer.append "foo"
|
writer.append "foo"
|
||||||
writer.append ["bar", "baz"]
|
writer.append ["bar", "baz"]
|
||||||
writer.append [30, 40, 50]
|
writer.append [uint64 30, 40, 50]
|
||||||
|
|
||||||
var
|
var
|
||||||
bytes = writer.finish
|
bytes = writer.finish
|
||||||
|
@ -108,14 +116,14 @@ suite "test api usage":
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
bytes = encodeList(6000,
|
bytes = encodeList(uint64 6000,
|
||||||
"Lorem ipsum dolor sit amet",
|
"Lorem ipsum dolor sit amet",
|
||||||
"Donec ligula tortor, egestas eu est vitae")
|
"Donec ligula tortor, egestas eu est vitae")
|
||||||
|
|
||||||
rlp = rlpFromBytes bytes
|
rlp = rlpFromBytes bytes
|
||||||
check:
|
check:
|
||||||
rlp.listLen == 3
|
rlp.listLen == 3
|
||||||
rlp.listElem(0).toInt(int) == 6000
|
rlp.listElem(0).toInt(uint64) == 6000
|
||||||
rlp.listElem(1).toString == "Lorem ipsum dolor sit amet"
|
rlp.listElem(1).toString == "Lorem ipsum dolor sit amet"
|
||||||
rlp.listElem(2).toString == "Donec ligula tortor, egestas eu est vitae"
|
rlp.listElem(2).toString == "Donec ligula tortor, egestas eu est vitae"
|
||||||
|
|
||||||
|
@ -127,8 +135,8 @@ suite "test api usage":
|
||||||
check list.toString == "Lorem ipsum dolor sit amet"
|
check list.toString == "Lorem ipsum dolor sit amet"
|
||||||
list.skipElem
|
list.skipElem
|
||||||
|
|
||||||
check list.toInt(int32) == 6000.int32
|
check list.toInt(uint32) == 6000.uint32
|
||||||
var intVar: int
|
var intVar: uint32
|
||||||
list >> intVar
|
list >> intVar
|
||||||
check intVar == 6000
|
check intVar == 6000
|
||||||
|
|
||||||
|
@ -146,19 +154,19 @@ suite "test api usage":
|
||||||
tok.toHex == "40ef02798f211da2e8173d37f255be908871ae65060dbb2f77fb29c0421447f4"
|
tok.toHex == "40ef02798f211da2e8173d37f255be908871ae65060dbb2f77fb29c0421447f4"
|
||||||
|
|
||||||
test "nested lists":
|
test "nested lists":
|
||||||
let listBytes = encode([[1, 2, 3], [5, 6, 7]])
|
let listBytes = encode([[uint64 1, 2, 3], [uint64 5, 6, 7]])
|
||||||
let listRlp = rlpFromBytes listBytes
|
let listRlp = rlpFromBytes listBytes
|
||||||
let sublistRlp0 = listRlp.listElem(0)
|
let sublistRlp0 = listRlp.listElem(0)
|
||||||
let sublistRlp1 = listRlp.listElem(1)
|
let sublistRlp1 = listRlp.listElem(1)
|
||||||
check sublistRlp0.listElem(0).toInt(int) == 1
|
check sublistRlp0.listElem(0).toInt(uint64) == 1
|
||||||
check sublistRlp0.listElem(1).toInt(int) == 2
|
check sublistRlp0.listElem(1).toInt(uint64) == 2
|
||||||
check sublistRlp0.listElem(2).toInt(int) == 3
|
check sublistRlp0.listElem(2).toInt(uint64) == 3
|
||||||
check sublistRlp1.listElem(0).toInt(int) == 5
|
check sublistRlp1.listElem(0).toInt(uint64) == 5
|
||||||
check sublistRlp1.listElem(1).toInt(int) == 6
|
check sublistRlp1.listElem(1).toInt(uint64) == 6
|
||||||
check sublistRlp1.listElem(2).toInt(int) == 7
|
check sublistRlp1.listElem(2).toInt(uint64) == 7
|
||||||
|
|
||||||
test "encoding length":
|
test "encoding length":
|
||||||
let listBytes = encode([1,2,3,4,5])
|
let listBytes = encode([uint64 1,2,3,4,5])
|
||||||
let listRlp = rlpFromBytes listBytes
|
let listRlp = rlpFromBytes listBytes
|
||||||
check listRlp.listLen == 5
|
check listRlp.listLen == 5
|
||||||
|
|
||||||
|
@ -208,8 +216,8 @@ suite "test api usage":
|
||||||
bar = 0x01
|
bar = 0x01
|
||||||
|
|
||||||
var writer = initRlpWriter()
|
var writer = initRlpWriter()
|
||||||
writer.append(1) # valid
|
writer.append(byte 1) # valid
|
||||||
writer.append(2) # invalid
|
writer.append(byte 2) # invalid
|
||||||
writer.append(cast[uint64](-1)) # invalid
|
writer.append(cast[uint64](-1)) # invalid
|
||||||
let bytes = writer.finish()
|
let bytes = writer.finish()
|
||||||
var rlp = rlpFromBytes(bytes)
|
var rlp = rlpFromBytes(bytes)
|
||||||
|
@ -231,10 +239,10 @@ suite "test api usage":
|
||||||
baz = 0x0100
|
baz = 0x0100
|
||||||
|
|
||||||
var writer = initRlpWriter()
|
var writer = initRlpWriter()
|
||||||
writer.append(1) # valid
|
writer.append(1'u64) # valid
|
||||||
writer.append(2) # invalid - enum hole value
|
writer.append(2'u64) # invalid - enum hole value
|
||||||
writer.append(256) # valid
|
writer.append(256'u64) # valid
|
||||||
writer.append(257) # invalid - too large
|
writer.append(257'u64) # invalid - too large
|
||||||
let bytes = writer.finish()
|
let bytes = writer.finish()
|
||||||
var rlp = rlpFromBytes(bytes)
|
var rlp = rlpFromBytes(bytes)
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ type
|
||||||
HelloObj = object
|
HelloObj = object
|
||||||
version*: uint
|
version*: uint
|
||||||
clientId*: string
|
clientId*: string
|
||||||
capabilities*: seq[(string,int)]
|
capabilities*: seq[(string,uint)]
|
||||||
listenPort*: uint
|
listenPort*: uint
|
||||||
nodeId*: array[64, byte]
|
nodeId*: array[64, byte]
|
||||||
|
|
||||||
|
|
|
@ -8,15 +8,15 @@ import
|
||||||
|
|
||||||
type
|
type
|
||||||
Transaction = object
|
Transaction = object
|
||||||
amount: int
|
amount: uint64
|
||||||
time: Time
|
time: uint64
|
||||||
sender: string
|
sender: string
|
||||||
receiver: string
|
receiver: string
|
||||||
|
|
||||||
Foo = object
|
Foo = object
|
||||||
x: uint64
|
x: uint64
|
||||||
y: string
|
y: string
|
||||||
z: seq[int]
|
z: seq[uint64]
|
||||||
|
|
||||||
Bar = object
|
Bar = object
|
||||||
b: string
|
b: string
|
||||||
|
@ -24,7 +24,7 @@ type
|
||||||
|
|
||||||
CustomSerialized = object
|
CustomSerialized = object
|
||||||
customFoo {.rlpCustomSerialization.}: Foo
|
customFoo {.rlpCustomSerialization.}: Foo
|
||||||
ignored {.rlpIgnore.}: int
|
ignored {.rlpIgnore.}: uint64
|
||||||
|
|
||||||
rlpFields Foo,
|
rlpFields Foo,
|
||||||
x, y, z
|
x, y, z
|
||||||
|
@ -34,19 +34,19 @@ rlpFields Transaction,
|
||||||
|
|
||||||
proc append*(rlpWriter: var RlpWriter, holder: CustomSerialized, f: Foo) =
|
proc append*(rlpWriter: var RlpWriter, holder: CustomSerialized, f: Foo) =
|
||||||
rlpWriter.append(f.x)
|
rlpWriter.append(f.x)
|
||||||
rlpWriter.append(f.y.len)
|
rlpWriter.append(uint64 f.y.len)
|
||||||
rlpWriter.append(holder.ignored)
|
rlpWriter.append(holder.ignored)
|
||||||
|
|
||||||
proc read*(rlp: var Rlp, holder: var CustomSerialized, T: type Foo): Foo =
|
proc read*(rlp: var Rlp, holder: var CustomSerialized, T: type Foo): Foo =
|
||||||
result.x = rlp.read(uint64)
|
result.x = rlp.read(uint64)
|
||||||
result.y = newString(rlp.read(int))
|
result.y = newString(rlp.read(uint64))
|
||||||
holder.ignored = rlp.read(int) * 2
|
holder.ignored = rlp.read(uint64) * 2
|
||||||
|
|
||||||
proc suite() =
|
proc suite() =
|
||||||
suite "object serialization":
|
suite "object serialization":
|
||||||
test "encoding and decoding an object":
|
test "encoding and decoding an object":
|
||||||
var originalBar = Bar(b: "abracadabra",
|
var originalBar = Bar(b: "abracadabra",
|
||||||
f: Foo(x: 5'u64, y: "hocus pocus", z: @[100, 200, 300]))
|
f: Foo(x: 5'u64, y: "hocus pocus", z: @[uint64 100, 200, 300]))
|
||||||
|
|
||||||
var bytes = encode(originalBar)
|
var bytes = encode(originalBar)
|
||||||
var r = rlpFromBytes(bytes)
|
var r = rlpFromBytes(bytes)
|
||||||
|
@ -55,13 +55,13 @@ proc suite() =
|
||||||
check:
|
check:
|
||||||
originalBar == restoredBar
|
originalBar == restoredBar
|
||||||
|
|
||||||
var t1 = Transaction(time: getTime(), amount: 1000, sender: "Alice", receiver: "Bob")
|
var t1 = Transaction(time: 100, amount: 1000, sender: "Alice", receiver: "Bob")
|
||||||
bytes = encode(t1)
|
bytes = encode(t1)
|
||||||
var t2 = bytes.decode(Transaction)
|
var t2 = bytes.decode(Transaction)
|
||||||
|
|
||||||
check:
|
check:
|
||||||
bytes.toHex == "cd85416c69636583426f628203e8" # verifies that Alice comes first
|
bytes.toHex == "cd85416c69636583426f628203e8" # verifies that Alice comes first
|
||||||
t2.time == default(Time)
|
t2.time == 0
|
||||||
t2.sender == "Alice"
|
t2.sender == "Alice"
|
||||||
t2.receiver == "Bob"
|
t2.receiver == "Bob"
|
||||||
t2.amount == 1000
|
t2.amount == 1000
|
||||||
|
|
|
@ -9,9 +9,11 @@ proc append(output: var RlpWriter, js: JsonNode) =
|
||||||
of JNull, JFloat, JObject:
|
of JNull, JFloat, JObject:
|
||||||
raise newException(ValueError, "Unsupported JSON value type " & $js.kind)
|
raise newException(ValueError, "Unsupported JSON value type " & $js.kind)
|
||||||
of JBool:
|
of JBool:
|
||||||
output.append js.bval.int
|
output.append js.bval
|
||||||
of JInt:
|
of JInt:
|
||||||
output.append int(js.num)
|
if js.num < 0:
|
||||||
|
raise newException(ValueError, "Integer out of range: " & $js.num)
|
||||||
|
output.append uint64(js.num)
|
||||||
of JString:
|
of JString:
|
||||||
output.append js.str
|
output.append js.str
|
||||||
of JArray:
|
of JArray:
|
||||||
|
|
Loading…
Reference in New Issue