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

Add Proof size limit to sync client #1269

Merged
merged 55 commits into from
Apr 17, 2023
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
64600c4
Add Proof size limit to client
dboehm-avalabs Mar 30, 2023
60438cb
Update network_server_test.go
dboehm-avalabs Mar 30, 2023
1bfce3b
Address comments
dboehm-avalabs Mar 30, 2023
79775ad
Fix error case condition for missing start root
dboehm-avalabs Mar 30, 2023
bb3b25b
improve tests
dboehm-avalabs Mar 31, 2023
22218e5
Update client_test.go
dboehm-avalabs Mar 31, 2023
8f134d7
import nit
Apr 3, 2023
bea0493
import nits
Apr 3, 2023
b7a033b
naming nit
Apr 3, 2023
9dbf918
import nit
Apr 3, 2023
c5a0102
lengthen eventually check to reduce flakiness
Apr 3, 2023
edc68f0
nits
Apr 3, 2023
be0f5c0
import nit
Apr 3, 2023
d74d9bf
Update history.go
dboehm-avalabs Apr 10, 2023
ba94b47
remove dependency on binary.varint
dboehm-avalabs Apr 10, 2023
088d6d8
dd tests to enforce connection between byteslicesize and encodebyteslice
dboehm-avalabs Apr 10, 2023
a866a65
move byte estimation to codec
dboehm-avalabs Apr 10, 2023
3b032f3
Merge branch 'dev' into ProofSizes
dboehm-avalabs Apr 10, 2023
604ba92
lint
dboehm-avalabs Apr 10, 2023
39b9cd5
use smaller max bytes size
dboehm-avalabs Apr 11, 2023
90e3468
Update codec.go
dboehm-avalabs Apr 11, 2023
71cbbb2
Update syncmanager.go
dboehm-avalabs Apr 11, 2023
a406b32
Merge branch 'dev' into ProofSizes
dboehm-avalabs Apr 11, 2023
d479c98
Update network_server.go
dboehm-avalabs Apr 11, 2023
98720ef
create max size
dboehm-avalabs Apr 11, 2023
05983d4
Merge remote-tracking branch 'upstream/dev' into ProofSizes
Apr 11, 2023
fa91204
nits
Apr 11, 2023
b63ebaf
Update network_server.go
dboehm-avalabs Apr 11, 2023
008c8c4
Update network_server_test.go
dboehm-avalabs Apr 11, 2023
89be9d4
Update network_server.go
dboehm-avalabs Apr 11, 2023
5db6c9c
import nit
Apr 11, 2023
113a028
add comment and constant
Apr 11, 2023
467c482
import nit
Apr 11, 2023
0ca36e5
Update network_server.go
dboehm-avalabs Apr 12, 2023
6bfa30f
switch order
dboehm-avalabs Apr 12, 2023
97a080c
Merge branch 'dev' into ProofSizes
dboehm-avalabs Apr 12, 2023
7578494
Update network_server.go
dboehm-avalabs Apr 12, 2023
e8b070a
Merge branch 'ProofSizes' of https://github.com/ava-labs/avalanchego …
dboehm-avalabs Apr 12, 2023
aa4526b
Merge branch 'ProofSizes' of github.com:ava-labs/avalanchego into Pro…
Apr 12, 2023
87d6266
Update network_server.go
dboehm-avalabs Apr 12, 2023
0377470
Merge branch 'ProofSizes' of https://github.com/ava-labs/avalanchego …
dboehm-avalabs Apr 12, 2023
fd382fd
Update network_server.go
dboehm-avalabs Apr 12, 2023
aca8108
Update network_server.go
dboehm-avalabs Apr 12, 2023
a9d8596
remove unused codec functions
Apr 12, 2023
46f7326
update constants
Apr 12, 2023
4b44b87
fix test
Apr 12, 2023
3ab91a6
Update client_test.go
dboehm-avalabs Apr 12, 2023
90e4209
Update client_test.go
dboehm-avalabs Apr 12, 2023
e714c1d
Merge branch 'dev' into ProofSizes
Apr 13, 2023
5a9cf34
Merge branch 'dev' into ProofSizes
Apr 13, 2023
a464452
Merge branch 'dev' into ProofSizes
Apr 13, 2023
51bdf7f
Update network_server_test.go
dboehm-avalabs Apr 13, 2023
a6cceb1
Update network_server_test.go
dboehm-avalabs Apr 13, 2023
38d8929
Merge branch 'dev' into ProofSizes
dboehm-avalabs Apr 17, 2023
03a171f
Merge branch 'dev' into ProofSizes
dboehm-avalabs Apr 17, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 23 additions & 18 deletions x/merkledb/history.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,27 +97,32 @@ func (th *trieHistory) getValueChanges(startRoot, endRoot ids.ID, start, end []b
}

