feat: Waku v2 bridge

Issue #12610
This commit is contained in:
Michal Iskierko
2023-11-12 13:29:38 +01:00
parent 56e7bd01ca
commit 6d31343205
6716 changed files with 1982502 additions and 5891 deletions

View File

@@ -0,0 +1,67 @@
package sqlite
import (
"database/sql"
_ "github.com/mutecomm/go-sqlcipher/v4" // We require go sqlcipher that overrides default implementation
"github.com/pkg/errors"
"github.com/status-im/migrate/v4"
)
const communitiesMigrationVersion uint = 1605075346
// FixCommunitiesMigration fixes an issue with a released migration
// In some instances if it was interrupted the migration would be skipped
// but marked as completed.
// What we do here is that we check whether we are at that migration, if
// so we check that the communities table is present, if not we re-run that
// migration.
func FixCommunitiesMigration(version uint, dirty bool, m *migrate.Migrate, db *sql.DB) error {
// If the version is not the same, ignore
if version != communitiesMigrationVersion {
return nil
}
// If it's dirty, it will be replayed anyway
if dirty {
return nil
}
// Otherwise we check whether it actually succeeded by checking for the
// presence of the communities_communities table
var name string
err := db.QueryRow(`SELECT name FROM sqlite_master WHERE type='table' AND name='communities_communities'`).Scan(&name)
// If the err is nil, it means the migration went through fine
if err == nil {
return nil
}
// If any other other, we return the error as that's unexpected
if err != sql.ErrNoRows {
return errors.Wrap(err, "failed to find the communities table")
}
// We replay the migration then
return ReplayLastMigration(version, m)
}
func ReplayLastMigration(version uint, m *migrate.Migrate) error {
// Force version if dirty so it's not dirty anymore
if err := m.Force(int(version)); err != nil {
return errors.Wrap(err, "failed to force migration")
}
// Step down 1 and we retry
if err := m.Steps(-1); err != nil {
return errors.Wrap(err, "failed to step down")
}
return nil
}
func ApplyAdHocMigrations(version uint, dirty bool, m *migrate.Migrate, db *sql.DB) error {
return FixCommunitiesMigration(version, dirty, m, db)
}

View File

@@ -0,0 +1,88 @@
package sqlite
import (
"database/sql"
"github.com/pkg/errors"
_ "github.com/mutecomm/go-sqlcipher/v4" // We require go sqlcipher that overrides default implementation
"github.com/status-im/migrate/v4"
"github.com/status-im/migrate/v4/database/sqlcipher"
bindata "github.com/status-im/migrate/v4/source/go_bindata"
mvdsmigrations "github.com/status-im/mvds/persistenceutil"
)
var migrationsTable = "status_protocol_go_" + sqlcipher.DefaultMigrationsTable
// applyMigrations allows to apply bindata migrations on the current *sql.DB.
// `assetNames` is a list of assets with migrations and `assetGetter` is responsible
// for returning the content of the asset with a given name.
func applyMigrations(db *sql.DB, assetNames []string, assetGetter func(name string) ([]byte, error)) error {
resources := bindata.Resource(
assetNames,
assetGetter,
)
source, err := bindata.WithInstance(resources)
if err != nil {
return errors.Wrap(err, "failed to create migration source")
}
driver, err := sqlcipher.WithInstance(db, &sqlcipher.Config{
MigrationsTable: migrationsTable,
})
if err != nil {
return errors.Wrap(err, "failed to create driver")
}
m, err := migrate.NewWithInstance(
"go-bindata",
source,
"sqlcipher",
driver,
)
if err != nil {
return errors.Wrap(err, "failed to create migration instance")
}
version, dirty, err := m.Version()
if err != nil && err != migrate.ErrNilVersion {
return errors.Wrap(err, "could not get version")
}
err = ApplyAdHocMigrations(version, dirty, m, db)
if err != nil {
return errors.Wrap(err, "failed to apply ad-hoc migrations")
}
if dirty {
err = ReplayLastMigration(version, m)
if err != nil {
return errors.Wrap(err, "failed to replay last migration")
}
}
if err = m.Up(); err != migrate.ErrNoChange {
return errors.Wrap(err, "failed to migrate")
}
return nil
}
func Migrate(database *sql.DB) error {
// Apply migrations for all components.
err := mvdsmigrations.Migrate(database)
if err != nil {
return errors.Wrap(err, "failed to apply mvds migrations")
}
migrationNames, migrationGetter, err := prepareMigrations(defaultMigrations)
if err != nil {
return errors.Wrap(err, "failed to prepare status-go/protocol migrations")
}
err = applyMigrations(database, migrationNames, migrationGetter)
if err != nil {
return errors.Wrap(err, "failed to apply status-go/protocol migrations")
}
return nil
}

View File

@@ -0,0 +1,7 @@
// Package sqlite is responsible for creation of encrypted sqlite3 database using sqlcipher driver.
// It is optimized for mobile usage as well.
//
// sqlite package also provides a capability to apply bindata migration.
// You can keep your migrations close to your business logic and use this package
// to create an encrypted sqlite3 database and then apply the migrations easily.
package sqlite

View File

@@ -0,0 +1,75 @@
package sqlite
import (
"strings"
"github.com/pkg/errors"
encryptmigrations "github.com/status-im/status-go/protocol/encryption/migrations"
appmigrations "github.com/status-im/status-go/protocol/migrations"
push_notification_client_migrations "github.com/status-im/status-go/protocol/pushnotificationclient/migrations"
push_notification_server_migrations "github.com/status-im/status-go/protocol/pushnotificationserver/migrations"
wakumigrations "github.com/status-im/status-go/protocol/transport/migrations"
)
type getter func(string) ([]byte, error)
type migrationsWithGetter struct {
Names []string
Getter getter
}
var defaultMigrations = []migrationsWithGetter{
{
Names: wakumigrations.AssetNames(),
Getter: wakumigrations.Asset,
},
{
Names: encryptmigrations.AssetNames(),
Getter: encryptmigrations.Asset,
},
{
Names: appmigrations.AssetNames(),
Getter: appmigrations.Asset,
},
{
Names: push_notification_server_migrations.AssetNames(),
Getter: push_notification_server_migrations.Asset,
},
{
Names: push_notification_client_migrations.AssetNames(),
Getter: push_notification_client_migrations.Asset,
},
}
func prepareMigrations(migrations []migrationsWithGetter) ([]string, getter, error) {
var allNames []string
nameToGetter := make(map[string]getter)
for _, m := range migrations {
for _, name := range m.Names {
if !validateName(name) {
continue
}
if _, ok := nameToGetter[name]; ok {
return nil, nil, errors.Errorf("migration with name %s already exists", name)
}
allNames = append(allNames, name)
nameToGetter[name] = m.Getter
}
}
return allNames, func(name string) ([]byte, error) {
getter, ok := nameToGetter[name]
if !ok {
return nil, errors.Errorf("no migration for name %s", name)
}
return getter(name)
}, nil
}
// validateName verifies that only *.sql files are taken into consideration.
func validateName(name string) bool {
return strings.HasSuffix(name, ".sql")
}