diff --git a/consensus/ethash/ethash.go b/consensus/ethash/ethash.go
index ec06d02a548f..4e33d99c8dde 100644
--- a/consensus/ethash/ethash.go
+++ b/consensus/ethash/ethash.go
@@ -136,13 +136,16 @@ func memoryMapAndGenerate(path string, size uint64, lock bool, generator func(bu
if err != nil {
return nil, nil, nil, err
}
- if err = dump.Truncate(int64(len(dumpMagic))*4 + int64(size)); err != nil {
+ if err = ensureSize(dump, int64(len(dumpMagic))*4+int64(size)); err != nil {
+ dump.Close()
+ os.Remove(temp)
return nil, nil, nil, err
}
// Memory map the file for writing and fill it with the generator
mem, buffer, err := memoryMapFile(dump, true)
if err != nil {
dump.Close()
+ os.Remove(temp)
return nil, nil, nil, err
}
copy(buffer, dumpMagic)
@@ -358,7 +361,7 @@ func (d *dataset) generate(dir string, limit int, lock bool, test bool) {
if err != nil {
logger.Error("Failed to generate mapped ethash dataset", "err", err)
- d.dataset = make([]uint32, dsize/2)
+ d.dataset = make([]uint32, dsize/4)
generateDataset(d.dataset, d.epoch, cache)
}
// Iterate over all previous instances and delete old ones
diff --git a/consensus/ethash/mmap_help_linux.go b/consensus/ethash/mmap_help_linux.go
new file mode 100644
index 000000000000..b40a1dd25c05
--- /dev/null
+++ b/consensus/ethash/mmap_help_linux.go
@@ -0,0 +1,35 @@
+// Copyright 2021 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 .
+
+//go:build linux
+// +build linux
+
+package ethash
+
+import (
+ "os"
+
+ "golang.org/x/sys/unix"
+)
+
+// ensureSize expands the file to the given size. This is to prevent runtime
+// errors later on, if the underlying file expands beyond the disk capacity,
+// even though it ostensibly is already expanded, but due to being sparse
+// does not actually occupy the full declared size on disk.
+func ensureSize(f *os.File, size int64) error {
+ // Docs: https://www.man7.org/linux/man-pages/man2/fallocate.2.html
+ return unix.Fallocate(int(f.Fd()), 0, 0, size)
+}
diff --git a/consensus/ethash/mmap_help_other.go b/consensus/ethash/mmap_help_other.go
new file mode 100644
index 000000000000..8ad514ce423e
--- /dev/null
+++ b/consensus/ethash/mmap_help_other.go
@@ -0,0 +1,36 @@
+// Copyright 2021 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 .
+
+//go:build !linux
+// +build !linux
+
+package ethash
+
+import (
+ "os"
+)
+
+// ensureSize expands the file to the given size. This is to prevent runtime
+// errors later on, if the underlying file expands beyond the disk capacity,
+// even though it ostensibly is already expanded, but due to being sparse
+// does not actually occupy the full declared size on disk.
+func ensureSize(f *os.File, size int64) error {
+ // On systems which do not support fallocate, we merely truncate it.
+ // More robust alternatives would be to
+ // - Use posix_fallocate, or
+ // - explicitly fill the file with zeroes.
+ return f.Truncate(size)
+}