func getUsedAddrHash(ns walletdb.ReadBucket, poolID []byte, seriesID uint32, branch Branch,
	index Index) []byte {
	usedAddrs := ns.NestedReadBucket(poolID).NestedReadBucket(usedAddrsBucketName)
	bucket := usedAddrs.NestedReadBucket(getUsedAddrBucketID(seriesID, branch))
	if bucket == nil {
		return nil
	}
	return bucket.Get(uint32ToBytes(uint32(index)))
}
getUsedAddrHash returns the addr hash with the given index from the used
addresses bucket of the given pool, series and branch.
package votingpool
import (
	"bytes"
	"encoding/binary"
	"encoding/gob"
	"fmt"
	"github.com/gcash/bchd/txscript"
	"github.com/gcash/bchd/wire"
	"github.com/gcash/bchutil"
	"github.com/gcash/bchwallet/snacl"
	"github.com/gcash/bchwallet/walletdb"
)
const (
	seriesKeyLength = snacl.Overhead + 111 + snacl.NonceSize
	seriesMinSerial = 4 + 1 + 4 + 4
	seriesMaxSerial = seriesMinSerial + 15*seriesKeyLength*2
	seriesMaxVersion = 1
)
var (
	usedAddrsBucketName   = []byte("usedaddrs")
	seriesBucketName      = []byte("series")
	withdrawalsBucketName = []byte("withdrawals")
	seriesNullPrivKey = [seriesKeyLength]byte{}
)
type dbSeriesRow struct {
	version           uint32
	active            bool
	reqSigs           uint32
	pubKeysEncrypted  [][]byte
	privKeysEncrypted [][]byte
}
type dbWithdrawalRow struct {
	Requests      []dbOutputRequest
	StartAddress  dbWithdrawalAddress
	ChangeStart   dbChangeAddress
	LastSeriesID  uint32
	DustThreshold bchutil.Amount
	Status        dbWithdrawalStatus
}
type dbWithdrawalAddress struct {
	SeriesID uint32
	Branch   Branch
	Index    Index
}
type dbChangeAddress struct {
	SeriesID uint32
	Index    Index
}
type dbOutputRequest struct {
	Addr        string
	Amount      bchutil.Amount
	Server      string
	Transaction uint32
}
type dbWithdrawalOutput struct {
	OutBailmentID OutBailmentID
	Status        outputStatus
	Outpoints     []dbOutBailmentOutpoint
}
type dbOutBailmentOutpoint struct {
	Ntxid  Ntxid
	Index  uint32
	Amount bchutil.Amount
}
type dbChangeAwareTx struct {
	SerializedMsgTx []byte
	ChangeIdx       int32
}
type dbWithdrawalStatus struct {
	NextInputAddr  dbWithdrawalAddress
	NextChangeAddr dbChangeAddress
	Fees           bchutil.Amount
	Outputs        map[OutBailmentID]dbWithdrawalOutput
	Sigs           map[Ntxid]TxSigs
	Amounts        map[Ntxid]InputAmounts
	Transactions   map[Ntxid]dbChangeAwareTx
}
func getUsedAddrBucketID(seriesID uint32, branch Branch) []byte {
	var bucketID [9]byte
	binary.LittleEndian.PutUint32(bucketID[0:4], seriesID)
	bucketID[4] = ':'
	binary.LittleEndian.PutUint32(bucketID[5:9], uint32(branch))
	return bucketID[:]
}
func putUsedAddrHash(ns walletdb.ReadWriteBucket, poolID []byte, seriesID uint32, branch Branch,
	index Index, encryptedHash []byte) error {
	usedAddrs := ns.NestedReadWriteBucket(poolID).NestedReadWriteBucket(usedAddrsBucketName)
	bucket, err := usedAddrs.CreateBucketIfNotExists(getUsedAddrBucketID(seriesID, branch))
	if err != nil {
		return newError(ErrDatabase, "failed to store used address hash", err)
	}
	return bucket.Put(uint32ToBytes(uint32(index)), encryptedHash)
}