Skip to content

Commit 8fb7816

Browse files
authored
Merge pull request #111 from BoostryJP/109-feature
Optimize trie database
2 parents 29f7b9c + d8f1608 commit 8fb7816

File tree

6 files changed

+55
-31
lines changed

6 files changed

+55
-31
lines changed

eth/fetcher/block_fetcher.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -832,15 +832,17 @@ func (f *BlockFetcher) importBlocks(peer string, block *types.Block) {
832832
// internal state.
833833
func (f *BlockFetcher) forgetHash(hash common.Hash) {
834834
// Remove all pending announces and decrement DOS counters
835-
for _, announce := range f.announced[hash] {
836-
f.announces[announce.origin]--
837-
if f.announces[announce.origin] <= 0 {
838-
delete(f.announces, announce.origin)
835+
if announceMap, ok := f.announced[hash]; ok {
836+
for _, announce := range announceMap {
837+
f.announces[announce.origin]--
838+
if f.announces[announce.origin] <= 0 {
839+
delete(f.announces, announce.origin)
840+
}
841+
}
842+
delete(f.announced, hash)
843+
if f.announceChangeHook != nil {
844+
f.announceChangeHook(hash, false)
839845
}
840-
}
841-
delete(f.announced, hash)
842-
if f.announceChangeHook != nil {
843-
f.announceChangeHook(hash, false)
844846
}
845847
// Remove any pending fetches and decrement the DOS counters
846848
if announce := f.fetching[hash]; announce != nil {

eth/fetcher/block_fetcher_test.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,7 @@ func testInvalidNumberAnnouncement(t *testing.T, light bool) {
698698
badBodyFetcher := tester.makeBodyFetcher("bad", blocks, 0)
699699

700700
imported := make(chan interface{})
701+
announced := make(chan interface{})
701702
tester.fetcher.importedHook = func(header *types.Header, block *types.Block) {
702703
if light {
703704
if header == nil {
@@ -712,21 +713,35 @@ func testInvalidNumberAnnouncement(t *testing.T, light bool) {
712713
}
713714
}
714715
// Announce a block with a bad number, check for immediate drop
716+
tester.fetcher.announceChangeHook = func(hash common.Hash, b bool) {
717+
announced <- nil
718+
}
715719
tester.fetcher.Notify("bad", hashes[0], 2, time.Now().Add(-arriveTimeout), badHeaderFetcher, badBodyFetcher)
720+
verifyAnnounce := func() {
721+
for i := 0; i < 2; i++ {
722+
select {
723+
case <-announced:
724+
continue
725+
case <-time.After(1 * time.Second):
726+
t.Fatal("announce timeout")
727+
return
728+
}
729+
}
730+
}
731+
verifyAnnounce()
716732
verifyImportEvent(t, imported, false)
717-
718733
tester.lock.RLock()
719734
dropped := tester.drops["bad"]
720735
tester.lock.RUnlock()
721736

722737
if !dropped {
723738
t.Fatalf("peer with invalid numbered announcement not dropped")
724739
}
725-
726740
goodHeaderFetcher := tester.makeHeaderFetcher("good", blocks, -gatherSlack)
727741
goodBodyFetcher := tester.makeBodyFetcher("good", blocks, 0)
728742
// Make sure a good announcement passes without a drop
729743
tester.fetcher.Notify("good", hashes[0], 1, time.Now().Add(-arriveTimeout), goodHeaderFetcher, goodBodyFetcher)
744+
verifyAnnounce()
730745
verifyImportEvent(t, imported, true)
731746

732747
tester.lock.RLock()

les/pruner.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ func (p *pruner) loop() {
6262

6363
// cleanTicker is the ticker used to trigger a history clean 2 times a day.
6464
var cleanTicker = time.NewTicker(12 * time.Hour)
65+
defer cleanTicker.Stop()
6566

6667
// pruning finds the sections that have been processed by all indexers
6768
// and deletes all historical chain data.

trie/database.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -703,12 +703,6 @@ func (db *Database) Commit(node common.Hash, report bool, callback func(common.H
703703
// Move all of the accumulated preimages into a write batch
704704
if db.preimages != nil {
705705
rawdb.WritePreimages(batch, db.preimages)
706-
if batch.ValueSize() > ethdb.IdealBatchSize {
707-
if err := batch.Write(); err != nil {
708-
return err
709-
}
710-
batch.Reset()
711-
}
712706
// Since we're going to replay trie node writes into the clean cache, flush out
713707
// any batched pre-images before continuing.
714708
if err := batch.Write(); err != nil {

trie/sync_bloom.go

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,12 @@ var (
4545
// provided disk database on creation in a background thread and will only start
4646
// returning live results once that's finished.
4747
type SyncBloom struct {
48-
bloom *bloomfilter.Filter
49-
inited uint32
50-
closer sync.Once
51-
closed uint32
52-
pend sync.WaitGroup
48+
bloom *bloomfilter.Filter
49+
inited uint32
50+
closer sync.Once
51+
closed uint32
52+
pend sync.WaitGroup
53+
closeCh chan struct{}
5354
}
5455

5556
// NewSyncBloom creates a new bloom filter of the given size (in megabytes) and
@@ -64,7 +65,8 @@ func NewSyncBloom(memory uint64, database ethdb.Iteratee) *SyncBloom {
6465

6566
// Assemble the fast sync bloom and init it from previous sessions
6667
b := &SyncBloom{
67-
bloom: bloom,
68+
bloom: bloom,
69+
closeCh: make(chan struct{}),
6870
}
6971
b.pend.Add(2)
7072
go func() {
@@ -125,16 +127,17 @@ func (b *SyncBloom) init(database ethdb.Iteratee) {
125127
// meter periodically recalculates the false positive error rate of the bloom
126128
// filter and reports it in a metric.
127129
func (b *SyncBloom) meter() {
130+
// check every second
131+
tick := time.NewTicker(1 * time.Second)
132+
defer tick.Stop()
133+
128134
for {
129-
// Report the current error ration. No floats, lame, scale it up.
130-
bloomErrorGauge.Update(int64(b.bloom.FalsePosititveProbability() * 100000))
131-
132-
// Wait one second, but check termination more frequently
133-
for i := 0; i < 10; i++ {
134-
if atomic.LoadUint32(&b.closed) == 1 {
135-
return
136-
}
137-
time.Sleep(100 * time.Millisecond)
135+
select {
136+
case <-tick.C:
137+
// Report the current error ration. No floats, lame, scale it up.
138+
bloomErrorGauge.Update(int64(b.bloom.FalsePosititveProbability() * 100000))
139+
case <-b.closeCh:
140+
return
138141
}
139142
}
140143
}
@@ -145,6 +148,7 @@ func (b *SyncBloom) Close() error {
145148
b.closer.Do(func() {
146149
// Ensure the initializer is stopped
147150
atomic.StoreUint32(&b.closed, 1)
151+
close(b.closeCh)
148152
b.pend.Wait()
149153

150154
// Wipe the bloom, but mark it "uninited" just in case someone attempts an access

trie/trie.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,14 @@ func (t *Trie) delete(n node, prefix, key []byte) (bool, node, error) {
405405
n.flags = t.newFlag()
406406
n.Children[key[0]] = nn
407407

408+
// Because n is a full node, it must've contained at least two children
409+
// before the delete operation. If the new child value is non-nil, n still
410+
// has at least two children after the deletion, and cannot be reduced to
411+
// a short node.
412+
if nn != nil {
413+
return true, n, nil
414+
}
415+
// Reduction:
408416
// Check how many non-nil entries are left after deleting and
409417
// reduce the full node to a short node if only one entry is
410418
// left. Since n must've contained at least two children

0 commit comments

Comments
 (0)