Skip to content
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

Refactor to use eventuals for monitoring network data #54

Closed
wants to merge 1 commit into from

Conversation

Jannis
Copy link
Collaborator

@Jannis Jannis commented Sep 21, 2023

Eventuals are like tokio::sync::watch, except they only trigger an update downstream if their value changes, not every time a new value is written into it. It's a nice primitive to ensure we always have the latest value available and only do something when there are changes.

This switches to eventuals for the following things:

  • Monitoring the indexer's own allocations. This outputs an update to date list of active and recently closed allocations and updates every 30s.
  • Creating attestation signers. This takes the indexer's allocations and ensures that we can always sign attestations for queries made against the subgraphs that were allocated to.

@Jannis Jannis force-pushed the jannis/eventuals branch 2 times, most recently from df129d2 to 6e52bd1 Compare September 21, 2023 13:11
Specifically, use one eventual for monitoring the indexer's active and
recently closed allocations, and one for establishing attestation signers
for these allocations.
@github-actions
Copy link
Contributor

Pull Request Test Coverage Report for Build 6262267806

  • 80 of 296 (27.03%) changed or added relevant lines in 11 files are covered.
  • 168 unchanged lines in 7 files lost coverage.
  • Overall coverage decreased (-13.9%) to 31.313%

Changes Missing Coverage Covered Lines Changed/Added Lines %
common/src/network_subgraph/mod.rs 7 9 77.78%
service/src/server/mod.rs 0 2 0.0%
common/src/allocations/mod.rs 0 3 0.0%
common/src/attestations/signer.rs 57 62 91.94%
service/src/query_processor.rs 3 9 33.33%
service/src/tap_manager.rs 0 7 0.0%
service/src/main.rs 0 9 0.0%
service/src/server/routes/network.rs 0 13 0.0%
common/src/attestations/signers.rs 0 27 0.0%
common/src/allocations/monitor.rs 0 142 0.0%
Files with Coverage Reduction New Missed Lines %
service/src/main.rs 1 0.0%
service/src/tap_manager.rs 1 0.0%
common/src/attestations/signers.rs 6 0.0%
common/src/types.rs 7 92.13%
common/src/allocations/monitor.rs 14 0.0%
common/src/allocations/mod.rs 23 0.0%
common/src/test_vectors.rs 116 0.0%
Totals Coverage Status
Change from base Build 6261178694: -13.9%
Covered Lines: 749
Relevant Lines: 2392

💛 - Coveralls

@aasseman aasseman added size:large Large p2 Medium priority type:refactor Changes not visible to users labels Sep 21, 2023
Copy link
Collaborator

@hopeyen hopeyen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sweet sweet abstractions with eventuals and network subgraph generic query🤌

for i in 0..100 {
// The allocation was either created at the epoch it intended to or one
// epoch later. So try both both.
for created_at_epoch in [allocation.created_at_epoch, allocation.created_at_epoch - 1] {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might be missing context for this one even though this is the same as in the ts impl
is created_at_epoch the intended epoch, or created_at_epoch - 1 the intended epoch? trying to wrap my head around the -1 for one epoch later when the epoch increments wrt time

const INDEXER_OPERATOR_MNEMONIC: &str = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";

#[test]
fn test_derive_key_pair() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we keep these unit tests around?

Copy link
Contributor

@aasseman aasseman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had a bit of a hard time reviewing because there is a lot of changes that are not strictly related to the implementation of eventuals (refactor of the internals of the signers code, network subgraph), and the removal of many tests, some of which I think could have worked without significant modifications, prevents me from checking that the behavior is correct.

In general I prefer single concern PRs as they are more palatable to the reviewer, and it's easier to rollback PRs if there's a problem in the future without rolling back unrelated changes.

Comment on lines +22 to +26
// Keep a cache of the most recent 1000 signers around so we don't need to recreate them
// every time there is a small change in the allocations
let cache: &'static Mutex<LruCache<_, _>> = Box::leak(Box::new(Mutex::new(LruCache::new(
NonZeroUsize::new(1000).unwrap(),
))));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the rationale for using an LRU cache? Wasn't it overall simpler and more efficient to just update a HashMap in place directly? Especially when you consider that the LRU cache is a souped up HashMap itself.

@@ -61,26 +62,24 @@ async fn main() -> Result<(), std::io::Error> {
// Make an instance of network subgraph at either
// graph_node_query_endpoint/subgraphs/id/network_subgraph_deployment
// or network_subgraph_endpoint
let network_subgraph = NetworkSubgraph::new(
let network_subgraph: &'static NetworkSubgraph = Box::leak(Box::new(NetworkSubgraph::new(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works, but since NetworkSubgraph is ARC, it could also have been cloned around. Since it indeed is supposed to stick around the whole lifetime of the program it does not technically make a big difference though.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps I should have used this pattern since the beginning though, makes a lot of things even simpler. I suppose the only downside is that it makes everything expect a static reference, which can be sometimes limiting in a library?

@Jannis
Copy link
Collaborator Author

Jannis commented Sep 22, 2023

@aasseman I can try to pick the changes apart a bit and submit separate PRs. I like more incremental PRs as well. And yes, I need to invest more into testing again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
p2 Medium priority size:large Large type:refactor Changes not visible to users
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants