Skip to content

Commit 5e0990b

Browse files
committed
merge main
2 parents 6e7faea + 989304e commit 5e0990b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+4785
-1009
lines changed

CHANGELOG.md

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,178 @@
1+
# 0.0.117 - Oct 3, 2023 - "Everything but the Twelve Sinks"
2+
3+
## API Updates
4+
* `ProbabilisticScorer`'s internal models have been substantially improved,
5+
including better decaying (#1789), a more granular historical channel
6+
liquidity tracker (#2176) and a now-default option to make our estimate for a
7+
channel's current liquidity nonlinear in the channel's capacity (#2547). In
8+
total, these changes should result in improved payment success rates at the
9+
cost of slightly worse routefinding performance.
10+
* Support for custom TLVs for recipients of HTLCs has been added (#2308).
11+
* Support for generating transactions for third-party watchtowers has been
12+
added to `ChannelMonitor/Update`s (#2337).
13+
* `KVStorePersister` has been replaced with a more generic and featureful
14+
`KVStore` interface (#2472).
15+
* A new `MonitorUpdatingPersister` is provided which wraps a `KVStore` and
16+
implements `Persist` by writing differential updates rather than full
17+
`ChannelMonitor`s (#2359).
18+
* Batch funding of outbound channels is now supported using the new
19+
`ChannelManager::batch_funding_transaction_generated` method (#2486).
20+
* `ChannelManager::send_preflight_probes` has been added to probe a payment's
21+
potential paths while a user is providing approval for a payment (#2534).
22+
* Fully asynchronous `ChannelMonitor` updating is available as an alpha
23+
preview. There remain a few known but incredibly rare race conditions which
24+
may lead to loss of funds (#2112, #2169, #2562).
25+
* `ChannelMonitorUpdateStatus::PermanentFailure` has been removed in favor of a
26+
new `ChannelMonitorUpdateStatus::UnrecoverableError`. The new variant panics
27+
on use, rather than force-closing a channel in an unsafe manner, which the
28+
previous variant did (#2562). Rather than panicking with the new variant,
29+
users may wish to use the new asynchronous `ChannelMonitor` updating using
30+
`ChannelMonitorUpdateStatus::InProgress`.
31+
* `RouteParameters::max_total_routing_fee_msat` was added to limit the fees
32+
paid when routing, defaulting to 1% + 50sats when using the new
33+
`from_payment_params_and_value` constructor (#2417, #2603, #2604).
34+
* Implementations of `UtxoSource` are now provided in `lightning-block-sync`.
35+
Those running with a full node should use this to validate gossip (#2248).
36+
* `LockableScore` now supports read locking for parallel routefinding (#2197).
37+
* `ChannelMonitor::get_spendable_outputs` was added to allow for re-generation
38+
of `SpendableOutputDescriptor`s for a channel after they were provided via
39+
`Event::SpendableOutputs` (#2609, #2624).
40+
* `[u8; 32]` has been replaced with a `ChannelId` newtype for chan ids (#2485).
41+
* `NetAddress` was renamed `SocketAddress` (#2549) and `FromStr` impl'd (#2134)
42+
* For `no-std` users, `parse_onion_address` was added which creates a
43+
`NetAddress` from a "...onion" string and port (#2134, #2633).
44+
* HTLC information is now provided in `Event::PaymentClaimed::htlcs` (#2478).
45+
* The success probability used in historical penalties when scoring is now
46+
available via `historical_estimated_payment_success_probability` (#2466).
47+
* `RecentPaymentDetails::*::payment_id` has been added (#2567).
48+
* `Route` now contains a `RouteParameters` rather than a `PaymentParameters`,
49+
tracking the original arguments passed to routefinding (#2555).
50+
* `Balance::*::claimable_amount_satoshis` was renamed `amount_satoshis` (#2460)
51+
* `*Features::set_*_feature_bit` have been added for non-custom flags (#2522).
52+
* `channel_id` was added to `SpendableOutputs` events (#2511).
53+
* `counterparty_node_id` and `channel_capacity_sats` were added to
54+
`ChannelClosed` events (#2387).
55+
* `ChannelMonitor` now implements `Clone` for `Clone`able signers (#2448).
56+
* `create_onion_message` was added to build an onion message (#2583, #2595).
57+
* `HTLCDescriptor` now implements `Writeable`/`Readable` (#2571).
58+
* `SpendableOutputDescriptor` now implements `Hash` (#2602).
59+
* `MonitorUpdateId` now implements `Debug` (#2594).
60+
* `Payment{Hash,Id,Preimage}` now implement `Display` (#2492).
61+
* `NodeSigner::sign_bolt12_invoice{,request}` were added for future use (#2432)
62+
63+
## Backwards Compatibility
64+
* Users migrating to the new `KVStore` can use a concatentation of
65+
`[{primary_namespace}/[{secondary_namespace}/]]{key}` to build a key
66+
compatible with the previous `KVStorePersister` interface (#2472).
67+
* Downgrading after receipt of a payment with custom HTLC TLVs may result in
68+
unintentionally accepting payments with TLVs you do not understand (#2308).
69+
* `Route` objects (including pending payments) written by LDK versions prior
70+
to 0.0.117 won't be retryable after being deserialized by LDK 0.0.117 or
71+
above (#2555).
72+
* Users of the `MonitorUpdatingPersister` can upgrade seamlessly from the
73+
default `KVStore` `Persist` implementation, however the stored
74+
`ChannelMonitor`s are deliberately unreadable by the default `Persist`. This
75+
ensures the correct downgrade procedure is followed, which is: (#2359)
76+
* First, make a backup copy of all channel state,
77+
* then ensure all `ChannelMonitorUpdate`s stored are fully applied to the
78+
relevant `ChannelMonitor`,
79+
* finally, write each full `ChannelMonitor` using your new `Persist` impl.
80+
81+
## Bug Fixes
82+
* Anchor channels which were closed by a counterparty broadcasting its
83+
commitment transaction (i.e. force-closing) would previously not generate a
84+
`SpendableOutputs` event for our `to_remote` (i.e. non-HTLC-encumbered)
85+
balance. Those with such balances available should fetch the missing
86+
`SpendableOutputDescriptor`s using the new
87+
`ChannelMonitor::get_spendable_outputs` method (#2605).
88+
* Anchor channels may result in spurious or missing `Balance` entries for HTLC
89+
balances (#2610).
90+
* `ChannelManager::send_spontaneous_payment_with_retry` spuriously did not
91+
provide the recipient with enough information to claim the payment, leading
92+
to all spontaneous payments failing (#2475).
93+
`send_spontaneous_payment_with_route` was unaffected.
94+
* The `keysend` feature on node announcements was spuriously un-set in 0.0.112
95+
and has been re-enabled (#2465).
96+
* Fixed several races which could lead to deadlock when force-closing a channel
97+
(#2597). These races have not been seen in production.
98+
* The `ChannelManager` is persisted substantially less when it has not changed,
99+
leading to substantially less I/O traffic for it (#2521, #2617).
100+
* Passing new block data to `ChainMonitor` no longer results in all other
101+
monitor operations being blocked until it completes (#2528).
102+
* When retrying payments, any excess amount sent to the recipient in order to
103+
meet an `htlc_minimum` constraint on the path is now no longer included in
104+
the amount we send in the retry (#2575).
105+
* Several edge cases in route-finding around HTLC minimums were fixed which
106+
could have caused invalid routes or panics when built with debug assertions
107+
(#2570, #2575).
108+
* Several edge cases in route-finding around HTLC minimums and route hints
109+
were fixed which would spuriously result in no route found (#2575, #2604).
110+
* The `user_channel_id` passed to `SignerProvider::generate_channel_keys_id`
111+
for inbound channels is now correctly using the one passed to
112+
`ChannelManager::accept_inbound_channel` rather than a default value (#2428).
113+
* Users of `impl_writeable_tlv_based!` no longer have use requirements (#2506).
114+
* No longer force-close channels when counterparties send a `channel_update`
115+
with a bogus `htlc_minimum_msat`, which LND users can manually build (#2611).
116+
117+
## Node Compatibility
118+
* LDK now ignores `error` messages generated by LND in response to a
119+
`shutdown` message, avoiding force-closes due to LND bug 6039. This may
120+
lead to non-trivial bandwidth usage with LND peers exhibiting this bug
121+
during the cooperative shutdown process (#2507).
122+
123+
## Security
124+
0.0.117 fixes several loss-of-funds vulnerabilities in anchor output channels,
125+
support for which was added in 0.0.116, in reorg handling, and when accepting
126+
channel(s) from counterparties which are miners.
127+
* When a counterparty broadcasts their latest commitment transaction for a
128+
channel with anchor outputs, we'd previously fail to build claiming
129+
transactions against any HTLC outputs in that transaction. This could lead
130+
to loss of funds if the counterparty is able to eventually claim the HTLC
131+
after a timeout (#2606).
132+
* Anchor channels HTLC claims on-chain previously spent the entire value of any
133+
HTLCs as fee, which has now been fixed (#2587).
134+
* If a channel is closed via an on-chain commitment transaction confirmation
135+
with a pending outbound HTLC in the commitment transaction, followed by a
136+
reorg which replaces the confirmed commitment transaction with a different
137+
(but non-revoked) commitment transaction, all before we learn the payment
138+
preimage for this HTLC, we may previously have not generated a proper
139+
claiming transaction for the HTLC's value (#2623).
140+
* 0.0.117 now correctly handles channels for which our counterparty funded the
141+
channel with a coinbase transaction. As such transactions are not spendable
142+
until they've reached 100 confirmations, this could have resulted in
143+
accepting HTLC(s) which are not enforcible on-chain (#1924).
144+
145+
In total, this release features 121 files changed, 20477 insertions, 8184
146+
deletions in 381 commits from 27 authors, in alphabetical order:
147+
* Alec Chen
148+
* Allan Douglas R. de Oliveira
149+
* Antonio Yang
150+
* Arik Sosman
151+
* Chris Waterson
152+
* David Caseria
153+
* DhananjayPurohit
154+
* Dom Zippilli
155+
* Duncan Dean
156+
* Elias Rohrer
157+
* Erik De Smedt
158+
* Evan Feenstra
159+
* Gabor Szabo
160+
* Gursharan Singh
161+
* Jeffrey Czyz
162+
* Joseph Goulden
163+
* Lalitmohansharma1
164+
* Matt Corallo
165+
* Rachel Malonson
166+
* Sergi Delgado Segura
167+
* Valentine Wallace
168+
* Vladimir Fomene
169+
* Willem Van Lint
170+
* Wilmer Paulino
171+
* benthecarman
172+
* jbesraa
173+
* optout
174+
175+
1176
# 0.0.116 - Jul 21, 2023 - "Anchoring the Roadmap"
2177

3178
## API Updates

fuzz/src/chanmon_consistency.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ impl chain::Watch<TestChannelSigner> for TestChainMonitor {
155155
};
156156
let deserialized_monitor = <(BlockHash, channelmonitor::ChannelMonitor<TestChannelSigner>)>::
157157
read(&mut Cursor::new(&map_entry.get().1), (&*self.keys, &*self.keys)).unwrap().1;
158-
deserialized_monitor.update_monitor(update, &&TestBroadcaster{}, &FuzzEstimator { ret_val: atomic::AtomicU32::new(253) }, &self.logger).unwrap();
158+
deserialized_monitor.update_monitor(update, &&TestBroadcaster{}, &&FuzzEstimator { ret_val: atomic::AtomicU32::new(253) }, &self.logger).unwrap();
159159
let mut ser = VecWriter(Vec::new());
160160
deserialized_monitor.write(&mut ser).unwrap();
161161
map_entry.insert((update.update_id, ser.0));

fuzz/src/router.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
233233
force_close_spend_delay: None,
234234
is_outbound: true, is_channel_ready: true,
235235
is_usable: true, is_public: true,
236+
balance_msat: 0,
236237
outbound_capacity_msat: capacity.saturating_mul(1000),
237238
next_outbound_htlc_limit_msat: capacity.saturating_mul(1000),
238239
next_outbound_htlc_minimum_msat: 0,

lightning-background-processor/Cargo.toml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "lightning-background-processor"
3-
version = "0.0.117-alpha1"
3+
version = "0.0.117"
44
authors = ["Valentine Wallace <[email protected]>"]
55
license = "MIT OR Apache-2.0"
66
repository = "https://github.com/lightningdevkit/rust-lightning"
@@ -22,11 +22,11 @@ default = ["std"]
2222

2323
[dependencies]
2424
bitcoin = { version = "0.29.0", default-features = false }
25-
lightning = { version = "0.0.117-alpha1", path = "../lightning", default-features = false }
26-
lightning-rapid-gossip-sync = { version = "0.0.117-alpha1", path = "../lightning-rapid-gossip-sync", default-features = false }
25+
lightning = { version = "0.0.117", path = "../lightning", default-features = false }
26+
lightning-rapid-gossip-sync = { version = "0.0.117", path = "../lightning-rapid-gossip-sync", default-features = false }
2727

2828
[dev-dependencies]
2929
tokio = { version = "1.14", features = [ "macros", "rt", "rt-multi-thread", "sync", "time" ] }
30-
lightning = { version = "0.0.117-alpha1", path = "../lightning", features = ["_test_utils"] }
31-
lightning-invoice = { version = "0.25.0-alpha1", path = "../lightning-invoice" }
32-
lightning-persister = { version = "0.0.117-alpha1", path = "../lightning-persister" }
30+
lightning = { version = "0.0.117", path = "../lightning", features = ["_test_utils"] }
31+
lightning-invoice = { version = "0.25.0", path = "../lightning-invoice" }
32+
lightning-persister = { version = "0.0.117", path = "../lightning-persister" }

lightning-background-processor/src/lib.rs

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -501,15 +501,15 @@ use core::task;
501501
/// could setup `process_events_async` like this:
502502
/// ```
503503
/// # use lightning::io;
504-
/// # use std::sync::{Arc, Mutex};
504+
/// # use std::sync::{Arc, RwLock};
505505
/// # use std::sync::atomic::{AtomicBool, Ordering};
506506
/// # use lightning_background_processor::{process_events_async, GossipSync};
507507
/// # struct MyStore {}
508508
/// # impl lightning::util::persist::KVStore for MyStore {
509-
/// # fn read(&self, namespace: &str, sub_namespace: &str, key: &str) -> io::Result<Vec<u8>> { Ok(Vec::new()) }
510-
/// # fn write(&self, namespace: &str, sub_namespace: &str, key: &str, buf: &[u8]) -> io::Result<()> { Ok(()) }
511-
/// # fn remove(&self, namespace: &str, sub_namespace: &str, key: &str, lazy: bool) -> io::Result<()> { Ok(()) }
512-
/// # fn list(&self, namespace: &str, sub_namespace: &str) -> io::Result<Vec<String>> { Ok(Vec::new()) }
509+
/// # fn read(&self, primary_namespace: &str, secondary_namespace: &str, key: &str) -> io::Result<Vec<u8>> { Ok(Vec::new()) }
510+
/// # fn write(&self, primary_namespace: &str, secondary_namespace: &str, key: &str, buf: &[u8]) -> io::Result<()> { Ok(()) }
511+
/// # fn remove(&self, primary_namespace: &str, secondary_namespace: &str, key: &str, lazy: bool) -> io::Result<()> { Ok(()) }
512+
/// # fn list(&self, primary_namespace: &str, secondary_namespace: &str) -> io::Result<Vec<String>> { Ok(Vec::new()) }
513513
/// # }
514514
/// # struct MyEventHandler {}
515515
/// # impl MyEventHandler {
@@ -528,11 +528,11 @@ use core::task;
528528
/// # type MyFilter = dyn lightning::chain::Filter + Send + Sync;
529529
/// # type MyLogger = dyn lightning::util::logger::Logger + Send + Sync;
530530
/// # type MyChainMonitor = lightning::chain::chainmonitor::ChainMonitor<lightning::sign::InMemorySigner, Arc<MyFilter>, Arc<MyBroadcaster>, Arc<MyFeeEstimator>, Arc<MyLogger>, Arc<MyStore>>;
531-
/// # type MyPeerManager = lightning::ln::peer_handler::SimpleArcPeerManager<MySocketDescriptor, MyChainMonitor, MyBroadcaster, MyFeeEstimator, MyUtxoLookup, MyLogger>;
531+
/// # type MyPeerManager = lightning::ln::peer_handler::SimpleArcPeerManager<MySocketDescriptor, MyChainMonitor, MyBroadcaster, MyFeeEstimator, Arc<MyUtxoLookup>, MyLogger>;
532532
/// # type MyNetworkGraph = lightning::routing::gossip::NetworkGraph<Arc<MyLogger>>;
533533
/// # type MyGossipSync = lightning::routing::gossip::P2PGossipSync<Arc<MyNetworkGraph>, Arc<MyUtxoLookup>, Arc<MyLogger>>;
534534
/// # type MyChannelManager = lightning::ln::channelmanager::SimpleArcChannelManager<MyChainMonitor, MyBroadcaster, MyFeeEstimator, MyLogger>;
535-
/// # type MyScorer = Mutex<lightning::routing::scoring::ProbabilisticScorer<Arc<MyNetworkGraph>, Arc<MyLogger>>>;
535+
/// # type MyScorer = RwLock<lightning::routing::scoring::ProbabilisticScorer<Arc<MyNetworkGraph>, Arc<MyLogger>>>;
536536
///
537537
/// # async fn setup_background_processing(my_persister: Arc<MyStore>, my_event_handler: Arc<MyEventHandler>, my_chain_monitor: Arc<MyChainMonitor>, my_channel_manager: Arc<MyChannelManager>, my_gossip_sync: Arc<MyGossipSync>, my_logger: Arc<MyLogger>, my_scorer: Arc<MyScorer>, my_peer_manager: Arc<MyPeerManager>) {
538538
/// let background_persister = Arc::clone(&my_persister);
@@ -868,7 +868,10 @@ mod tests {
868868
use lightning::util::config::UserConfig;
869869
use lightning::util::ser::Writeable;
870870
use lightning::util::test_utils;
871-
use lightning::util::persist::{KVStore, CHANNEL_MANAGER_PERSISTENCE_NAMESPACE, CHANNEL_MANAGER_PERSISTENCE_SUB_NAMESPACE, CHANNEL_MANAGER_PERSISTENCE_KEY, NETWORK_GRAPH_PERSISTENCE_NAMESPACE, NETWORK_GRAPH_PERSISTENCE_SUB_NAMESPACE, NETWORK_GRAPH_PERSISTENCE_KEY, SCORER_PERSISTENCE_NAMESPACE, SCORER_PERSISTENCE_SUB_NAMESPACE, SCORER_PERSISTENCE_KEY};
871+
use lightning::util::persist::{KVStore,
872+
CHANNEL_MANAGER_PERSISTENCE_PRIMARY_NAMESPACE, CHANNEL_MANAGER_PERSISTENCE_SECONDARY_NAMESPACE, CHANNEL_MANAGER_PERSISTENCE_KEY,
873+
NETWORK_GRAPH_PERSISTENCE_PRIMARY_NAMESPACE, NETWORK_GRAPH_PERSISTENCE_SECONDARY_NAMESPACE, NETWORK_GRAPH_PERSISTENCE_KEY,
874+
SCORER_PERSISTENCE_PRIMARY_NAMESPACE, SCORER_PERSISTENCE_SECONDARY_NAMESPACE, SCORER_PERSISTENCE_KEY};
872875
use lightning_persister::fs_store::FilesystemStore;
873876
use std::collections::VecDeque;
874877
use std::{fs, env};
@@ -983,22 +986,22 @@ mod tests {
983986
}
984987

985988
impl KVStore for Persister {
986-
fn read(&self, namespace: &str, sub_namespace: &str, key: &str) -> lightning::io::Result<Vec<u8>> {
987-
self.kv_store.read(namespace, sub_namespace, key)
989+
fn read(&self, primary_namespace: &str, secondary_namespace: &str, key: &str) -> lightning::io::Result<Vec<u8>> {
990+
self.kv_store.read(primary_namespace, secondary_namespace, key)
988991
}
989992

990-
fn write(&self, namespace: &str, sub_namespace: &str, key: &str, buf: &[u8]) -> lightning::io::Result<()> {
991-
if namespace == CHANNEL_MANAGER_PERSISTENCE_NAMESPACE &&
992-
sub_namespace == CHANNEL_MANAGER_PERSISTENCE_SUB_NAMESPACE &&
993+
fn write(&self, primary_namespace: &str, secondary_namespace: &str, key: &str, buf: &[u8]) -> lightning::io::Result<()> {
994+
if primary_namespace == CHANNEL_MANAGER_PERSISTENCE_PRIMARY_NAMESPACE &&
995+
secondary_namespace == CHANNEL_MANAGER_PERSISTENCE_SECONDARY_NAMESPACE &&
993996
key == CHANNEL_MANAGER_PERSISTENCE_KEY
994997
{
995998
if let Some((error, message)) = self.manager_error {
996999
return Err(std::io::Error::new(error, message))
9971000
}
9981001
}
9991002

1000-
if namespace == NETWORK_GRAPH_PERSISTENCE_NAMESPACE &&
1001-
sub_namespace == NETWORK_GRAPH_PERSISTENCE_SUB_NAMESPACE &&
1003+
if primary_namespace == NETWORK_GRAPH_PERSISTENCE_PRIMARY_NAMESPACE &&
1004+
secondary_namespace == NETWORK_GRAPH_PERSISTENCE_SECONDARY_NAMESPACE &&
10021005
key == NETWORK_GRAPH_PERSISTENCE_KEY
10031006
{
10041007
if let Some(sender) = &self.graph_persistence_notifier {
@@ -1013,24 +1016,24 @@ mod tests {
10131016
}
10141017
}
10151018

1016-
if namespace == SCORER_PERSISTENCE_NAMESPACE &&
1017-
sub_namespace == SCORER_PERSISTENCE_SUB_NAMESPACE &&
1019+
if primary_namespace == SCORER_PERSISTENCE_PRIMARY_NAMESPACE &&
1020+
secondary_namespace == SCORER_PERSISTENCE_SECONDARY_NAMESPACE &&
10181021
key == SCORER_PERSISTENCE_KEY
10191022
{
10201023
if let Some((error, message)) = self.scorer_error {
10211024
return Err(std::io::Error::new(error, message))
10221025
}
10231026
}
10241027

1025-
self.kv_store.write(namespace, sub_namespace, key, buf)
1028+
self.kv_store.write(primary_namespace, secondary_namespace, key, buf)
10261029
}
10271030

1028-
fn remove(&self, namespace: &str, sub_namespace: &str, key: &str, lazy: bool) -> lightning::io::Result<()> {
1029-
self.kv_store.remove(namespace, sub_namespace, key, lazy)
1031+
fn remove(&self, primary_namespace: &str, secondary_namespace: &str, key: &str, lazy: bool) -> lightning::io::Result<()> {
1032+
self.kv_store.remove(primary_namespace, secondary_namespace, key, lazy)
10301033
}
10311034

1032-
fn list(&self, namespace: &str, sub_namespace: &str) -> lightning::io::Result<Vec<String>> {
1033-
self.kv_store.list(namespace, sub_namespace)
1035+
fn list(&self, primary_namespace: &str, secondary_namespace: &str) -> lightning::io::Result<Vec<String>> {
1036+
self.kv_store.list(primary_namespace, secondary_namespace)
10341037
}
10351038
}
10361039

@@ -1178,7 +1181,7 @@ mod tests {
11781181
let network_graph = Arc::new(NetworkGraph::new(network, logger.clone()));
11791182
let scorer = Arc::new(Mutex::new(TestScorer::new()));
11801183
let seed = [i as u8; 32];
1181-
let router = Arc::new(DefaultRouter::new(network_graph.clone(), logger.clone(), seed, scorer.clone(), ()));
1184+
let router = Arc::new(DefaultRouter::new(network_graph.clone(), logger.clone(), seed, scorer.clone(), Default::default()));
11821185
let chain_source = Arc::new(test_utils::TestChainSource::new(Network::Bitcoin));
11831186
let kv_store = Arc::new(FilesystemStore::new(format!("{}_persister_{}", &persist_dir, i).into()));
11841187
let now = Duration::from_secs(genesis_block.header.time as u64);

0 commit comments

Comments
 (0)