eth/downloader: save and load trie sync progress

This commit is contained in:
Péter Szilágyi 2018-03-01 17:08:33 +02:00
parent 5a150e1b77
commit 3327cab50b
No known key found for this signature in database
GPG key ID: E9AE538CEDF8293D
3 changed files with 29 additions and 1 deletions

View file

@ -47,6 +47,7 @@ var (
headHeaderKey = []byte("LastHeader") headHeaderKey = []byte("LastHeader")
headBlockKey = []byte("LastBlock") headBlockKey = []byte("LastBlock")
headFastKey = []byte("LastFast") headFastKey = []byte("LastFast")
trieSyncKey = []byte("TrieSync")
// Data item prefixes (use single byte to avoid mixing data types, avoid `i`). // Data item prefixes (use single byte to avoid mixing data types, avoid `i`).
headerPrefix = []byte("h") // headerPrefix + num (uint64 big endian) + hash -> header headerPrefix = []byte("h") // headerPrefix + num (uint64 big endian) + hash -> header
@ -146,6 +147,16 @@ func GetHeadFastBlockHash(db DatabaseReader) common.Hash {
return common.BytesToHash(data) return common.BytesToHash(data)
} }
// GetTrieSyncProgress retrieves the number of tries nodes fast synced to allow
// reportinc correct numbers across restarts.
func GetTrieSyncProgress(db DatabaseReader) uint64 {
data, _ := db.Get(trieSyncKey)
if len(data) == 0 {
return 0
}
return new(big.Int).SetBytes(data).Uint64()
}
// GetHeaderRLP retrieves a block header in its raw RLP database encoding, or nil // GetHeaderRLP retrieves a block header in its raw RLP database encoding, or nil
// if the header's not found. // if the header's not found.
func GetHeaderRLP(db DatabaseReader, hash common.Hash, number uint64) rlp.RawValue { func GetHeaderRLP(db DatabaseReader, hash common.Hash, number uint64) rlp.RawValue {
@ -374,6 +385,15 @@ func WriteHeadFastBlockHash(db ethdb.Putter, hash common.Hash) error {
return nil return nil
} }
// WriteTrieSyncProgress stores the fast sync trie process counter to support
// retrieving it across restarts.
func WriteTrieSyncProgress(db ethdb.Putter, count uint64) error {
if err := db.Put(trieSyncKey, new(big.Int).SetUint64(count).Bytes()); err != nil {
log.Crit("Failed to store fast sync trie progress", "err", err)
}
return nil
}
// WriteHeader serializes a block header into the database. // WriteHeader serializes a block header into the database.
func WriteHeader(db ethdb.Putter, header *types.Header) error { func WriteHeader(db ethdb.Putter, header *types.Header) error {
data, err := rlp.EncodeToBytes(header) data, err := rlp.EncodeToBytes(header)

View file

@ -27,6 +27,7 @@ import (
ethereum "github.com/ethereum/go-ethereum" ethereum "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
@ -221,7 +222,10 @@ func New(mode SyncMode, stateDb ethdb.Database, mux *event.TypeMux, chain BlockC
quitCh: make(chan struct{}), quitCh: make(chan struct{}),
stateCh: make(chan dataPack), stateCh: make(chan dataPack),
stateSyncStart: make(chan *stateSync), stateSyncStart: make(chan *stateSync),
trackStateReq: make(chan *stateReq), syncStatsState: stateSyncStats{
processed: core.GetTrieSyncProgress(stateDb),
},
trackStateReq: make(chan *stateReq),
} }
go dl.qosTuner() go dl.qosTuner()
go dl.stateFetcher() go dl.stateFetcher()

View file

@ -23,6 +23,7 @@ import (
"time" "time"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/crypto/sha3" "github.com/ethereum/go-ethereum/crypto/sha3"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
@ -466,4 +467,7 @@ func (s *stateSync) updateStats(written, duplicate, unexpected int, duration tim
if written > 0 || duplicate > 0 || unexpected > 0 { if written > 0 || duplicate > 0 || unexpected > 0 {
log.Info("Imported new state entries", "count", written, "elapsed", common.PrettyDuration(duration), "processed", s.d.syncStatsState.processed, "pending", s.d.syncStatsState.pending, "retry", len(s.tasks), "duplicate", s.d.syncStatsState.duplicate, "unexpected", s.d.syncStatsState.unexpected) log.Info("Imported new state entries", "count", written, "elapsed", common.PrettyDuration(duration), "processed", s.d.syncStatsState.processed, "pending", s.d.syncStatsState.pending, "retry", len(s.tasks), "duplicate", s.d.syncStatsState.duplicate, "unexpected", s.d.syncStatsState.unexpected)
} }
if written > 0 {
core.WriteTrieSyncProgress(s.d.stateDB, s.d.syncStatsState.processed)
}
} }