Skip to content

dataset.generate

Source (upstream pre-purge) Current
File consensus/ethash/ethash.go ethash.go
Symbol dataset.generate dataset.generate
Ref dde2da0ef~1 etc/v1.17.3-full-node

Identical to core-geth v1.12.20. Differences vs upstream are ECIP-1099 adaptations (variable epochLength, new file naming scheme with epoch, legacy file cleanup).

3-way merge — purge → getc ← upstream

pre-purgecore-geth
// generate ensures that the dataset content is generated before use.
func (d *dataset) generate(dir string, limit int, lock bool, test bool) {
d.once.Do(func() {
// Mark the dataset generated after we're done. This is needed for remote
defer d.done.Store(true)
csize := cacheSize(d.epoch)
dsize := datasetSize(d.epoch)
seed := seedHash(d.epoch, d.epochLength)
if test {
csize = 1024
dsize = 32 * 1024
}
// If we don't store anything on disk, generate and return
if dir == "" {
cache := make([]uint32, csize/4)
generateCache(cache, d.epoch, d.epochLength, seed)
d.dataset = make([]uint32, dsize/4)
generateDataset(d.dataset, d.epoch, d.epochLength, cache)
return
}
// Disk storage is needed, this will get fancy
var endian string
if !isLittleEndian() {
endian = ".be"
}
path := filepath.Join(dir, fmt.Sprintf("full-R%d-%d-%x%s", algorithmRevision, d.epoch, seed[:8], endian))
logger := log.New("epoch", d.epoch)
// We're about to mmap the file, ensure that the mapping is cleaned up when the
// cache becomes unused.
runtime.SetFinalizer(d, (*dataset).finalizer)
// Try to load the file from disk and memory map it
var err error
d.dump, d.mmap, d.dataset, err = memoryMap(path, lock)
if err == nil {
logger.Debug("Loaded old ethash dataset from disk", "path", path)
return
}
logger.Debug("Failed to load old ethash dataset", "err", err)
// No usable previous dataset available, create a new dataset file to fill
cache := make([]uint32, csize/4)
generateCache(cache, d.epoch, d.epochLength, seed)
d.dump, d.mmap, d.dataset, err = memoryMapAndGenerate(path, dsize, lock, func(buffer []uint32) { generateDataset(buffer, d.epoch, d.epochLength, cache) })
if err != nil {
logger.Error("Failed to generate mapped ethash dataset", "err", err)
d.dataset = make([]uint32, dsize/4)
generateDataset(d.dataset, d.epoch, d.epochLength, cache)
}
// Iterate over all full file instances, deleting any out of bounds (where epoch is below lower limit, or above upper limit).
matches, _ := filepath.Glob(filepath.Join(dir, fmt.Sprintf("full-R%d*", algorithmRevision)))
for _, file := range matches {
var ar int // algorithm revision
var e uint64 // epoch
var s string // seed
if _, err := fmt.Sscanf(filepath.Base(file), "full-R%d-%d-%s"+endian, &ar, &e, &s); err != nil {
// There is an unrecognized file in this directory.
// See if the name matches the expected pattern of the legacy naming scheme.
if _, err := fmt.Sscanf(filepath.Base(file), "full-R%d-%s"+endian, &ar, &s); err == nil {
// This file matches the previous generation naming pattern (sans epoch).
if err := os.Remove(file); err != nil {
logger.Error("Failed to remove legacy ethash full file", "file", file, "err", err)
} else {
logger.Warn("Deleted legacy ethash full file", "path", file)
}
}
// Else the file is unrecognized (unknown name format), leave it alone.
continue
}
if e <= d.epoch-uint64(limit) || e > d.epoch+1 {
if err := os.Remove(file); err == nil {
logger.Debug("Deleted ethash full file", "target.epoch", e, "file", file)
} else {
logger.Error("Failed to delete ethash full file", "target.epoch", e, "file", file, "err", err)
}
}
}
})
}
core-geth validation — **Identical** ✅ | | | |---|---| | File | [`ethash.go`](https://github.com/etclabscore/core-geth/blob/v1.12.20/consensus/ethash/ethash.go) | | Symbol | `dataset.generate` | | Ref | `v1.12.20` |

← Consensus & Ethash