Files
ark/server/internal/infrastructure/db/service.go
Louis Singer ff96524f22 Ark Notes (#379)
* ark credits

* rename "ecash" --> "ark credit"

* rework note_test.go

* NewFromString

* create several notes

* note repo: rename "push" to "add"

* RegisterInputsForNextRoundRequest: move "notes" to field #3

* use uint64 as note ID

* rename to voucher

* add nostr notification

* nostr notification test and fixes

* bump badger to 4.3

* allow npub to be registered

* rename poolTxID

* add default relays

* Update server/internal/config/config.go

Co-authored-by: Marco Argentieri <3596602+tiero@users.noreply.github.com>

* fix RedeemVouchers test

* notification = voucher

* WASM wrappers

* fix arkd voucher cmd

* test_utils.go ignore gosec rule G101

* fix permissions

* rename ALL to notes

* add URI prefix

* note.go : fix signature encoding

* fix decode note.Data

* Update server/internal/infrastructure/notifier/nostr/nostr.go

Co-authored-by: Pietralberto Mazza <18440657+altafan@users.noreply.github.com>

* Update pkg/client-sdk/wasm/browser/wrappers.go

Co-authored-by: Pietralberto Mazza <18440657+altafan@users.noreply.github.com>

* Update server/internal/infrastructure/notifier/nostr/nostr.go

Co-authored-by: Pietralberto Mazza <18440657+altafan@users.noreply.github.com>

* rework note and entity db + sqlite implementations

* NOTIFICATION_PREFIX -> NOTE_URI_PREFIX

* validate NOTE_URI_PREFIX

* Update defaults to convenant-less mainnet (#2)

* config: defaults to convenant-less tx builder

* Drop env var for blockchain scanner

---------

Co-authored-by: altafan <18440657+altafan@users.noreply.github.com>

* add // before URI prefix

* add URI prefix in admin CreateNote

* Fixes

* rework nonces encoding (#4)

* rework nonces encoding

* add a check in Musig2Nonce decode function

* musig2_test: increase number of signers to 20

* musig2.json: add a test case with a 35 leaves tree

* GetEventStream REST rework

* fix round phases time intervals

* [SDK] Use server-side streams in rest client

* Fix history

* make the URI optional

* Updates

* Fix settled txs in history

* fix e2e test

* go work sync in sdk unit test

* fix signMessage in btc and liquid sdk wallets

---------

Co-authored-by: Marco Argentieri <3596602+tiero@users.noreply.github.com>
Co-authored-by: Pietralberto Mazza <18440657+altafan@users.noreply.github.com>
2024-11-15 19:07:33 +01:00

206 lines
5.6 KiB
Go

package db
import (
"errors"
"fmt"
"path/filepath"
"github.com/ark-network/ark/server/internal/core/domain"
"github.com/ark-network/ark/server/internal/core/ports"
badgerdb "github.com/ark-network/ark/server/internal/infrastructure/db/badger"
sqlitedb "github.com/ark-network/ark/server/internal/infrastructure/db/sqlite"
"github.com/golang-migrate/migrate/v4"
sqlitemigrate "github.com/golang-migrate/migrate/v4/database/sqlite"
_ "github.com/golang-migrate/migrate/v4/source/file"
)
var (
eventStoreTypes = map[string]func(...interface{}) (domain.RoundEventRepository, error){
"badger": badgerdb.NewRoundEventRepository,
}
roundStoreTypes = map[string]func(...interface{}) (domain.RoundRepository, error){
"badger": badgerdb.NewRoundRepository,
"sqlite": sqlitedb.NewRoundRepository,
}
vtxoStoreTypes = map[string]func(...interface{}) (domain.VtxoRepository, error){
"badger": badgerdb.NewVtxoRepository,
"sqlite": sqlitedb.NewVtxoRepository,
}
noteStoreTypes = map[string]func(...interface{}) (domain.NoteRepository, error){
"badger": badgerdb.NewNoteRepository,
"sqlite": sqlitedb.NewNoteRepository,
}
entityStoreTypes = map[string]func(...interface{}) (domain.EntityRepository, error){
"badger": badgerdb.NewEntityRepository,
"sqlite": sqlitedb.NewEntityRepository,
}
)
const (
sqliteDbFile = "sqlite.db"
)
type ServiceConfig struct {
EventStoreType string
DataStoreType string
EventStoreConfig []interface{}
DataStoreConfig []interface{}
}
type service struct {
eventStore domain.RoundEventRepository
roundStore domain.RoundRepository
vtxoStore domain.VtxoRepository
noteStore domain.NoteRepository
entityStore domain.EntityRepository
}
func NewService(config ServiceConfig) (ports.RepoManager, error) {
eventStoreFactory, ok := eventStoreTypes[config.EventStoreType]
if !ok {
return nil, fmt.Errorf("event store type not supported")
}
roundStoreFactory, ok := roundStoreTypes[config.DataStoreType]
if !ok {
return nil, fmt.Errorf("round store type not supported")
}
vtxoStoreFactory, ok := vtxoStoreTypes[config.DataStoreType]
if !ok {
return nil, fmt.Errorf("vtxo store type not supported")
}
noteStoreFactory, ok := noteStoreTypes[config.DataStoreType]
if !ok {
return nil, fmt.Errorf("note store type not supported")
}
entityStoreFactory, ok := entityStoreTypes[config.DataStoreType]
if !ok {
return nil, fmt.Errorf("entity store type not supported")
}
var eventStore domain.RoundEventRepository
var roundStore domain.RoundRepository
var vtxoStore domain.VtxoRepository
var noteStore domain.NoteRepository
var entityStore domain.EntityRepository
var err error
switch config.EventStoreType {
case "badger":
eventStore, err = eventStoreFactory(config.EventStoreConfig...)
if err != nil {
return nil, fmt.Errorf("failed to open event store: %s", err)
}
default:
return nil, fmt.Errorf("unknown event store db type")
}
switch config.DataStoreType {
case "badger":
roundStore, err = roundStoreFactory(config.DataStoreConfig...)
if err != nil {
return nil, fmt.Errorf("failed to open round store: %s", err)
}
vtxoStore, err = vtxoStoreFactory(config.DataStoreConfig...)
if err != nil {
return nil, fmt.Errorf("failed to open vtxo store: %s", err)
}
entityStore, err = entityStoreFactory(config.DataStoreConfig...)
if err != nil {
return nil, fmt.Errorf("failed to open entity store: %s", err)
}
noteStore, err = noteStoreFactory(config.DataStoreConfig...)
if err != nil {
return nil, fmt.Errorf("failed to open note store: %s", err)
}
case "sqlite":
if len(config.DataStoreConfig) != 2 {
return nil, fmt.Errorf("invalid data store config")
}
baseDir, ok := config.DataStoreConfig[0].(string)
if !ok {
return nil, fmt.Errorf("invalid base directory")
}
migrationPath, ok := config.DataStoreConfig[1].(string)
if !ok {
return nil, fmt.Errorf("invalid migration path")
}
dbFile := filepath.Join(baseDir, sqliteDbFile)
db, err := sqlitedb.OpenDb(dbFile)
if err != nil {
return nil, fmt.Errorf("failed to open db: %s", err)
}
driver, err := sqlitemigrate.WithInstance(db, &sqlitemigrate.Config{})
if err != nil {
return nil, err
}
m, err := migrate.NewWithDatabaseInstance(
migrationPath,
"arkdb",
driver,
)
if err != nil {
return nil, fmt.Errorf("failed to create migration instance: %s", err)
}
if err := m.Up(); err != nil && !errors.Is(err, migrate.ErrNoChange) {
return nil, fmt.Errorf("failed to run migrations: %s", err)
}
roundStore, err = roundStoreFactory(db)
if err != nil {
return nil, fmt.Errorf("failed to open round store: %s", err)
}
vtxoStore, err = vtxoStoreFactory(db)
if err != nil {
return nil, fmt.Errorf("failed to open vtxo store: %s", err)
}
entityStore, err = entityStoreFactory(db)
if err != nil {
return nil, fmt.Errorf("failed to open entity store: %s", err)
}
noteStore, err = noteStoreFactory(db)
if err != nil {
return nil, fmt.Errorf("failed to open note store: %s", err)
}
}
return &service{eventStore, roundStore, vtxoStore, noteStore, entityStore}, nil
}
func (s *service) RegisterEventsHandler(handler func(round *domain.Round)) {
s.eventStore.RegisterEventsHandler(handler)
}
func (s *service) Events() domain.RoundEventRepository {
return s.eventStore
}
func (s *service) Rounds() domain.RoundRepository {
return s.roundStore
}
func (s *service) Vtxos() domain.VtxoRepository {
return s.vtxoStore
}
func (s *service) Notes() domain.NoteRepository {
return s.noteStore
}
func (s *service) Entities() domain.EntityRepository {
return s.entityStore
}
func (s *service) Close() {
s.eventStore.Close()
s.roundStore.Close()
s.vtxoStore.Close()
s.noteStore.Close()
}