// [lastStartRootChange] is the latest appearance of [startRoot]
// which came before [lastEndRootChange].
var lastStartRootChange *changeSummaryAndIndex
th.history.DescendLessOrEqual(
lastEndRootChange,
func(item *changeSummaryAndIndex) bool {
if item == lastEndRootChange {
return true // Skip first iteration
}
if item.rootID == startRoot {
lastStartRootChange = item
return false
}
return true
},
)

// There's no change resulting in [startRoot] before the latest change resulting in [endRoot].
if lastStartRootChange == nil {
lastStartRootChange, ok := th.lastChanges[startRoot]
dboehm-avalabs marked this conversation as resolved.
Show resolved Hide resolved
if !ok {
return nil, ErrStartRootNotFound
}

// if lastStartRootChange is after the lastEndRootChange, then attempt to find an entry that comes before lastEndRootChange
if lastStartRootChange.index > lastEndRootChange.index {
th.history.DescendLessOrEqual(
lastEndRootChange,
func(item *changeSummaryAndIndex) bool {
if item == lastEndRootChange {
return true // Skip first iteration
}
if item.rootID == startRoot {
lastStartRootChange = item
return false
}
return true
},
)
// There's no change resulting in [startRoot] before the latest change resulting in [endRoot].
if lastStartRootChange.index > lastEndRootChange.index {
return nil, ErrStartRootNotFound
}
}

// Keep changes sorted so the largest can be removed in order to stay within the maxLength limit.
sortedKeys := btree.NewG(
2,
Expand Down
4 changes: 4 additions & 0 deletions x/sync/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
## TODOs

- [ ] Handle errors on proof requests. Currently, any errors that occur server side are not sent back to the client.
darioush marked this conversation as resolved.
Show resolved Hide resolved
- [ ] Handle missing roots in change proofs by returning a range proof instead of failing
19 changes: 14 additions & 5 deletions x/sync/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ var (
_ Client = &client{}

errInvalidRangeProof = errors.New("failed to verify range proof")
errTooManyLeaves = errors.New("response contains more than requested leaves")
errTooManyKeys = errors.New("response contains more than requested keys")
errTooManyBytes = errors.New("response contains more than requested bytes")
)

// Client synchronously fetches data from the network to fulfill state sync requests.
Expand Down Expand Up @@ -76,15 +77,19 @@ func NewClient(config *ClientConfig) Client {
// The returned change proof is verified.
func (c *client) GetChangeProof(ctx context.Context, req *ChangeProofRequest, db *merkledb.Database) (*merkledb.ChangeProof, error) {
parseFn := func(ctx context.Context, responseBytes []byte) (*merkledb.ChangeProof, error) {
if len(responseBytes) > int(req.BytesLimit) {
return nil, fmt.Errorf("%w: (%d) > %d)", errTooManyBytes, len(responseBytes), req.BytesLimit)
}

changeProof := &merkledb.ChangeProof{}
if _, err := merkledb.Codec.DecodeChangeProof(responseBytes, changeProof); err != nil {
return nil, err
}

// Ensure the response does not contain more than the requested number of leaves
// and the start and end roots match the requested roots.
if len(changeProof.KeyValues)+len(changeProof.DeletedKeys) > int(req.Limit) {
return nil, fmt.Errorf("%w: (%d) > %d)", errTooManyLeaves, len(changeProof.KeyValues), req.Limit)
if len(changeProof.KeyValues)+len(changeProof.DeletedKeys) > int(req.KeyLimit) {
return nil, fmt.Errorf("%w: (%d) > %d)", errTooManyKeys, len(changeProof.KeyValues), req.KeyLimit)
}

if err := changeProof.Verify(ctx, db, req.Start, req.End, req.EndingRoot); err != nil {
Expand All @@ -100,14 +105,18 @@ func (c *client) GetChangeProof(ctx context.Context, req *ChangeProofRequest, db
// The returned range proof is verified.
func (c *client) GetRangeProof(ctx context.Context, req *RangeProofRequest) (*merkledb.RangeProof, error) {
parseFn := func(ctx context.Context, responseBytes []byte) (*merkledb.RangeProof, error) {
if len(responseBytes) > int(req.BytesLimit) {
return nil, fmt.Errorf("%w: (%d) > %d)", errTooManyBytes, len(responseBytes), req.BytesLimit)
}

rangeProof := &merkledb.RangeProof{}
if _, err := merkledb.Codec.DecodeRangeProof(responseBytes, rangeProof); err != nil {
return nil, err
}

// Ensure the response does not contain more than the maximum requested number of leaves.
if len(rangeProof.KeyValues) > int(req.Limit) {
return nil, fmt.Errorf("%w: (%d) > %d)", errTooManyLeaves, len(rangeProof.KeyValues), req.Limit)
if len(rangeProof.KeyValues) > int(req.KeyLimit) {
return nil, fmt.Errorf("%w: (%d) > %d)", errTooManyKeys, len(rangeProof.KeyValues), req.KeyLimit)
}

if err := rangeProof.Verify(
Expand Down
Loading