-
Notifications
You must be signed in to change notification settings - Fork 160
Stop keeping all DataStore entries in-memory, add pagination
#1024
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
1e38d24
957212b
b5b8130
6696f2f
352188b
83624ed
b891bab
e33a4ae
ce435be
a968238
ffcd9a9
2700cee
2ada5f7
41ae88b
2633a38
241b3d8
1807a9c
c14cb71
e918649
320ec0b
d569490
0bd0246
b61d043
a386723
3b51b96
4a13f71
17fbb7a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -50,18 +50,20 @@ use crate::config::{ | |
| default_user_config, may_announce_channel, AnnounceError, AsyncPaymentsRole, | ||
| BitcoindRestClientConfig, Config, ElectrumSyncConfig, EsploraSyncConfig, HRNResolverConfig, | ||
| TorConfig, DEFAULT_ESPLORA_SERVER_URL, DEFAULT_LOG_FILENAME, DEFAULT_LOG_LEVEL, | ||
| DEFAULT_MAX_PROBE_AMOUNT_MSAT, DEFAULT_MIN_PROBE_AMOUNT_MSAT, | ||
| DEFAULT_MAX_PROBE_AMOUNT_MSAT, DEFAULT_MIN_PROBE_AMOUNT_MSAT, PAYMENT_CACHE_CAPACITY, | ||
| PAYMENT_CACHE_WARMUP_COUNT, | ||
| }; | ||
| use crate::connection::ConnectionManager; | ||
| use crate::data_store::{KeepAllEntries, KeepLeastRecentlyUsed}; | ||
| use crate::entropy::NodeEntropy; | ||
| use crate::event::EventQueue; | ||
| use crate::fee_estimator::OnchainFeeEstimator; | ||
| use crate::gossip::GossipSource; | ||
| use crate::io::sqlite_store::SqliteStore; | ||
| use crate::io::utils::{ | ||
| open_or_migrate_fs_store, read_all_objects, read_event_queue, | ||
| read_external_pathfinding_scores_from_cache, read_network_graph, read_node_metrics, | ||
| read_output_sweeper, read_peer_info, read_scorer, | ||
| read_external_pathfinding_scores_from_cache, read_n_objects, read_network_graph, | ||
| read_node_metrics, read_output_sweeper, read_peer_info, read_scorer, | ||
| }; | ||
| use crate::io::vss_store::VssStoreBuilder; | ||
| use crate::io::{ | ||
|
|
@@ -1458,10 +1460,11 @@ fn build_with_store_internal( | |
| let (payment_store_res, node_metris_res, pending_payment_store_res, address_pool_res) = runtime | ||
| .block_on(async move { | ||
| tokio::join!( | ||
| read_all_objects( | ||
| read_n_objects( | ||
| &*kv_store_ref, | ||
| PAYMENT_INFO_PERSISTENCE_PRIMARY_NAMESPACE, | ||
| PAYMENT_INFO_PERSISTENCE_SECONDARY_NAMESPACE, | ||
| PAYMENT_CACHE_WARMUP_COUNT, | ||
| Arc::clone(&logger_ref), | ||
| ), | ||
| read_node_metrics(&*kv_store_ref, Arc::clone(&logger_ref)), | ||
|
|
@@ -1490,7 +1493,11 @@ fn build_with_store_internal( | |
|
|
||
| let payment_store = match payment_store_res { | ||
| Ok(payments) => Arc::new(PaymentStore::new( | ||
| payments, | ||
| // The read hands us the newest payments first, while the cache treats the objects it | ||
| // is seeded with as increasingly recently used. Reverse them, so that the newest | ||
| // payment is the last one to be evicted rather than the first. | ||
| payments.into_iter().rev().collect(), | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. LRU seeding order is guarded only by a comment — |
||
| KeepLeastRecentlyUsed::new(PAYMENT_CACHE_CAPACITY), | ||
| PAYMENT_INFO_PERSISTENCE_PRIMARY_NAMESPACE.to_string(), | ||
| PAYMENT_INFO_PERSISTENCE_SECONDARY_NAMESPACE.to_string(), | ||
| Arc::clone(&kv_store), | ||
|
|
@@ -1745,8 +1752,12 @@ fn build_with_store_internal( | |
| }; | ||
|
|
||
| let pending_payment_store = match pending_payment_store_res { | ||
| // NOTE: This store must keep all its entries in memory: the wallet scans it in full on | ||
| // every chain tip change and to resolve replaced transactions. It stays bounded anyway, | ||
| // as entries are removed once a payment is no longer pending. | ||
| Ok(pending_payments) => Arc::new(PendingPaymentStore::new( | ||
| pending_payments, | ||
| KeepAllEntries, | ||
| PENDING_PAYMENT_INFO_PERSISTENCE_PRIMARY_NAMESPACE.to_string(), | ||
| PENDING_PAYMENT_INFO_PERSISTENCE_SECONDARY_NAMESPACE.to_string(), | ||
| Arc::clone(&kv_store), | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,7 @@ | |
| //! Objects for configuring the node. | ||
|
|
||
| use std::fmt; | ||
| use std::num::NonZeroUsize; | ||
| use std::str::FromStr; | ||
| use std::time::Duration; | ||
|
|
||
|
|
@@ -48,6 +49,22 @@ pub(crate) const DEFAULT_FEE_RATE_CACHE_UPDATE_TIMEOUT_SECS: u64 = 10; | |
| // The default timeout after which we abort a transaction broadcast operation. | ||
| pub(crate) const DEFAULT_TX_BROADCAST_TIMEOUT_SECS: u64 = 10; | ||
|
|
||
| // The number of payments we keep in memory. | ||
| // | ||
| // The payment history grows for the lifetime of a node, so we cache only the most recently used | ||
| // payments and read the rest back from the store as they are needed. At roughly 400 to 500 bytes | ||
| // per cached payment, this bounds the payment store's share of memory at well under a megabyte, | ||
| // while still covering the recent payments a node actually works with. | ||
| pub(crate) const PAYMENT_CACHE_CAPACITY: NonZeroUsize = NonZeroUsize::new(1000).unwrap(); | ||
|
|
||
| // The number of payments we read into the cache when starting up. | ||
| // | ||
| // This matches the built-in storage backends' page size, so warming the cache costs a single page | ||
| // listing and one batch of reads. Immediately after startup, a first-page `Node::list_payments` | ||
| // call reads only its keys from storage; the payment bodies come from the cache. Later activity | ||
| // may displace those entries. | ||
| pub(crate) const PAYMENT_CACHE_WARMUP_COUNT: NonZeroUsize = NonZeroUsize::new(50).unwrap(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we have this
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, we have some
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. well the comment highlights that its equal ot the page size. We have separate consts for posgres and sqlite page size. Should unify those and use that const here
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, not sure? It's basically a coincidence that it's a page size, though likely a multiple of page size makes sense? Not sure if we want to couple the concepts strongly here, would also be a layer violation somewhat, and one additional thing we'd need to disentangle when upstreaming VSS/Postgres stores? |
||
|
|
||
| // The default {Esplora,Electrum} client timeout we're using. | ||
| const DEFAULT_PER_REQUEST_TIMEOUT_SECS: u8 = 10; | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also async now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still sync? Or maybe misunderstanding?