diff --git a/docs/merry-go-round-sync.md b/docs/merry-go-round-sync.md new file mode 100644 index 000000000..f83f0d9d8 --- /dev/null +++ b/docs/merry-go-round-sync.md @@ -0,0 +1,25 @@ +# Merry-Go-Round sync (turbo-geth design) + +Initial discussion here: https://ethresear.ch/t/merry-go-round-sync/7158 + +## Participants + +We divide participants into two types: seeders and leechers. Seeders are the ones who have the full copy of the current Ethereum +state, and they also keep updating it as new blocks appear. Leechers are the ones that join the Merry-Go-Round network to +either acquire the full copy of the state, or "sift" through it to acquire some part of the state (this is what some "Stateless" +node might like to do in the beginning). + +## Syncing cycles + +The process of syncing happens in cycles. During each cycle, all participants attempt to distribute the entire content of the +Ethereum state to each other. Therefore the duration of one cycle for the Ethereum mainnet is likely to be some hours. +Cycle is divided into ticks. For convinience, we can say that each ticks starts after the mining of certain block, and lasts +for some predetermined amount of time, let's say, 30 seconds. This definition means that the ticks will often overlap, but not +always, as shown onn the picture below. + +![cycles-and-ticks](mgr-sync-1.png) + + + +## How will seeders produce sync schedule + diff --git a/docs/mgr-sync-1.png b/docs/mgr-sync-1.png new file mode 100644 index 000000000..f3e5f86c1 Binary files /dev/null and b/docs/mgr-sync-1.png differ diff --git a/trie/resolver_stateful_cached.go b/trie/resolver_stateful_cached.go index b7b8a342c..b51d4b7ea 100644 --- a/trie/resolver_stateful_cached.go +++ b/trie/resolver_stateful_cached.go @@ -333,11 +333,18 @@ func (tr *ResolverStatefulCached) MultiWalk2(db *bolt.DB, blockNr uint64, bucket startkey := startkeys[rangeIdx] err := db.View(func(tx *bolt.Tx) error { - cache := tx.Bucket(dbutils.IntermediateTrieHashBucket).Cursor() + cacheBucket := tx.Bucket(dbutils.IntermediateTrieHashBucket) + var cache *bolt.Cursor + if cacheBucket != nil { + cache = cacheBucket.Cursor() + } c := tx.Bucket(bucket).Cursor() k, v := c.Seek(startkey) - cacheK, cacheV := cache.Seek(startkey) + var cacheK, cacheV []byte + if cache != nil { + cacheK, cacheV = cache.Seek(startkey) + } var minKey []byte var fromCache bool