Skip to content

Commit

Permalink
29 improve architecture expand and improve event log structure (#33)
Browse files Browse the repository at this point in the history
* improvement: added event instructions

* feat: event log cache stores transaction logs grouped by event log type. Created new method to get logs from cache by transaction hash and type.

* chore: removed unused functions

* fix: minor bug fix

* feat: using publishing subject name described in event instructions

* Improvement: created event instructions creation function, included some renamings

* Improvement: moved wrapped event log creation to method of Analytics (with initialization of operation), added some event log methods, did some renaming
  • Loading branch information
Ssimonas authored Nov 20, 2023
1 parent b2fd2ae commit 27903d9
Show file tree
Hide file tree
Showing 8 changed files with 214 additions and 215 deletions.
9 changes: 7 additions & 2 deletions publisher/internal/analytics/ethereum/analytics.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,12 @@ type Analytics struct {
db repository.Repository
ctx context.Context

eventLogCache *cache.Cache
eventLogCache *EventLogCache
}

type CacheRecord map[string]interface{}
type EventLogCache struct {
*cache.Cache
}

func init() {
Expand All @@ -56,7 +61,7 @@ func New(ctx context.Context, db repository.Repository, opts ...Option) (*Analyt
return nil, errors.New("token fetcher must be set")
}

ret.eventLogCache = cache.New(ret.Options.eventLogCacheExpirationTime, ret.Options.eventLogCachePurgeTime)
ret.eventLogCache = &EventLogCache{cache.New(ret.Options.eventLogCacheExpirationTime, ret.Options.eventLogCachePurgeTime)}

return ret, nil
}
Expand Down
41 changes: 0 additions & 41 deletions publisher/internal/analytics/ethereum/checks.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package ethereum

import (
"log"
"strings"
)

Expand All @@ -13,34 +12,6 @@ func isUniswapPositionsNFT(address string) bool {
return false
}

func isTransferEvent(evLog EventLog) bool {
return strings.HasPrefix(evLog.Topics[0], transferSig)
}

func (a *Analytics) isMintEvent(evLog EventLog) bool {
return strings.HasPrefix(evLog.Topics[0], mintSig)
}

func (a *Analytics) isBurnEvent(evLog EventLog) bool {
return strings.HasPrefix(evLog.Topics[0], burnSig)
}

func hasTopics(evLog EventLog) bool {
for _, str := range evLog.Topics {
if str != "" {
return true
}
}
log.Println("Log message of TX", evLog.TransactionHash, "has no topics.")
return false
}

func isOrderCorrect(position Position) bool {
token0 := position.Token0
token1 := position.Token1
return strings.EqualFold(token1.Address, addressWETH) || strings.EqualFold(token0.Address, addressUSDC) || strings.EqualFold(token0.Address, addressUSDT)
}

func isStableOrNativeInvolved(position Position) bool {
token0 := position.Token0
token1 := position.Token1
Expand All @@ -51,15 +22,3 @@ func isStableOrNativeInvolved(position Position) bool {
}
return false
}

func isEitherTokenUnknown(position Position) bool {
token0 := position.Token0
token1 := position.Token1
return (strings.EqualFold(token0.Address, "") || strings.EqualFold(token1.Address, ""))
}

func isEitherTokenAmountZero(position Position) bool {
token0 := position.Token0
token1 := position.Token1
return (token0.Amount == 0 || token1.Amount == 0)
}
11 changes: 8 additions & 3 deletions publisher/internal/analytics/ethereum/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,18 @@ func convertTickToRatio(tick, token0Decimal, token1Decimal int) float64 {
return math.Pow(1.0001, float64(tick)) / math.Pow(10, float64(token1Decimal-token0Decimal))
}

func parseEventLogMessage(data []byte) EventLog {
func parseEventLogMessage(data []byte) (EventLog, error) {
var eLog EventLog
err := json.Unmarshal(data, &eLog)
if err != nil {
log.Println("--- ERROR: Encountered an error when unmarshaling EventLog:", err)
return EventLog{}, err
}
return eLog

if !eLog.hasTopics() {
return EventLog{}, fmt.Errorf("parsed event log has no topics.")
}

return eLog, nil
}

// convertTransferAmount converts Transfer's hex amount into scaled actual amount of tokens
Expand Down
94 changes: 13 additions & 81 deletions publisher/internal/analytics/ethereum/ethereum_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func Test_tickConversion(t *testing.T) {

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
test.input.calculateInterval()
test.input.calculate()
resLowerRatio := test.input.LowerRatio
resUpperRatio := test.input.UpperRatio
if math.Abs(resLowerRatio-test.trueLowerRatio)*1.0 > tolerance ||
Expand Down Expand Up @@ -147,74 +147,6 @@ func Test_isUniswapPositionsNFT(t *testing.T) {
}
}

func Test_isTransferEvent(t *testing.T) {
tests := []struct {
name string
inputEventLog EventLog
trueRes bool
}{
{"Topic with Transfer sig", EventLog{Topics: []string{"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"}}, true},
{"Topic with other sig", EventLog{Topics: []string{"0x0c396cd989a39f4459b5fa1aed6a9a8dcdbc45908acfd67e028cd568da98982c"}}, false},
{"Transfer sig", EventLog{Topics: []string{"0xddf252ad1be2c89"}}, true},
{"Other sig", EventLog{Topics: []string{"0xddf252"}}, false},
{"Empty string", EventLog{Topics: []string{""}}, false},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
res := isTransferEvent(test.inputEventLog)
if res != test.trueRes {
t.Errorf("isTransferEvent(%v) = (%v); expected (%v)", test.inputEventLog, res, test.trueRes)
}
})
}
}

