73 lines
1.5 KiB
Go
73 lines
1.5 KiB
Go
package genesis
|
|
|
|
import (
|
|
"archive/tar"
|
|
"crypto/sha256"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
|
|
bin "github.com/gagliardetto/binary"
|
|
"go.firedancer.io/radiance/pkg/archiveutil"
|
|
)
|
|
|
|
// ReadGenesisFromFile is a convenience wrapper for ReadGenesisFromArchive.
|
|
func ReadGenesisFromFile(fpath string) (genesis *Genesis, hash *[32]byte, err error) {
|
|
f, err := os.Open(fpath)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
defer f.Close()
|
|
return ReadGenesisFromArchive(f)
|
|
}
|
|
|
|
// ReadGenesisFromArchive reads a `genesis.tar.bz2` file.
|
|
func ReadGenesisFromArchive(archive io.Reader) (genesis *Genesis, hash *[32]byte, err error) {
|
|
var files *tar.Reader
|
|
var hdr *tar.Header
|
|
files, err = archiveutil.OpenTar(archive)
|
|
if err != nil {
|
|
return
|
|
}
|
|
hdr, err = files.Next()
|
|
if err != nil {
|
|
return
|
|
}
|
|
if hdr.Name != "genesis.bin" {
|
|
err = fmt.Errorf("first file is not genesis.bin")
|
|
return
|
|
}
|
|
|
|
// Read and hash first file
|
|
const maxSize = 10_000_001
|
|
var rd io.Reader
|
|
rd = files
|
|
hasher := sha256.New()
|
|
rd = io.TeeReader(rd, hasher)
|
|
rd = io.LimitReader(rd, maxSize)
|
|
|
|
// Decode content
|
|
var genesisBytes []byte
|
|
genesisBytes, err = io.ReadAll(rd)
|
|
if err != nil {
|
|
return
|
|
}
|
|
if len(genesisBytes) >= maxSize {
|
|
err = fmt.Errorf("genesis.bin too large")
|
|
return
|
|
}
|
|
genesis = new(Genesis)
|
|
dec := bin.NewBinDecoder(genesisBytes)
|
|
err = dec.Decode(genesis)
|
|
if err == nil {
|
|
if dec.HasRemaining() {
|
|
err = fmt.Errorf("not all of genesis.bin was read (%d bytes remaining)", dec.Remaining())
|
|
} else {
|
|
hash = new([32]byte)
|
|
hasher.Sum(hash[:0])
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|