github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/tm2/pkg/bft/state/eventstore/file/file.go (about)

     1  package file
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/gnolang/gno/tm2/pkg/amino"
     7  	"github.com/gnolang/gno/tm2/pkg/autofile"
     8  	storetypes "github.com/gnolang/gno/tm2/pkg/bft/state/eventstore/types"
     9  	"github.com/gnolang/gno/tm2/pkg/bft/types"
    10  	"github.com/gnolang/gno/tm2/pkg/errors"
    11  )
    12  
    13  const (
    14  	EventStoreType = "file"
    15  	Path           = "path"
    16  )
    17  
    18  var (
    19  	errMissingPath = errors.New("missing path param")
    20  	errInvalidType = errors.New("invalid config for file event store specified")
    21  )
    22  
    23  // TxEventStore is the implementation of a transaction event store
    24  // that outputs to the local filesystem
    25  type TxEventStore struct {
    26  	headPath string
    27  	group    *autofile.Group
    28  }
    29  
    30  // NewTxEventStore creates a new file-based tx event store
    31  func NewTxEventStore(cfg *storetypes.Config) (*TxEventStore, error) {
    32  	// Parse config params
    33  	if EventStoreType != cfg.EventStoreType {
    34  		return nil, errInvalidType
    35  	}
    36  
    37  	headPath, ok := cfg.GetParam(Path).(string)
    38  	if !ok {
    39  		return nil, errMissingPath
    40  	}
    41  
    42  	return &TxEventStore{
    43  		headPath: headPath,
    44  	}, nil
    45  }
    46  
    47  // Start starts the file transaction event store, by opening the autofile group
    48  func (t *TxEventStore) Start() error {
    49  	// Open the group
    50  	group, err := autofile.OpenGroup(t.headPath)
    51  	if err != nil {
    52  		return fmt.Errorf("unable to open file group for writing, %w", err)
    53  	}
    54  
    55  	t.group = group
    56  
    57  	return nil
    58  }
    59  
    60  // Stop stops the file transaction event store, by closing the autofile group
    61  func (t *TxEventStore) Stop() error {
    62  	// Close off the group
    63  	t.group.Close()
    64  
    65  	return nil
    66  }
    67  
    68  // GetType returns the file transaction event store type
    69  func (t *TxEventStore) GetType() string {
    70  	return EventStoreType
    71  }
    72  
    73  // Append marshals the transaction using amino, and writes it to the disk
    74  func (t *TxEventStore) Append(tx types.TxResult) error {
    75  	// Serialize the transaction using amino
    76  	txRaw, err := amino.MarshalJSON(tx)
    77  	if err != nil {
    78  		return fmt.Errorf("unable to marshal transaction, %w", err)
    79  	}
    80  
    81  	// Write the serialized transaction info to the file group
    82  	if err = t.group.WriteLine(string(txRaw)); err != nil {
    83  		return fmt.Errorf("unable to save transaction event, %w", err)
    84  	}
    85  
    86  	// Flush output to storage
    87  	if err := t.group.FlushAndSync(); err != nil {
    88  		return fmt.Errorf("unable to flush and sync transaction event, %w", err)
    89  	}
    90  
    91  	return nil
    92  }