From c9064d5a3707ff49d21719fbe8eba0a40b9fad91 Mon Sep 17 00:00:00 2001 From: Daniel Karzel Date: Wed, 26 May 2021 11:40:55 +1000 Subject: [PATCH] Add ping protocol to ensure connection is alive Adds the ping behaviour to both ASB and CLI behaviour that periodically pings a connected party to ensure that the underlying network connection is still alive. This fixes problems with long-running connections that become dead without a connection closure being reported back to the swarm. --- CHANGELOG.md | 6 ++++++ Cargo.lock | 16 ++++++++++++++++ swap/Cargo.toml | 2 +- swap/src/protocol/alice/behaviour.rs | 13 +++++++++++++ swap/src/protocol/bob/behaviour.rs | 13 +++++++++++++ 5 files changed, 49 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b1f68d7..5d0d8e4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed + +- An issue where long-running connections are dead without a connection closure being reported back to the swarm. + Adding a periodic ping ensures that the connection is kept alive, and a broken connection is reported back resulting in a close event on the swarm. + This fixes the error of the ASB being unable to send a transfer proof to the CLI. + ## [0.6.0] - 2021-05-24 ### Added diff --git a/Cargo.lock b/Cargo.lock index c69a4e49..4fafdf54 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1767,6 +1767,7 @@ dependencies = [ "libp2p-dns", "libp2p-mplex", "libp2p-noise", + "libp2p-ping", "libp2p-request-response", "libp2p-swarm", "libp2p-swarm-derive", @@ -1876,6 +1877,21 @@ dependencies = [ "zeroize", ] +[[package]] +name = "libp2p-ping" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4bfaffac63bf3c7ec11ed9d8879d455966ddea7e78ee14737f0b6dce0d1cd1" +dependencies = [ + "futures", + "libp2p-core", + "libp2p-swarm", + "log 0.4.14", + "rand 0.7.3", + "void", + "wasm-timer", +] + [[package]] name = "libp2p-request-response" version = "0.11.0" diff --git a/swap/Cargo.toml b/swap/Cargo.toml index 60d91106..3747cf67 100644 --- a/swap/Cargo.toml +++ b/swap/Cargo.toml @@ -29,7 +29,7 @@ ecdsa_fun = { git = "https://github.com/LLFourn/secp256kfun", features = [ "libs ed25519-dalek = "1" futures = { version = "0.3", default-features = false } itertools = "0.10" -libp2p = { version = "0.38", default-features = false, features = [ "tcp-tokio", "yamux", "mplex", "dns-tokio", "noise", "request-response", "websocket" ] } +libp2p = { version = "0.38", default-features = false, features = [ "tcp-tokio", "yamux", "mplex", "dns-tokio", "noise", "request-response", "websocket", "ping" ] } libp2p-async-await = { git = "https://github.com/comit-network/rust-libp2p-async-await" } miniscript = { version = "5", features = [ "serde" ] } monero = { version = "0.12", features = [ "serde_support" ] } diff --git a/swap/src/protocol/alice/behaviour.rs b/swap/src/protocol/alice/behaviour.rs index 6d2ad548..ce7334b9 100644 --- a/swap/src/protocol/alice/behaviour.rs +++ b/swap/src/protocol/alice/behaviour.rs @@ -4,6 +4,7 @@ use crate::protocol::alice::event_loop::LatestRate; use crate::protocol::alice::{execution_setup, spot_price, State3}; use crate::{env, monero}; use anyhow::{anyhow, Error}; +use libp2p::ping::{Ping, PingEvent}; use libp2p::request_response::{RequestId, ResponseChannel}; use libp2p::{NetworkBehaviour, PeerId}; use uuid::Uuid; @@ -75,6 +76,11 @@ where pub execution_setup: execution_setup::Behaviour, pub transfer_proof: transfer_proof::Behaviour, pub encrypted_signature: encrypted_signature::Behaviour, + + /// Ping behaviour that ensures that the underlying network connection is + /// still alive. If the ping fails a connection close event will be + /// emitted that is picked up as swarm event. + ping: Ping, } impl Behaviour @@ -104,6 +110,13 @@ where execution_setup: Default::default(), transfer_proof: transfer_proof::alice(), encrypted_signature: encrypted_signature::alice(), + ping: Ping::default(), } } } + +impl From for OutEvent { + fn from(_: PingEvent) -> Self { + OutEvent::Other + } +} diff --git a/swap/src/protocol/bob/behaviour.rs b/swap/src/protocol/bob/behaviour.rs index 6eab91fa..8f156e1b 100644 --- a/swap/src/protocol/bob/behaviour.rs +++ b/swap/src/protocol/bob/behaviour.rs @@ -4,6 +4,7 @@ use crate::protocol::bob; use crate::protocol::bob::{execution_setup, State2}; use anyhow::{anyhow, Error, Result}; use libp2p::core::Multiaddr; +use libp2p::ping::{Ping, PingEvent}; use libp2p::request_response::{RequestId, ResponseChannel}; use libp2p::{NetworkBehaviour, PeerId}; use std::time::Duration; @@ -66,6 +67,11 @@ pub struct Behaviour { pub transfer_proof: transfer_proof::Behaviour, pub encrypted_signature: encrypted_signature::Behaviour, pub redial: redial::Behaviour, + + /// Ping behaviour that ensures that the underlying network connection is + /// still alive. If the ping fails a connection close event will be + /// emitted that is picked up as swarm event. + ping: Ping, } impl Behaviour { @@ -77,6 +83,7 @@ impl Behaviour { transfer_proof: transfer_proof::bob(), encrypted_signature: encrypted_signature::bob(), redial: redial::Behaviour::new(alice, Duration::from_secs(2)), + ping: Ping::default(), } } @@ -88,3 +95,9 @@ impl Behaviour { self.encrypted_signature.add_address(&peer_id, address); } } + +impl From for OutEvent { + fn from(_: PingEvent) -> Self { + OutEvent::Other + } +}