Eric Mastro 3b718baa97
feat: allow msgIdProvider to fail (#688)
* feat: allow msgIdProvider to fail

Closes: #642.

Changes the return type of the msgIdProvider to `Result[MessageID, string]` so that message id generation can fail.

String error type was chosen as this `msgIdProvider` mainly because the failed message id generation drops the message and logs the error provided. Because `msgIdProvider` can be externally provided by library consumers, an enum didn’t make sense and a object seemed to be overkill. Exceptions could have been used as well, however, in this case, Result ergonomics were warranted and prevented wrapping quite a large block of code in try/except.

The `defaultMsgIdProvider` function previously allowed message id generation to fail silently for use in the tests: when seqno or source peerid were not valid, the message id generated was based on a hash of the message data and topic ids. The silent failing was moved to the `defaultMsgIdProvider` used only in the tests so that it could not fail silently in applications.

Unit tests were added for the `defaultMsgIdProvider`.

* Change MsgIdProvider error type to ValidationResult
2022-02-21 16:04:17 +01:00

76 lines
2.4 KiB
Nim

import unittest2
{.used.}
import options
import stew/byteutils
import ../../libp2p/[peerid, peerinfo,
crypto/crypto,
protocols/pubsub/errors,
protocols/pubsub/rpc/message,
protocols/pubsub/rpc/messages]
let rng = newRng()
suite "Message":
test "signature":
var seqno = 11'u64
let
peer = PeerInfo.new(PrivateKey.random(ECDSA, rng[]).get())
msg = Message.init(some(peer), @[], "topic", some(seqno), sign = true)
check verify(msg)
test "defaultMsgIdProvider success":
let
seqno = 11'u64
pkHex =
"""08011240B9EA7F0357B5C1247E4FCB5AD09C46818ECB07318CA84711875F4C6C
E6B946186A4EB44E0D714B2A2D48263D75CF52D30BEF9D9AE2A9FEB7DAF1775F
E731065A"""
seckey = PrivateKey.init(fromHex(stripSpaces(pkHex)))
.expect("invalid private key bytes")
peer = PeerInfo.new(seckey)
msg = Message.init(some(peer), @[], "topic", some(seqno), sign = true)
msgIdResult = msg.defaultMsgIdProvider()
check:
msgIdResult.isOk
string.fromBytes(msgIdResult.get) ==
"000000000000000b12D3KooWGyLzSt9g4U9TdHYDvVWAs5Ht4WrocgoyqPxxvnqAL8qw"
test "defaultMsgIdProvider error - no source peer id":
let
seqno = 11'u64
pkHex =
"""08011240B9EA7F0357B5C1247E4FCB5AD09C46818ECB07318CA84711875F4C6C
E6B946186A4EB44E0D714B2A2D48263D75CF52D30BEF9D9AE2A9FEB7DAF1775F
E731065A"""
seckey = PrivateKey.init(fromHex(stripSpaces(pkHex)))
.expect("invalid private key bytes")
peer = PeerInfo.new(seckey)
var msg = Message.init(peer.some, @[], "topic", some(seqno), sign = true)
msg.fromPeer = PeerId()
let msgIdResult = msg.defaultMsgIdProvider()
check:
msgIdResult.isErr
msgIdResult.error == ValidationResult.Reject
test "defaultMsgIdProvider error - no source seqno":
let
pkHex =
"""08011240B9EA7F0357B5C1247E4FCB5AD09C46818ECB07318CA84711875F4C6C
E6B946186A4EB44E0D714B2A2D48263D75CF52D30BEF9D9AE2A9FEB7DAF1775F
E731065A"""
seckey = PrivateKey.init(fromHex(stripSpaces(pkHex)))
.expect("invalid private key bytes")
peer = PeerInfo.new(seckey)
msg = Message.init(some(peer), @[], "topic", uint64.none, sign = true)
msgIdResult = msg.defaultMsgIdProvider()
check:
msgIdResult.isErr
msgIdResult.error == ValidationResult.Reject