Skip to content

Commit

Permalink
Merge branch 'master' into feature/cleanup-ci
Browse files Browse the repository at this point in the history
* master:
  feat: adding onValidated observer (#1128)
  fix: add gcc 14 support (#1151)
  fix(ci): windows-amd64 (Nim version-1-6) (#1160)
  • Loading branch information
AlejandroCabeza committed Aug 1, 2024
2 parents c5a3632 + a60f0c5 commit 183c6a6
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 10 deletions.
22 changes: 20 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ jobs:
cpu: amd64
- os: linux
cpu: i386
- os: linux-gcc-14
cpu: amd64
- os: macos
cpu: amd64
- os: windows
Expand All @@ -34,9 +36,13 @@ jobs:
include:
- platform:
os: linux
builder: ubuntu-22.04
builder: ubuntu-24.04
shell: bash
- platform:
os: linux-gcc-14
builder: ubuntu-24.04
shell: bash
- target:
os: macos
builder: macos-13
shell: bash
Expand Down Expand Up @@ -79,16 +85,28 @@ jobs:
uses: actions/cache@v3
with:
path: nimbledeps
key: nimbledeps-${{ hashFiles('.pinned') }}
# Using nim.branch as a simple way to differentiate between nimble using the "pkgs" or "pkgs2" directories.
# The change happened on Nimble v0.14.0.
key: nimbledeps-${{ matrix.nim.branch }}-${{ hashFiles('.pinned') }} # hashFiles returns a different value on windows

- name: Install deps
if: ${{ steps.deps-cache.outputs.cache-hit != 'true' }}
run: |
nimble install_pinned
- name: Use gcc 14
if : ${{ matrix.target.os == 'linux-gcc-14'}}
run: |
# Add GCC-14 to alternatives
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-14 14
# Set GCC-14 as the default
sudo update-alternatives --set gcc /usr/bin/gcc-14
- name: Run tests
run: |
nim --version
nimble --version
gcc --version
NIMFLAGS="${NIMFLAGS} --mm:${{ matrix.nim.memory_management }}"
nimble test
4 changes: 2 additions & 2 deletions .pinned
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
bearssl;https://github.com/status-im/nim-bearssl@#e4157639db180e52727712a47deaefcbbac6ec86
bearssl;https://github.com/status-im/nim-bearssl@#667b40440a53a58e9f922e29e20818720c62d9ac
chronicles;https://github.com/status-im/nim-chronicles@#32ac8679680ea699f7dbc046e8e0131cac97d41a
chronos;https://github.com/status-im/nim-chronos@#672db137b7cad9b384b8f4fb551fb6bbeaabfe1b
chronos;https://github.com/status-im/nim-chronos@#dc3847e4d6733dfc3811454c2a9c384b87343e26
dnsclient;https://github.com/ba0f3/dnsclient.nim@#23214235d4784d24aceed99bbfe153379ea557c8
faststreams;https://github.com/status-im/nim-faststreams@#720fc5e5c8e428d9d0af618e1e27c44b42350309
httputils;https://github.com/status-im/nim-http-utils@#3b491a40c60aad9e8d3407443f46f62511e63b18
Expand Down
4 changes: 2 additions & 2 deletions libp2p.nimble
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ license = "MIT"
skipDirs = @["tests", "examples", "Nim", "tools", "scripts", "docs"]

requires "nim >= 1.6.0",
"nimcrypto >= 0.4.1", "dnsclient >= 0.3.0 & < 0.4.0", "bearssl >= 0.1.4",
"chronicles >= 0.10.2", "chronos >= 4.0.0", "metrics", "secp256k1", "stew#head",
"nimcrypto >= 0.4.1", "dnsclient >= 0.3.0 & < 0.4.0", "bearssl >= 0.2.5",
"chronicles >= 0.10.2", "chronos >= 4.0.2", "metrics", "secp256k1", "stew#head",
"websock", "unittest2"

let nimc = getEnv("NIMC", "nim") # Which nim compiler to use
Expand Down
4 changes: 3 additions & 1 deletion libp2p/crypto/curve25519.nim
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@ proc public*(private: Curve25519Key): Curve25519Key =
proc random*(_: type[Curve25519Key], rng: var HmacDrbgContext): Curve25519Key =
var res: Curve25519Key
let defaultBrEc = ecGetDefault()
let len = ecKeygen(addr rng.vtable, defaultBrEc, nil, addr res[0], EC_curve25519)
let len = ecKeygen(
PrngClassPointerConst(addr rng.vtable), defaultBrEc, nil, addr res[0], EC_curve25519
)
# Per bearssl documentation, the keygen only fails if the curve is
# unrecognised -
doAssert len == Curve25519KeySize, "Could not generate curve"
Expand Down
6 changes: 5 additions & 1 deletion libp2p/crypto/ecnist.nim
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,11 @@ proc random*(
var ecimp = ecGetDefault()
var res = new EcPrivateKey
if ecKeygen(
addr rng.vtable, ecimp, addr res.key, addr res.buffer[0], safeConvert[cint](kind)
PrngClassPointerConst(addr rng.vtable),
ecimp,
addr res.key,
addr res.buffer[0],
safeConvert[cint](kind),
) == 0:
err(EcKeyGenError)
else:
Expand Down
3 changes: 3 additions & 0 deletions libp2p/protocols/pubsub/gossipsub.nim
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,9 @@ proc validateAndRelay(

g.rewardDelivered(peer, topic, true)

# trigger hooks
peer.validatedObservers(msg, msgId)

# The send list typically matches the idontwant list from above, but
# might differ if validation takes time
var toSendPeers = HashSet[PubSubPeer]()
Expand Down
15 changes: 13 additions & 2 deletions libp2p/protocols/pubsub/pubsubpeer.nim
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ type
PubSubObserver* = ref object
onRecv*: proc(peer: PubSubPeer, msgs: var RPCMsg) {.gcsafe, raises: [].}
onSend*: proc(peer: PubSubPeer, msgs: var RPCMsg) {.gcsafe, raises: [].}
onValidated*:
proc(peer: PubSubPeer, msg: Message, msgId: MessageId) {.gcsafe, raises: [].}

PubSubPeerEventKind* {.pure.} = enum
StreamOpened
Expand Down Expand Up @@ -170,14 +172,23 @@ proc recvObservers*(p: PubSubPeer, msg: var RPCMsg) =
if not (isNil(p.observers)) and p.observers[].len > 0:
for obs in p.observers[]:
if not (isNil(obs)): # TODO: should never be nil, but...
obs.onRecv(p, msg)
if not (isNil(obs.onRecv)):
obs.onRecv(p, msg)

proc validatedObservers*(p: PubSubPeer, msg: Message, msgId: MessageId) =
# trigger hooks
if not (isNil(p.observers)) and p.observers[].len > 0:
for obs in p.observers[]:
if not (isNil(obs.onValidated)):
obs.onValidated(p, msg, msgId)

proc sendObservers(p: PubSubPeer, msg: var RPCMsg) =
# trigger hooks
if not (isNil(p.observers)) and p.observers[].len > 0:
for obs in p.observers[]:
if not (isNil(obs)): # TODO: should never be nil, but...
obs.onSend(p, msg)
if not (isNil(obs.onSend)):
obs.onSend(p, msg)

proc handle*(p: PubSubPeer, conn: Connection) {.async.} =
debug "starting pubsub read loop", conn, peer = p, closed = conn.closed
Expand Down
57 changes: 57 additions & 0 deletions tests/pubsub/testgossipsub.nim
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,63 @@ suite "GossipSub":

await allFuturesThrowing(nodesFut.concat())

asyncTest "GossipSub's observers should run after message is sent, received and validated":
var
recvCounter = 0
sendCounter = 0
validatedCounter = 0

proc handler(topic: string, data: seq[byte]) {.async.} =
discard

proc onRecv(peer: PubSubPeer, msgs: var RPCMsg) =
inc recvCounter

proc onSend(peer: PubSubPeer, msgs: var RPCMsg) =
inc sendCounter

proc onValidated(peer: PubSubPeer, msg: Message, msgId: MessageId) =
inc validatedCounter

let obs0 = PubSubObserver(onSend: onSend)
let obs1 = PubSubObserver(onRecv: onRecv, onValidated: onValidated)

let nodes = generateNodes(2, gossip = true)
# start switches
discard await allFinished(nodes[0].switch.start(), nodes[1].switch.start())

await subscribeNodes(nodes)

nodes[0].addObserver(obs0)
nodes[1].addObserver(obs1)
nodes[1].subscribe("foo", handler)
nodes[1].subscribe("bar", handler)

proc validator(
topic: string, message: Message
): Future[ValidationResult] {.async.} =
result = if topic == "foo": ValidationResult.Accept else: ValidationResult.Reject

nodes[1].addValidator("foo", "bar", validator)

# Send message that will be accepted by the receiver's validator
tryPublish await nodes[0].publish("foo", "Hello!".toBytes()), 1

check:
recvCounter == 1
validatedCounter == 1
sendCounter == 1

# Send message that will be rejected by the receiver's validator
tryPublish await nodes[0].publish("bar", "Hello!".toBytes()), 1

check:
recvCounter == 2
validatedCounter == 1
sendCounter == 2

await allFuturesThrowing(nodes[0].switch.stop(), nodes[1].switch.stop())

asyncTest "GossipSub unsub - resub faster than backoff":
var handlerFut = newFuture[bool]()
proc handler(topic: string, data: seq[byte]) {.async.} =
Expand Down

0 comments on commit 183c6a6

Please sign in to comment.