func Test_isMintEvent(t *testing.T) {
tests := []struct {
name string
inputEventLog EventLog
trueRes bool
}{
{"Topic with other sig", EventLog{Topics: []string{"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"}}, false},
{"Topic with Mint sig", EventLog{Topics: []string{"0x7a53080ba414158be7ec69b987b5fb7d07dee101fe85488f0853ae16239d0bde"}}, true},
{"Mint sig", EventLog{Topics: []string{"0x7a53080ba414158"}}, true},
{"Other sig", EventLog{Topics: []string{"0x7a53"}}, false},
{"Empty string", EventLog{Topics: []string{""}}, false},
}
a := Analytics{}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
res := a.isMintEvent(test.inputEventLog)
if res != test.trueRes {
t.Errorf("isMintEvent(%v) = (%v); expected (%v)", test.inputEventLog, res, test.trueRes)
}
})
}
}

func Test_isBurnEvent(t *testing.T) {
tests := []struct {
name string
inputEventLog EventLog
trueRes bool
}{
{"Topic with other sig", EventLog{Topics: []string{"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"}}, false},
{"Topic with Burn sig", EventLog{Topics: []string{"0x0c396cd989a39f4459b5fa1aed6a9a8dcdbc45908acfd67e028cd568da98982c"}}, true},
{"Burn sig", EventLog{Topics: []string{"0x0c396cd989a39f4"}}, true},
{"Other sig", EventLog{Topics: []string{"0x0c396c"}}, false},
{"Empty string", EventLog{Topics: []string{""}}, false},
}
a := Analytics{}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
res := a.isBurnEvent(test.inputEventLog)
if res != test.trueRes {
t.Errorf("isBurnEvent(%v) = (%v); expected (%v)", test.inputEventLog, res, test.trueRes)
}
})
}
}

func Test_hasTopics(t *testing.T) {
tests := []struct {
name string
Expand All @@ -228,7 +160,7 @@ func Test_hasTopics(t *testing.T) {
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
res := hasTopics(test.inputEventLog)
res := test.inputEventLog.hasTopics()
if res != test.trueRes {
t.Errorf("hasTopics(%v) = (%v); expected (%v)", test.inputEventLog, res, test.trueRes)
}
Expand All @@ -253,7 +185,7 @@ func Test_isOrderCorrect(t *testing.T) {
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
res := isOrderCorrect(test.input)
res := test.input.isOrderCorrect()
if res != test.trueRes {
t.Errorf("isOrderCorrect(%v) = (%v); expected (%v)", test.input, res, test.trueRes)
}
Expand Down Expand Up @@ -282,24 +214,24 @@ func Test_isStableOrNativeInvolved(t *testing.T) {
}
}

func Test_isEitherTokenUnknown(t *testing.T) {
func Test_areTokensSet(t *testing.T) {
unknownToken := TokenTransaction{Token: repository.Token{}}
tests := []struct {
name string
input Position
trueRes bool
}{
{"unknown/native", Position{Token0: unknownToken, Token1: knownTokens["WETH"]}, true},
{"custom/unknown", Position{Token0: knownTokens["MATIC"], Token1: unknownToken}, true},
{"stable/unknown", Position{Token0: knownTokens["USDC"], Token1: unknownToken}, true},
{"stable/native", Position{Token0: knownTokens["USDC"], Token1: knownTokens["WETH"]}, false},
{"native/unknown", Position{Token0: knownTokens["WETH"], Token1: unknownToken}, true},
{"custom/custom", Position{Token0: knownTokens["MATIC"], Token1: knownTokens["WBTC"]}, false},
{"unknown/custom", Position{Token0: unknownToken, Token1: knownTokens["PEPE"]}, true},
{"unknown/native", Position{Token0: unknownToken, Token1: knownTokens["WETH"]}, false},
{"custom/unknown", Position{Token0: knownTokens["MATIC"], Token1: unknownToken}, false},
{"stable/unknown", Position{Token0: knownTokens["USDC"], Token1: unknownToken}, false},
{"stable/native", Position{Token0: knownTokens["USDC"], Token1: knownTokens["WETH"]}, true},
{"native/unknown", Position{Token0: knownTokens["WETH"], Token1: unknownToken}, false},
{"custom/custom", Position{Token0: knownTokens["MATIC"], Token1: knownTokens["WBTC"]}, true},
{"unknown/custom", Position{Token0: unknownToken, Token1: knownTokens["PEPE"]}, false},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
res := isEitherTokenUnknown(test.input)
res := test.input.areTokensSet()
if res != test.trueRes {
t.Errorf("isEitherTokenUnknown(%v) = (%v); expected (%v)", test.input, res, test.trueRes)
}
Expand All @@ -324,7 +256,7 @@ func Test_isEitherTokenAmountIsZero(t *testing.T) {
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
res := isEitherTokenAmountZero(test.input)
res := test.input.isEitherTokenAmountZero()
if res != test.trueRes {
t.Errorf("isEitherTokenAmountIsZero(%v) = (%v); expected (%v)", test.input, res, test.trueRes)
}
Expand Down
Loading

0 comments on commit 27903d9

Please sign in to comment.