From 9a639ffe2033d187da2e2bb23d982c0600dffe37 Mon Sep 17 00:00:00 2001 From: "aleksej.paschenko" Date: Mon, 9 Oct 2023 18:42:52 +0300 Subject: [PATCH] Blacklist jettons which have symbols similar to any well-known jettons --- go.mod | 2 +- go.sum | 11 ++--------- pkg/addressbook/addressbook.go | 7 +------ pkg/api/account_handlers.go | 3 +-- pkg/api/handler.go | 7 +++---- pkg/api/interfaces.go | 2 +- pkg/api/jetton_handlers.go | 4 ++-- pkg/api/jetton_handlers_test.go | 5 +++-- pkg/api/normalized_metadata.go | 8 ++++++-- pkg/api/testdata/jetton-balances.json | 16 ++++++++++++++++ pkg/spam/spam.go | 8 ++++---- 11 files changed, 40 insertions(+), 33 deletions(-) diff --git a/go.mod b/go.mod index c069914e..3c012732 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/shurcooL/graphql v0.0.0-20220606043923-3cf50f8a0a29 github.com/sourcegraph/conc v0.3.0 github.com/stretchr/testify v1.8.4 - github.com/tonkeeper/scam_backoffice_rules v0.0.0-20230911133119-702402af5714 + github.com/tonkeeper/scam_backoffice_rules v0.0.0-20231009153936-f766159e8ddb github.com/tonkeeper/tongo v1.3.3-0.20231009134841-2a04a2067cea go.opentelemetry.io/otel v1.16.0 go.opentelemetry.io/otel/metric v1.16.0 diff --git a/go.sum b/go.sum index 19cfcb21..d5ff0d06 100644 --- a/go.sum +++ b/go.sum @@ -255,21 +255,14 @@ github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9yS github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/tonkeeper/scam_backoffice_rules v0.0.0-20230911133119-702402af5714 h1:HwtfwtwZK6OyeqvTCqFTxiY8p7gPSS23pV8nir/tKmk= -github.com/tonkeeper/scam_backoffice_rules v0.0.0-20230911133119-702402af5714/go.mod h1:JS7CStRKXjl+nZtRk+f0PReL+mVityMP4O3HupHfyfg= -github.com/tonkeeper/tongo v1.2.3-0.20230917154429-c63ea34ee004 h1:arw/GFHDaoxFdbXkwCCYmeMt6BVsUNAPR/RWYrGQzt4= -github.com/tonkeeper/tongo v1.2.3-0.20230917154429-c63ea34ee004/go.mod h1:LdOBjpUz6vLp1EdX3E0XLNks9YI5XMSqaQahfOMrBEY= -github.com/tonkeeper/tongo v1.3.1 h1:L4BLmT95l/xQZqUdKunn+uYCkMNrwTS1jVu99odbxgA= -github.com/tonkeeper/tongo v1.3.1/go.mod h1:LdOBjpUz6vLp1EdX3E0XLNks9YI5XMSqaQahfOMrBEY= -github.com/tonkeeper/tongo v1.3.2 h1:7UnoQSGojjp1CslJTHxtcdx09sxksUuNZbB1g8Iqi1c= -github.com/tonkeeper/tongo v1.3.2/go.mod h1:LdOBjpUz6vLp1EdX3E0XLNks9YI5XMSqaQahfOMrBEY= +github.com/tonkeeper/scam_backoffice_rules v0.0.0-20231009153936-f766159e8ddb h1:2LTKp4o9QhUinV1lVme5P2nDS/6GyGKuULlkkdFwbVQ= +github.com/tonkeeper/scam_backoffice_rules v0.0.0-20231009153936-f766159e8ddb/go.mod h1:Yz73oGYjlqIFq6s7h5gFy6TouLVK9ortBxcXDiU38J4= github.com/tonkeeper/tongo v1.3.3-0.20231009134841-2a04a2067cea h1:+cBmJqBYluwRJe+XlVxqUMAjwr1djv8zeHUNz7MXi2w= github.com/tonkeeper/tongo v1.3.3-0.20231009134841-2a04a2067cea/go.mod h1:LdOBjpUz6vLp1EdX3E0XLNks9YI5XMSqaQahfOMrBEY= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= diff --git a/pkg/addressbook/addressbook.go b/pkg/addressbook/addressbook.go index 1370e3d6..b055659b 100644 --- a/pkg/addressbook/addressbook.go +++ b/pkg/addressbook/addressbook.go @@ -161,12 +161,7 @@ func (b *Book) GetCollectionInfoByAddress(a tongo.AccountID) (KnownCollection, b func (b *Book) GetKnownJettons() map[tongo.AccountID]KnownJetton { b.mu.RLock() defer b.mu.RUnlock() - - jettons := make(map[tongo.AccountID]KnownJetton, len(b.jettons)) - for accountID, jetton := range b.jettons { - jettons[accountID] = jetton - } - return jettons + return maps.Clone(b.jettons) } func (b *Book) GetJettonInfoByAddress(a tongo.AccountID) (KnownJetton, bool) { diff --git a/pkg/api/account_handlers.go b/pkg/api/account_handlers.go index 9f7d1ffd..2c0fb282 100644 --- a/pkg/api/account_handlers.go +++ b/pkg/api/account_handlers.go @@ -12,7 +12,6 @@ import ( "github.com/tonkeeper/opentonapi/internal/g" "github.com/tonkeeper/opentonapi/pkg/addressbook" - rules "github.com/tonkeeper/scam_backoffice_rules" "github.com/tonkeeper/tongo/code" "github.com/tonkeeper/tongo/utils" @@ -192,7 +191,7 @@ func (h Handler) SearchAccounts(ctx context.Context, params oas.SearchAccountsPa continue } if account.Symbol != "" { - if h.spamFilter.CheckJettonAction(accountID, account.Symbol) == rules.Drop { + if h.spamFilter.IsJettonBlacklisted(accountID, account.Symbol) { continue } } diff --git a/pkg/api/handler.go b/pkg/api/handler.go index a4445595..8a140047 100644 --- a/pkg/api/handler.go +++ b/pkg/api/handler.go @@ -168,9 +168,8 @@ func NewHandler(logger *zap.Logger, opts ...Option) (*Handler, error) { func (h Handler) GetJettonNormalizedMetadata(ctx context.Context, master tongo.AccountID) NormalizedMetadata { meta, _ := h.metaCache.getJettonMeta(ctx, master) // TODO: should we ignore the second returned value? - info, ok := h.addressBook.GetJettonInfoByAddress(master) - if ok { - return NormalizeMetadata(meta, &info) + if info, ok := h.addressBook.GetJettonInfoByAddress(master); ok { + return NormalizeMetadata(meta, &info, false) } - return NormalizeMetadata(meta, nil) + return NormalizeMetadata(meta, nil, h.spamFilter.IsJettonBlacklisted(master, meta.Symbol)) } diff --git a/pkg/api/interfaces.go b/pkg/api/interfaces.go index 09e58d6e..851b49a9 100644 --- a/pkg/api/interfaces.go +++ b/pkg/api/interfaces.go @@ -151,7 +151,7 @@ type ratesSource interface { type spamFilter interface { GetRules() rules.Rules - CheckJettonAction(address tongo.AccountID, symbol string) rules.TypeOfAction + IsJettonBlacklisted(address tongo.AccountID, symbol string) bool } type metadataCache struct { diff --git a/pkg/api/jetton_handlers.go b/pkg/api/jetton_handlers.go index e072be23..94181ec3 100644 --- a/pkg/api/jetton_handlers.go +++ b/pkg/api/jetton_handlers.go @@ -50,9 +50,9 @@ func (h Handler) GetAccountJettonsBalances(ctx context.Context, params oas.GetAc var normalizedMetadata NormalizedMetadata info, ok := h.addressBook.GetJettonInfoByAddress(wallet.JettonAddress) if ok { - normalizedMetadata = NormalizeMetadata(meta, &info) + normalizedMetadata = NormalizeMetadata(meta, &info, false) } else { - normalizedMetadata = NormalizeMetadata(meta, nil) + normalizedMetadata = NormalizeMetadata(meta, nil, h.spamFilter.IsJettonBlacklisted(wallet.JettonAddress, meta.Symbol)) } jettonBalance.Jetton = jettonPreview(wallet.JettonAddress, normalizedMetadata) balances.Balances = append(balances.Balances, jettonBalance) diff --git a/pkg/api/jetton_handlers_test.go b/pkg/api/jetton_handlers_test.go index b9ca9ab4..79d5c95e 100644 --- a/pkg/api/jetton_handlers_test.go +++ b/pkg/api/jetton_handlers_test.go @@ -29,8 +29,9 @@ func TestHandler_GetJettonsBalances(t *testing.T) { t.Run(tt.name, func(t *testing.T) { logger, _ := zap.NewDevelopment() liteStorage, err := litestorage.NewLiteStorage(logger, litestorage.WithKnownJettons([]tongo.AccountID{ - tongo.MustParseAccountID("0:beb5d4638e860ccf7317296e298fde5b35982f4725b0676dc98b1de987b82ebc"), // Jetton kingy - tongo.MustParseAccountID("0:65de083a0007638233b6668354e50e44cd4225f1730d66b8b1f19e5d26690751"), // Lavandos + tongo.MustParseAddress("0:beb5d4638e860ccf7317296e298fde5b35982f4725b0676dc98b1de987b82ebc").ID, // Jetton kingy + tongo.MustParseAddress("0:65de083a0007638233b6668354e50e44cd4225f1730d66b8b1f19e5d26690751").ID, // Lavandos + tongo.MustParseAddress("0:274b605badfcecca83130b27cd375e6a73233f6e15d782a31dd2a80aff097cc0").ID, // fake jUSDT (with cyrillic T) })) require.Nil(t, err) h, err := NewHandler(logger, WithStorage(liteStorage), WithExecutor(liteStorage)) diff --git a/pkg/api/normalized_metadata.go b/pkg/api/normalized_metadata.go index 136baa1b..20d0e5dd 100644 --- a/pkg/api/normalized_metadata.go +++ b/pkg/api/normalized_metadata.go @@ -1,13 +1,13 @@ package api import ( - imgGenerator "github.com/tonkeeper/opentonapi/pkg/image" "math/big" "strconv" "strings" "github.com/shopspring/decimal" "github.com/tonkeeper/opentonapi/pkg/addressbook" + imgGenerator "github.com/tonkeeper/opentonapi/pkg/image" "github.com/tonkeeper/opentonapi/pkg/references" "github.com/tonkeeper/tongo/tep64" "github.com/tonkeeper/tongo/tlb" @@ -19,6 +19,7 @@ type VerificationType string const ( VerificationWhitelist VerificationType = "whitelist" + VerificationBlacklist VerificationType = "blacklist" VerificationNone VerificationType = "none" ) @@ -38,8 +39,11 @@ type NormalizedMetadata struct { Websites []string } -func NormalizeMetadata(meta tep64.Metadata, info *addressbook.KnownJetton) NormalizedMetadata { +func NormalizeMetadata(meta tep64.Metadata, info *addressbook.KnownJetton, isBlacklisted bool) NormalizedMetadata { verification := VerificationNone + if isBlacklisted { + verification = VerificationBlacklist + } name := meta.Name if name == "" { name = "Unknown Token" diff --git a/pkg/api/testdata/jetton-balances.json b/pkg/api/testdata/jetton-balances.json index 716880b1..90a71986 100644 --- a/pkg/api/testdata/jetton-balances.json +++ b/pkg/api/testdata/jetton-balances.json @@ -31,6 +31,22 @@ "image": "https://i.ibb.co/Bj5KqK4/IMG-20221213-115545-207.png", "verification": "whitelist" } + }, + { + "balance": "10000000000000", + "wallet_address": { + "address": "0:876b3031dd0f2b0e34198063950ea38b5cd31081c18b8eda2bd2f02c81affdfd", + "is_scam": false, + "is_wallet": false + }, + "jetton": { + "address": "0:274b605badfcecca83130b27cd375e6a73233f6e15d782a31dd2a80aff097cc0", + "name": "jUSCDT", + "symbol": "jUSDТ", + "decimals": 9, + "image": "https://raw.githubusercontent.com/tonkeeper/opentonapi/master/pkg/references/media/token_placeholder.png", + "verification": "blacklist" + } } ] } \ No newline at end of file diff --git a/pkg/spam/spam.go b/pkg/spam/spam.go index 6538582e..e0db0d57 100644 --- a/pkg/spam/spam.go +++ b/pkg/spam/spam.go @@ -7,13 +7,13 @@ import ( type SpamFilter struct { Rules rules.Rules - JettonEvaluate *rules.JettonEvaluate + jettonVerifier *rules.JettonVerifier } func NewSpamFilter() *SpamFilter { return &SpamFilter{ Rules: rules.GetDefaultRules(), - JettonEvaluate: rules.NewJettonEvaluate(), + jettonVerifier: rules.NewJettonVerifier(), } } @@ -21,6 +21,6 @@ func (s *SpamFilter) GetRules() rules.Rules { return s.Rules } -func (s *SpamFilter) CheckJettonAction(address tongo.AccountID, symbol string) rules.TypeOfAction { - return s.JettonEvaluate.SearchAction(address, symbol) +func (s *SpamFilter) IsJettonBlacklisted(address tongo.AccountID, symbol string) bool { + return s.jettonVerifier.IsBlacklisted(address, symbol) }