eclair { datadir = ${user.home}"/.eclair" chain = "mainnet" // "regtest" for regtest, "testnet" for testnet, "mainnet" for mainnet, "signet" for signet server { public-ips = [] // external ips, will be announced on the network binding-ip = "0.0.0.0" port = 9735 } api { enabled = false // disabled by default for security reasons binding-ip = "127.0.0.1" port = 8080 password = "" // password for basic auth, must be non empty if json-rpc api is enabled } bitcoind { host = "localhost" rpcport = 8332 auth = "password" // "password" for user/password authentication, "safecookie" for cookie authentication cookie = ${user.home}"/.bitcoin/.cookie" rpcuser = "foo" rpcpassword = "bar" // Name of the bitcoind wallet that should be used to fund channels. // Once set you should NOT change it if your node has channels open, otherwise you may lose funds. // NB: leave this field commented to automatically select the default loaded wallet. // wallet = "" zmqblock = "tcp://127.0.0.1:29000" zmqtx = "tcp://127.0.0.1:29000" // Batching requests saves bandwidth but may slightly degrade latency and reliability. It is useful for the watcher, // which can generate a lot of requests to validate channels, iterate over blocks to find a spending tx, etc. // You may want to disable this when bitcoin is running on a remote machine with an unreliable network. batch-watcher-requests = true // If some utxos are locked when eclair starts, it is likely because it was previously stopped in the middle of // funding a transaction. The supported behaviors to handle this case are: // - stop: eclair won't start until the corresponding utxos are unlocked by the node operator // - unlock: eclair will automatically unlock the corresponding utxos // - ignore: eclair will leave these utxos locked and start startup-locked-utxos-behavior = "stop" final-address-refresh-delay = 3 seconds // If true, eclair will poll bitcoind for 30 seconds at start-up before giving up. wait-for-bitcoind-up = true // The txid of a transaction that exists in your custom signet network or "" to skip this check. signet-check-tx = "ff1027486b628b2d160859205a3401fb2ee379b43527153b0b50a92c17ee7955" // coinbase of block #5000 of default signet } node-alias = "eclair" node-color = "49daaa" trampoline-payments-enable = false // TODO: @t-bast: once spec-ed this should use a global feature flag // see https://github.com/lightningnetwork/lightning-rfc/blob/master/09-features.md features { // option_upfront_shutdown_script is not activated by default. // If you activate it, eclair will ask bitcoin core for a wallet address whenever a new channel is created, and // funds will be sent to that address when the channel is closed. // You will not be able to change this address, which can be dangerous, especially for very long lived channels. // Make sure you understand what it implies before you activate this feature. option_upfront_shutdown_script = disabled option_data_loss_protect = mandatory gossip_queries = optional gossip_queries_ex = optional var_onion_optin = mandatory option_static_remotekey = mandatory payment_secret = mandatory basic_mpp = optional option_support_large_channel = optional // NB: option_anchors_zero_fee_htlc_tx should always be preferred to option_anchor_outputs (it's safer). // Do not enable option_anchor_outputs unless you really know what you're doing. option_anchor_outputs = disabled option_anchors_zero_fee_htlc_tx = optional option_route_blinding = optional option_shutdown_anysegwit = optional option_dual_fund = optional option_quiesce = optional option_attribution_data = optional // If you want to relay onion messages only from peers with whom you have channels, you should disable // option_onion_messages and enable option_onion_messages_only_channels instead. // If you don't want to relay onion messages at all, you should disable both features. option_onion_messages = optional option_onion_messages_only_channels = disabled zero_fee_commitments = disabled // This feature should only be enabled when acting as an LSP for mobile wallets. // When activating this feature, the peer-storage section should be customized to match desired SLAs. option_provide_storage = disabled option_channel_type = mandatory option_scid_alias = optional option_payment_metadata = optional // By enabling option_zeroconf, you will be trusting your peer as fundee. You will lose funds if they double spend // their funding tx. Eclair does not let you activate this feature by default, you have to activate it for every // node that you trust using override-init-features (see below). option_zeroconf = disabled keysend = disabled option_simple_close = optional option_splice = optional option_simple_taproot = optional trampoline_payment_prototype = disabled async_payment_prototype = disabled on_the_fly_funding = disabled } // The following section lets you customize features for specific nodes. // The overrides will be applied on top of the default features settings. override-init-features = [ // optional per-node features # { # nodeid = "02aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" # features { } # } ] channel { channel-flags { announce-channel = true } funding { // Each RBF attempt adds more data that we need to store and process, so we want to limit our peers to a reasonable use of RBF. remote-rbf-limits { max-attempts = 10 // maximum number of RBF attempts our peer is allowed to make attempt-delta-blocks = 3 // minimum number of blocks between RBF attempts } // Duration after which we abort a channel creation. If our peer seems unresponsive and doesn't complete the // funding protocol in time, they're likely buggy or malicious. timeout = 60 seconds } dust-limit-satoshis = 546 // Starting with anchor outputs channels, the on-chain feerate is not taken into account when trimming outputs. // We must thus use a high enough dust limit to ensure that the outputs can economically be spent on-chain. max-remote-dust-limit-satoshis = 5000 htlc-minimum-msat = 1 // The following parameters apply to each HTLC direction (incoming or outgoing), which means that the maximum amount in flight will be at most twice what is set here. // Note that our peer may use a lower value than ours, which would reduce the maximum amount in flight. // The smallest value of max-htlc-value-in-flight-msat and max-htlc-value-in-flight-percent will be applied when opening channels. // If for example you open a 60 mBTC channel, eclair will set max-htlc-value-in-flight to 27 mBTC. max-htlc-value-in-flight-msat = 5000000000 // 50 mBTC max-htlc-value-in-flight-percent = 45 // 45% of the channel capacity max-accepted-htlcs = 30 reserve-to-funding-ratio = 0.01 // recommended by BOLT #2 max-reserve-to-funding-ratio = 0.05 // channel reserve can't be more than 5% of the funding amount (recommended: 1%) min-public-funding-satoshis = 100000 min-private-funding-satoshis = 100000 max-funding-satoshis = 5000000000 // 50 BTC: we reject channels that are larger than this require-confirmed-inputs-for-dual-funding = false // if true, only confirmed inputs will be accepted for channel dual funding to-remote-delay-blocks = 720 // number of blocks that the other node's to-self outputs must be delayed (720 ~ 5 days) max-to-local-delay-blocks = 2016 // maximum number of blocks that we are ready to accept for our own delayed outputs (2016 ~ 2 weeks) min-depth-blocks = 8 // minimum number of confirmations for channel transactions to be safe from reorgs expiry-delta-blocks = 144 max-expiry-delta-blocks = 2016 // we won't forward HTLCs with timeouts greater than this delta // When we receive the preimage for an HTLC and want to fulfill it but the upstream peer stops responding, we want to // avoid letting its HTLC-timeout transaction become enforceable on-chain (otherwise there is a race condition between // our HTLC-success and their HTLC-timeout). // We will close the channel when the HTLC-timeout will happen in less than this number. // NB: this number effectively reduces the expiry-delta-blocks, so you may want to take that into account and increase // expiry-delta-blocks. fulfill-safety-before-timeout-blocks = 24 min-final-expiry-delta-blocks = 30 // Bolt 11 invoice's min_final_cltv_expiry; must be strictly greater than fulfill-safety-before-timeout-blocks max-restart-watch-delay = 60 seconds // we add a random delay before watching funding transactions after restart max-block-processing-delay = 30 seconds // we add a random delay before processing blocks, capped at this value, to prevent herd effect max-tx-publish-retry-delay = 60 seconds // we add a random delay before retrying failed transaction publication // When a channel has been spent while we were offline, we limit how many blocks in the past we scan, otherwise we // may scan the entire blockchain (which is very costly). It doesn't make sense to scan too far in the past, as an // attacker will already have swept the funds if we didn't detect a channel close that happened a long time ago. max-channel-spent-rescan-blocks = 720 // When a new block is found, we will analyze its transactions to see if some of our channels were spent. // We also scan previous blocks if we missed them, which may happen during reorgs: this parameter should be larger // than the longest reorg expected. scan-previous-blocks-depth = 6 // The default strategy, when we encounter an unhandled exception or internal error, is to locally force-close the // channel. Not only is there a delay before the channel balance gets refunded, but if the exception was due to some // misconfiguration or bug in eclair that affects all channels, we risk force-closing all channels. // This is why an alternative behavior is to simply log an error and stop the node. Note that if you don't closely // monitor your node, there is a risk that your peers take advantage of the downtime to try and cheat by publishing a // revoked commitment. Additionally, while there is no known way of triggering an internal error in eclair from the // outside, there may very well be a bug that allows just that, which could be used as a way to remotely stop the node // (with the default behavior, it would "only" cause a local force-close of the channel). unhandled-exception-strategy = "local-close" // local-close or stop revocation-timeout = 60 seconds // after sending a commit_sig, we will wait for at most that duration before disconnecting channel-open-limits { max-pending-channels-per-peer = 3 // maximum number of pending channels we will accept from a given peer max-total-pending-channels-private-nodes = 99 // maximum number of pending channels we will accept from all private nodes channel-opener-whitelist = [] // a list of public keys; we will ignore rate limits on pending channels from these peers } quiescence-timeout = 1 minutes // maximum time we will stay quiescent (or wait to reach quiescence) before disconnecting channel-update { // Balance thresholds at which to update the maximum HTLC amount // Must be in increasing order. // Set balance-thresholds = [] to disable this feature. balance-thresholds = [{ available-sat = 1000 // If our balance goes below this, max-htlc-sat = 0 // set the maximum HTLC amount to this (or htlc-minimum-msat if it's higher). },{ available-sat = 10000 max-htlc-sat = 1000 },{ available-sat = 100000 max-htlc-sat = 10000 },{ available-sat = 200000 max-htlc-sat = 100000 },{ available-sat = 400000 max-htlc-sat = 200000 },{ available-sat = 800000 max-htlc-sat = 400000 },{ available-sat = 1600000 max-htlc-sat = 800000 }] min-time-between-updates = 1 hour // minimum time between channel updates because the balance changed } } balance-check-interval = 1 hour send { // When sending a payment, if the cltv expiry used for the final node is very close to the current block height, it // lets intermediate nodes figure out their position in the route. To protect against this, a random delta will be // added to the current block height, which makes it look like there are more hops after the final node. recipient-final-expiry { min-delta = 150 // minimum value to add to the current block height max-delta = 350 // maximum value to add to the current block height } } relay { fees { // Fees for public channels public-channels { fee-base-msat = 1000 fee-proportional-millionths = 200 // fee charged per transferred satoshi in millionths of a satoshi (200 = 0.02%) } // Fees for private channels private-channels { fee-base-msat = 1000 fee-proportional-millionths = 100 } // Minimum fees for trampoline relays min-trampoline { fee-base-msat = 1000 fee-proportional-millionths = 100 } // By default, if the fees values are updated in configuration, they will automatically be applied to existing // channels on restart (except if custom per-node settings have been defined, in which case they take precedence). // There is a performance hit on restart if there is a large number (> 100s) of channels, so it can be disabled. reset-existing-channels = true // Delay enforcement of channel fee updates enforcement-delay = 10 minutes } async-payments { // Maximum number of blocks to hold an async payment while waiting to receive a trigger from the receiver hold-timeout-blocks = 1008 // Number of blocks before the incoming HTLC expires that an async payment must be triggered by the receiver cancel-safety-before-timeout-blocks = 144 } // We assign reputation to our peers to prioritize payments during congestion. // The reputation is computed as fees paid divided by what should have been paid if all payments were successful. peer-reputation { // Set this parameter to false to disable the reputation algorithm and simply relay the incoming accountability. enabled = true // Reputation decays with the following half life to emphasize recent behavior. half-life = 30 days // Payments that stay pending for longer than this get penalized. max-relay-duration = 5 minutes } reserved-for-accountable = 0.5 // Fraction of a channel slots and usable liquidity that is reserved for accountable HTLCs } on-chain-fees { min-feerate = 1 // minimum feerate in satoshis per byte smoothing-window = 6 // 1 = no smoothing default-feerates { // the following values are in satoshis per byte minimum = 1 slow = 2 medium = 5 fast = 10 fastest = 20 } // confirmation priority for each transaction type, can be slow/medium/fast confirmation-priority { funding = medium closing = medium } // Maximum feerate that will be used when closing channels for outputs that aren't at risk (main balance and HTLC 3rd-stage transactions). // Using a low value here ensures that you won't be paying high fees when the mempool is congested and you're not in // a hurry to get your channel funds back. // If closing transactions don't confirm and you need to get the funds back quickly, you should increase this value // and restart your node: closing transactions will automatically be RBF-ed to match the current feerate. // This value is in satoshis per byte. max-closing-feerate = 10 feerate-tolerance { ratio-low = 0.5 // will allow remote fee rates as low as half our local feerate for funding/splice transactions ratio-high = 10.0 // will allow remote fee rates as high as 10 times our local feerate for commitment transactions and funding/splice transactions // when using anchor outputs, we only need to use a commitment feerate that allows the tx to propagate: we will use CPFP to speed up confirmation if needed. // the following value is the maximum feerate we'll use for our commit tx (in sat/byte) anchor-output-max-commit-feerate = 10 // the following section lets you configure your tolerance to dust outputs dust-tolerance { // dust htlcs cannot be claimed on-chain and will instead go to miners if the channel is force-closed // a malicious peer may want to abuse that, so we limit the value of pending dust htlcs in a channel // this value cannot be lowered too much if you plan to relay a lot of htlcs max-exposure-satoshis = 50000 // when we receive an update_fee, it could increase our dust exposure and overflow max-exposure-satoshis // this parameter should be set to true if you want to force-close the channel when that happens close-on-update-fee-overflow = false } } override-feerate-tolerance = [ // optional per-node feerate tolerance # { # nodeid = "02aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" # feerate-tolerance { # ratio-low = 0.1 # ratio-high = 20.0 # anchor-output-max-commit-feerate = 10 # dust-tolerance { # max-exposure-satoshis = 25000 # close-on-update-fee-overflow = true # } # } # } ] // when our utxos count is below this threshold, we will use more aggressive confirmation targets in force-close scenarios safe-utxos-threshold = 10 // if false, the commitment transaction will not be fee-bumped when we have no htlcs to claim (used in force-close scenario) // it can still be manually fee-bumped using the bumpforceclose RPC // *do not change this unless you know what you are doing* spend-anchor-without-htlcs = true // maximum amount of fees we will pay to bump an anchor output when we have no HTLC at risk anchor-without-htlcs-max-fee-satoshis = 10000 close-on-offline-feerate-mismatch = true // do not change this unless you know what you are doing // the channel initiator will send an UpdateFee message if the difference between current commitment fee and actual // current network fee is greater than this ratio. update-fee-min-diff-ratio = 0.1 } // Liquidity Ads allow remote nodes to pay us to provide them with inbound liquidity. liquidity-ads { // Multiple funding rates can be provided, for different funding amounts. funding-rates = [] // Sample funding rates: // funding-rates = [ // { // min-funding-amount-satoshis = 100000 // minimum funding amount at this rate // max-funding-amount-satoshis = 500000 // maximum funding amount at this rate // // The seller can ask the buyer to pay for some of the weight of the funding transaction (for the inputs and // // outputs added by the seller). This field contains the transaction weight (in vbytes) that the seller asks the // // buyer to pay for. The default value matches the weight of one p2wpkh input with one p2wpkh change output. // funding-weight = 400 // fee-base-satoshis = 500 // flat fee that we will receive every time we accept a liquidity request // fee-basis-points = 250 // proportional fee based on the amount requested by our peer (2.5%) // channel-creation-fee-satoshis = 2500 // flat fee that is added when creating a new channel // }, // { // min-funding-amount-satoshis = 500000 // max-funding-amount-satoshis = 5000000 // funding-weight = 750 // fee-base-satoshis = 1000 // fee-basis-points = 200 // 2% // channel-creation-fee-satoshis = 2000 // } // ] // Multiple ways of paying the liquidity fees can be provided. payment-types = [ // Liquidity fees must be paid from the buyer's channel balance during the transaction creation. // This doesn't involve trust from the buyer or the seller. "from_channel_balance" ] // When selling your liquidity, malicious nodes can attempt a liquidity griefing attack against your node where // they initiate a purchase and stop responding before finalizing the funding transaction. By default, the utxos // used for this funding transaction will be locked to avoid accidentally double-spending ourselves. The funding // attempt will automatically be cancelled after a timeout and utxos unlocked, but the attacker will have succeeded // in "locking" some of our liquidity for a short duration. By continually repeating this process, they may prevent // your node from successfully selling liquidity to honest nodes. More details can be found here: // https://delvingbitcoin.org/t/liquidity-griefing-in-multi-party-transaction-protocols/264 // // The only way to fully prevent this attack is to set the following parameter to false, which means that utxos // will never be locked during funding attempts, and can thus immediately be reused until an honest node completes // a liquidity purchase. However, there is a drawback: it means that all funding transactions may now be double // spent accidentally, even funding transactions with honest nodes, which requires retrying the purchase when it // fails and isn't a very good UX. It is up to the node operator to decide which trade-off they're comfortable with // and to set this flag accordingly. lock-utxos-during-funding = true } // On-the-fly funding leverages liquidity ads to fund channels with wallet peers based on their payment patterns. on-the-fly-funding { // If our peer doesn't respond to our funding proposal, we must fail the corresponding upstream HTLCs. // Since MPP may be used, we should use a timeout greater than the MPP timeout. proposal-timeout = 90 seconds // If too many peers act suspiciously, for example by accepting an on-the-fly funding where fees are paid from // HTLCs that will be relayed *after* funding but then reject the HTLCs when receiving them, we automatically // disable funding from future HTLCs. max-suspicious-peers = 10 } peer-connection { auth-timeout = 30 seconds // will disconnect if connection authentication doesn't happen within that timeframe init-timeout = 30 seconds // will disconnect if initialization doesn't happen within that timeframe ping-interval = 30 seconds ping-timeout = 60 seconds // will disconnect if peer takes longer than that to respond ping-disconnect = true // disconnect if no answer to our pings // When enabled, if we receive an incoming connection, we will echo the source IP address in our init message. // This should be disabled if your node is behind a load balancer that doesn't preserve source IP addresses. send-remote-address-init = true max-no-channels = 64 // maximum number of incoming connections from peers that do not have any channels with us // Maximum number of incoming connections that haven't completed the BOLT 8 handshake yet. Peers that connect // without ever authenticating cost us memory, file descriptors and CPU, so we bound how many of them we keep // around: when this limit is reached, we drop the oldest pending connection to make room for the new one. // NB: this is only a last-resort safety net, DDoS protection is much more efficiently handled at the network // layer (e.g. by a cloud provider). max-pending-incoming-connections = 500 // We never drop a pending connection before it reaches that age, which guarantees that honest peers always have // enough time to complete the handshake, even while we're being flooded with connection attempts. When every // pending connection is more recent than that, we reject the incoming connection instead. pending-connection-min-age = 1 second // Whenever we had to drop a pending connection, we wait for that duration before accepting the next one. This lets // the kernel backlog absorb (and discard) the excess connection attempts instead of spending our own resources on // them. Note that this only applies while we're at `max-pending-incoming-connections`: it never slows down // connections that we have capacity for. pending-connection-accept-delay = 100 milliseconds } // When relaying payments or messages to mobile peers who are disconnected, we may try to wake them up using a mobile // notification system, or we attempt connecting to the last known address. peer-wake-up { enabled = false timeout = 60 seconds } auto-reconnect = true initial-random-reconnect-delay = 5 seconds // we add a random delay before the first reconnection attempt, capped by this value max-reconnect-interval = 1 hour // max interval between two reconnection attempts, after the exponential backoff period invoice-expiry = 1 hour // default expiry for invoices generated by this node multi-part-payment-expiry = 60 seconds // default expiry for receiving all parts of a multi-part payment max-payment-attempts = 5 autoprobe-count = 0 // number of parallel tasks that send test payments to detect invalid channels router { watch-spent-window = 60 minutes // at startup watches on public channels will be put back within that window to reduce herd effect; must be > 0s // when we detect that a remote channel has been spent on-chain, we wait for 72 blocks before removing it from the graph // if this was a splice instead of a close, we will be able to simply update the channel in our graph and keep its reputation channel-spent-splice-delay = 72 channel-exclude-duration = 60 seconds // when a temporary channel failure is returned, we exclude the channel from our payment routes for this duration broadcast-interval = 60 seconds // see BOLT #7 balance-estimate-half-life = 1 day // time after which the confidence of the balance estimate is halved sync { request-node-announcements = true // if true we will ask for node announcements when we receive channel ids that we don't know channel-range-chunk-size = 1500 // max number of short_channel_ids (+ timestamps + checksums) in reply_channel_range *do not change this unless you know what you are doing* channel-query-chunk-size = 100 // max number of short_channel_ids in query_short_channel_ids *do not change this unless you know what you are doing* // Our peer decides when a sync ends, so we bound the number of `query_short_channel_ids` we're willing to buffer // for it: it could otherwise keep sending us channel ids that don't exist until we run out of memory. At the // default `channel-query-chunk-size` this is 200 000 channels, which is several times the size of the network. max-queries-per-sync = 2000 peer-limit = 5 // number of peers to do the initial sync with. We limit the initial sync to the peers that have the largest capacity with us when starting the node. whitelist = [] // a list of public keys to do the initial sync with, in addition to the top peers by capacity // A `query_channel_range` is cheap to send but expensive to answer (we must scan our whole routing table), so we // limit how many of them we accept from a given peer: honest peers only need to send a few of them per connection. max-queries-per-second = 5 } message-path-finding { max-route-length = 6 ratios { // The next three weights must sum to one. base = 0.6 // when computing the weight for a channel, proportion that stays the same for all channels channel-age = 0.1 // when computing the weight for a channel, consider its AGE in this proportion channel-capacity = 0.3 // when computing the weight for a channel, consider its CAPACITY in this proportion } } path-finding { default { randomize-route-selection = true // when computing a route for a payment we randomize the final selection mpp { min-amount-satoshis = 15000 // minimum amount sent via partial HTLCs max-parts = 5 // maximum number of HTLCs sent per payment: increasing this value will impact performance splitting-strategy = "randomize" // Can be either "full-capacity", "randomize" or "max-expected-amount" } boundaries { max-route-length = 6 // max route length for the 'first pass', if none is found then a second pass is made with no limit max-cltv = 2016 // max acceptable cltv expiry for the payment (2016 ~ 2 weeks) // the route must have a fee that's below max-fee-flat-sat OR below max-fee-proportional-percent / 100 * total-amount max-fee-flat-sat = 21 max-fee-proportional-percent = 3 // that's 3% } hop-cost { // virtual fee for additional hops: how much you are willing to pay to get one less hop in the payment path fee-base-msat = 500 fee-proportional-millionths = 200 } locked-funds-risk = 1e-8 // msat per msat locked per block. It should be your expected interest rate per block multiplied by the probability that something goes wrong and your funds stay locked. // 1e-8 corresponds to an interest rate of ~5% per year (1e-6 per block) and a probability of 1% that the channel will fail and our funds will be locked. // virtual fee for failed payments: how much you are willing to pay to get one less failed payment attempt failure-cost { fee-base-msat = 2000 fee-proportional-millionths = 500 } // Using a failure cost breaks Dijkstra (the path returned is no longer guaranteed to be shortest one), if // that's a concern, you can penalize paths with a low success chance by using the logarithm of the probability // of success. It satisfies Dijkstra's requirements and is a very good approximation for paths with a high // probability of success, however is penalizes less the paths with a low probability of success. use-log-probability = false // When set to false, we assume that the balances of channels are uniformly distributed. That means the // probability that we can send an amount X through a channel of capacity C is 1 - X / C. // When set to true, past payments attempts will be used to compute a better estimate. use-past-relay-data = false } // The path-finding algo uses one or more sets of parameters named experiments. Each experiment has a percentage // assigned, allowing AB-testing. By default, there is a single 'control' experiment with a percentage of 100 %. // // To enable AB-testing, you need to define experiments below. Note that: // - each experiment must have a unique name, may override the default parameters, and must provide a percentage // - the percentages for all experiments must sum to 100 // - experiments should be immutable; if you alter parameters of an experiment, you should also rename it // - for a complete example, refer to the documentation. experiments { control = ${eclair.router.path-finding.default} { percentage = 100 // 100% of the traffic use the default configuration } } } } socks5 { enabled = false host = "127.0.0.1" port = 9050 use-for-ipv4 = true use-for-ipv6 = true use-for-tor = true use-for-watchdogs = true use-for-dnshostnames = true randomize-credentials = false // this allows tor stream isolation } tor { enabled = false auth = "safecookie" // safecookie, password password = "foobar" // used when auth=password, which requires host to be a local address host = "127.0.0.1" // must be a local address unless auth=safecookie port = 9051 private-key-file = "tor.dat" targets = [] // a list of address:port, for advanced use (e.g. to send traffic to front servers). See the tor man page for syntax details. publish-onion-address = true } db { driver = "sqlite" // sqlite, postgres postgres { database = "eclair" host = "localhost" port = 5432 username = "" password = "" readonly-user = "" // if defined, this user will be granted read-only access to all tables in the database reset-json-columns = false // in case of a json format change, this allows a full re-serialization of json data pool { max-size = 10 // recommended value = number_of_cpu_cores * 2 connection-timeout = 30 seconds idle-timeout = 10 minutes max-life-time = 30 minutes } lock-type = "lease" // lease or none (do not use none in production) lease { interval = 5 minutes // lease-interval must be greater than lease-renew-interval renew-interval = 1 minute lock-timeout = 5 seconds // timeout for the lock statement on the lease table auto-release-at-shutdown = true // automatically release the lock when eclair is stopping } safety-checks { // A set of basic checks on data to make sure we use the correct database // Those checks are disabled by default because they would not pass on a fresh new node with // zero channels. You should enable them when you already have channels, so that there is // something to compare to, and the values should be specific to your setup, especially // for local channels. If your operate a busy node, you can reduce max-age.local-channels // and max-age.audit-relayed to just a few minutes, this will significantly improve the safety. enabled = false max-age { local-channels = 15 minutes // last time a local channel was updated network-nodes = 30 minutes // most recent public node announcement audit-relayed = 1 hour // last time a payment was relayed } min-count { local-channels = 10 // minimum number of local channels, this entirely depends on your setup network-nodes = 3000 // minimum number of public nodes in the routing table network-channels = 20000 // minimum number of public channels in the routing table } } } // During normal channel operation, we need to store information about past HTLCs to be able to punish our peer if // they publish a revoked commitment. Once a channel closes or a splice transaction confirms, we can clean up past // data (which reduces the size of our DB). Since there may be millions of rows to delete and we don't want to slow // down the node, we delete those rows in batches at regular intervals. revoked-htlc-info-cleaner { // Number of rows to delete per batch: a higher value will clean up the DB faster, but may have a higher impact on performance. batch-size = 500 // Frequency at which batches of rows are deleted: a lower value will clean up the DB faster, but may have a higher impact on performance. // If you are frequently closing or splicing channels, you may want to increase the default interval if you're seeing IO performance issues. interval = 1 seconds } } file-backup { enabled = true // enable the automatic sqlite db backup; do not change this unless you know what you are doing interval = 10 seconds // interval between two backups target-file = "eclair.sqlite.bak" // name of the target backup file; will be placed under the chain directory // override this with a script/exe that will be called everytime a new database backup has been created # notify-script = "/absolute/path/to/script.sh" } blockchain-watchdog { // all available blockchain watchdog sources // you can remove items from this list to disable failing or non-needed sources sources = [ "bitcoinheaders.net", "blockcypher.com", "blockstream.info", "mempool.space" ] // maximum lag of chain height observed by eclair to blockchain watchdog sources missing-blocks-threshold = 7 } onion-messages { // Transient connections opened to relay messages will be closed after this delay of inactivity. kill-transient-connection-after = 30 seconds // Maximum number of onion messages accepted per second (for each peer). max-per-peer-per-second = 10 // Minimum number of hops before our node to hide it in the reply paths that we build. min-intermediate-hops = 6 // Consider a message to be lost if we haven't received a reply after that amount of time. reply-timeout = 15 seconds // If we expect a reply but do not get one, retry until we reach this number of attempts. max-attempts = 3 } purge-expired-invoices { enabled = true // enable automatic purges of expired invoices from the database interval = 24 hours // interval between expired invoice purges } peer-storage { // Peer storage is persisted only after this delay to reduce the number of writes when updating it multiple times in a row. // A small delay may result in a lot of IO write operations, which can have a negative performance impact on the node. // But using a large delay increases the risk of not storing the latest peer data if you restart your node while writes are pending. write-delay = 1 minute // Peer storage is kept this long after the last channel with that peer has been closed. // A long delay here guarantees that peers who are offline while their channels are closed will be able to get their funds // back if they restore from seed on a different device after the channels have been closed. removal-delay = 30 days // Frequency at which we clean our DB to remove peer storage from nodes with whom we don't have channels anymore. cleanup-frequency = 1 day } // We keep track of peer statistics to find the most profitable peers and fund channels with them to optimize our // payment volume and fees earned. peer-scoring { // Set this to true if you want to start collecting data to score peers. enabled = false // Frequency at which we run our peer scoring algorithm. frequency = 1 hour // Maximum number of peers to select as candidates for liquidity and relay fee updates. top-peers-count = 10 // A list of node_ids with whom we will try to maintain liquidity. top-peers-whitelist = [] // On restart, we read all past events from the previous week from the DB, which is expensive. // We do this in 56 3-hour chunks to avoid performance issues, with a delay between each chunk. // We only read the first chunk after an initial delay, since this isn't critical and there are already a lot of DB // reads when restarting an eclair node that have higher priority. past-events { init-delay = 10 minutes chunk-delay = 10 seconds } // We can automatically allocate liquidity to our top peers when necessary. liquidity { // If true, we will automatically fund channels. auto-fund = false // If true, we will automatically close unused channels to reclaim liquidity. auto-close = false // We only fund channels if at least this amount is necessary. min-funding-amount-satoshis = 1000000 // 0.01 btc // We never fund channels with more than this amount. max-funding-amount-satoshis = 50000000 // 0.5 btc // Maximum total capacity (across all channels) per peer. max-per-peer-capacity-satoshis = 1000000000 // 10 btc // We won't close channels if our local balance is below this amount. local-balance-closing-threshold-satoshis = 10000000 // 0.1 btc // We won't close channels where the remote balance exceeds this amount. remote-balance-closing-threshold-satoshis = 5000000 // 0.05 btc // We won't close channels if this percentage of the channel capacity has been used during the past week. idle-channel-closing-threshold-percent = 0.075 // 7.5% // We stop funding channels if our on-chain balance is below this amount. min-on-chain-balance-satoshis = 50000000 // 0.5 btc // We stop funding channels if the on-chain feerate is above this value. max-feerate-sat-per-byte = 5 // Rate-limit the number of funding transactions we make per day (on average). max-funding-tx-per-day = 6 // If true, we will occasionally try to fund idle large capacity peers that have most funds on their side. revive-old-peers = false // Minimum time between funding the same peer, to evaluate whether the previous funding was effective. funding-cooldown = 72 hours } // We can automatically update our relay fees to our top peers when necessary. relay-fees { // If true, we will automatically update our relay fees based on variations in outgoing payment volume. auto-update = false // We will not lower our fees below these values. min-fee-base-msat = 1 min-fee-proportional-millionths = 500 // We will not increase our fees above these values. max-fee-base-msat = 10000 max-fee-proportional-millionths = 5000 // We only increase fees if the daily outgoing payment volume exceeds this threshold or daily-payment-volume-threshold-percent. daily-payment-volume-threshold-satoshis = 10000000 // 0.1 btc // We only increase fees if the daily outgoing payment volume exceeds this percentage of our peer capacity or daily-payment-volume-threshold. daily-payment-volume-threshold-percent = 0.05 } } offers { // Minimum length of an offer blinded path when hiding our real node id message-path-min-length = 2 // Number of payment paths to put in Bolt12 invoices when hiding our real node id payment-path-count = 2 // Length of payment paths to put in Bolt12 invoices when hiding our real node id payment-path-length = 2 // Expiry delta of payment paths to put in Bolt12 invoices when hiding our real node id payment-path-expiry-delta = 500 } } akka { io { tcp { # The maximum number of bytes delivered by a `Received` message. Before # more data is read from the network the connection actor will try to # do other work. # The purpose of this setting is to impose a smaller limit than the # configured receive buffer size. When using value 'unlimited' it will # try to read all from the receive buffer. # As per BOLT#8 lightning messages are at most 2 + 16 + 65535 + 16 = 65569bytes # As a tradeoff to reduce the RAM consumption, in conjunction with tcp pull mode, # the default value is chosen to allow for a decent number of messages to be prefetched. max-received-message-size = 300000b } } actor { warn-about-java-serializer-usage = on allow-java-serialization = off serializers { lightning = "fr.acinq.eclair.remote.LightningMessageSerializer" eclair-internals = "fr.acinq.eclair.remote.EclairInternalsSerializer" } serialization-bindings { "fr.acinq.eclair.wire.protocol.LightningMessage" = lightning "fr.acinq.eclair.remote.EclairInternalsSerializer$RemoteTypes" = eclair-internals } } remote.artery { transport = "tcp" // switching to tls-tcp is highly recommended in a production environment // We are using a simple setup (https://doc.akka.io/docs/akka/current/remoting-artery.html#remote-security): // > Have a single set of keys and a single certificate for all nodes and disable hostname checking // > - The single set of keys and the single certificate is distributed to all nodes. The certificate can be self-signed as it is distributed both as a certificate for authentication but also as the trusted certificate. // > - If the keys/certificate are lost, someone else can connect to your cluster. // > - Adding nodes to the cluster is simple as the key material can be deployed / distributed to the new node. // Command line used to generate the self-signed certificate: // keytool -genkeypair -v \ // -keystore akka-cluster-tls.jks \ // -dname "O=ACINQ, C=FR" \ // -keypass:env PW \ // -storepass:env PW \ // -keyalg RSA \ // -keysize 4096 \ // -validity 9999 ssl.config-ssl-engine { key-store = ${eclair.datadir}"/akka-cluster-tls.jks" trust-store = ${eclair.datadir}"/akka-cluster-tls.jks" key-store-password = ${?AKKA_TLS_PASSWORD} key-password = ${?AKKA_TLS_PASSWORD} trust-store-password = ${?AKKA_TLS_PASSWORD} protocol = "TLSv1.2" enabled-algorithms = [TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256] } } cluster { role { backend.min-nr-of-members = 1 frontend.min-nr-of-members = 0 } seed-nodes = ["akka://eclair-node@127.0.0.1:25520"] } }