From 7812fb28ea2c433091428d4299321a79d80b6563 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Wed, 11 Sep 2019 20:28:49 +0300 Subject: [PATCH 1/3] core: optimize blockchain init with existing DB There is no need to generate genesis block (it's already in the DB) and we can add all hashes at once without iterating over them. --- pkg/core/blockchain.go | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index dcd0167dd..dd8416c35 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -84,12 +84,6 @@ func NewBlockchain(ctx context.Context, s storage.Store, cfg config.ProtocolConf } func (bc *Blockchain) init() error { - genesisBlock, err := createGenesisBlock(bc.config) - if err != nil { - return err - } - bc.headerList = NewHeaderHashList(genesisBlock.Hash()) - // If we could not find the version in the Store, we know that there is nothing stored. ver, err := storage.Version(bc.Store) if err != nil { @@ -97,6 +91,11 @@ func (bc *Blockchain) init() error { if err = storage.PutVersion(bc.Store, version); err != nil { return err } + genesisBlock, err := createGenesisBlock(bc.config) + if err != nil { + return err + } + bc.headerList = NewHeaderHashList(genesisBlock.Hash()) return bc.persistBlock(genesisBlock) } if ver != version { @@ -119,12 +118,8 @@ func (bc *Blockchain) init() error { return err } - for _, hash := range hashes { - if !genesisBlock.Hash().Equals(hash) { - bc.headerList.Add(hash) - bc.storedHeaderCount++ - } - } + bc.headerList = NewHeaderHashList(hashes...) + bc.storedHeaderCount = uint32(len(hashes)) currHeaderHeight, currHeaderHash, err := storage.CurrentHeaderHeight(bc.Store) if err != nil { From 4f60fd3e8e7d27f819e3e205df8e9a0b61d9e810 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Wed, 11 Sep 2019 20:32:30 +0300 Subject: [PATCH 2/3] core: optimize persist() for the case when no next block found If there is no next block in the cache, looping through the whole cache won't help. --- pkg/core/blockchain.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index dd8416c35..f37e8441e 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -409,6 +409,9 @@ func (bc *Blockchain) persist(ctx context.Context) (err error) { } bc.blockCache.Delete(hash) persisted++ + } else { + // no next block in the cache, no reason to continue looping + break } } } From 4395cea3440893b34ab15a1e1beda59a899cb375 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Wed, 11 Sep 2019 20:33:41 +0300 Subject: [PATCH 3/3] storage: fix reading overlapping hash blocks from the DB In the unlikely event of overlapping hash block written to the DB we might end up with wrong hash list. That happened to me for some reason when synching with the testnet leading to the following keys with respective values: 150000 -> 2000 hashes 152000 -> 2000 hashes 153999 -> 2000 hashes Reading it hashes number 153999 and 154000 got the same values and the chain couldn't sync correctly. --- pkg/core/storage/helpers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/core/storage/helpers.go b/pkg/core/storage/helpers.go index 2776da38c..4a35d9ad7 100644 --- a/pkg/core/storage/helpers.go +++ b/pkg/core/storage/helpers.go @@ -74,7 +74,7 @@ func HeaderHashes(s Store) ([]util.Uint256, error) { sort.Sort(uint32Slice(sortedKeys)) for _, key := range sortedKeys { - hashes = append(hashes, hashMap[key]...) + hashes = append(hashes[:key], hashMap[key]...) } return hashes, nil