func (*ProductionDependencies) OpenDatabase(m persist.Metadata, s string) (*persist.BoltDatabase, error) {
	return persist.OpenDatabase(m, s)
}
OpenDatabase creates a database that the host can use to interact with large
volumes of persistent data.
package modules
import (
	"errors"
	"io"
	"io/ioutil"
	"net"
	"os"
	"sync"
	"time"
	"github.com/NebulousLabs/Sia/build"
	"github.com/NebulousLabs/Sia/persist"
	"github.com/NebulousLabs/fastrand"
)
var ProdDependencies = new(ProductionDependencies)
type (
	Dependencies interface {
		AtLeastOne() uint64
		CreateFile(string) (File, error)
		Destruct()
		DialTimeout(NetAddress, time.Duration) (net.Conn, error)
		Disrupt(string) bool
		Listen(string, string) (net.Listener, error)
		LoadFile(persist.Metadata, interface{}, string) error
		MkdirAll(string, os.FileMode) error
		NewLogger(string) (*persist.Logger, error)
		OpenDatabase(persist.Metadata, string) (*persist.BoltDatabase, error)
		OpenFile(string, int, os.FileMode) (File, error)
		RandRead([]byte) (int, error)
		ReadFile(string) ([]byte, error)
		RemoveFile(string) error
		RenameFile(string, string) error
		SaveFileSync(persist.Metadata, interface{}, string) error
		Sleep(time.Duration)
		Symlink(s1, s2 string) error
		WriteFile(string, []byte, os.FileMode) error
	}
	File interface {
		io.ReadWriteCloser
		Name() string
		ReadAt([]byte, int64) (int, error)
		Sync() error
		Truncate(int64) error
		WriteAt([]byte, int64) (int, error)
	}
)
type (
	ProductionDependencies struct {
		shouldInit bool
		openFiles  map[string]int
		mu         sync.Mutex
	}
	ProductionFile struct {
		pd *ProductionDependencies
		*os.File
	}
)
func (pf *ProductionFile) Close() error {
	if !build.DEBUG {
		return pf.File.Close()
	}
	pf.pd.mu.Lock()
	if pf.pd.openFiles == nil {
		pf.pd.openFiles = make(map[string]int)
	}
	v, exists := pf.pd.openFiles[pf.File.Name()]
	if !exists {
		panic("file not registered")
	}
	if v == 1 {
		delete(pf.pd.openFiles, pf.File.Name())
	} else if v > 1 {
		pf.pd.openFiles[pf.File.Name()] = v - 1
	} else {
		panic("inconsistent state")
	}
	pf.pd.mu.Unlock()
	return pf.File.Close()
}
func (*ProductionDependencies) AtLeastOne() uint64 {
	if !build.DEBUG {
		return 1
	}
	val := uint64(1)
	for fastrand.Intn(2) != 0 {
		val++
	}
	return val
}
func (pd *ProductionDependencies) CreateFile(s string) (File, error) {
	if !build.DEBUG {
		return os.Create(s)
	}
	f, err := os.Create(s)
	if err != nil {
		return f, err
	}
	pd.mu.Lock()
	if pd.openFiles == nil {
		pd.openFiles = make(map[string]int)
	}
	v := pd.openFiles[s]
	pd.openFiles[s] = v + 1
	pd.mu.Unlock()
	return &ProductionFile{
		pd:   pd,
		File: f,
	}, nil
}
func (pd *ProductionDependencies) Destruct() {
	if !build.DEBUG {
		return
	}
	pd.mu.Lock()
	l := len(pd.openFiles)
	pd.mu.Unlock()
	if l != 0 {
		panic("unclosed resources - most likely file handles")
	}
}
func (*ProductionDependencies) DialTimeout(addr NetAddress, timeout time.Duration) (net.Conn, error) {
	return net.DialTimeout("tcp", string(addr), timeout)
}
func (*ProductionDependencies) Disrupt(string) bool {
	return false
}
func (*ProductionDependencies) Listen(s1, s2 string) (net.Listener, error) {
	return net.Listen(s1, s2)
}
func (*ProductionDependencies) LoadFile(meta persist.Metadata, data interface{}, filename string) error {
	return persist.LoadJSON(meta, data, filename)
}
func (*ProductionDependencies) SaveFileSync(meta persist.Metadata, data interface{}, filename string) error {
	return persist.SaveJSON(meta, data, filename)
}
func (*ProductionDependencies) MkdirAll(s string, fm os.FileMode) error {
	return os.MkdirAll(s, fm)
}
func (*ProductionDependencies) NewLogger(s string) (*persist.Logger, error) {
	return persist.NewFileLogger(s)
}