Skip to content

Commit b08a339

Browse files
authored
chore(signed-envelope): utilize protobuf-serialization (#2650)
1 parent 2cf1b25 commit b08a339

19 files changed

Lines changed: 72 additions & 129 deletions

libp2p/extended_peer_record.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ proc isValid*(xpr: SignedExtendedPeerRecord): bool =
138138
if not svc.isValid():
139139
return false
140140
let encoded = xpr.encode()
141-
if encoded.isErr or encoded.get().len == 0 or encoded.get().len > MaxXPRSize:
141+
if encoded.len == 0 or encoded.len > MaxXPRSize:
142142
return false
143143
true
144144

libp2p/protocols/connectivity/relay/relay.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ proc createReserveResponse(
8484
rsrv = Reservation(
8585
expire: Opt.some(expireUnix),
8686
addrs: r.switch.peerInfo.addrs.mapIt(?it.concat(ma).orErr(CryptoError.KeyError)),
87-
svoucher: Opt.some(?sv.encode),
87+
svoucher: Opt.some(sv.encode),
8888
)
8989
msg = HopMessage(
9090
msgType: Opt.some(HopMessageType.Status),

libp2p/protocols/identify.nim

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,7 @@ proc makeIdentifyMsg(
9393
## Optionally populate signedPeerRecord field.
9494
## See https://github.com/libp2p/go-libp2p/blob/ddf96ce1cfa9e19564feb9bd3e8269958bbc0aba/p2p/protocol/identify/pb/identify.proto for reference.
9595
if sign:
96-
pi.signedPeerRecord.envelope.encode().withValue(value):
97-
spr = Opt.some(value)
96+
spr = Opt.some(pi.signedPeerRecord.envelope.encode())
9897

9998
IdentifyMsg(
10099
publicKey: Opt.some(pi.publicKey),

libp2p/protocols/pubsub/gossipsub/behavior.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ proc peerExchangeList*(g: GossipSub, topic: string): seq[PeerInfoMsg] =
123123
peerId: x.peerId,
124124
signedPeerRecord:
125125
if x.peerId in sprBook:
126-
sprBook[x.peerId].encode().get(default(seq[byte]))
126+
sprBook[x.peerId].encode()
127127
else:
128128
default(seq[byte]),
129129
)

libp2p/protocols/rendezvous/rendezvous.nim

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -327,8 +327,7 @@ proc advertise*[E](
327327
info "Can't create the signed peer record", error = error
328328
return
329329

330-
let pBuff = signedPeerRecord.encode().valueOr:
331-
raise newException(AdvertiseError, "Wrong Custom Peer Record")
330+
let pBuff = signedPeerRecord.encode()
332331
await rdv.advertise(ns, ttl, peers, Opt.some(pBuff))
333332

334333
proc advertise*[E](
@@ -364,8 +363,7 @@ method advertise*(
364363
if rdv.switch.isNil:
365364
# I don't like this, but adding this as i don't understand why we have a constructor without switch as arg
366365
raise newException(AdvertiseError, "Rendezvous not setup with a switch")
367-
let sprBuff = rdv.switch.peerInfo.signedPeerRecord.encode().valueOr:
368-
raise newException(AdvertiseError, "Wrong Signed Peer Record")
366+
let sprBuff = rdv.switch.peerInfo.signedPeerRecord.encode()
369367
await rdv.advertise(ns, lttl, rdv.peers, sprBuff)
370368

371369
proc requestLocally*[E](rdv: GenericRendezVous[E], ns: string): seq[E] =

libp2p/protocols/service_discovery.nim

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,7 @@ proc refreshSelfSignedPeerRecord(
2323
error "Failed to create signed extended peer record", error
2424
return
2525

26-
let encodedSR = extPeerRecord.encode().valueOr:
27-
error "Failed to encode signed peer record", error
28-
return
29-
26+
let encodedSR = extPeerRecord.encode()
3027
let key = disco.switch.peerInfo.peerId.toKey()
3128

3229
debug "Publishing Signed XPR", xpr = $extPeerRecord

libp2p/protocols/service_discovery/advertiser.nim

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,7 @@ proc getAdvertBytes(disco: ServiceDiscovery, explicit: Opt[seq[byte]]): Opt[seq[
4343
let extRecord = disco.record().valueOr:
4444
error "failed to create extended peer record", error
4545
return Opt.none(seq[byte])
46-
let bytes = extRecord.encode().valueOr:
47-
error "failed to encode advertisement", error
48-
return Opt.none(seq[byte])
49-
Opt.some(bytes)
46+
Opt.some(extRecord.encode())
5047

5148
proc advertiseToRegistrar*(
5249
disco: ServiceDiscovery,

libp2p/protocols/service_discovery/types.nim

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,7 @@ proc encode*(ads: seq[Advertisement], fReturn: int): seq[seq[byte]] {.raises: []
140140
for ad in ads:
141141
if adBytes.len >= fReturn:
142142
break
143-
let encoded = ad.encode().valueOr:
144-
error "failed to encode advertisement", error
145-
continue
146-
adBytes.add(encoded)
143+
adBytes.add(ad.encode())
147144
adBytes
148145

149146
proc hashServiceId*(serviceStr: string): ServiceId =

libp2p/signed_envelope.nim

Lines changed: 39 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77

88
import std/sugar
99
import pkg/stew/byteutils, pkg/results
10-
import multicodec, crypto/crypto, protobuf/minprotobuf, vbuffer
10+
import multicodec, crypto/crypto, vbuffer
11+
import protobuf_serialization
1112

1213
export crypto
1314

@@ -18,46 +19,21 @@ type
1819
EnvelopeInvalidSignature
1920
EnvelopeWrongType
2021

21-
Envelope* = object
22-
publicKey*: PublicKey
23-
domain*: string
24-
payloadType*: seq[byte]
25-
payload: seq[byte]
26-
signature*: Signature
22+
Envelope* {.proto3.} = object
23+
publicKey* {.fieldNumber: 1, ext.}: PublicKey
24+
payloadType* {.fieldNumber: 2.}: seq[byte]
25+
payload {.fieldNumber: 3.}: seq[byte]
26+
signature* {.fieldNumber: 5, ext.}: Signature
2727

28-
proc mapProtobufError(e: ProtoError): EnvelopeError =
29-
case e
30-
of RequiredFieldMissing: EnvelopeFieldMissing
31-
else: EnvelopeInvalidProtobuf
32-
33-
proc getSignatureBuffer(e: Envelope): seq[byte] =
28+
proc getSignatureBuffer(e: Envelope, domain: string): seq[byte] =
3429
var buffer = initVBuffer()
3530

36-
let domainBytes = e.domain.toBytes()
37-
buffer.writeSeq(domainBytes)
31+
buffer.writeSeq(domain.toBytes())
3832
buffer.writeSeq(e.payloadType)
3933
buffer.writeSeq(e.payload)
4034

4135
buffer.buffer
4236

43-
proc decode*(
44-
T: typedesc[Envelope], buf: sink seq[byte], domain: string
45-
): Result[Envelope, EnvelopeError] =
46-
let pb = initProtoBuffer(move(buf))
47-
var envelope = Envelope()
48-
49-
envelope.domain = domain
50-
?pb.getRequiredField(1, envelope.publicKey).mapErr(mapProtobufError)
51-
discard ?pb.getField(2, envelope.payloadType).mapErr(mapProtobufError)
52-
?pb.getRequiredField(3, envelope.payload).mapErr(mapProtobufError)
53-
?pb.getRequiredField(5, envelope.signature).mapErr(mapProtobufError)
54-
55-
if envelope.signature.verify(envelope.getSignatureBuffer(), envelope.publicKey) ==
56-
false:
57-
err(EnvelopeInvalidSignature)
58-
else:
59-
ok(envelope)
60-
6137
proc init*(
6238
T: typedesc[Envelope],
6339
privateKey: PrivateKey,
@@ -67,49 +43,43 @@ proc init*(
6743
): Result[Envelope, CryptoError] =
6844
var envelope = Envelope(
6945
publicKey: ?privateKey.getPublicKey(),
70-
domain: domain,
7146
payloadType: move(payloadType),
7247
payload: move(payload),
7348
)
7449

75-
envelope.signature = ?privateKey.sign(envelope.getSignatureBuffer())
50+
envelope.signature = ?privateKey.sign(envelope.getSignatureBuffer(domain))
7651

7752
ok(envelope)
7853

79-
proc encode*(env: Envelope): Result[seq[byte], CryptoError] =
80-
var pb = initProtoBuffer()
54+
proc verify*(envelope: Envelope, domain: string): bool =
55+
envelope.signature.verify(envelope.getSignatureBuffer(domain), envelope.publicKey)
56+
57+
proc encode*(envelope: Envelope): seq[byte] =
58+
Protobuf.encode(envelope)
8159

82-
try:
83-
pb.write(1, env.publicKey)
84-
pb.write(2, env.payloadType)
85-
pb.write(3, env.payload)
86-
pb.write(5, env.signature)
87-
except ResultError[CryptoError] as exc:
88-
return err(exc.error)
60+
proc decode*(
61+
_: type Envelope, buf: seq[byte], domain: string
62+
): Result[Envelope, EnvelopeError] =
63+
let envelope =
64+
try:
65+
Protobuf.decode(buf, Envelope)
66+
except SerializationError:
67+
return err(EnvelopeInvalidProtobuf)
8968

90-
pb.finish()
91-
ok(pb.buffer)
69+
if envelope.publicKey.getBytes().isErr:
70+
return err(EnvelopeFieldMissing)
9271

93-
proc payload*(env: Envelope): seq[byte] =
72+
if envelope.signature.data.len == 0:
73+
return err(EnvelopeFieldMissing)
74+
75+
if not envelope.verify(domain):
76+
return err(EnvelopeInvalidSignature)
77+
78+
ok(envelope)
79+
80+
proc payload*(envelope: Envelope): seq[byte] =
9481
# Payload is readonly
95-
env.payload
96-
97-
proc getField*(
98-
pb: ProtoBuffer, field: int, value: var Envelope, domain: string
99-
): ProtoResult[bool] =
100-
var buffer: seq[byte]
101-
let res = ?pb.getField(field, buffer)
102-
if not (res):
103-
ok(false)
104-
else:
105-
value = Envelope.decode(move(buffer), domain).valueOr:
106-
return err(ProtoError.IncorrectBlob)
107-
ok(true)
108-
109-
proc write*(pb: var ProtoBuffer, field: int, env: Envelope): Result[void, CryptoError] =
110-
let e = ?env.encode()
111-
pb.write(field, e)
112-
ok()
82+
envelope.payload
11383

11484
type SignedPayload*[T] = object
11585
# T needs to have .encode(), .decode(), .payloadType(), .payloadDomain()
@@ -126,31 +96,20 @@ proc init*[T](
12696

12797
ok(SignedPayload[T](data: data, envelope: envelope))
12898

129-
proc getField*[T](
130-
pb: ProtoBuffer, field: int, value: var SignedPayload[T]
131-
): ProtoResult[bool] =
132-
if not ?getField(pb, field, value.envelope, T.payloadDomain):
133-
ok(false)
134-
else:
135-
mixin decode
136-
value.data = ?T.decode(value.envelope.payload).mapErr(x => ProtoError.IncorrectBlob)
137-
ok(true)
138-
13999
proc decode*[T](
140100
_: typedesc[SignedPayload[T]], envelope: Envelope
141101
): Result[SignedPayload[T], EnvelopeError] =
142102
mixin decode
143103

144-
if envelope.domain != T.payloadDomain:
104+
if envelope.payloadType != T.payloadType:
145105
return err(EnvelopeWrongType)
106+
if not envelope.verify(T.payloadDomain):
107+
return err(EnvelopeInvalidSignature)
146108

147109
let
148110
data = ?T.decode(envelope.payload).mapErr(x => EnvelopeInvalidProtobuf)
149111
signedPayload = SignedPayload[T](envelope: envelope, data: data)
150112

151-
if envelope.payloadType != T.payloadType:
152-
return err(EnvelopeWrongType)
153-
154113
when compiles(?signedPayload.checkValid()):
155114
?signedPayload.checkValid()
156115

@@ -162,5 +121,5 @@ proc decode*[T](
162121
let envelope = ?Envelope.decode(move(buffer), T.payloadDomain)
163122
SignedPayload[T].decode(envelope)
164123

165-
proc encode*[T](msg: SignedPayload[T]): Result[seq[byte], CryptoError] =
124+
proc encode*[T](msg: SignedPayload[T]): seq[byte] =
166125
msg.envelope.encode()

tests/libp2p/discovery/test_rendezvous.nim

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,7 @@ proc advertise*(
113113
rdv.switch.peerInfo.privateKey, customPeerRecord
114114
).valueOr:
115115
raise newException(AdvertiseError, "Failed to sign Custom Peer Record")
116-
let sprBuff = se.encode().valueOr:
117-
raise newException(AdvertiseError, "Wrong Signed Peer Record")
116+
let sprBuff = se.encode()
118117
await rdv.advertise(namespace, rdv.config.minDuration, rdv.peers, sprBuff)
119118

120119
suite "RendezVous":

0 commit comments

Comments
 (0)