| 
									
										
										
										
											2018-09-24 15:57:49 +03:00
										 |  |  | // Copyright 2018 The go-ethereum Authors | 
					
						
							|  |  |  | // This file is part of the go-ethereum library. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // The go-ethereum library is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  | // it under the terms of the GNU Lesser General Public License as published by | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | // (at your option) any later version. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // The go-ethereum library is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
					
						
							|  |  |  | // GNU Lesser General Public License for more details. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // You should have received a copy of the GNU Lesser General Public License | 
					
						
							|  |  |  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package rawdb | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
											
												core, cmd, vendor: fixes and database inspection tool (#15)
* core, eth: some fixes for freezer
* vendor, core/rawdb, cmd/geth: add db inspector
* core, cmd/utils: check ancient store path forceily
* cmd/geth, common, core/rawdb: a few fixes
* cmd/geth: support windows file rename and fix rename error
* core: support ancient plugin
* core, cmd: streaming file copy
* cmd, consensus, core, tests: keep genesis in leveldb
* core: write txlookup during ancient init
* core: bump database version
											
										 
											2019-05-14 22:07:44 +08:00
										 |  |  | 	"bytes" | 
					
						
							| 
									
										
										
										
											2019-05-16 14:30:11 +03:00
										 |  |  | 	"errors" | 
					
						
							| 
									
										
										
										
											2019-03-14 14:59:47 +08:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
											
												core, cmd, vendor: fixes and database inspection tool (#15)
* core, eth: some fixes for freezer
* vendor, core/rawdb, cmd/geth: add db inspector
* core, cmd/utils: check ancient store path forceily
* cmd/geth, common, core/rawdb: a few fixes
* cmd/geth: support windows file rename and fix rename error
* core: support ancient plugin
* core, cmd: streaming file copy
* cmd, consensus, core, tests: keep genesis in leveldb
* core: write txlookup during ancient init
* core: bump database version
											
										 
											2019-05-14 22:07:44 +08:00
										 |  |  | 	"os" | 
					
						
							| 
									
										
										
										
											2020-08-20 13:01:24 +03:00
										 |  |  | 	"sync/atomic" | 
					
						
							| 
									
										
										
											
												core, cmd, vendor: fixes and database inspection tool (#15)
* core, eth: some fixes for freezer
* vendor, core/rawdb, cmd/geth: add db inspector
* core, cmd/utils: check ancient store path forceily
* cmd/geth, common, core/rawdb: a few fixes
* cmd/geth: support windows file rename and fix rename error
* core: support ancient plugin
* core, cmd: streaming file copy
* cmd, consensus, core, tests: keep genesis in leveldb
* core: write txlookup during ancient init
* core: bump database version
											
										 
											2019-05-14 22:07:44 +08:00
										 |  |  | 	"time" | 
					
						
							| 
									
										
										
										
											2019-03-14 14:59:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
											
												core, cmd, vendor: fixes and database inspection tool (#15)
* core, eth: some fixes for freezer
* vendor, core/rawdb, cmd/geth: add db inspector
* core, cmd/utils: check ancient store path forceily
* cmd/geth, common, core/rawdb: a few fixes
* cmd/geth: support windows file rename and fix rename error
* core: support ancient plugin
* core, cmd: streaming file copy
* cmd, consensus, core, tests: keep genesis in leveldb
* core: write txlookup during ancient init
* core: bump database version
											
										 
											2019-05-14 22:07:44 +08:00
										 |  |  | 	"github.com/ethereum/go-ethereum/common" | 
					
						
							| 
									
										
										
										
											2018-09-24 15:57:49 +03:00
										 |  |  | 	"github.com/ethereum/go-ethereum/ethdb" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/ethdb/leveldb" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/ethdb/memorydb" | 
					
						
							| 
									
										
										
											
												core, cmd, vendor: fixes and database inspection tool (#15)
* core, eth: some fixes for freezer
* vendor, core/rawdb, cmd/geth: add db inspector
* core, cmd/utils: check ancient store path forceily
* cmd/geth, common, core/rawdb: a few fixes
* cmd/geth: support windows file rename and fix rename error
* core: support ancient plugin
* core, cmd: streaming file copy
* cmd, consensus, core, tests: keep genesis in leveldb
* core: write txlookup during ancient init
* core: bump database version
											
										 
											2019-05-14 22:07:44 +08:00
										 |  |  | 	"github.com/ethereum/go-ethereum/log" | 
					
						
							|  |  |  | 	"github.com/olekukonko/tablewriter" | 
					
						
							| 
									
										
										
										
											2018-09-24 15:57:49 +03:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												all: integrate the freezer with fast sync
* all: freezer style syncing
core, eth, les, light: clean up freezer relative APIs
core, eth, les, trie, ethdb, light: clean a bit
core, eth, les, light: add unit tests
core, light: rewrite setHead function
core, eth: fix downloader unit tests
core: add receipt chain insertion test
core: use constant instead of hardcoding table name
core: fix rollback
core: fix setHead
core/rawdb: remove canonical block first and then iterate side chain
core/rawdb, ethdb: add hasAncient interface
eth/downloader: calculate ancient limit via cht first
core, eth, ethdb: lots of fixes
* eth/downloader: print ancient disable log only for fast sync
											
										 
											2019-04-25 22:59:48 +08:00
										 |  |  | // freezerdb is a database wrapper that enabled freezer data retrievals. | 
					
						
							| 
									
										
										
										
											2019-03-08 15:56:20 +02:00
										 |  |  | type freezerdb struct { | 
					
						
							|  |  |  | 	ethdb.KeyValueStore | 
					
						
							| 
									
										
										
										
											2019-03-14 14:59:47 +08:00
										 |  |  | 	ethdb.AncientStore | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Close implements io.Closer, closing both the fast key-value store as well as | 
					
						
							|  |  |  | // the slow ancient tables. | 
					
						
							|  |  |  | func (frdb *freezerdb) Close() error { | 
					
						
							|  |  |  | 	var errs []error | 
					
						
							| 
									
										
										
										
											2020-05-11 07:11:17 -05:00
										 |  |  | 	if err := frdb.AncientStore.Close(); err != nil { | 
					
						
							| 
									
										
										
										
											2019-03-14 14:59:47 +08:00
										 |  |  | 		errs = append(errs, err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-05-11 07:11:17 -05:00
										 |  |  | 	if err := frdb.KeyValueStore.Close(); err != nil { | 
					
						
							| 
									
										
										
										
											2019-03-14 14:59:47 +08:00
										 |  |  | 		errs = append(errs, err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if len(errs) != 0 { | 
					
						
							|  |  |  | 		return fmt.Errorf("%v", errs) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2019-03-08 15:56:20 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-20 13:01:24 +03:00
										 |  |  | // Freeze is a helper method used for external testing to trigger and block until | 
					
						
							|  |  |  | // a freeze cycle completes, without having to sleep for a minute to trigger the | 
					
						
							|  |  |  | // automatic background run. | 
					
						
							|  |  |  | func (frdb *freezerdb) Freeze(threshold uint64) { | 
					
						
							|  |  |  | 	// Set the freezer threshold to a temporary value | 
					
						
							|  |  |  | 	defer func(old uint64) { | 
					
						
							|  |  |  | 		atomic.StoreUint64(&frdb.AncientStore.(*freezer).threshold, old) | 
					
						
							|  |  |  | 	}(atomic.LoadUint64(&frdb.AncientStore.(*freezer).threshold)) | 
					
						
							|  |  |  | 	atomic.StoreUint64(&frdb.AncientStore.(*freezer).threshold, threshold) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Trigger a freeze cycle and block until it's done | 
					
						
							|  |  |  | 	trigger := make(chan struct{}, 1) | 
					
						
							|  |  |  | 	frdb.AncientStore.(*freezer).trigger <- trigger | 
					
						
							|  |  |  | 	<-trigger | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-08 15:56:20 +02:00
										 |  |  | // nofreezedb is a database wrapper that disables freezer data retrievals. | 
					
						
							|  |  |  | type nofreezedb struct { | 
					
						
							|  |  |  | 	ethdb.KeyValueStore | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												all: integrate the freezer with fast sync
* all: freezer style syncing
core, eth, les, light: clean up freezer relative APIs
core, eth, les, trie, ethdb, light: clean a bit
core, eth, les, light: add unit tests
core, light: rewrite setHead function
core, eth: fix downloader unit tests
core: add receipt chain insertion test
core: use constant instead of hardcoding table name
core: fix rollback
core: fix setHead
core/rawdb: remove canonical block first and then iterate side chain
core/rawdb, ethdb: add hasAncient interface
eth/downloader: calculate ancient limit via cht first
core, eth, ethdb: lots of fixes
* eth/downloader: print ancient disable log only for fast sync
											
										 
											2019-04-25 22:59:48 +08:00
										 |  |  | // HasAncient returns an error as we don't have a backing chain freezer. | 
					
						
							|  |  |  | func (db *nofreezedb) HasAncient(kind string, number uint64) (bool, error) { | 
					
						
							|  |  |  | 	return false, errNotSupported | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Ancient returns an error as we don't have a backing chain freezer. | 
					
						
							| 
									
										
										
										
											2019-03-08 15:56:20 +02:00
										 |  |  | func (db *nofreezedb) Ancient(kind string, number uint64) ([]byte, error) { | 
					
						
							| 
									
										
										
											
												all: integrate the freezer with fast sync
* all: freezer style syncing
core, eth, les, light: clean up freezer relative APIs
core, eth, les, trie, ethdb, light: clean a bit
core, eth, les, light: add unit tests
core, light: rewrite setHead function
core, eth: fix downloader unit tests
core: add receipt chain insertion test
core: use constant instead of hardcoding table name
core: fix rollback
core: fix setHead
core/rawdb: remove canonical block first and then iterate side chain
core/rawdb, ethdb: add hasAncient interface
eth/downloader: calculate ancient limit via cht first
core, eth, ethdb: lots of fixes
* eth/downloader: print ancient disable log only for fast sync
											
										 
											2019-04-25 22:59:48 +08:00
										 |  |  | 	return nil, errNotSupported | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Ancients returns an error as we don't have a backing chain freezer. | 
					
						
							|  |  |  | func (db *nofreezedb) Ancients() (uint64, error) { | 
					
						
							|  |  |  | 	return 0, errNotSupported | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												core, cmd, vendor: fixes and database inspection tool (#15)
* core, eth: some fixes for freezer
* vendor, core/rawdb, cmd/geth: add db inspector
* core, cmd/utils: check ancient store path forceily
* cmd/geth, common, core/rawdb: a few fixes
* cmd/geth: support windows file rename and fix rename error
* core: support ancient plugin
* core, cmd: streaming file copy
* cmd, consensus, core, tests: keep genesis in leveldb
* core: write txlookup during ancient init
* core: bump database version
											
										 
											2019-05-14 22:07:44 +08:00
										 |  |  | // AncientSize returns an error as we don't have a backing chain freezer. | 
					
						
							|  |  |  | func (db *nofreezedb) AncientSize(kind string) (uint64, error) { | 
					
						
							|  |  |  | 	return 0, errNotSupported | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												all: integrate the freezer with fast sync
* all: freezer style syncing
core, eth, les, light: clean up freezer relative APIs
core, eth, les, trie, ethdb, light: clean a bit
core, eth, les, light: add unit tests
core, light: rewrite setHead function
core, eth: fix downloader unit tests
core: add receipt chain insertion test
core: use constant instead of hardcoding table name
core: fix rollback
core: fix setHead
core/rawdb: remove canonical block first and then iterate side chain
core/rawdb, ethdb: add hasAncient interface
eth/downloader: calculate ancient limit via cht first
core, eth, ethdb: lots of fixes
* eth/downloader: print ancient disable log only for fast sync
											
										 
											2019-04-25 22:59:48 +08:00
										 |  |  | // AppendAncient returns an error as we don't have a backing chain freezer. | 
					
						
							|  |  |  | func (db *nofreezedb) AppendAncient(number uint64, hash, header, body, receipts, td []byte) error { | 
					
						
							|  |  |  | 	return errNotSupported | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // TruncateAncients returns an error as we don't have a backing chain freezer. | 
					
						
							|  |  |  | func (db *nofreezedb) TruncateAncients(items uint64) error { | 
					
						
							|  |  |  | 	return errNotSupported | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Sync returns an error as we don't have a backing chain freezer. | 
					
						
							|  |  |  | func (db *nofreezedb) Sync() error { | 
					
						
							|  |  |  | 	return errNotSupported | 
					
						
							| 
									
										
										
										
											2019-03-08 15:56:20 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-24 15:57:49 +03:00
										 |  |  | // NewDatabase creates a high level database on top of a given key-value data | 
					
						
							|  |  |  | // store without a freezer moving immutable chain segments into cold storage. | 
					
						
							|  |  |  | func NewDatabase(db ethdb.KeyValueStore) ethdb.Database { | 
					
						
							| 
									
										
										
										
											2019-03-08 15:56:20 +02:00
										 |  |  | 	return &nofreezedb{ | 
					
						
							|  |  |  | 		KeyValueStore: db, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // NewDatabaseWithFreezer creates a high level database on top of a given key- | 
					
						
							|  |  |  | // value data store with a freezer moving immutable chain segments into cold | 
					
						
							|  |  |  | // storage. | 
					
						
							|  |  |  | func NewDatabaseWithFreezer(db ethdb.KeyValueStore, freezer string, namespace string) (ethdb.Database, error) { | 
					
						
							| 
									
										
										
										
											2019-05-16 14:30:11 +03:00
										 |  |  | 	// Create the idle freezer instance | 
					
						
							| 
									
										
										
										
											2019-03-08 15:56:20 +02:00
										 |  |  | 	frdb, err := newFreezer(freezer, namespace) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-05-16 14:30:11 +03:00
										 |  |  | 	// Since the freezer can be stored separately from the user's key-value database, | 
					
						
							|  |  |  | 	// there's a fairly high probability that the user requests invalid combinations | 
					
						
							|  |  |  | 	// of the freezer and database. Ensure that we don't shoot ourselves in the foot | 
					
						
							|  |  |  | 	// by serving up conflicting data, leading to both datastores getting corrupted. | 
					
						
							|  |  |  | 	// | 
					
						
							|  |  |  | 	//   - If both the freezer and key-value store is empty (no genesis), we just | 
					
						
							|  |  |  | 	//     initialized a new empty freezer, so everything's fine. | 
					
						
							|  |  |  | 	//   - If the key-value store is empty, but the freezer is not, we need to make | 
					
						
							|  |  |  | 	//     sure the user's genesis matches the freezer. That will be checked in the | 
					
						
							|  |  |  | 	//     blockchain, since we don't have the genesis block here (nor should we at | 
					
						
							|  |  |  | 	//     this point care, the key-value/freezer combo is valid). | 
					
						
							|  |  |  | 	//   - If neither the key-value store nor the freezer is empty, cross validate | 
					
						
							|  |  |  | 	//     the genesis hashes to make sure they are compatible. If they are, also | 
					
						
							|  |  |  | 	//     ensure that there's no gap between the freezer and sunsequently leveldb. | 
					
						
							|  |  |  | 	//   - If the key-value store is not empty, but the freezer is we might just be | 
					
						
							|  |  |  | 	//     upgrading to the freezer release, or we might have had a small chain and | 
					
						
							|  |  |  | 	//     not frozen anything yet. Ensure that no blocks are missing yet from the | 
					
						
							|  |  |  | 	//     key-value store, since that would mean we already had an old freezer. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// If the genesis hash is empty, we have a new key-value store, so nothing to | 
					
						
							|  |  |  | 	// validate in this method. If, however, the genesis hash is not nil, compare | 
					
						
							|  |  |  | 	// it to the freezer content. | 
					
						
							|  |  |  | 	if kvgenesis, _ := db.Get(headerHashKey(0)); len(kvgenesis) > 0 { | 
					
						
							|  |  |  | 		if frozen, _ := frdb.Ancients(); frozen > 0 { | 
					
						
							|  |  |  | 			// If the freezer already contains something, ensure that the genesis blocks | 
					
						
							|  |  |  | 			// match, otherwise we might mix up freezers across chains and destroy both | 
					
						
							|  |  |  | 			// the freezer and the key-value store. | 
					
						
							| 
									
										
										
										
											2020-07-14 02:43:30 +08:00
										 |  |  | 			frgenesis, err := frdb.Ancient(freezerHashTable, 0) | 
					
						
							|  |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				return nil, fmt.Errorf("failed to retrieve genesis from ancient %v", err) | 
					
						
							|  |  |  | 			} else if !bytes.Equal(kvgenesis, frgenesis) { | 
					
						
							| 
									
										
										
										
											2019-05-16 14:30:11 +03:00
										 |  |  | 				return nil, fmt.Errorf("genesis mismatch: %#x (leveldb) != %#x (ancients)", kvgenesis, frgenesis) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			// Key-value store and freezer belong to the same network. Ensure that they | 
					
						
							|  |  |  | 			// are contiguous, otherwise we might end up with a non-functional freezer. | 
					
						
							|  |  |  | 			if kvhash, _ := db.Get(headerHashKey(frozen)); len(kvhash) == 0 { | 
					
						
							|  |  |  | 				// Subsequent header after the freezer limit is missing from the database. | 
					
						
							|  |  |  | 				// Reject startup is the database has a more recent head. | 
					
						
							|  |  |  | 				if *ReadHeaderNumber(db, ReadHeadHeaderHash(db)) > frozen-1 { | 
					
						
							|  |  |  | 					return nil, fmt.Errorf("gap (#%d) in the chain between ancients and leveldb", frozen) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				// Database contains only older data than the freezer, this happens if the | 
					
						
							|  |  |  | 				// state was wiped and reinited from an existing freezer. | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-11-27 09:50:30 +01:00
										 |  |  | 			// Otherwise, key-value store continues where the freezer left off, all is fine. | 
					
						
							|  |  |  | 			// We might have duplicate blocks (crash after freezer write but before key-value | 
					
						
							|  |  |  | 			// store deletion, but that's fine). | 
					
						
							| 
									
										
										
										
											2019-05-16 14:30:11 +03:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			// If the freezer is empty, ensure nothing was moved yet from the key-value | 
					
						
							|  |  |  | 			// store, otherwise we'll end up missing data. We check block #1 to decide | 
					
						
							|  |  |  | 			// if we froze anything previously or not, but do take care of databases with | 
					
						
							|  |  |  | 			// only the genesis block. | 
					
						
							|  |  |  | 			if ReadHeadHeaderHash(db) != common.BytesToHash(kvgenesis) { | 
					
						
							|  |  |  | 				// Key-value store contains more data than the genesis block, make sure we | 
					
						
							|  |  |  | 				// didn't freeze anything yet. | 
					
						
							|  |  |  | 				if kvblob, _ := db.Get(headerHashKey(1)); len(kvblob) == 0 { | 
					
						
							|  |  |  | 					return nil, errors.New("ancient chain segments already extracted, please set --datadir.ancient to the correct path") | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				// Block #1 is still in the database, we're allowed to init a new feezer | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-11-27 09:50:30 +01:00
										 |  |  | 			// Otherwise, the head header is still the genesis, we're allowed to init a new | 
					
						
							|  |  |  | 			// feezer. | 
					
						
							| 
									
										
										
										
											2019-05-16 14:30:11 +03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// Freezer is consistent with the key-value database, permit combining the two | 
					
						
							| 
									
										
										
										
											2019-03-08 15:56:20 +02:00
										 |  |  | 	go frdb.freeze(db) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return &freezerdb{ | 
					
						
							|  |  |  | 		KeyValueStore: db, | 
					
						
							| 
									
										
										
										
											2019-03-14 14:59:47 +08:00
										 |  |  | 		AncientStore:  frdb, | 
					
						
							| 
									
										
										
										
											2019-03-08 15:56:20 +02:00
										 |  |  | 	}, nil | 
					
						
							| 
									
										
										
										
											2018-09-24 15:57:49 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // NewMemoryDatabase creates an ephemeral in-memory key-value database without a | 
					
						
							|  |  |  | // freezer moving immutable chain segments into cold storage. | 
					
						
							|  |  |  | func NewMemoryDatabase() ethdb.Database { | 
					
						
							|  |  |  | 	return NewDatabase(memorydb.New()) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-08 15:56:20 +02:00
										 |  |  | // NewMemoryDatabaseWithCap creates an ephemeral in-memory key-value database | 
					
						
							|  |  |  | // with an initial starting capacity, but without a freezer moving immutable | 
					
						
							|  |  |  | // chain segments into cold storage. | 
					
						
							| 
									
										
										
										
											2018-09-24 15:57:49 +03:00
										 |  |  | func NewMemoryDatabaseWithCap(size int) ethdb.Database { | 
					
						
							|  |  |  | 	return NewDatabase(memorydb.NewWithCap(size)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // NewLevelDBDatabase creates a persistent key-value database without a freezer | 
					
						
							|  |  |  | // moving immutable chain segments into cold storage. | 
					
						
							|  |  |  | func NewLevelDBDatabase(file string, cache int, handles int, namespace string) (ethdb.Database, error) { | 
					
						
							|  |  |  | 	db, err := leveldb.New(file, cache, handles, namespace) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return NewDatabase(db), nil | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-03-08 15:56:20 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | // NewLevelDBDatabaseWithFreezer creates a persistent key-value database with a | 
					
						
							|  |  |  | // freezer moving immutable chain segments into cold storage. | 
					
						
							|  |  |  | func NewLevelDBDatabaseWithFreezer(file string, cache int, handles int, freezer string, namespace string) (ethdb.Database, error) { | 
					
						
							|  |  |  | 	kvdb, err := leveldb.New(file, cache, handles, namespace) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	frdb, err := NewDatabaseWithFreezer(kvdb, freezer, namespace) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		kvdb.Close() | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return frdb, nil | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
											
												core, cmd, vendor: fixes and database inspection tool (#15)
* core, eth: some fixes for freezer
* vendor, core/rawdb, cmd/geth: add db inspector
* core, cmd/utils: check ancient store path forceily
* cmd/geth, common, core/rawdb: a few fixes
* cmd/geth: support windows file rename and fix rename error
* core: support ancient plugin
* core, cmd: streaming file copy
* cmd, consensus, core, tests: keep genesis in leveldb
* core: write txlookup during ancient init
* core: bump database version
											
										 
											2019-05-14 22:07:44 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-17 10:23:56 +02:00
										 |  |  | type counter uint64 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (c counter) String() string { | 
					
						
							|  |  |  | 	return fmt.Sprintf("%d", c) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (c counter) Percentage(current uint64) string { | 
					
						
							|  |  |  | 	return fmt.Sprintf("%d", current*100/uint64(c)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // stat stores sizes and count for a parameter | 
					
						
							|  |  |  | type stat struct { | 
					
						
							|  |  |  | 	size  common.StorageSize | 
					
						
							|  |  |  | 	count counter | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Add size to the stat and increase the counter by 1 | 
					
						
							|  |  |  | func (s *stat) Add(size common.StorageSize) { | 
					
						
							|  |  |  | 	s.size += size | 
					
						
							|  |  |  | 	s.count++ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (s *stat) Size() string { | 
					
						
							|  |  |  | 	return s.size.String() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (s *stat) Count() string { | 
					
						
							|  |  |  | 	return s.count.String() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												core, cmd, vendor: fixes and database inspection tool (#15)
* core, eth: some fixes for freezer
* vendor, core/rawdb, cmd/geth: add db inspector
* core, cmd/utils: check ancient store path forceily
* cmd/geth, common, core/rawdb: a few fixes
* cmd/geth: support windows file rename and fix rename error
* core: support ancient plugin
* core, cmd: streaming file copy
* cmd, consensus, core, tests: keep genesis in leveldb
* core: write txlookup during ancient init
* core: bump database version
											
										 
											2019-05-14 22:07:44 +08:00
										 |  |  | // InspectDatabase traverses the entire database and checks the size | 
					
						
							|  |  |  | // of all different categories of data. | 
					
						
							|  |  |  | func InspectDatabase(db ethdb.Database) error { | 
					
						
							| 
									
										
										
										
											2020-04-15 13:08:53 +02:00
										 |  |  | 	it := db.NewIterator(nil, nil) | 
					
						
							| 
									
										
										
											
												core, cmd, vendor: fixes and database inspection tool (#15)
* core, eth: some fixes for freezer
* vendor, core/rawdb, cmd/geth: add db inspector
* core, cmd/utils: check ancient store path forceily
* cmd/geth, common, core/rawdb: a few fixes
* cmd/geth: support windows file rename and fix rename error
* core: support ancient plugin
* core, cmd: streaming file copy
* cmd, consensus, core, tests: keep genesis in leveldb
* core: write txlookup during ancient init
* core: bump database version
											
										 
											2019-05-14 22:07:44 +08:00
										 |  |  | 	defer it.Release() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var ( | 
					
						
							|  |  |  | 		count  int64 | 
					
						
							|  |  |  | 		start  = time.Now() | 
					
						
							|  |  |  | 		logged = time.Now() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Key-value store statistics | 
					
						
							| 
									
										
										
										
											2020-09-17 10:23:56 +02:00
										 |  |  | 		headers         stat | 
					
						
							|  |  |  | 		bodies          stat | 
					
						
							|  |  |  | 		receipts        stat | 
					
						
							|  |  |  | 		tds             stat | 
					
						
							|  |  |  | 		numHashPairings stat | 
					
						
							|  |  |  | 		hashNumPairings stat | 
					
						
							|  |  |  | 		tries           stat | 
					
						
							|  |  |  | 		codes           stat | 
					
						
							|  |  |  | 		txLookups       stat | 
					
						
							|  |  |  | 		accountSnaps    stat | 
					
						
							|  |  |  | 		storageSnaps    stat | 
					
						
							|  |  |  | 		preimages       stat | 
					
						
							|  |  |  | 		bloomBits       stat | 
					
						
							|  |  |  | 		cliqueSnaps     stat | 
					
						
							| 
									
										
										
											
												core, cmd, vendor: fixes and database inspection tool (#15)
* core, eth: some fixes for freezer
* vendor, core/rawdb, cmd/geth: add db inspector
* core, cmd/utils: check ancient store path forceily
* cmd/geth, common, core/rawdb: a few fixes
* cmd/geth: support windows file rename and fix rename error
* core: support ancient plugin
* core, cmd: streaming file copy
* cmd, consensus, core, tests: keep genesis in leveldb
* core: write txlookup during ancient init
* core: bump database version
											
										 
											2019-05-14 22:07:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Ancient store statistics | 
					
						
							| 
									
										
										
										
											2020-09-17 10:23:56 +02:00
										 |  |  | 		ancientHeadersSize  common.StorageSize | 
					
						
							|  |  |  | 		ancientBodiesSize   common.StorageSize | 
					
						
							|  |  |  | 		ancientReceiptsSize common.StorageSize | 
					
						
							|  |  |  | 		ancientTdsSize      common.StorageSize | 
					
						
							|  |  |  | 		ancientHashesSize   common.StorageSize | 
					
						
							| 
									
										
										
											
												core, cmd, vendor: fixes and database inspection tool (#15)
* core, eth: some fixes for freezer
* vendor, core/rawdb, cmd/geth: add db inspector
* core, cmd/utils: check ancient store path forceily
* cmd/geth, common, core/rawdb: a few fixes
* cmd/geth: support windows file rename and fix rename error
* core: support ancient plugin
* core, cmd: streaming file copy
* cmd, consensus, core, tests: keep genesis in leveldb
* core: write txlookup during ancient init
* core: bump database version
											
										 
											2019-05-14 22:07:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Les statistic | 
					
						
							| 
									
										
										
										
											2020-09-17 10:23:56 +02:00
										 |  |  | 		chtTrieNodes   stat | 
					
						
							|  |  |  | 		bloomTrieNodes stat | 
					
						
							| 
									
										
										
										
											2019-05-15 14:33:33 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// Meta- and unaccounted data | 
					
						
							| 
									
										
										
										
											2020-09-17 10:23:56 +02:00
										 |  |  | 		metadata    stat | 
					
						
							|  |  |  | 		unaccounted stat | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// Totals | 
					
						
							|  |  |  | 		total common.StorageSize | 
					
						
							| 
									
										
										
											
												core, cmd, vendor: fixes and database inspection tool (#15)
* core, eth: some fixes for freezer
* vendor, core/rawdb, cmd/geth: add db inspector
* core, cmd/utils: check ancient store path forceily
* cmd/geth, common, core/rawdb: a few fixes
* cmd/geth: support windows file rename and fix rename error
* core: support ancient plugin
* core, cmd: streaming file copy
* cmd, consensus, core, tests: keep genesis in leveldb
* core: write txlookup during ancient init
* core: bump database version
											
										 
											2019-05-14 22:07:44 +08:00
										 |  |  | 	) | 
					
						
							|  |  |  | 	// Inspect key-value database first. | 
					
						
							|  |  |  | 	for it.Next() { | 
					
						
							|  |  |  | 		var ( | 
					
						
							|  |  |  | 			key  = it.Key() | 
					
						
							|  |  |  | 			size = common.StorageSize(len(key) + len(it.Value())) | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 		total += size | 
					
						
							|  |  |  | 		switch { | 
					
						
							|  |  |  | 		case bytes.HasPrefix(key, headerPrefix) && len(key) == (len(headerPrefix)+8+common.HashLength): | 
					
						
							| 
									
										
										
										
											2020-09-17 10:23:56 +02:00
										 |  |  | 			headers.Add(size) | 
					
						
							| 
									
										
										
											
												core, cmd, vendor: fixes and database inspection tool (#15)
* core, eth: some fixes for freezer
* vendor, core/rawdb, cmd/geth: add db inspector
* core, cmd/utils: check ancient store path forceily
* cmd/geth, common, core/rawdb: a few fixes
* cmd/geth: support windows file rename and fix rename error
* core: support ancient plugin
* core, cmd: streaming file copy
* cmd, consensus, core, tests: keep genesis in leveldb
* core: write txlookup during ancient init
* core: bump database version
											
										 
											2019-05-14 22:07:44 +08:00
										 |  |  | 		case bytes.HasPrefix(key, blockBodyPrefix) && len(key) == (len(blockBodyPrefix)+8+common.HashLength): | 
					
						
							| 
									
										
										
										
											2020-09-17 10:23:56 +02:00
										 |  |  | 			bodies.Add(size) | 
					
						
							| 
									
										
										
											
												core, cmd, vendor: fixes and database inspection tool (#15)
* core, eth: some fixes for freezer
* vendor, core/rawdb, cmd/geth: add db inspector
* core, cmd/utils: check ancient store path forceily
* cmd/geth, common, core/rawdb: a few fixes
* cmd/geth: support windows file rename and fix rename error
* core: support ancient plugin
* core, cmd: streaming file copy
* cmd, consensus, core, tests: keep genesis in leveldb
* core: write txlookup during ancient init
* core: bump database version
											
										 
											2019-05-14 22:07:44 +08:00
										 |  |  | 		case bytes.HasPrefix(key, blockReceiptsPrefix) && len(key) == (len(blockReceiptsPrefix)+8+common.HashLength): | 
					
						
							| 
									
										
										
										
											2020-09-17 10:23:56 +02:00
										 |  |  | 			receipts.Add(size) | 
					
						
							|  |  |  | 		case bytes.HasPrefix(key, headerPrefix) && bytes.HasSuffix(key, headerTDSuffix): | 
					
						
							|  |  |  | 			tds.Add(size) | 
					
						
							|  |  |  | 		case bytes.HasPrefix(key, headerPrefix) && bytes.HasSuffix(key, headerHashSuffix): | 
					
						
							|  |  |  | 			numHashPairings.Add(size) | 
					
						
							|  |  |  | 		case bytes.HasPrefix(key, headerNumberPrefix) && len(key) == (len(headerNumberPrefix)+common.HashLength): | 
					
						
							|  |  |  | 			hashNumPairings.Add(size) | 
					
						
							|  |  |  | 		case len(key) == common.HashLength: | 
					
						
							|  |  |  | 			tries.Add(size) | 
					
						
							|  |  |  | 		case bytes.HasPrefix(key, codePrefix) && len(key) == len(codePrefix)+common.HashLength: | 
					
						
							|  |  |  | 			codes.Add(size) | 
					
						
							| 
									
										
										
											
												core, cmd, vendor: fixes and database inspection tool (#15)
* core, eth: some fixes for freezer
* vendor, core/rawdb, cmd/geth: add db inspector
* core, cmd/utils: check ancient store path forceily
* cmd/geth, common, core/rawdb: a few fixes
* cmd/geth: support windows file rename and fix rename error
* core: support ancient plugin
* core, cmd: streaming file copy
* cmd, consensus, core, tests: keep genesis in leveldb
* core: write txlookup during ancient init
* core: bump database version
											
										 
											2019-05-14 22:07:44 +08:00
										 |  |  | 		case bytes.HasPrefix(key, txLookupPrefix) && len(key) == (len(txLookupPrefix)+common.HashLength): | 
					
						
							| 
									
										
										
										
											2020-09-17 10:23:56 +02:00
										 |  |  | 			txLookups.Add(size) | 
					
						
							| 
									
										
										
										
											2019-11-26 09:48:29 +02:00
										 |  |  | 		case bytes.HasPrefix(key, SnapshotAccountPrefix) && len(key) == (len(SnapshotAccountPrefix)+common.HashLength): | 
					
						
							| 
									
										
										
										
											2020-09-17 10:23:56 +02:00
										 |  |  | 			accountSnaps.Add(size) | 
					
						
							| 
									
										
										
										
											2019-11-26 09:48:29 +02:00
										 |  |  | 		case bytes.HasPrefix(key, SnapshotStoragePrefix) && len(key) == (len(SnapshotStoragePrefix)+2*common.HashLength): | 
					
						
							| 
									
										
										
										
											2020-09-17 10:23:56 +02:00
										 |  |  | 			storageSnaps.Add(size) | 
					
						
							| 
									
										
										
											
												core, cmd, vendor: fixes and database inspection tool (#15)
* core, eth: some fixes for freezer
* vendor, core/rawdb, cmd/geth: add db inspector
* core, cmd/utils: check ancient store path forceily
* cmd/geth, common, core/rawdb: a few fixes
* cmd/geth: support windows file rename and fix rename error
* core: support ancient plugin
* core, cmd: streaming file copy
* cmd, consensus, core, tests: keep genesis in leveldb
* core: write txlookup during ancient init
* core: bump database version
											
										 
											2019-05-14 22:07:44 +08:00
										 |  |  | 		case bytes.HasPrefix(key, preimagePrefix) && len(key) == (len(preimagePrefix)+common.HashLength): | 
					
						
							| 
									
										
										
										
											2020-09-17 10:23:56 +02:00
										 |  |  | 			preimages.Add(size) | 
					
						
							| 
									
										
										
											
												core, cmd, vendor: fixes and database inspection tool (#15)
* core, eth: some fixes for freezer
* vendor, core/rawdb, cmd/geth: add db inspector
* core, cmd/utils: check ancient store path forceily
* cmd/geth, common, core/rawdb: a few fixes
* cmd/geth: support windows file rename and fix rename error
* core: support ancient plugin
* core, cmd: streaming file copy
* cmd, consensus, core, tests: keep genesis in leveldb
* core: write txlookup during ancient init
* core: bump database version
											
										 
											2019-05-14 22:07:44 +08:00
										 |  |  | 		case bytes.HasPrefix(key, bloomBitsPrefix) && len(key) == (len(bloomBitsPrefix)+10+common.HashLength): | 
					
						
							| 
									
										
										
										
											2020-09-17 10:23:56 +02:00
										 |  |  | 			bloomBits.Add(size) | 
					
						
							| 
									
										
										
										
											2019-05-15 14:33:33 +03:00
										 |  |  | 		case bytes.HasPrefix(key, []byte("clique-")) && len(key) == 7+common.HashLength: | 
					
						
							| 
									
										
										
										
											2020-09-17 10:23:56 +02:00
										 |  |  | 			cliqueSnaps.Add(size) | 
					
						
							| 
									
										
										
											
												core, cmd, vendor: fixes and database inspection tool (#15)
* core, eth: some fixes for freezer
* vendor, core/rawdb, cmd/geth: add db inspector
* core, cmd/utils: check ancient store path forceily
* cmd/geth, common, core/rawdb: a few fixes
* cmd/geth: support windows file rename and fix rename error
* core: support ancient plugin
* core, cmd: streaming file copy
* cmd, consensus, core, tests: keep genesis in leveldb
* core: write txlookup during ancient init
* core: bump database version
											
										 
											2019-05-14 22:07:44 +08:00
										 |  |  | 		case bytes.HasPrefix(key, []byte("cht-")) && len(key) == 4+common.HashLength: | 
					
						
							| 
									
										
										
										
											2020-09-17 10:23:56 +02:00
										 |  |  | 			chtTrieNodes.Add(size) | 
					
						
							| 
									
										
										
											
												core, cmd, vendor: fixes and database inspection tool (#15)
* core, eth: some fixes for freezer
* vendor, core/rawdb, cmd/geth: add db inspector
* core, cmd/utils: check ancient store path forceily
* cmd/geth, common, core/rawdb: a few fixes
* cmd/geth: support windows file rename and fix rename error
* core: support ancient plugin
* core, cmd: streaming file copy
* cmd, consensus, core, tests: keep genesis in leveldb
* core: write txlookup during ancient init
* core: bump database version
											
										 
											2019-05-14 22:07:44 +08:00
										 |  |  | 		case bytes.HasPrefix(key, []byte("blt-")) && len(key) == 4+common.HashLength: | 
					
						
							| 
									
										
										
										
											2020-09-17 10:23:56 +02:00
										 |  |  | 			bloomTrieNodes.Add(size) | 
					
						
							| 
									
										
										
										
											2019-05-15 14:33:33 +03:00
										 |  |  | 		default: | 
					
						
							|  |  |  | 			var accounted bool | 
					
						
							| 
									
										
										
										
											2019-05-16 14:30:11 +03:00
										 |  |  | 			for _, meta := range [][]byte{databaseVerisionKey, headHeaderKey, headBlockKey, headFastBlockKey, fastTrieProgressKey} { | 
					
						
							| 
									
										
										
										
											2019-05-15 14:33:33 +03:00
										 |  |  | 				if bytes.Equal(key, meta) { | 
					
						
							| 
									
										
										
										
											2020-09-17 10:23:56 +02:00
										 |  |  | 					metadata.Add(size) | 
					
						
							| 
									
										
										
										
											2019-05-15 14:33:33 +03:00
										 |  |  | 					accounted = true | 
					
						
							|  |  |  | 					break | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if !accounted { | 
					
						
							| 
									
										
										
										
											2020-09-17 10:23:56 +02:00
										 |  |  | 				unaccounted.Add(size) | 
					
						
							| 
									
										
										
										
											2019-05-15 14:33:33 +03:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
											
												core, cmd, vendor: fixes and database inspection tool (#15)
* core, eth: some fixes for freezer
* vendor, core/rawdb, cmd/geth: add db inspector
* core, cmd/utils: check ancient store path forceily
* cmd/geth, common, core/rawdb: a few fixes
* cmd/geth: support windows file rename and fix rename error
* core: support ancient plugin
* core, cmd: streaming file copy
* cmd, consensus, core, tests: keep genesis in leveldb
* core: write txlookup during ancient init
* core: bump database version
											
										 
											2019-05-14 22:07:44 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-09-17 10:23:56 +02:00
										 |  |  | 		count++ | 
					
						
							| 
									
										
										
											
												core, cmd, vendor: fixes and database inspection tool (#15)
* core, eth: some fixes for freezer
* vendor, core/rawdb, cmd/geth: add db inspector
* core, cmd/utils: check ancient store path forceily
* cmd/geth, common, core/rawdb: a few fixes
* cmd/geth: support windows file rename and fix rename error
* core: support ancient plugin
* core, cmd: streaming file copy
* cmd, consensus, core, tests: keep genesis in leveldb
* core: write txlookup during ancient init
* core: bump database version
											
										 
											2019-05-14 22:07:44 +08:00
										 |  |  | 		if count%1000 == 0 && time.Since(logged) > 8*time.Second { | 
					
						
							|  |  |  | 			log.Info("Inspecting database", "count", count, "elapsed", common.PrettyDuration(time.Since(start))) | 
					
						
							|  |  |  | 			logged = time.Now() | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// Inspect append-only file store then. | 
					
						
							| 
									
										
										
										
											2020-09-17 10:23:56 +02:00
										 |  |  | 	ancientSizes := []*common.StorageSize{&ancientHeadersSize, &ancientBodiesSize, &ancientReceiptsSize, &ancientHashesSize, &ancientTdsSize} | 
					
						
							| 
									
										
										
											
												core, cmd, vendor: fixes and database inspection tool (#15)
* core, eth: some fixes for freezer
* vendor, core/rawdb, cmd/geth: add db inspector
* core, cmd/utils: check ancient store path forceily
* cmd/geth, common, core/rawdb: a few fixes
* cmd/geth: support windows file rename and fix rename error
* core: support ancient plugin
* core, cmd: streaming file copy
* cmd, consensus, core, tests: keep genesis in leveldb
* core: write txlookup during ancient init
* core: bump database version
											
										 
											2019-05-14 22:07:44 +08:00
										 |  |  | 	for i, category := range []string{freezerHeaderTable, freezerBodiesTable, freezerReceiptTable, freezerHashTable, freezerDifficultyTable} { | 
					
						
							|  |  |  | 		if size, err := db.AncientSize(category); err == nil { | 
					
						
							| 
									
										
										
										
											2020-09-17 10:23:56 +02:00
										 |  |  | 			*ancientSizes[i] += common.StorageSize(size) | 
					
						
							| 
									
										
										
											
												core, cmd, vendor: fixes and database inspection tool (#15)
* core, eth: some fixes for freezer
* vendor, core/rawdb, cmd/geth: add db inspector
* core, cmd/utils: check ancient store path forceily
* cmd/geth, common, core/rawdb: a few fixes
* cmd/geth: support windows file rename and fix rename error
* core: support ancient plugin
* core, cmd: streaming file copy
* cmd, consensus, core, tests: keep genesis in leveldb
* core: write txlookup during ancient init
* core: bump database version
											
										 
											2019-05-14 22:07:44 +08:00
										 |  |  | 			total += common.StorageSize(size) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-09-17 10:23:56 +02:00
										 |  |  | 	// Get number of ancient rows inside the freezer | 
					
						
							|  |  |  | 	ancients := counter(0) | 
					
						
							|  |  |  | 	if count, err := db.Ancients(); err == nil { | 
					
						
							|  |  |  | 		ancients = counter(count) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
											
												core, cmd, vendor: fixes and database inspection tool (#15)
* core, eth: some fixes for freezer
* vendor, core/rawdb, cmd/geth: add db inspector
* core, cmd/utils: check ancient store path forceily
* cmd/geth, common, core/rawdb: a few fixes
* cmd/geth: support windows file rename and fix rename error
* core: support ancient plugin
* core, cmd: streaming file copy
* cmd, consensus, core, tests: keep genesis in leveldb
* core: write txlookup during ancient init
* core: bump database version
											
										 
											2019-05-14 22:07:44 +08:00
										 |  |  | 	// Display the database statistic. | 
					
						
							|  |  |  | 	stats := [][]string{ | 
					
						
							| 
									
										
										
										
											2020-09-17 10:23:56 +02:00
										 |  |  | 		{"Key-Value store", "Headers", headers.Size(), headers.Count()}, | 
					
						
							|  |  |  | 		{"Key-Value store", "Bodies", bodies.Size(), bodies.Count()}, | 
					
						
							|  |  |  | 		{"Key-Value store", "Receipt lists", receipts.Size(), receipts.Count()}, | 
					
						
							|  |  |  | 		{"Key-Value store", "Difficulties", tds.Size(), tds.Count()}, | 
					
						
							|  |  |  | 		{"Key-Value store", "Block number->hash", numHashPairings.Size(), numHashPairings.Count()}, | 
					
						
							|  |  |  | 		{"Key-Value store", "Block hash->number", hashNumPairings.Size(), hashNumPairings.Count()}, | 
					
						
							|  |  |  | 		{"Key-Value store", "Transaction index", txLookups.Size(), txLookups.Count()}, | 
					
						
							|  |  |  | 		{"Key-Value store", "Bloombit index", bloomBits.Size(), bloomBits.Count()}, | 
					
						
							|  |  |  | 		{"Key-Value store", "Contract codes", codes.Size(), codes.Count()}, | 
					
						
							|  |  |  | 		{"Key-Value store", "Trie nodes", tries.Size(), tries.Count()}, | 
					
						
							|  |  |  | 		{"Key-Value store", "Trie preimages", preimages.Size(), preimages.Count()}, | 
					
						
							|  |  |  | 		{"Key-Value store", "Account snapshot", accountSnaps.Size(), accountSnaps.Count()}, | 
					
						
							|  |  |  | 		{"Key-Value store", "Storage snapshot", storageSnaps.Size(), storageSnaps.Count()}, | 
					
						
							|  |  |  | 		{"Key-Value store", "Clique snapshots", cliqueSnaps.Size(), cliqueSnaps.Count()}, | 
					
						
							|  |  |  | 		{"Key-Value store", "Singleton metadata", metadata.Size(), metadata.Count()}, | 
					
						
							|  |  |  | 		{"Ancient store", "Headers", ancientHeadersSize.String(), ancients.String()}, | 
					
						
							|  |  |  | 		{"Ancient store", "Bodies", ancientBodiesSize.String(), ancients.String()}, | 
					
						
							|  |  |  | 		{"Ancient store", "Receipt lists", ancientReceiptsSize.String(), ancients.String()}, | 
					
						
							|  |  |  | 		{"Ancient store", "Difficulties", ancientTdsSize.String(), ancients.String()}, | 
					
						
							|  |  |  | 		{"Ancient store", "Block number->hash", ancientHashesSize.String(), ancients.String()}, | 
					
						
							|  |  |  | 		{"Light client", "CHT trie nodes", chtTrieNodes.Size(), chtTrieNodes.Count()}, | 
					
						
							|  |  |  | 		{"Light client", "Bloom trie nodes", bloomTrieNodes.Size(), bloomTrieNodes.Count()}, | 
					
						
							| 
									
										
										
											
												core, cmd, vendor: fixes and database inspection tool (#15)
* core, eth: some fixes for freezer
* vendor, core/rawdb, cmd/geth: add db inspector
* core, cmd/utils: check ancient store path forceily
* cmd/geth, common, core/rawdb: a few fixes
* cmd/geth: support windows file rename and fix rename error
* core: support ancient plugin
* core, cmd: streaming file copy
* cmd, consensus, core, tests: keep genesis in leveldb
* core: write txlookup during ancient init
* core: bump database version
											
										 
											2019-05-14 22:07:44 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	table := tablewriter.NewWriter(os.Stdout) | 
					
						
							| 
									
										
										
										
											2020-09-17 10:23:56 +02:00
										 |  |  | 	table.SetHeader([]string{"Database", "Category", "Size", "Items"}) | 
					
						
							|  |  |  | 	table.SetFooter([]string{"", "Total", total.String(), " "}) | 
					
						
							| 
									
										
										
											
												core, cmd, vendor: fixes and database inspection tool (#15)
* core, eth: some fixes for freezer
* vendor, core/rawdb, cmd/geth: add db inspector
* core, cmd/utils: check ancient store path forceily
* cmd/geth, common, core/rawdb: a few fixes
* cmd/geth: support windows file rename and fix rename error
* core: support ancient plugin
* core, cmd: streaming file copy
* cmd, consensus, core, tests: keep genesis in leveldb
* core: write txlookup during ancient init
* core: bump database version
											
										 
											2019-05-14 22:07:44 +08:00
										 |  |  | 	table.AppendBulk(stats) | 
					
						
							|  |  |  | 	table.Render() | 
					
						
							| 
									
										
										
										
											2019-05-15 14:33:33 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-17 10:23:56 +02:00
										 |  |  | 	if unaccounted.size > 0 { | 
					
						
							|  |  |  | 		log.Error("Database contains unaccounted data", "size", unaccounted.size, "count", unaccounted.count) | 
					
						
							| 
									
										
										
										
											2019-05-15 14:33:33 +03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-09-17 10:23:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
											
												core, cmd, vendor: fixes and database inspection tool (#15)
* core, eth: some fixes for freezer
* vendor, core/rawdb, cmd/geth: add db inspector
* core, cmd/utils: check ancient store path forceily
* cmd/geth, common, core/rawdb: a few fixes
* cmd/geth: support windows file rename and fix rename error
* core: support ancient plugin
* core, cmd: streaming file copy
* cmd, consensus, core, tests: keep genesis in leveldb
* core: write txlookup during ancient init
* core: bump database version
											
										 
											2019-05-14 22:07:44 +08:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } |