Skip to content

Commit

Permalink
Merge pull request #131 from eqlabs/latenssi/clean-up
Browse files Browse the repository at this point in the history
Handle env variable tokens in memory
  • Loading branch information
latenssi authored Jul 8, 2021
2 parents 50abc17 + 5145ca7 commit b89c0df
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 25 deletions.
4 changes: 2 additions & 2 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1576,7 +1576,7 @@ func TestTemplateHandlers(t *testing.T) {
method: http.MethodGet,
contentType: "application/json",
url: "/tokens",
expected: fmt.Sprintf(`\[*{"id":\d+,"name":"TestToken","address":"%s","type":"Unknown"}*\]`, cfg.AdminAddress),
expected: fmt.Sprintf(`\[{"id":\d+,"name":"TestToken","address":"%s","type":"Unknown"}.*\]`, cfg.AdminAddress),
status: http.StatusOK,
},
}
Expand All @@ -1603,7 +1603,7 @@ func TestTemplateHandlers(t *testing.T) {
method: http.MethodGet,
contentType: "application/json",
url: "/tokens/1",
expected: `{"id":1,.*"type":"FT"}`,
expected: `{"id":1,.*"type":"Unknown"}`,
status: http.StatusOK,
},
}
Expand Down
19 changes: 12 additions & 7 deletions templates/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ type Service struct {

func NewService(store Store) *Service {
cfg := parseConfig()

// Add all enabled tokens from config as fungible tokens
for _, t := range cfg.enabledTokens {
if _, err := store.GetByName(t.Name); err == nil {
// Token already in database
fmt.Printf("Warning: Skipping %s configuration from environment variables as it already exists in database. ", t.Name)
fmt.Printf("Consider removing it from database or from environment variables.\n")
continue
} else {
if !strings.Contains(err.Error(), "record not found") {
Expand All @@ -27,15 +30,17 @@ func NewService(store Store) *Service {
}
}

t.Type = FT
t.Setup = FungibleSetupCode(&t)
t.Transfer = FungibleTransferCode(&t)
t.Balance = FungibleBalanceCode(&t)
// Copy the value so we get an individual pointer, this is important
token := t
token.Type = FT // We only allow fungible tokens through env variables config
token.Setup = FungibleSetupCode(&token)
token.Transfer = FungibleTransferCode(&token)
token.Balance = FungibleBalanceCode(&token)

if err := store.Insert(&t); err != nil {
panic(err)
}
// Write to temp storage (memory), instead of database
store.InsertTemp(&token)
}

return &Service{store, cfg}
}

Expand Down
3 changes: 3 additions & 0 deletions templates/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@ type Store interface {
GetById(id uint64) (*Token, error)
GetByName(name string) (*Token, error)
Remove(id uint64) error
// Insert a token that is available only for this instances runtime (in-memory)
// Used when enabling a token via environment variables
InsertTemp(*Token)
}
39 changes: 30 additions & 9 deletions templates/store_gorm.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,53 @@ package templates

import (
"database/sql"
"strings"

"gorm.io/gorm"
)

type GormStore struct {
db *gorm.DB
db *gorm.DB
tempStore map[string]*Token
}

func NewGormStore(db *gorm.DB) *GormStore {
db.AutoMigrate(&Token{})
return &GormStore{db}
return &GormStore{db, make(map[string]*Token)}
}

func (s *GormStore) Insert(q *Token) error {
return s.db.Omit("ID").Create(q).Error
}

func (s *GormStore) List(tType *TokenType) (*[]BasicToken, error) {
var tt = &[]BasicToken{}
var err error

fromTemp := make([]BasicToken, 0, len(s.tempStore))
for _, t := range s.tempStore {
if tType == nil || t.Type == *tType {
fromTemp = append(fromTemp, t.BasicToken())
}
}

fromDB := []BasicToken{}

q := s.db.Model(&Token{})

if tType != nil {
// Filter by type
q = q.Where(&Token{Type: *tType})
}

err = q.Find(tt).Error
err = q.Find(&fromDB).Error

if err != nil {
return nil, err
}

return tt, nil
result := append(fromDB, fromTemp...)

return &result, nil
}

func (s *GormStore) GetById(id uint64) (*Token, error) {
Expand All @@ -49,14 +61,23 @@ func (s *GormStore) GetById(id uint64) (*Token, error) {
}

func (s *GormStore) GetByName(name string) (*Token, error) {
var token Token
err := s.db.Where("UPPER(name) LIKE UPPER(@name)", sql.Named("name", name)).First(&token).Error
if err != nil {
fromTemp, ok := s.tempStore[strings.ToLower(name)]
if ok {
return fromTemp, nil
}

var fromDB Token
if err := s.db.Where("LOWER(name) LIKE LOWER(@name)", sql.Named("name", name)).First(&fromDB).Error; err != nil {
return nil, err
}
return &token, nil

return &fromDB, nil
}

func (s *GormStore) Remove(id uint64) error {
return s.db.Delete(&Token{}, id).Error
}

func (s *GormStore) InsertTemp(token *Token) {
s.tempStore[strings.ToLower(token.Name)] = token
}
13 changes: 11 additions & 2 deletions templates/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
)

type Token struct {
ID uint64 `json:"id"`
ID uint64 `json:"id,omitempty"`
Name string `json:"name" gorm:"uniqueIndex;not null"` // Declaration name
NameLowerCase string `json:"nameLowerCase,omitempty"` // For generic fungible token transaction templates
Address string `json:"address" gorm:"not null"`
Expand All @@ -22,7 +22,7 @@ type Token struct {

// BasicToken is a simplifed representation of a Token used in listings
type BasicToken struct {
ID uint64 `json:"id"`
ID uint64 `json:"id,omitempty"`
Name string `json:"name"`
Address string `json:"address"`
Type TokenType `json:"type"`
Expand Down Expand Up @@ -52,6 +52,15 @@ func makeReplacers(t templateVariables) chainReplacers {
return r
}

func (token Token) BasicToken() BasicToken {
return BasicToken{
ID: token.ID,
Name: token.Name,
Address: token.Address,
Type: token.Type,
}
}

func TokenCode(token *Token, tmplStr string) string {

// Regex that matches all references to cadence source files
Expand Down
4 changes: 2 additions & 2 deletions tokens/account_events.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func (h *AccountAddedHandler) Handle(payload accounts.AccountAddedPayload) {
func (h *AccountAddedHandler) addFlowToken(address string) {
token, err := h.TemplateService.GetTokenByName("FlowToken")
if err != nil {
fmt.Printf("error while adding FlowToken to new account: %s\n", err)
fmt.Printf("Error while adding FlowToken to new account: %s\n", err)
}

// No need to setup FlowToken
Expand All @@ -33,6 +33,6 @@ func (h *AccountAddedHandler) addFlowToken(address string) {
TokenType: token.Type,
})
if err != nil {
fmt.Printf("error while adding FlowToken to new account: %s\n", err)
fmt.Printf("Error while adding FlowToken to new account: %s\n", err)
}
}
2 changes: 1 addition & 1 deletion tokens/chain_events.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func (h *ChainEventHandler) handleDeposit(event flow.Event) {
}

if err = h.TokenService.RegisterDeposit(token, event.TransactionID.Hex(), amountOrNftID.String(), account.Address); err != nil {
fmt.Printf("error while registering a deposit: %s\n", err)
fmt.Printf("Error while registering a deposit: %s\n", err)
return
}
}
4 changes: 2 additions & 2 deletions tokens/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func (s *Service) Setup(ctx context.Context, sync bool, tokenName, address strin
TokenType: token.Type,
})
if err != nil {
fmt.Printf("error while adding account token: %s\n", err)
fmt.Printf("Error while adding account token: %s\n", err)
}
}()

Expand Down Expand Up @@ -207,7 +207,7 @@ func (s *Service) CreateWithdrawal(ctx context.Context, runSync bool, sender str
}
t.TransactionId = tx.TransactionId
if err := s.store.InsertTokenTransfer(t); err != nil {
fmt.Printf("error while inserting token transfer: %s\n", err)
fmt.Printf("Error while inserting token transfer: %s\n", err)
}
}()

Expand Down

0 comments on commit b89c0df

Please sign in to comment.