wormhole/node/pkg/db/db.go

93 lines
1.7 KiB
Go

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
}