func deserializeBlockLoc(serializedLoc []byte) blockLocation {
	return blockLocation{
		blockFileNum: byteOrder.Uint32(serializedLoc[0:4]),
		fileOffset:   byteOrder.Uint32(serializedLoc[4:8]),
		blockLen:     byteOrder.Uint32(serializedLoc[8:12]),
	}
}
deserializeBlockLoc deserializes the passed serialized block location
information.  This is data stored into the block index metadata for each
block.  The serialized data passed to this function MUST be at least
blockLocSize bytes or it will panic.  The error check is avoided here because
this information will always be coming from the block index which includes a
checksum to detect corruption.  Thus it is safe to use this unchecked here.
package ffldb
import (
	"container/list"
	"encoding/binary"
	"fmt"
	"hash/crc32"
	"io"
	"os"
	"path/filepath"
	"sync"
	"github.com/soteria-dag/soterd/chaincfg/chainhash"
	"github.com/soteria-dag/soterd/database"
	"github.com/soteria-dag/soterd/wire"
)
const (
	blockFilenameTemplate = "%09d.fdb"
	maxOpenFiles = 25
	maxBlockFileSize uint32 = 512 * 1024 * 1024  
	blockLocSize = 12
)
var (
	castagnoli = crc32.MakeTable(crc32.Castagnoli)
)
type filer interface {
	io.Closer
	io.WriterAt
	io.ReaderAt
	Truncate(size int64) error
	Sync() error
}
type lockableFile struct {
	sync.RWMutex
	file filer
}
type writeCursor struct {
	sync.RWMutex
	curFile *lockableFile
	curFileNum uint32
	curOffset uint32
}
type blockStore struct {
	network wire.SoterNet
	basePath string
	maxBlockFileSize uint32
	obfMutex         sync.RWMutex
	lruMutex         sync.Mutex
	openBlocksLRU    *list.List  
	fileNumToLRUElem map[uint32]*list.Element
	openBlockFiles   map[uint32]*lockableFile
	writeCursor *writeCursor
	openFileFunc      func(fileNum uint32) (*lockableFile, error)
	openWriteFileFunc func(fileNum uint32) (filer, error)
	deleteFileFunc    func(fileNum uint32) error
}
type blockLocation struct {
	blockFileNum uint32
	fileOffset   uint32
	blockLen     uint32
}