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

[Merged by Bors] - sync2: implement database-backed sync based on FPTree #6406

Closed
wants to merge 40 commits into from

Conversation

ivan4th
Copy link
Contributor

@ivan4th ivan4th commented Oct 23, 2024


Motivation

The new set reconciliation mechanism requires an efficient data structure for handling range fingerprint queries.

Description

fptree.FPTree provides a sufficiently efficient data structure for
performing range fingerprinting on data residing in database tables,
speeding up the queries at expense of some memory use.

dbset.DBSet builds on fptree.FPTree and provides a database-backed
implementation of the multipeer.OrderedSet interface.

#6405 needs to be merged before this one.

Given that after recent item sync is done (if it's needed at all), the
range set reconciliation algorithm no longer depends on newly received
item being added to the set, we can save memory by not adding the
received items during reconciliation.

During real sync, the received items will be sent to the respective
handlers and after the corresponding data are fetched and validated,
they will be added to the database, without the need to add them to
cloned OrderedSets which are used to sync against particular peers.
Copy link

codecov bot commented Oct 23, 2024

Codecov Report

Attention: Patch coverage is 81.02288% with 282 lines in your changes missing coverage. Please review.

Project coverage is 79.9%. Comparing base (d512f24) to head (44d888f).
Report is 25 commits behind head on develop.

Files with missing lines Patch % Lines
sync2/fptree/fptree.go 85.9% 91 Missing and 34 partials ⚠️
sync2/dbset/dbset.go 67.6% 35 Missing and 20 partials ⚠️
sync2/fptree/trace.go 18.0% 40 Missing and 1 partial ⚠️
sync2/fptree/nodepool.go 74.1% 18 Missing and 11 partials ⚠️
sync2/fptree/refcountpool.go 74.0% 7 Missing and 7 partials ⚠️
sync2/fptree/prefix.go 89.3% 7 Missing and 5 partials ⚠️
sync2/fptree/testtree.go 91.4% 2 Missing and 4 partials ⚠️
Additional details and impacted files
@@            Coverage Diff            @@
##           develop   #6406     +/-   ##
=========================================
+ Coverage     79.8%   79.9%   +0.1%     
=========================================
  Files          341     352     +11     
  Lines        44204   46096   +1892     
=========================================
+ Hits         35285   36862   +1577     
- Misses        6918    7151    +233     
- Partials      2001    2083     +82     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.


🚨 Try these New Features:

This adds multi-peer synchronization support.
When the local set differs too much from the remote sets,
"torrent-style" "split sync" is attempted which splits the set into
subranges and syncs each sub-range against a separate peer.
Otherwise, the full sync is done, syncing the whole set against
each of the synchronization peers.
Full sync is also done after each split sync run.
The local set can be considered synchronized after the specified
number of full syncs has happened.

The approach is loosely based on [SREP: Out-Of-Band Sync of
Transaction Pools for Large-Scale
Blockchains](https://people.bu.edu/staro/2023-ICBC-Novak.pdf) paper by
Novak Boškov, Sevval Simsek, Ari Trachtenberg, and David Starobinski.
The `sqlstore` package provides simple sequence-based interface to the
tables being synchronized. It is used by the FPTree data structure as
the database layer, and doesn't do range fingerprinting by itself.

`SyncedTable` and `SyncedTableSnapshot` provide methods that wrap the
necessary SQL operations. `sql/expr` package was added to facilitate
SQL generation.
`fptree.FPTree` provides a sufficiently efficient data structure for
performing range fingerprinting on data residing in database tables,
speeding up the queries at expense of some memory use.

`dbset.DBSet` builds on `fptree.FPTree` and provides a database-backed
implementation of the `multipeer.OrderedSet` interface.
@spacemesh-bors spacemesh-bors bot changed the base branch from sync2/sqlstore to develop November 3, 2024 06:23
Copy link
Contributor

@acud acud left a comment

Choose a reason for hiding this comment

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

I have some minor comments

sync2/dbset/dbset.go Outdated Show resolved Hide resolved
sync2/dbset/dbset.go Show resolved Hide resolved
sync2/dbset/dbset.go Show resolved Hide resolved
sync2/dbset/dbset.go Show resolved Hide resolved
sync2/dbset/dbset.go Show resolved Hide resolved
return rowsA, rowsB, combined
}

func TestP2P(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

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

i guess that this test is an e2e test that checks that the whole syncing flow works with a db backed dataset. it is however huge and very complex. having at least a modest comment about what this test is supposed to do would be nice.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added a comment

// EnableTrace enables or disables tracing for the tree.
func (ft *FPTree) EnableTrace(enable bool) {
ft.traceEnabled = enable
}
Copy link
Contributor

Choose a reason for hiding this comment

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

i think that reviewing this file while understanding everything which is happening here will probably take me a week. i will therefore "trust you on this"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not insisting on reading this right now, but for future reference, the docs on how FPTree works are in the dev-docs folder.
https://github.com/spacemeshos/go-spacemesh/blob/44d888f22e96d0f1b0a59480af19548b23ba38de/dev-docs/sync2-set-reconciliation.md#fptree-data-structure

require.Equal(t, foo{x: 12}, pool.item(idx5))

// // don't replace an item with multiple refs
// pool.ref(idx5)
Copy link
Contributor

Choose a reason for hiding this comment

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

is this still needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed, thanks

@ivan4th
Copy link
Contributor Author

ivan4th commented Nov 8, 2024

bors merge

spacemesh-bors bot pushed a commit that referenced this pull request Nov 8, 2024
-------

## Motivation

The new set reconciliation mechanism requires an efficient data structure for handling range fingerprint queries.
@spacemesh-bors
Copy link

spacemesh-bors bot commented Nov 8, 2024

Build failed:

  • systest-status

@ivan4th
Copy link
Contributor Author

ivan4th commented Nov 8, 2024

Unrelated TestSmeshing systest failure:

    smeshing_test.go:114: 
        	Error Trace:	/src/systest/tests/smeshing_test.go:170
        	            				/src/systest/tests/smeshing_test.go:114
        	            				/src/systest/tests/smeshing_test.go:51
        	Error:      	Not equal: 
        	            	expected: 26
        	            	actual  : 51
        	Test:       	TestSmeshing
        	Messages:   	0xfc9d997f8b3870be67e24ab7506f62b7c52c8ed41b90d577926fdb3dbbee9419

@ivan4th
Copy link
Contributor Author

ivan4th commented Nov 8, 2024

bors merge

spacemesh-bors bot pushed a commit that referenced this pull request Nov 8, 2024
-------

## Motivation

The new set reconciliation mechanism requires an efficient data structure for handling range fingerprint queries.
@fasmat
Copy link
Member

fasmat commented Nov 8, 2024

That's not the test that failed, this is the workflow that failed: https://github.com/spacemeshos/go-spacemesh/actions/runs/11748167959

And the reason it failed is because a node generated a malfeasance proof that couldn't be validated during publication: https://grafana.spacemesh.dev/goto/sKk1avMNg?orgId=1

It appears that the node correctly detected the post as invalid, created a malfeasance proof for it but then failed to validate that malfeasance proof when publishing it (so it never did).

I have never seen this before, the post that we generate in that test is guaranteed to be invalid so a malfeasance proof generated for it should be valid...

cc @poszu

@ivan4th
Copy link
Contributor Author

ivan4th commented Nov 8, 2024

SyncV2 is not used in systests yet (and not integrated with ATXs yet in this PR).
So this needs to be checked, but I think it's not related to the changes here

@spacemesh-bors
Copy link

spacemesh-bors bot commented Nov 8, 2024

Pull request successfully merged into develop.

Build succeeded:

@spacemesh-bors spacemesh-bors bot changed the title sync2: implement database-backed sync based on FPTree [Merged by Bors] - sync2: implement database-backed sync based on FPTree Nov 8, 2024
@spacemesh-bors spacemesh-bors bot closed this Nov 8, 2024
@spacemesh-bors spacemesh-bors bot deleted the sync2/fptree branch November 8, 2024 22:07
@ivan4th ivan4th mentioned this pull request Nov 25, 2024
35 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants