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

Optimize db lookup extensions while sync & fast-reply-database #2269

Merged
merged 19 commits into from
Sep 8, 2020

Conversation

andreibancioiu
Copy link
Collaborator

@andreibancioiu andreibancioiu commented Sep 3, 2020

  • Call RecordBlock synchronously with Commit(). Consume notifications only on "receive notifications" goroutines.
  • Hold LRU caches for recently handled records so that performance at sync is improved not needed anymore
  • Remove dependency from block tracker's notifications. Notification performed at commit time, by shardBlock / metaBlock processor.

Handle repeated commits of same block (protect against overriding the miniblockMetadata) / EN-7520. Edge case was:

  • routine A - commit → save to storer
  • routine B - receive notification, put it in map at key Foo, start processing notifications (in progress), notification is seen, still in map
  • routine A - then commit again same block
  • routine C - receive notification, put in map at same key Foo
  • routine B - finish processing notification, remove Foo from map
  • routine A - put in storer, override what was written at B.

@andreibancioiu andreibancioiu added the type:feature New feature or request label Sep 3, 2020
@andreibancioiu andreibancioiu self-assigned this Sep 3, 2020
@andreibancioiu andreibancioiu marked this pull request as ready for review September 5, 2020 18:43
@@ -50,6 +50,7 @@ type historyRepository struct {
// that could mistakenly override the "patch()" operations performed when consuming notarization notifications.
deduplicationCacheForInsertMiniblockMetadata storage.Cacher

// Question for review: this can be removed now, using the new approach (without the block tracker), right?
Copy link
Contributor

Choose a reason for hiding this comment

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

The only situation when the notifications will be redundant will be when a node will do a rollback. In this situation the same final block/blocks will be notified again, after another new block will be constructed upon it. But this case should not be a regular pattern and could be considered as an exception. If this redundant notifications will not break something in the implementation logic and the below method was used just as an optimization for this case, I would say that you can remove it now, considering the new approach.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The implementation of OnNotarizedBlocks() is all right with being called twice with some redundant data in case of rollbacks. Removed the extra optimization, thanks!

@@ -246,12 +247,14 @@ func (hr *historyRepository) OnNotarizedBlocks(shardID uint32, headers []data.He
for i, headerHandler := range headers {
headerHash := headersHashes[i]

log.Debug("onNotarizedBlocks():", "shardID", shardID, "nonce", headerHandler.GetNonce(), "headerHash", headerHash, "type", fmt.Sprintf("%T", headerHandler))

// Question for review: this optimization is not required anymore, right?
Copy link
Contributor

Choose a reason for hiding this comment

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

The same response as above

@@ -645,7 +645,7 @@
PollingIntervalInMinutes = 65

[DbLookupExtensions]
Enabled = false
Enabled = true # TODO DISABLE AFTER TESTS
Copy link
Contributor

Choose a reason for hiding this comment

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

don't forget to revert

@@ -158,6 +176,14 @@ func (hr *historyRepository) computeMiniblockHash(miniblock *block.MiniBlock) ([
return core.CalculateHash(hr.marshalizer, hr.hasher, miniblock)
}

func (hr *historyRepository) hasRecentlyInsertedMiniblockMetadata(miniblockHash []byte) bool {
return hr.deduplicationCacheForInsertMiniblockMetadata.Has(miniblockHash)
Copy link
Contributor

Choose a reason for hiding this comment

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

In case of a miniblock added in epoch x on a fork, but added again in epoch x+1 on canonical chain, the "miniblock hash to epoch" will not be updated with the correct epoch.

maybe add also the epoch in this cache as value, and only deduplicate if the epoch value is the same, otherwise update.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Very very nice catch 🥳

Fixed by using a composite key for the deduplication cache. Is it all right?

Copy link
Contributor

Choose a reason for hiding this comment

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

looks good

SebastianMarian
SebastianMarian previously approved these changes Sep 7, 2020
Copy link
Contributor

@LucianMincu LucianMincu left a comment

Choose a reason for hiding this comment

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

System tests passed.

@LucianMincu LucianMincu merged commit 8357aff into development Sep 8, 2020
@LucianMincu LucianMincu deleted the EN-7520-hyperblocks branch September 8, 2020 10:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:feature New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants