package db import ( "errors" "fmt" "github.com/certusone/wormhole/node/pkg/vaa" "github.com/dgraph-io/badger/v3" ) type Database struct { db *badger.DB } type VAAID struct { EmitterChain vaa.ChainID EmitterAddress vaa.Address Sequence uint64 } func vaaIDFromVAA(v *vaa.VAA) *VAAID { return &VAAID{ EmitterChain: v.EmitterChain, EmitterAddress: v.EmitterAddress, Sequence: v.Sequence, } } var ( ErrVAANotFound = errors.New("requested VAA not found in store") ) func (i *VAAID) Bytes() []byte { return []byte(fmt.Sprintf("signed/%d/%s/%d", i.EmitterChain, i.EmitterAddress, i.Sequence)) } func Open(path string) (*Database, error) { db, err := badger.Open(badger.DefaultOptions(path)) if err != nil { return nil, fmt.Errorf("failed to open database: %w", err) } return &Database{ db: db, }, nil } func (d *Database) Close() error { return d.db.Close() } func (d *Database) StoreSignedVAA(v *vaa.VAA) error { if len(v.Signatures) == 0 { panic("StoreSignedVAA called for unsigned VAA") } b, _ := v.Marshal() // TODO: panic if same VAA is stored with different value err := d.db.Update(func(txn *badger.Txn) error { if err := txn.Set(vaaIDFromVAA(v).Bytes(), b); err != nil { return err } return nil }) if err != nil { return fmt.Errorf("failed to commit tx: %w", err) } return nil } func (d *Database) GetSignedVAABytes(id VAAID) (b []byte, err error) { if err := d.db.View(func(txn *badger.Txn) error { item, err := txn.Get(id.Bytes()) if err != nil { return err } if val, err := item.ValueCopy(nil); err != nil { return err } else { b = val } return nil }); err != nil { if err == badger.ErrKeyNotFound { return nil, ErrVAANotFound } return nil, err } return }