Skip to content

Commit 4012643

Browse files
committed
Refactor balance store to setup for more tables
1 parent 043d5d5 commit 4012643

File tree

9 files changed

+77
-77
lines changed

9 files changed

+77
-77
lines changed

pkg/code/balance/calculator.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ func CalculateFromBlockchain(ctx context.Context, data code_data.Provider, token
121121
var cachedQuarks uint64
122122
var cachedSlot uint64
123123
var cachedUpdateTs time.Time
124-
checkpointRecord, err := data.GetBalanceCheckpoint(ctx, tokenAccount.PublicKey().ToBase58())
124+
checkpointRecord, err := data.GetExternalBalanceCheckpoint(ctx, tokenAccount.PublicKey().ToBase58())
125125
if err == nil {
126126
cachedQuarks = checkpointRecord.Quarks
127127
cachedSlot = checkpointRecord.SlotCheckpoint
@@ -157,12 +157,12 @@ func CalculateFromBlockchain(ctx context.Context, data code_data.Provider, token
157157

158158
// Observed a balance that's more recent. Best-effort update the checkpoint.
159159
if cachedSlot == 0 || (slot > cachedSlot && quarks != cachedQuarks) {
160-
newCheckpointRecord := &balance.Record{
160+
newCheckpointRecord := &balance.ExternalCheckpointRecord{
161161
TokenAccount: tokenAccount.PublicKey().ToBase58(),
162162
Quarks: quarks,
163163
SlotCheckpoint: slot,
164164
}
165-
data.SaveBalanceCheckpoint(ctx, newCheckpointRecord)
165+
data.SaveExternalBalanceCheckpoint(ctx, newCheckpointRecord)
166166
}
167167

168168
return quarks, BlockchainSource, nil

pkg/code/data/balance/checkpoint.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ import (
55
"time"
66
)
77

8-
// Note: Only supports external balances
9-
type Record struct {
8+
type ExternalCheckpointRecord struct {
109
Id uint64
1110

1211
TokenAccount string
@@ -16,16 +15,16 @@ type Record struct {
1615
LastUpdatedAt time.Time
1716
}
1817

19-
func (r *Record) Validate() error {
18+
func (r *ExternalCheckpointRecord) Validate() error {
2019
if len(r.TokenAccount) == 0 {
2120
return errors.New("token account is required")
2221
}
2322

2423
return nil
2524
}
2625

27-
func (r *Record) Clone() Record {
28-
return Record{
26+
func (r *ExternalCheckpointRecord) Clone() ExternalCheckpointRecord {
27+
return ExternalCheckpointRecord{
2928
Id: r.Id,
3029

3130
TokenAccount: r.TokenAccount,
@@ -36,7 +35,7 @@ func (r *Record) Clone() Record {
3635
}
3736
}
3837

39-
func (r *Record) CopyTo(dst *Record) {
38+
func (r *ExternalCheckpointRecord) CopyTo(dst *ExternalCheckpointRecord) {
4039
dst.Id = r.Id
4140

4241
dst.TokenAccount = r.TokenAccount

pkg/code/data/balance/memory/store.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,18 @@ import (
99
)
1010

1111
type store struct {
12-
mu sync.Mutex
13-
records []*balance.Record
14-
last uint64
12+
mu sync.Mutex
13+
externalCheckpointRecords []*balance.ExternalCheckpointRecord
14+
last uint64
1515
}
1616

1717
// New returns a new in memory balance.Store
1818
func New() balance.Store {
1919
return &store{}
2020
}
2121

22-
// SaveCheckpoint implements balance.Store.SaveCheckpoint
23-
func (s *store) SaveCheckpoint(_ context.Context, data *balance.Record) error {
22+
// SaveExternalCheckpoint implements balance.Store.SaveExternalCheckpoint
23+
func (s *store) SaveExternalCheckpoint(_ context.Context, data *balance.ExternalCheckpointRecord) error {
2424
if err := data.Validate(); err != nil {
2525
return err
2626
}
@@ -29,7 +29,7 @@ func (s *store) SaveCheckpoint(_ context.Context, data *balance.Record) error {
2929
defer s.mu.Unlock()
3030

3131
s.last++
32-
if item := s.find(data); item != nil {
32+
if item := s.findExternalCheckpoint(data); item != nil {
3333
if data.SlotCheckpoint <= item.SlotCheckpoint {
3434
return balance.ErrStaleCheckpoint
3535
}
@@ -44,26 +44,26 @@ func (s *store) SaveCheckpoint(_ context.Context, data *balance.Record) error {
4444
}
4545
data.LastUpdatedAt = time.Now()
4646
c := data.Clone()
47-
s.records = append(s.records, &c)
47+
s.externalCheckpointRecords = append(s.externalCheckpointRecords, &c)
4848
}
4949

5050
return nil
5151
}
5252

53-
// GetCheckpoint implements balance.Store.GetCheckpoint
54-
func (s *store) GetCheckpoint(_ context.Context, account string) (*balance.Record, error) {
53+
// GetExternalCheckpoint implements balance.Store.GetExternalCheckpoint
54+
func (s *store) GetExternalCheckpoint(_ context.Context, account string) (*balance.ExternalCheckpointRecord, error) {
5555
s.mu.Lock()
5656
defer s.mu.Unlock()
5757

58-
if item := s.findByTokenAccount(account); item != nil {
58+
if item := s.findExternalCheckpointByTokenAccount(account); item != nil {
5959
cloned := item.Clone()
6060
return &cloned, nil
6161
}
6262
return nil, balance.ErrCheckpointNotFound
6363
}
6464

65-
func (s *store) find(data *balance.Record) *balance.Record {
66-
for _, item := range s.records {
65+
func (s *store) findExternalCheckpoint(data *balance.ExternalCheckpointRecord) *balance.ExternalCheckpointRecord {
66+
for _, item := range s.externalCheckpointRecords {
6767
if item.Id == data.Id {
6868
return item
6969
}
@@ -74,8 +74,8 @@ func (s *store) find(data *balance.Record) *balance.Record {
7474
return nil
7575
}
7676

77-
func (s *store) findByTokenAccount(account string) *balance.Record {
78-
for _, item := range s.records {
77+
func (s *store) findExternalCheckpointByTokenAccount(account string) *balance.ExternalCheckpointRecord {
78+
for _, item := range s.externalCheckpointRecords {
7979
if account == item.TokenAccount {
8080
return item
8181
}
@@ -87,6 +87,6 @@ func (s *store) reset() {
8787
s.mu.Lock()
8888
defer s.mu.Unlock()
8989

90-
s.records = nil
90+
s.externalCheckpointRecords = nil
9191
s.last = 0
9292
}

pkg/code/data/balance/postgres/model.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ import (
1212
)
1313

1414
const (
15-
tableName = "codewallet__core_balancecheckpoint"
15+
externalCheckpointTableName = "codewallet__core_balanceexternalcheckpoint"
1616
)
1717

18-
type model struct {
18+
type externalCheckpointModel struct {
1919
Id sql.NullInt64 `db:"id"`
2020

2121
TokenAccount string `db:"token_account"`
@@ -25,21 +25,21 @@ type model struct {
2525
LastUpdatedAt time.Time `db:"last_updated_at"`
2626
}
2727

28-
func toModel(obj *balance.Record) (*model, error) {
28+
func toExternalCheckpointModel(obj *balance.ExternalCheckpointRecord) (*externalCheckpointModel, error) {
2929
if err := obj.Validate(); err != nil {
3030
return nil, err
3131
}
3232

33-
return &model{
33+
return &externalCheckpointModel{
3434
TokenAccount: obj.TokenAccount,
3535
Quarks: obj.Quarks,
3636
SlotCheckpoint: obj.SlotCheckpoint,
3737
LastUpdatedAt: obj.LastUpdatedAt,
3838
}, nil
3939
}
4040

41-
func fromModel(obj *model) *balance.Record {
42-
return &balance.Record{
41+
func fromExternalCheckpoingModel(obj *externalCheckpointModel) *balance.ExternalCheckpointRecord {
42+
return &balance.ExternalCheckpointRecord{
4343
Id: uint64(obj.Id.Int64),
4444
TokenAccount: obj.TokenAccount,
4545
Quarks: obj.Quarks,
@@ -48,16 +48,16 @@ func fromModel(obj *model) *balance.Record {
4848
}
4949
}
5050

51-
func (m *model) dbSave(ctx context.Context, db *sqlx.DB) error {
51+
func (m *externalCheckpointModel) dbSave(ctx context.Context, db *sqlx.DB) error {
5252
return pgutil.ExecuteInTx(ctx, db, sql.LevelDefault, func(tx *sqlx.Tx) error {
53-
query := `INSERT INTO ` + tableName + `
53+
query := `INSERT INTO ` + externalCheckpointTableName + `
5454
(token_account, quarks, slot_checkpoint, last_updated_at)
5555
VALUES ($1, $2, $3, $4)
5656
5757
ON CONFLICT (token_account)
5858
DO UPDATE
5959
SET quarks = $2, slot_checkpoint = $3, last_updated_at = $4
60-
WHERE ` + tableName + `.token_account = $1 AND ` + tableName + `.slot_checkpoint < $3
60+
WHERE ` + externalCheckpointTableName + `.token_account = $1 AND ` + externalCheckpointTableName + `.slot_checkpoint < $3
6161
6262
RETURNING
6363
id, token_account, quarks, slot_checkpoint, last_updated_at`
@@ -77,12 +77,12 @@ func (m *model) dbSave(ctx context.Context, db *sqlx.DB) error {
7777
})
7878
}
7979

80-
func dbGetCheckpoint(ctx context.Context, db *sqlx.DB, account string) (*model, error) {
81-
res := &model{}
80+
func dbGetExternalCheckpoint(ctx context.Context, db *sqlx.DB, account string) (*externalCheckpointModel, error) {
81+
res := &externalCheckpointModel{}
8282

8383
query := `SELECT
8484
id, token_account, quarks, slot_checkpoint, last_updated_at
85-
FROM ` + tableName + `
85+
FROM ` + externalCheckpointTableName + `
8686
WHERE token_account = $1
8787
LIMIT 1`
8888

pkg/code/data/balance/postgres/store.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ func New(db *sql.DB) balance.Store {
2020
}
2121
}
2222

23-
// SaveCheckpoint implements balance.Store.SaveCheckpoint
24-
func (s *store) SaveCheckpoint(ctx context.Context, record *balance.Record) error {
25-
model, err := toModel(record)
23+
// SaveExternalCheckpoint implements balance.Store.SaveExternalCheckpoint
24+
func (s *store) SaveExternalCheckpoint(ctx context.Context, record *balance.ExternalCheckpointRecord) error {
25+
model, err := toExternalCheckpointModel(record)
2626
if err != nil {
2727
return err
2828
}
@@ -31,17 +31,17 @@ func (s *store) SaveCheckpoint(ctx context.Context, record *balance.Record) erro
3131
return err
3232
}
3333

34-
res := fromModel(model)
34+
res := fromExternalCheckpoingModel(model)
3535
res.CopyTo(record)
3636

3737
return nil
3838
}
3939

40-
// GetCheckpoint implements balance.Store.GetCheckpoint
41-
func (s *store) GetCheckpoint(ctx context.Context, account string) (*balance.Record, error) {
42-
model, err := dbGetCheckpoint(ctx, s.db, account)
40+
// GetExternalCheckpoint implements balance.Store.GetExternalCheckpoint
41+
func (s *store) GetExternalCheckpoint(ctx context.Context, account string) (*balance.ExternalCheckpointRecord, error) {
42+
model, err := dbGetExternalCheckpoint(ctx, s.db, account)
4343
if err != nil {
4444
return nil, err
4545
}
46-
return fromModel(model), nil
46+
return fromExternalCheckpoingModel(model), nil
4747
}

pkg/code/data/balance/postgres/store_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ var (
2424
const (
2525
// Used for testing ONLY, the table and migrations are external to this repository
2626
tableCreate = `
27-
CREATE TABLE codewallet__core_balancecheckpoint (
27+
CREATE TABLE codewallet__core_balanceexternalcheckpoint (
2828
id SERIAL NOT NULL PRIMARY KEY,
2929
3030
token_account TEXT NOT NULL,
@@ -33,13 +33,13 @@ const (
3333
3434
last_updated_at TIMESTAMP WITH TIME ZONE,
3535
36-
CONSTRAINT codewallet__core_balancecheckpoint__uniq__token_account UNIQUE (token_account)
36+
CONSTRAINT codewallet__core_balanceexternalcheckpoint__uniq__token_account UNIQUE (token_account)
3737
);
3838
`
3939

4040
// Used for testing ONLY, the table and migrations are external to this repository
4141
tableDestroy = `
42-
DROP TABLE codewallet__core_balancecheckpoint;
42+
DROP TABLE codewallet__core_balanceexternalcheckpoint;
4343
`
4444
)
4545

pkg/code/data/balance/store.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@ var (
1212
)
1313

1414
type Store interface {
15-
// SaveCheckpoint saves a balance at a checkpoint. ErrStaleCheckpoint is returned
16-
// if the checkpoint is outdated
17-
SaveCheckpoint(ctx context.Context, record *Record) error
15+
// SaveExternalCheckpoint saves an external balance at a checkpoint.
16+
// ErrStaleCheckpoint is returned if the checkpoint is outdated
17+
SaveExternalCheckpoint(ctx context.Context, record *ExternalCheckpointRecord) error
1818

19-
// GetCheckpoint gets a balance checkpoint for a given account. ErrCheckpointNotFound
20-
// is returend if no DB record exists.
21-
GetCheckpoint(ctx context.Context, account string) (*Record, error)
19+
// GetExternalCheckpoint gets an exeternal balance checkpoint for a
20+
// given account. ErrCheckpointNotFound is returend if no DB record
21+
// exists.
22+
GetExternalCheckpoint(ctx context.Context, account string) (*ExternalCheckpointRecord, error)
2223
}

pkg/code/data/balance/tests/tests.go

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,68 +13,68 @@ import (
1313

1414
func RunTests(t *testing.T, s balance.Store, teardown func()) {
1515
for _, tf := range []func(t *testing.T, s balance.Store){
16-
testHappyPath,
16+
testExternalCheckpointHappyPath,
1717
} {
1818
tf(t, s)
1919
teardown()
2020
}
2121
}
2222

23-
func testHappyPath(t *testing.T, s balance.Store) {
24-
t.Run("testHappyPath", func(t *testing.T) {
23+
func testExternalCheckpointHappyPath(t *testing.T, s balance.Store) {
24+
t.Run("testExternalCheckpointHappyPath", func(t *testing.T) {
2525
ctx := context.Background()
2626

27-
_, err := s.GetCheckpoint(ctx, "token_account")
27+
_, err := s.GetExternalCheckpoint(ctx, "token_account")
2828
assert.Equal(t, balance.ErrCheckpointNotFound, err)
2929

3030
start := time.Now()
3131

32-
expected := &balance.Record{
32+
expected := &balance.ExternalCheckpointRecord{
3333
TokenAccount: "token_account",
3434
Quarks: 0,
3535
SlotCheckpoint: 0,
3636
}
3737
cloned := expected.Clone()
3838

39-
require.NoError(t, s.SaveCheckpoint(ctx, expected))
39+
require.NoError(t, s.SaveExternalCheckpoint(ctx, expected))
4040
assert.EqualValues(t, 1, expected.Id)
4141
assert.True(t, expected.LastUpdatedAt.After(start))
4242

43-
actual, err := s.GetCheckpoint(ctx, "token_account")
43+
actual, err := s.GetExternalCheckpoint(ctx, "token_account")
4444
require.NoError(t, err)
45-
assertEquivalentRecords(t, actual, &cloned)
45+
assertEquivalentExternalCheckpoingRecords(t, actual, &cloned)
4646

4747
start = time.Now()
4848

4949
expected.Quarks = 12345
5050
expected.SlotCheckpoint = 10
5151
cloned = expected.Clone()
5252

53-
require.NoError(t, s.SaveCheckpoint(ctx, expected))
53+
require.NoError(t, s.SaveExternalCheckpoint(ctx, expected))
5454
assert.EqualValues(t, 1, expected.Id)
5555
assert.True(t, expected.LastUpdatedAt.After(start))
5656

57-
actual, err = s.GetCheckpoint(ctx, "token_account")
57+
actual, err = s.GetExternalCheckpoint(ctx, "token_account")
5858
require.NoError(t, err)
59-
assertEquivalentRecords(t, actual, &cloned)
59+
assertEquivalentExternalCheckpoingRecords(t, actual, &cloned)
6060

6161
expected.Quarks = 67890
62-
assert.Equal(t, balance.ErrStaleCheckpoint, s.SaveCheckpoint(ctx, expected))
62+
assert.Equal(t, balance.ErrStaleCheckpoint, s.SaveExternalCheckpoint(ctx, expected))
6363

64-
actual, err = s.GetCheckpoint(ctx, "token_account")
64+
actual, err = s.GetExternalCheckpoint(ctx, "token_account")
6565
require.NoError(t, err)
66-
assertEquivalentRecords(t, actual, &cloned)
66+
assertEquivalentExternalCheckpoingRecords(t, actual, &cloned)
6767

6868
expected.SlotCheckpoint -= 1
69-
assert.Equal(t, balance.ErrStaleCheckpoint, s.SaveCheckpoint(ctx, expected))
69+
assert.Equal(t, balance.ErrStaleCheckpoint, s.SaveExternalCheckpoint(ctx, expected))
7070

71-
actual, err = s.GetCheckpoint(ctx, "token_account")
71+
actual, err = s.GetExternalCheckpoint(ctx, "token_account")
7272
require.NoError(t, err)
73-
assertEquivalentRecords(t, actual, &cloned)
73+
assertEquivalentExternalCheckpoingRecords(t, actual, &cloned)
7474
})
7575
}
7676

77-
func assertEquivalentRecords(t *testing.T, obj1, obj2 *balance.Record) {
77+
func assertEquivalentExternalCheckpoingRecords(t *testing.T, obj1, obj2 *balance.ExternalCheckpointRecord) {
7878
assert.Equal(t, obj1.TokenAccount, obj2.TokenAccount)
7979
assert.Equal(t, obj1.Quarks, obj2.Quarks)
8080
assert.Equal(t, obj1.SlotCheckpoint, obj2.SlotCheckpoint)

0 commit comments

Comments
 (0)