Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
390 changes: 369 additions & 21 deletions Tests/Host.lean

Large diffs are not rendered by default.

83 changes: 83 additions & 0 deletions Tests/HostPair.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import Conc
import Streams
import Libp2p.Identity
import Libp2p.Security
import Libp2p.Mux
import Libp2p.Host
import Multiformats.Multiaddr

/-!
# Two hosts over the sim

The protocol suites run their handlers between two real hosts, on the
test values of root §3.1 (PRINCIPLES 1.4): the in-memory sim transport,
the fixed-key Noise value with Ed25519 identities from one byte each,
and a test clock. The muxer is yamux. The server listens on
`/memory/4100`, and the client holds a session to it.
-/

set_option autoImplicit false

namespace Tests.HostPair

open Conc (Async Clock OnceRef TestClock)
open Libp2p.Host (Host Failure)

/-- A host on `net` and `clock`: the fixed-key Noise value with an
Ed25519 identity from one byte, yamux, and the sim transport. The
ephemeral keys come from an `Rng` seeded with 32 copies of
`idByte + 50`. Its failures go to `failures`. -/
def mkHost (net : Streams.Sim.Net) (clock : Clock) (idByte : UInt8)
(failures : OnceRef (List Failure)) : Async Host := do
let .ok identity := Libp2p.Identity.PrivKey.ofData? .ed25519 ⟨Array.replicate 32 idByte⟩
| throw (IO.userError "test identity does not build")
let some static := Libp2p.Security.Noise.Bytes32.ofByteArray? ⟨Array.replicate 32 (idByte + 100)⟩
| throw (IO.userError "test static key is not 32 bytes")
let noise := Libp2p.Security.Noise.fixedKeyProtocol { identity, static }
⟨Array.replicate 32 (idByte + 50)⟩
match ← (Host.new {
identity
transports := [net.transport]
security := [noise]
muxers := [Libp2p.Mux.yamux]
clock
onFailure := fun f => failures.update (f :: ·) } : BaseIO _) with
| .ok h => return h
| .error _ => throw (IO.userError "test host does not build")

/-- Two hosts over a new sim net: the server listens, and the client
holds a session to it. -/
structure Pair where
client : Host
server : Host
/-- The peer id the client proved for the server. -/
serverPeer : Libp2p.Identity.PeerId
/-- The address the server listens on. -/
serverAddr : Multiformats.Multiaddr
/-- The failures of the server's owned tasks, newest first. -/
failures : OnceRef (List Failure)
/-- The test clock both hosts run on. `Pair.close` closes it. -/
clock : TestClock

/-- The pair. With `split`, the sim delivers each byte as its own read. -/
def hostPair (split : Bool := false) : Async Pair := do
let net ← Streams.Sim.Net.new split
let tc ← TestClock.new
let failures ← OnceRef.new []
let client ← mkHost net tc.clock 1 (← OnceRef.new [])
let server ← mkHost net tc.clock 2 failures
let addr ← match Multiformats.Multiaddr.parse? "/memory/4100" with
| .ok a => pure a
| .error _ => throw (IO.userError "test address")
let .ok bound ← server.startListening addr | throw (IO.userError "listen failed")
let .ok serverPeer ← client.dial bound | throw (IO.userError "dial failed")
return { client, server, serverPeer, serverAddr := bound, failures, clock := tc }

/-- Close both hosts, then the clock. Each close joins its own tasks
(§5.5). -/
def Pair.close (p : Pair) : Async Unit := do
p.client.close
p.server.close
p.clock.close

end Tests.HostPair
Loading
Loading