Skip to content

Commit

Permalink
Strategy token aliases (#201)
Browse files Browse the repository at this point in the history
* new column to store strategy token alias, it identifies every token in the strategy predicate replacing the token symbol
* include migration down code
  • Loading branch information
lucasmenendez authored Jun 11, 2024
1 parent 0451e24 commit f63966b
Show file tree
Hide file tree
Showing 12 changed files with 72 additions and 36 deletions.
2 changes: 1 addition & 1 deletion api/censuses.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ func (capi *census3API) createAndPublishCensus(req *Census, qID string) (uint64,
}
strategyTokensBySymbol := map[string]*StrategyToken{}
for _, token := range strategyTokens {
strategyTokensBySymbol[token.Symbol] = &StrategyToken{
strategyTokensBySymbol[token.TokenAlias] = &StrategyToken{
ID: common.BytesToAddress(token.TokenID).String(),
ChainID: token.ChainID,
ExternalID: token.ExternalID,
Expand Down
6 changes: 3 additions & 3 deletions api/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ func (capi *census3API) CalculateStrategyHolders(ctx context.Context,
// init token information to get the token holders if the predicate is not a
// literal, and to get the latest block number of every token chain id
tokensInfo := map[string]*strategyoperators.TokenInformation{}
for _, t := range tokens {
for tokenAlias, t := range tokens {
token, err := capi.db.QueriesRO.GetToken(ctx, queries.GetTokenParams{
ID: common.HexToAddress(t.ID).Bytes(),
ChainID: t.ChainID,
Expand All @@ -265,12 +265,12 @@ func (capi *census3API) CalculateStrategyHolders(ctx context.Context,
if err != nil {
return nil, nil, 0, err
}
tokensInfo[token.Symbol] = &strategyoperators.TokenInformation{
tokensInfo[tokenAlias] = &strategyoperators.TokenInformation{
ID: common.BytesToAddress(token.ID).String(),
ChainID: token.ChainID,
MinBalance: t.MinBalance,
Decimals: token.Decimals,
ExternalID: token.ExternalID,
ExternalID: t.ExternalID,
}
provider, exists := capi.holderProviders[token.TypeID]
if !exists {
Expand Down
36 changes: 20 additions & 16 deletions api/strategies.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,10 @@ func (capi *census3API) getStrategies(msg *api.APIdata, ctx *httprouter.HTTPCont
return ErrCantGetStrategies.WithErr(err)
}
for _, strategyToken := range strategyTokens {
if strategyToken.Symbol == "" {
if strategyToken.TokenAlias == "" {
return ErrCantGetStrategies.With("invalid token symbol")
}
strategyResponse.Tokens[strategyToken.Symbol] = &StrategyToken{
strategyResponse.Tokens[strategyToken.TokenAlias] = &StrategyToken{
ID: common.BytesToAddress(strategyToken.TokenID).String(),
ChainID: strategyToken.ChainID,
MinBalance: strategyToken.MinBalance,
Expand Down Expand Up @@ -209,30 +209,32 @@ func (capi *census3API) createStrategy(msg *api.APIdata, ctx *httprouter.HTTPCon
if err != nil {
return ErrCantCreateStrategy.WithErr(err)
}
// iterate over the token symbols included in the predicate
for _, symbol := range validatedPredicate.AllLiterals() {
// iterate over the token aliases included in the predicate
for _, tokenAlias := range validatedPredicate.AllLiterals() {
// check if the request includes the token information
tokenData, ok := req.Tokens[symbol]
tokenData, ok := req.Tokens[tokenAlias]
if !ok {
return ErrNoEnoughtStrategyTokens.Withf("undefined ID and chainID for symbol %s", symbol)
return ErrNoEnoughtStrategyTokens.Withf("no information provided for %s", tokenAlias)
}
// check if the token exists in the database
exists, err := qtx.ExistsTokenByChainID(internalCtx, queries.ExistsTokenByChainIDParams{
ID: common.HexToAddress(tokenData.ID).Bytes(),
ChainID: tokenData.ChainID,
})
exists, err := qtx.ExistsTokenByChainIDAndExternalID(internalCtx,
queries.ExistsTokenByChainIDAndExternalIDParams{
ID: common.HexToAddress(tokenData.ID).Bytes(),
ChainID: tokenData.ChainID,
ExternalID: tokenData.ExternalID,
})
if err != nil {
return ErrCantCreateStrategy.WithErr(err)
}
if !exists {
return ErrNotFoundToken.Withf("the token with symbol %s not found", symbol)
return ErrNotFoundToken.Withf("the token with tokenAlias %s not found", tokenAlias)
}
// decode the min balance for the current token if it is provided,
// if not use one
minBalance := big.NewInt(1)
if tokenData.MinBalance != "" {
if _, ok := minBalance.SetString(tokenData.MinBalance, 10); !ok {
return ErrEncodeStrategy.Withf("error with %s minBalance", symbol)
return ErrEncodeStrategy.Withf("error with %s minBalance", tokenAlias)
}
}
// create the strategy_token in the database
Expand All @@ -242,12 +244,13 @@ func (capi *census3API) createStrategy(msg *api.APIdata, ctx *httprouter.HTTPCon
MinBalance: minBalance.String(),
ChainID: tokenData.ChainID,
ExternalID: tokenData.ExternalID,
TokenAlias: tokenAlias,
}); err != nil {
return ErrCantCreateStrategy.WithErr(err)
}
// get the chain address of the token
chainAddress, _ := capi.w3p.ChainAddress(tokenData.ChainID, tokenData.ID)
req.Tokens[symbol].ChainAddress = chainAddress
req.Tokens[tokenAlias].ChainAddress = chainAddress
}
// encode and compose final strategy data using the response of GET
// strategy endpoint
Expand Down Expand Up @@ -402,13 +405,13 @@ func (capi *census3API) importStrategyDump(ipfsURI string, dump []byte) (uint64,
}
// iterate over the token included in the strategy and create them in the
// database
for symbol, token := range importedStrategy.Tokens {
for tokenAlias, token := range importedStrategy.Tokens {
// decode the min balance for the current token if it is provided,
// if not use zero
minBalance := new(big.Int)
if token.MinBalance != "" {
if _, ok := minBalance.SetString(token.MinBalance, 10); !ok {
return 0, ErrEncodeStrategy.Withf("error with %s minBalance", symbol)
return 0, ErrEncodeStrategy.Withf("error with %s minBalance", tokenAlias)
}
}
// create the strategy token in the database
Expand All @@ -418,6 +421,7 @@ func (capi *census3API) importStrategyDump(ipfsURI string, dump []byte) (uint64,
MinBalance: minBalance.String(),
ChainID: token.ChainID,
ExternalID: token.ExternalID,
TokenAlias: tokenAlias,
}); err != nil {
return 0, ErrCantCreateStrategy.WithErr(err)
}
Expand Down Expand Up @@ -530,7 +534,7 @@ func (capi *census3API) getStrategy(msg *api.APIdata, ctx *httprouter.HTTPContex
}
// parse and encode tokens information
for _, tokenData := range tokensData {
strategy.Tokens[tokenData.Symbol] = &StrategyToken{
strategy.Tokens[tokenData.TokenAlias] = &StrategyToken{
ID: common.BytesToAddress(tokenData.TokenID).String(),
ChainAddress: tokenData.ChainAddress,
MinBalance: tokenData.MinBalance,
Expand Down
25 changes: 25 additions & 0 deletions db/migrations/0002_census3.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
-- +goose Up
ALTER TABLE strategy_tokens ADD COLUMN token_alias TEXT NOT NULL DEFAULT '';

CREATE INDEX idx_strategy_tokens_token_alias ON strategy_tokens(token_alias);

UPDATE strategy_tokens
SET token_alias = (
SELECT t.symbol
FROM tokens t
WHERE strategy_tokens.token_id = t.id
AND strategy_tokens.chain_id = t.chain_id
AND (strategy_tokens.external_id = t.external_id OR strategy_tokens.external_id IS NULL AND t.external_id IS NULL)
)
WHERE token_alias = '';

-- +goose Down
DROP INDEX IF EXISTS idx_strategy_tokens_token_alias;

CREATE TABLE strategy_tokens_temp AS
SELECT strategy_id, token_id, min_balance, chain_id, external_id
FROM strategy_tokens;

DROP TABLE strategy_tokens;

ALTER TABLE strategy_tokens_temp RENAME TO strategy_tokens;
7 changes: 4 additions & 3 deletions db/queries/strategies.sql
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,11 @@ INSERT INTO strategy_tokens (
token_id,
chain_id,
min_balance,
external_id
external_id,
token_alias
)
VALUES (
?, ?, ?, ?, ?
?, ?, ?, ?, ?, ?
);

-- name: ExistsStrategyByURI :one
Expand All @@ -57,7 +58,7 @@ WHERE st.strategy_id = ?
ORDER BY strategy_id, token_id;

-- name: StrategyTokens :many
SELECT st.token_id, st.min_balance, st.chain_id, st.external_id, t.chain_address, t.symbol, t.icon_uri
SELECT st.token_id, st.min_balance, st.chain_id, st.external_id, t.chain_address, st.token_alias, t.icon_uri
FROM strategy_tokens st
JOIN tokens t ON st.token_id = t.id AND st.chain_id = t.chain_id AND st.external_id = t.external_id
WHERE st.strategy_id = ?;
Expand Down
2 changes: 1 addition & 1 deletion db/sqlc/censuses.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion db/sqlc/db.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion db/sqlc/holders.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion db/sqlc/models.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 9 additions & 6 deletions db/sqlc/strategies.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion db/sqlc/tokenTypes.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions db/sqlc/tokens.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit f63966b

Please sign in to comment.