Skip to content

Commit

Permalink
[SDP-1001] Move all TSS-related tables to the tss schema (#141)
Browse files Browse the repository at this point in the history
### What

Move all TSS-related tables to the tss schema.

### Why

Close https://stellarorg.atlassian.net/browse/SDP-1001.
  • Loading branch information
marcelosalloum authored Jan 8, 2024
1 parent 23927cb commit 70cd0fb
Show file tree
Hide file tree
Showing 31 changed files with 326 additions and 148 deletions.
7 changes: 6 additions & 1 deletion cmd/channel_accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/stellar/go/txnbuild"

cmdUtils "github.com/stellar/stellar-disbursement-platform-backend/cmd/utils"
"github.com/stellar/stellar-disbursement-platform-backend/db/router"
"github.com/stellar/stellar-disbursement-platform-backend/internal/crashtracker"
di "github.com/stellar/stellar-disbursement-platform-backend/internal/dependencyinjection"
txSubSvc "github.com/stellar/stellar-disbursement-platform-backend/internal/transactionsubmission/services"
Expand Down Expand Up @@ -62,7 +63,11 @@ func (c *ChannelAccountsCommand) Command() *cobra.Command {
}

// Inject server dependencies
svcOpts.DatabaseDSN = globalOptions.DatabaseURL
tssDatabaseDSN, err := router.GetDNSForTSS(globalOptions.DatabaseURL)
if err != nil {
log.Ctx(ctx).Fatalf("Error getting TSS database DSN: %v", err)
}
svcOpts.DatabaseDSN = tssDatabaseDSN
svcOpts.NetworkPassphrase = globalOptions.NetworkPassphrase
c.Service, err = txSubSvc.NewChannelAccountService(ctx, *svcOpts)
if err != nil {
Expand Down
33 changes: 26 additions & 7 deletions cmd/channel_accounts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,50 @@ import (

"github.com/spf13/cobra"
"github.com/stellar/go/keypair"
"github.com/stellar/go/network"
"github.com/stellar/go/txnbuild"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/stellar/stellar-disbursement-platform-backend/cmd/db"
"github.com/stellar/stellar-disbursement-platform-backend/cmd/utils"
"github.com/stellar/stellar-disbursement-platform-backend/db/dbtest"
"github.com/stellar/stellar-disbursement-platform-backend/internal/crashtracker"
txSubSvc "github.com/stellar/stellar-disbursement-platform-backend/internal/transactionsubmission/services"
)

func Test_ChannelAccountsCommand_Command(t *testing.T) {
dbt := dbtest.Open(t)

caCommand := &ChannelAccountsCommand{}

dbt := dbtest.OpenWithoutMigrations(t)
root := rootCmd()
cmd := caCommand.Command()
root.AddCommand(cmd)

// Run tss migrations:
globalOptions := utils.GlobalOptionsType{
DatabaseURL: dbt.DSN,
NetworkPassphrase: network.TestNetworkPassphrase,
}
dbCommand := (&db.DatabaseCommand{}).Command(&globalOptions)
root.AddCommand(dbCommand)
root.SetArgs([]string{
"db",
"tss",
"migrate",
"up",
"--database-url",
dbt.DSN,
})
err := dbCommand.Execute()
require.NoError(t, err)

// Run channel accounts verify:
caCommand := (&ChannelAccountsCommand{}).Command()
root.AddCommand(caCommand)
root.SetArgs([]string{
"channel-accounts",
"verify",
"--database-url",
dbt.DSN,
})
err := cmd.Execute()
err = caCommand.Execute()
require.NoError(t, err)
}

Expand Down
3 changes: 2 additions & 1 deletion cmd/db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
adminmigrations "github.com/stellar/stellar-disbursement-platform-backend/db/migrations/admin-migrations"
authmigrations "github.com/stellar/stellar-disbursement-platform-backend/db/migrations/auth-migrations"
sdpmigrations "github.com/stellar/stellar-disbursement-platform-backend/db/migrations/sdp-migrations"
"github.com/stellar/stellar-disbursement-platform-backend/db/router"
"github.com/stellar/stellar-disbursement-platform-backend/internal/services"
sdpUtils "github.com/stellar/stellar-disbursement-platform-backend/internal/utils"
)
Expand Down Expand Up @@ -222,7 +223,7 @@ func (c *DatabaseCommand) tssMigrationsCmd(ctx context.Context, globalOptions *u
return fmt.Errorf("creating the 'tss' database schema if needed: %w", err)
}

dbURL, err := tssMigrationsManager.getTSSDatabaseDSN()
dbURL, err := router.GetDNSForTSS(tssMigrationsManager.RootDatabaseDSN)
if err != nil {
return fmt.Errorf("getting the TSS database DSN: %w", err)
}
Expand Down
18 changes: 3 additions & 15 deletions cmd/db/tss_migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ package db
import (
"context"
"fmt"
"net/url"

migrate "github.com/rubenv/sql-migrate"
"github.com/stellar/go/support/log"

"github.com/stellar/stellar-disbursement-platform-backend/db"
tssmigrations "github.com/stellar/stellar-disbursement-platform-backend/db/migrations/tss-migrations"
"github.com/stellar/stellar-disbursement-platform-backend/db/router"
)

type TSSDatabaseMigrationManager struct {
Expand All @@ -17,7 +18,7 @@ type TSSDatabaseMigrationManager struct {
}

func (m *TSSDatabaseMigrationManager) SchemaName() string {
return "tss"
return router.TSSSchemaName
}

func NewTSSDatabaseMigrationManager(rootDatabaseDSN string) (*TSSDatabaseMigrationManager, error) {
Expand All @@ -42,19 +43,6 @@ func (m *TSSDatabaseMigrationManager) createTSSSchemaIfNeeded(ctx context.Contex
return nil
}

func (m *TSSDatabaseMigrationManager) getTSSDatabaseDSN() (string, error) {
dbURL, err := url.Parse(m.RootDatabaseDSN)
if err != nil {
return "", fmt.Errorf("parsing database DSN: %w", err)
}

q := dbURL.Query()
q.Set("search_path", m.SchemaName())
dbURL.RawQuery = q.Encode()

return dbURL.String(), nil
}

func (m *TSSDatabaseMigrationManager) deleteTSSSchemaIfNeeded(ctx context.Context) error {
// Delete the `tss` schema if needed.
var numberOfRemainingTablesInTSSSchema int
Expand Down
16 changes: 0 additions & 16 deletions cmd/db/tss_migrations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,22 +111,6 @@ func Test_TSSDatabaseMigrationManager_deleteTSSSchemaIfNeeded(t *testing.T) {
assert.False(t, exists)
}

func Test_TSSDatabaseMigrationManager_getTSSDatabaseDSN(t *testing.T) {
dbt := dbtest.Open(t)
defer dbt.Close()
manager, err := NewTSSDatabaseMigrationManager(dbt.DSN)
require.NoError(t, err)
defer manager.RootDBConnectionPool.Close()

// Checks that the search_path is not set.
require.NotContains(t, manager.RootDatabaseDSN, "search_path=tss")

// Sets the search_path to tss.
updatedDSN, err := manager.getTSSDatabaseDSN()
require.NoError(t, err)
require.Contains(t, updatedDSN, "search_path=tss")
}

func Test_runTSSMigrations(t *testing.T) {
dbt := dbtest.OpenWithoutMigrations(t)
defer dbt.Close()
Expand Down
10 changes: 5 additions & 5 deletions cmd/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func Test_DatabaseCommand_db_help(t *testing.T) {
}

func Test_DatabaseCommand_db_sdp_migrate(t *testing.T) {
dbt := dbtest.OpenWithTenantMigrationsOnly(t)
dbt := dbtest.OpenWithAdminMigrationsOnly(t)
defer dbt.Close()

dbConnectionPool, err := db.OpenDBConnectionPool(dbt.DSN)
Expand Down Expand Up @@ -145,7 +145,7 @@ func Test_DatabaseCommand_db_sdp_migrate(t *testing.T) {
}
})

t.Run("migrate up and down --all", func(t *testing.T) {
t.Run("db sdp migrate up and down --all", func(t *testing.T) {
tenant.DeleteAllTenantsFixture(t, ctx, dbConnectionPool)

// Creating Tenants
Expand Down Expand Up @@ -213,7 +213,7 @@ func Test_DatabaseCommand_db_sdp_migrate(t *testing.T) {
tenant.TenantSchemaMatchTablesFixture(t, ctx, dbConnectionPool, "sdp_myorg2", []string{"sdp_migrations"})
})

t.Run("migrate up and down --tenant-id", func(t *testing.T) {
t.Run("db sdp migrate up and down --tenant-id", func(t *testing.T) {
tenant.DeleteAllTenantsFixture(t, ctx, dbConnectionPool)

// Creating Tenants
Expand Down Expand Up @@ -277,7 +277,7 @@ func Test_DatabaseCommand_db_sdp_migrate(t *testing.T) {
assert.NotContains(t, buf.String(), fmt.Sprintf("Applying migrations on tenant ID %s", tnt2.ID))
})

t.Run("migrate up and down auth migrations --all", func(t *testing.T) {
t.Run("db sdp migrate up and down auth migrations --all", func(t *testing.T) {
tenant.DeleteAllTenantsFixture(t, ctx, dbConnectionPool)

// Creating Tenants
Expand Down Expand Up @@ -345,7 +345,7 @@ func Test_DatabaseCommand_db_sdp_migrate(t *testing.T) {
tenant.TenantSchemaMatchTablesFixture(t, ctx, dbConnectionPool, "sdp_myorg2", []string{"auth_migrations"})
})

t.Run("migrate up and down auth migrations --tenant-id", func(t *testing.T) {
t.Run("db sdp migrate up and down auth migrations --tenant-id", func(t *testing.T) {
tenant.DeleteAllTenantsFixture(t, ctx, dbConnectionPool)

// Creating Tenants
Expand Down
7 changes: 6 additions & 1 deletion cmd/transaction_submitter.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/stellar/go/txnbuild"

cmdUtils "github.com/stellar/stellar-disbursement-platform-backend/cmd/utils"
"github.com/stellar/stellar-disbursement-platform-backend/db/router"
"github.com/stellar/stellar-disbursement-platform-backend/internal/crashtracker"
di "github.com/stellar/stellar-disbursement-platform-backend/internal/dependencyinjection"
"github.com/stellar/stellar-disbursement-platform-backend/internal/monitor"
Expand Down Expand Up @@ -170,8 +171,12 @@ func (c *TxSubmitterCommand) Command(submitterService TxSubmitterServiceInterfac
metricsServeOpts.MonitorService = &tssMonitorSvc

// Inject server dependencies
tssDatabaseDSN, err := router.GetDNSForTSS(globalOptions.DatabaseURL)
if err != nil {
log.Ctx(ctx).Fatalf("Error getting TSS database DSN: %v", err)
}
submitterOpts.DatabaseDSN = tssDatabaseDSN
submitterOpts.MonitorService = tssMonitorSvc
submitterOpts.DatabaseDSN = globalOptions.DatabaseURL
submitterOpts.NetworkPassphrase = globalOptions.NetworkPassphrase
submitterOpts.PrivateKeyEncrypter = tssUtils.DefaultPrivateKeyEncrypter{}

Expand Down
27 changes: 26 additions & 1 deletion db/dbtest/dbtest.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ import (
migrate "github.com/rubenv/sql-migrate"
"github.com/stellar/go/support/db/dbtest"
"github.com/stellar/go/support/db/schema"

adminmigrations "github.com/stellar/stellar-disbursement-platform-backend/db/migrations/admin-migrations"
authmigrations "github.com/stellar/stellar-disbursement-platform-backend/db/migrations/auth-migrations"
sdpmigrations "github.com/stellar/stellar-disbursement-platform-backend/db/migrations/sdp-migrations"
tssmigrations "github.com/stellar/stellar-disbursement-platform-backend/db/migrations/tss-migrations"
)

func OpenWithoutMigrations(t *testing.T) *dbtest.DB {
Expand Down Expand Up @@ -47,10 +49,18 @@ func Open(t *testing.T) *dbtest.DB {
if err != nil {
t.Fatal(err)
}

// TSS migrations
ms = migrate.MigrationSet{TableName: "tss_migrations"}
m = migrate.HttpFileSystemMigrationSource{FileSystem: http.FS(tssmigrations.FS)}
_, err = ms.ExecMax(conn.DB, "postgres", m, migrateDirection, 0)
if err != nil {
t.Fatal(err)
}
return db
}

func OpenWithTenantMigrationsOnly(t *testing.T) *dbtest.DB {
func OpenWithAdminMigrationsOnly(t *testing.T) *dbtest.DB {
db := OpenWithoutMigrations(t)

conn := db.Open()
Expand Down Expand Up @@ -94,3 +104,18 @@ func OpenWithAuthMigrationsOnly(t *testing.T) *dbtest.DB {
}
return db
}

func OpenWithTSSMigrationsOnly(t *testing.T) *dbtest.DB {
db := OpenWithoutMigrations(t)

conn := db.Open()
defer conn.Close()

migrateDirection := schema.MigrateUp
m := migrate.HttpFileSystemMigrationSource{FileSystem: http.FS(tssmigrations.FS)}
_, err := schema.Migrate(conn.DB, m, migrateDirection, 0)
if err != nil {
t.Fatal(err)
}
return db
}
5 changes: 5 additions & 0 deletions db/dbtest/dbtest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,9 @@ func TestOpen(t *testing.T) {
err = session.Get(&count, `SELECT COUNT(*) FROM auth_migrations`)
require.NoError(t, err)
assert.Greater(t, count, 0)

// Per-tenant Auth Migrations
err = session.Get(&count, `SELECT COUNT(*) FROM tss_migrations`)
require.NoError(t, err)
assert.Greater(t, count, 0)
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,4 @@ ALTER TABLE submitter_transactions
DROP COLUMN xdr_received,
ALTER COLUMN external_id DROP NOT NULL,
ALTER COLUMN status DROP DEFAULT,
ALTER COLUMN amount TYPE numeric(10,2),
DROP CONSTRAINT unique_stellar_transaction_hash,
DROP CONSTRAINT check_retry_count;
ALTER COLUMN amount TYPE NUMERIC(10,2);
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
-- +migrate Up

DROP TRIGGER refresh_submitter_transactions_updated_at ON submitter_transactions;

DROP TABLE submitter_transactions;

DROP FUNCTION create_submitter_transactions_status_history;

DROP TYPE transaction_status;


-- +migrate Down

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

CREATE TYPE transaction_status AS ENUM ('PENDING', 'PROCESSING', 'SUCCESS', 'ERROR');

-- +migrate StatementBegin
CREATE OR REPLACE FUNCTION create_submitter_transactions_status_history(time_stamp TIMESTAMP WITH TIME ZONE, tss_status transaction_status, status_message VARCHAR, stellar_transaction_hash TEXT, xdr_sent TEXT, xdr_received TEXT)
RETURNS jsonb AS $$
BEGIN
RETURN json_build_object(
'timestamp', time_stamp,
'status', tss_status,
'status_message', status_message,
'stellar_transaction_hash', stellar_transaction_hash,
'xdr_sent', xdr_sent,
'xdr_received', xdr_received
);
END;
$$ LANGUAGE plpgsql;
-- +migrate StatementEnd

CREATE TABLE submitter_transactions (
id VARCHAR(36) PRIMARY KEY DEFAULT public.uuid_generate_v4(),
external_id VARCHAR(64) NOT NULL,

status transaction_status NOT NULL DEFAULT 'PENDING'::transaction_status,
status_history jsonb[] NULL DEFAULT ARRAY[create_submitter_transactions_status_history(NOW(), 'PENDING', NULL, NULL, NULL, NULL)],
status_message TEXT NULL,

asset_code VARCHAR(12) NOT NULL,
asset_issuer VARCHAR(56) NOT NULL,
amount NUMERIC(10,7) NOT NULL,
destination VARCHAR(56) NOT NULL,

created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
locked_at TIMESTAMPTZ,
started_at TIMESTAMPTZ,
sent_at TIMESTAMPTZ,
completed_at TIMESTAMPTZ,
synced_at TIMESTAMPTZ,
locked_until_ledger_number INTEGER,

stellar_transaction_hash VARCHAR(64) UNIQUE,
attempts_count integer DEFAULT 0 CHECK (attempts_count >= 0),
xdr_sent TEXT UNIQUE,
xdr_received TEXT UNIQUE,

CONSTRAINT asset_issuer_length_check CHECK ((asset_code = 'XLM' AND char_length(asset_issuer) = 0) OR char_length(asset_issuer) = 56)
);

CREATE UNIQUE INDEX IF NOT EXISTS idx_unique_external_id ON submitter_transactions (external_id) WHERE status != 'ERROR';

-- TRIGGER: updated_at
CREATE TRIGGER refresh_submitter_transactions_updated_at BEFORE UPDATE ON submitter_transactions FOR EACH ROW EXECUTE PROCEDURE update_at_refresh();
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-- +migrate Up

DROP TRIGGER refresh_channel_accounts_updated_at ON channel_accounts;

DROP TABLE channel_accounts;


-- +migrate Down

CREATE TABLE channel_accounts (
public_key VARCHAR(64) PRIMARY KEY,
private_key VARCHAR(256),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
locked_at TIMESTAMPTZ,
locked_until_ledger_number INTEGER
);

-- TRIGGER: updated_at
CREATE TRIGGER refresh_channel_accounts_updated_at BEFORE UPDATE ON channel_accounts FOR EACH ROW EXECUTE PROCEDURE update_at_refresh();
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

-- +migrate Up

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "uuid-ossp" SCHEMA public;

CREATE TYPE transaction_status AS ENUM ('PENDING', 'PROCESSING', 'SUCCESS', 'ERROR');

Expand Down
Loading

0 comments on commit 70cd0fb

Please sign in to comment.