diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version5/ChannelCodecs5.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version5/ChannelCodecs5.scala index 47df80bace..6367e4216b 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version5/ChannelCodecs5.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/internal/channel/version5/ChannelCodecs5.scala @@ -319,7 +319,10 @@ private[channel] object ChannelCodecs5 { private val waitForRevCodec: Codec[WaitForRev] = ("sentAfterLocalCommitIndex" | uint64overflow).as[WaitForRev] - private val updateMessageCodec: Codec[UpdateMessage] = lengthDelimited(lightningMessageCodec.narrow[UpdateMessage](f => Attempt.successful(f.asInstanceOf[UpdateMessage]), g => g)) + private val updateMessageCodec: Codec[UpdateMessage] = lengthDelimited(lightningMessageCodec.narrow[UpdateMessage]({ + case f: UpdateMessage => Attempt.successful(f) + case _ => Attempt.failure(Err("not an UpdateMessage")) + }, g => g)) private val localChangesCodec: Codec[LocalChanges] = ( ("proposed" | listOfN(uint16, updateMessageCodec)) :: diff --git a/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/OnionMessageTlv.scala b/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/OnionMessageTlv.scala index 4e8ab13185..b6fc6b09ff 100644 --- a/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/OnionMessageTlv.scala +++ b/eclair-core/src/main/scala/fr/acinq/eclair/wire/protocol/OnionMessageTlv.scala @@ -16,10 +16,8 @@ package fr.acinq.eclair.wire.protocol -import fr.acinq.eclair.wire.protocol.CommonCodecs.varint -import fr.acinq.eclair.wire.protocol.TlvCodecs.tlvStream import scodec.Codec -import scodec.codecs.discriminated +import scodec.codecs.provide /** * Created by thomash on 10/09/2021. @@ -28,5 +26,7 @@ import scodec.codecs.discriminated sealed trait OnionMessageTlv extends Tlv object OnionMessageTlv { - val onionMessageTlvCodec: Codec[TlvStream[OnionMessageTlv]] = tlvStream(discriminated[OnionMessageTlv].by(varint)) + // We don't support any TLV for onion messages yet. Since onion messages can be spammy, we don't need to waste any + // resources trying to decode unknown TLVs that we'll throw away anyway. + val onionMessageTlvCodec: Codec[TlvStream[OnionMessageTlv]] = provide(TlvStream.empty[OnionMessageTlv]) } diff --git a/eclair-front/src/main/scala/fr/acinq/eclair/Boot.scala b/eclair-front/src/main/scala/fr/acinq/eclair/Boot.scala index aabbcd0617..5ca43bfd87 100644 --- a/eclair-front/src/main/scala/fr/acinq/eclair/Boot.scala +++ b/eclair-front/src/main/scala/fr/acinq/eclair/Boot.scala @@ -16,13 +16,12 @@ package fr.acinq.eclair -import java.io.File - import akka.actor.ActorSystem import com.typesafe.config.{ConfigFactory, ConfigParseOptions, ConfigSyntax} import grizzled.slf4j.Logging import kamon.Kamon +import java.io.File import scala.concurrent.ExecutionContext import scala.util.{Failure, Success} @@ -30,11 +29,13 @@ object Boot extends App with Logging { try { val datadir = new File(sys.props.getOrElse("eclair.datadir", sys.props("user.home") + "/.eclair")) val config = ConfigFactory.parseString( - sys.env.getOrElse("AKKA_CONF", "").replace(";", "\n"), - ConfigParseOptions.defaults().setSyntax(ConfigSyntax.PROPERTIES)) + sys.env.getOrElse("AKKA_CONF", "").replace(";", "\n"), + ConfigParseOptions.defaults().setSyntax(ConfigSyntax.PROPERTIES)) .withFallback(ConfigFactory.parseProperties(System.getProperties)) .withFallback(ConfigFactory.parseFile(new File(datadir, "eclair.conf"))) .withFallback(ConfigFactory.load()) + // It's unsafe to use the cluster mode with plain tcp: communications MUST be encrypted. + require(config.getString("akka.remote.artery.transport") == "tls-tcp", "frontend cluster communication must use tls-tcp") // the actor system name needs to be the same for all members of the cluster implicit val system: ActorSystem = ActorSystem("eclair-node", config) @@ -54,7 +55,7 @@ object Boot extends App with Logging { case t: Throwable => onError(t) } - def onError(t: Throwable): Unit = { + private def onError(t: Throwable): Unit = { val errorMsg = if (t.getMessage != null) t.getMessage else t.getClass.getSimpleName System.err.println(s"fatal error: $errorMsg") logger.error(s"fatal error: $errorMsg", t) diff --git a/eclair-node/src/main/scala/fr/acinq/eclair/api/directives/ErrorDirective.scala b/eclair-node/src/main/scala/fr/acinq/eclair/api/directives/ErrorDirective.scala index 39bdb99c88..869d3d31db 100644 --- a/eclair-node/src/main/scala/fr/acinq/eclair/api/directives/ErrorDirective.scala +++ b/eclair-node/src/main/scala/fr/acinq/eclair/api/directives/ErrorDirective.scala @@ -33,10 +33,10 @@ trait ErrorDirective { private val apiExceptionHandler = ExceptionHandler { case t: IllegalArgumentException => logger.error(s"API call failed with cause=${t.getMessage}") - complete(StatusCodes.BadRequest, ErrorResponse(t.getMessage)) + complete(StatusCodes.BadRequest, ErrorResponse("API call failed: check logs for more details")) case t: Throwable => logger.error(s"API call failed with cause=${t.getMessage}") - complete(StatusCodes.InternalServerError, ErrorResponse(t.getMessage)) + complete(StatusCodes.InternalServerError, ErrorResponse("API call failed: check logs for more details")) } // map all the rejections to a JSON error object ErrorResponse diff --git a/eclair-node/src/test/scala/fr/acinq/eclair/api/ApiServiceSpec.scala b/eclair-node/src/test/scala/fr/acinq/eclair/api/ApiServiceSpec.scala index f3205591f3..b943d3ccaa 100644 --- a/eclair-node/src/test/scala/fr/acinq/eclair/api/ApiServiceSpec.scala +++ b/eclair-node/src/test/scala/fr/acinq/eclair/api/ApiServiceSpec.scala @@ -612,7 +612,7 @@ class ApiServiceSpec extends AnyFunSuite with ScalatestRouteTest with IdiomaticM assert(handled) assert(status == BadRequest) val resp = entityAs[ErrorResponse](Json4sSupport.unmarshaller, ClassTag(classOf[ErrorResponse])) - assert(resp.error == "invoice has expired") + assert(resp.error == "API call failed: check logs for more details") eclair.send(None, 1258000 msat, any, any, any, any, any)(any[Timeout]).wasCalled(once) } }