-
Notifications
You must be signed in to change notification settings - Fork 249
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
maindb v4 #868
base: feat/db
Are you sure you want to change the base?
maindb v4 #868
Conversation
This PR is a successor of PR #635. |
@libotony could you sync the branch with |
b43bbfb
to
ef814c0
Compare
Done. |
Wired that tests won't run with this PR only, might be caused by the on-pull-request.yaml wasn't updated in the master branch, but after PR #871 was opened, CI was trigger for targeting master then with the same commit hash of this PR, the workflow was also linked here. |
@libotony looks like
|
Should be fixed. |
@@ -24,6 +24,7 @@ require ( | |||
github.com/prometheus/client_model v0.5.0 | |||
github.com/prometheus/common v0.45.0 | |||
github.com/qianbin/directcache v0.9.7 | |||
github.com/qianbin/drlp v0.0.0-20240102101024-e0e02518b5f9 |
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.
Seems the dependency is quite small, should we just copy the files over to this repo?
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.
wdyt? @qianbin
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.
sure
} | ||
|
||
// AddNodeBlob adds encoded node blob into the cache. | ||
func (c *cache) AddNodeBlob(keyBuf *[]byte, name string, path []byte, ver trie.Version, blob []byte, isCommitting bool) { |
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.
Looks like most of these methods are exported but not used outside the package. Maybe I'm wrong ? Probably doesn't matter too much anyhow
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.
Itself can be treated a standalone "class" to other ones, even it's inside the same package. IMHO, it's a good practice to define public/private functions even it's internal only.
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.
I'm good with either, but what if the other structs used an interface (like Cache
) instead of *cache
. Would that help, or make will it make it into future-proving land ?
api/accounts/accounts_test.go
Outdated
if err := repo.AddBlock(b, receipts, 0, false); err != nil { | ||
t.Fatal(err) | ||
} | ||
if err := repo.SetBestBlockID(b.Header().ID()); err != nil { |
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.
Likely worth removing the repo.SetBestBlockID
and setting repo.AddBlock(b, receipts, 0, true)
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.
Removed repo.SetBestBlockID
from most test files in commit ebed07a, but there is still a usage for it in https://github.com/vechain/thor/blob/tony/maindb-v4/bft/engine_test.go#L164, which I think is not avoidable.
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.
Agreed 👍
There's a tester pattern that can be applied in such cases where
type RepositoryTest struct {
Repository
}
func (r *RepositoryTest) SetBestBlockID(...) {}
I don't think there are a lot of other testing methods no point in using this, but wanted to highlight it if needed in the future!
{ | ||
tx, meta, err := c.GetTransaction(tx1.ID()) | ||
assert.Nil(t, err) | ||
assert.Equal(t, tx1Meta, meta) | ||
assert.Equal(t, tx1.ID(), tx.ID()) | ||
} | ||
{ | ||
r, err := c.GetTransactionReceipt(tx1.ID()) | ||
assert.Nil(t, err) | ||
got, _ := rlp.EncodeToBytes(r) | ||
want, _ := rlp.EncodeToBytes(tx1Receipt) | ||
assert.Equal(t, want, got) | ||
} | ||
|
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.
Nit - Perhaps the implode func M
can be reused here ? Or changed the M
so it's kinda the same type test approach ?
muxdb/engine/leveldb.go
Outdated
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.
I think it might be worth changing the error check with errors.Is
func (ldb *levelEngine) IsNotFound(err error) bool {
return err == leveldb.ErrNotFound
}
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.
My understanding here is comparing to the specific error and errors.Is
will have more checks including wrapped errors.
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.
Yes, it's comparing to the instance of leveldb.ErrNotFound
.
return err == leveldb.ErrNotFound
will fail iferr := fmt.Errorf("this be error: %w", errNotFound)
errors.Is
is meant to unwrap errors until it finds that type. So if for any reason the error is wrapped upstream, this won't be caught.
if err := bulk.Write(); err != nil { | ||
return nil, err | ||
} | ||
r.caches.summaries.Add(id, &summary) | ||
return &summary, bulk.Write() | ||
if asBest { | ||
r.bestSummary.Store(&summary) | ||
r.tick.Broadcast() | ||
} | ||
return &summary, nil |
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.
It looks like the saveBlock is also used during bootstrap - Could it be detrimental to cache those summaries at bootstrap time ?
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.
Bootstrapping can be ignored here, as it's not a common case. And the behavior is not detrimental as LRU will evict the oldest entry.
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.
Yes, I was considering if it could be an improvement to the bootstrap phase.
It looks like it's adding stuff to cache that will get (almost) immediately booted off ( given it bootstraps a lot of blocks).
Perhaps it's of negligible impact. I wish we had a benchmark test for bootstrapping
repo.caches.txs = newCache(2048) | ||
repo.caches.receipts = newCache(2048) |
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.
I probably missed the why, but it's no longer caching txs and receipts ?
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.
You probably are right, based on the perf test results.
func (r *Repository) getTransaction(key []byte) (*tx.Transaction, error) { | ||
var tx tx.Transaction | ||
if err := loadRLP(r.bodyStore, key, &tx); err != nil { |
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.
Did we miss the caching, or is it upstream ?
muxdb/cache.go
Outdated
if now-last > int64(time.Second*20) { | ||
log1, ok1 := c.nodeStats.ShouldLog("node cache stats") | ||
log2, ok2 := c.rootStats.ShouldLog("root cache stats") | ||
|
||
if ok1 || ok2 { | ||
log1() | ||
log2() | ||
} |
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.
I think this is fine, but can be simplified to just log at 20 seconds interval.
Looks like ShouldLog
only logs when the hitrate has changed and in this case both nodeStats
and rootStats
should have changed their hitrate.
I might be missing it, but I don't see the added value of checking if it should log or not. I'm starting to think it could be simpler to log in demand ?
* feat: add thorclient * refactor: remove roundTripper * refactor: change null check * clean: remove commented code * feat: add account revision and pending tx * fix: add licence headers and fix linter issue * refactor: rename package * refactor: change revision type to string * refactor: rename GetLogs and GetTransfers to FilterEvents and FilterTransfers * refactor: change FilterEvents and FilterTransactions request type to EventFilter * Adding common.EventWrapper to handle channel errors * tweak * update rawclient + update account tests * tidy up names * update tests * pr comments * adding raw tx * Tidy up method names and calls * options client * tweaks * pr comments * Update thorclient/common/common.go Co-authored-by: libotony <[email protected]> * pr comments * Adding Subscriptions * Pr comments * adjust func orders * pr comments * changing subscribe to use the channel close vs multiple channels * adding go-doc * no error after unsubscribe * pr comments * checking status code is 2xx * fix: change FilterTransfers argument --------- Co-authored-by: otherview <[email protected]> Co-authored-by: libotony <[email protected]>
* Refactor thor node * thorchain allows insertion of blocks * remove thorNode, added testchain * clean up + comments * adding license headers * adding templating tests for thorclient * Remove test event hacks * remove types * removed chain_builder + added logdb to testchain * pr comments * Update test/testchain/chain.go Co-authored-by: libotony <[email protected]> --------- Co-authored-by: libotony <[email protected]>
3e5f529
to
df4dc18
Compare
Rebased branch |
api/accounts/accounts_test.go
Outdated
if err := repo.AddBlock(b, receipts, 0, false); err != nil { | ||
t.Fatal(err) | ||
} | ||
if err := repo.SetBestBlockID(b.Header().ID()); err != nil { |
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.
Agreed 👍
There's a tester pattern that can be applied in such cases where
type RepositoryTest struct {
Repository
}
func (r *RepositoryTest) SetBestBlockID(...) {}
I don't think there are a lot of other testing methods no point in using this, but wanted to highlight it if needed in the future!
muxdb/engine/leveldb.go
Outdated
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.
Yes, it's comparing to the instance of leveldb.ErrNotFound
.
return err == leveldb.ErrNotFound
will fail iferr := fmt.Errorf("this be error: %w", errNotFound)
errors.Is
is meant to unwrap errors until it finds that type. So if for any reason the error is wrapped upstream, this won't be caught.
if err := bulk.Write(); err != nil { | ||
return nil, err | ||
} | ||
r.caches.summaries.Add(id, &summary) | ||
return &summary, bulk.Write() | ||
if asBest { | ||
r.bestSummary.Store(&summary) | ||
r.tick.Broadcast() | ||
} | ||
return &summary, nil |
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.
Yes, I was considering if it could be an improvement to the bootstrap phase.
It looks like it's adding stuff to cache that will get (almost) immediately booted off ( given it bootstraps a lot of blocks).
Perhaps it's of negligible impact. I wish we had a benchmark test for bootstrapping
Sorry, not sure what I did for the above comments to not stay in the thread 🙏 |
* change * reverted to previous format
* Add empty cache for inmem ops * changing name to dummyCache
…pace (#888) * first commit * first commit
* changes * removed log * sleeping any way * pr review
Description
This PR upgrades maindb to v4. It greatly reduces the storage space occupied and significantly reduces the This PR upgrades maindb to v4. It greatly reduces the storage space occupied and significantly reduces the synchronization time.
Check out commits for more detail.
Type of change
Please delete options that are not relevant.
Checklist: