github.com/decred/politeia@v1.4.0/politeiad/backendv2/tstorebe/store/store.go (about)

     1  // Copyright (c) 2020-2022 The Decred developers
     2  // Use of this source code is governed by an ISC
     3  // license that can be found in the LICENSE file.
     4  
     5  package store
     6  
     7  import (
     8  	"bytes"
     9  	"compress/gzip"
    10  	"encoding/base64"
    11  	"encoding/gob"
    12  	"encoding/hex"
    13  
    14  	"github.com/decred/politeia/util"
    15  	"github.com/pkg/errors"
    16  )
    17  
    18  var (
    19  	// ErrShutdown is returned when a action is attempted against a store that
    20  	// is shutdown.
    21  	ErrShutdown = errors.New("store is shutdown")
    22  )
    23  
    24  const (
    25  	// DataTypeStructure describes a blob entry that contains a structure.
    26  	DataTypeStructure = "struct"
    27  )
    28  
    29  // DataDescriptor provides hints about a data blob. In practice we JSON encode
    30  // this struture and stuff it into BlobEntry.DataHint.
    31  type DataDescriptor struct {
    32  	Type       string `json:"type"`                // Type of data
    33  	Descriptor string `json:"descriptor"`          // Description of the data
    34  	ExtraData  string `json:"extradata,omitempty"` // Value to be freely used
    35  }
    36  
    37  // BlobEntry is the structure used to store data in the key-value store.
    38  type BlobEntry struct {
    39  	Digest   string `json:"digest"`   // SHA256 digest of data, hex encoded
    40  	DataHint string `json:"datahint"` // Hint that describes data, base64 encoded
    41  	Data     string `json:"data"`     // Data payload, base64 encoded
    42  }
    43  
    44  // NewBlobEntry returns a new BlobEntry.
    45  func NewBlobEntry(dataHint, data []byte) BlobEntry {
    46  	return BlobEntry{
    47  		Digest:   hex.EncodeToString(util.Digest(data)),
    48  		DataHint: base64.StdEncoding.EncodeToString(dataHint),
    49  		Data:     base64.StdEncoding.EncodeToString(data),
    50  	}
    51  }
    52  
    53  // Blobify encodes the provided BlobEntry into a gzipped byte slice.
    54  func Blobify(be BlobEntry) ([]byte, error) {
    55  	var b bytes.Buffer
    56  	zw := gzip.NewWriter(&b)
    57  	enc := gob.NewEncoder(zw)
    58  	err := enc.Encode(be)
    59  	if err != nil {
    60  		zw.Close()
    61  		return nil, err
    62  	}
    63  	err = zw.Close() // we must flush gzip buffers
    64  	if err != nil {
    65  		return nil, err
    66  	}
    67  	return b.Bytes(), nil
    68  }
    69  
    70  // Deblob decodes the provided gzipped byte slice into a BlobEntry.
    71  func Deblob(blob []byte) (*BlobEntry, error) {
    72  	zr, err := gzip.NewReader(bytes.NewReader(blob))
    73  	if err != nil {
    74  		return nil, err
    75  	}
    76  	r := gob.NewDecoder(zr)
    77  	var be BlobEntry
    78  	err = r.Decode(&be)
    79  	if err != nil {
    80  		zr.Close()
    81  		return nil, err
    82  	}
    83  	err = zr.Close()
    84  	if err != nil {
    85  		return nil, err
    86  	}
    87  	return &be, nil
    88  }
    89  
    90  // BlobKV represents a blob key-value store.
    91  type BlobKV interface {
    92  	// Put saves the provided key-value entries to the database. New entries are
    93  	// inserted. Existing entries are updated.
    94  	//
    95  	// This operation is atomic.
    96  	Put(blobs map[string][]byte, encrypt bool) error
    97  
    98  	// Del deletes the key-value entries from the database for the provided keys.
    99  	//
   100  	// This operation is atomic.
   101  	Del(keys []string) error
   102  
   103  	// Get retrieves the key-value entries from the database for the provided
   104  	// keys.
   105  	//
   106  	// An entry will not exist in the returned map for any blobs that are not
   107  	// found. It is the responsibility of the caller to ensure a blob was
   108  	// returned for all provided keys.
   109  	Get(keys []string) (map[string][]byte, error)
   110  
   111  	// Close closes the database connection.
   112  	Close()
   113  }