Skip to content

Commit

Permalink
add bebop parser (#43)
Browse files Browse the repository at this point in the history
  • Loading branch information
ngocthanh1389 authored Jun 4, 2024
1 parent d20cda0 commit 3235dd2
Show file tree
Hide file tree
Showing 10 changed files with 1,482 additions and 34 deletions.
2 changes: 2 additions & 0 deletions cmd/tradelogs/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/KyberNetwork/tradelogs/pkg/dune"
"github.com/KyberNetwork/tradelogs/pkg/parser"
"github.com/KyberNetwork/tradelogs/pkg/parser/bebop"
"github.com/KyberNetwork/tradelogs/pkg/parser/oneinch"
"github.com/KyberNetwork/tradelogs/pkg/parser/oneinchv6"
"github.com/KyberNetwork/tradelogs/pkg/parser/uniswapx"
Expand Down Expand Up @@ -107,6 +108,7 @@ func run(c *cli.Context) error {
oneinch.MustNewParser(traceCalls),
oneinchv6.MustNewParser(traceCalls),
uniswapx.MustNewParser(traceCalls),
bebop.MustNewParser(traceCalls),
}

tradeLogChan := make(chan storage.TradeLog, 1000)
Expand Down
16 changes: 15 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ require (
github.com/rs/xid v1.5.0
github.com/shopspring/decimal v1.3.1
github.com/stretchr/testify v1.8.4
github.com/test-go/testify v1.1.4
github.com/urfave/cli v1.22.14
go.uber.org/zap v1.26.0
google.golang.org/api v0.150.0
Expand All @@ -28,6 +29,7 @@ require (
cloud.google.com/go/compute v1.23.3 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/iam v1.1.5 // indirect
github.com/DataDog/zstd v1.5.2 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/andybalholm/brotli v1.0.5 // indirect
github.com/apache/arrow/go/v12 v12.0.0 // indirect
Expand All @@ -39,14 +41,19 @@ require (
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
github.com/chenzhuoyu/iasm v0.9.1 // indirect
github.com/cockroachdb/errors v1.9.1 // indirect
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
github.com/cockroachdb/redact v1.1.3 // indirect
github.com/consensys/bavard v0.1.13 // indirect
github.com/consensys/gnark-crypto v0.12.1 // indirect
github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect
github.com/deckarep/golang-set/v2 v2.6.0 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/ethereum/c-kzg-4844 v0.4.0 // indirect
github.com/frankban/quicktest v1.14.4 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
Expand All @@ -63,16 +70,23 @@ require (
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 // indirect
github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3 // indirect
github.com/mitchellh/mapstructure v1.4.2 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mmcloughlin/addchain v0.4.0 // indirect
github.com/onsi/gomega v1.24.0 // indirect
github.com/pelletier/go-toml/v2 v2.1.1 // indirect
github.com/pierrec/lz4/v3 v3.3.5 // indirect
github.com/pierrec/lz4/v4 v4.1.16 // indirect
github.com/prometheus/client_golang v1.14.0 // indirect
github.com/prometheus/common v0.39.0 // indirect
github.com/prometheus/procfs v0.9.0 // indirect
github.com/rogpeppe/go-internal v1.10.0 // indirect
github.com/supranational/blst v0.3.11 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect
github.com/zeebo/xxh3 v1.0.2 // indirect
go.opencensus.io v0.24.0 // indirect
go.uber.org/goleak v1.2.1 // indirect
golang.org/x/arch v0.7.0 // indirect
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a // indirect
golang.org/x/mod v0.14.0 // indirect
Expand Down
182 changes: 150 additions & 32 deletions go.sum

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion internal/worker/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func (w *Worker) processMessages(m []evmlistenerclient.Message) error {

func (w *Worker) retryParseLog() error {
insertOrders := []storage.TradeLog{}
logs, err := w.s.GetErrorLogsSince(time.Now().Add(-time.Hour * 24).Unix())
logs, err := w.s.GetErrorLogsSince(time.Now().Add(-time.Minute * 5).Unix())
if err != nil {
return err
}
Expand Down
1 change: 1 addition & 0 deletions pkg/parser/bebop/abi.json

Large diffs are not rendered by default.

1,063 changes: 1,063 additions & 0 deletions pkg/parser/bebop/bebop.go

Large diffs are not rendered by default.

73 changes: 73 additions & 0 deletions pkg/parser/bebop/bebop_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package bebop

import (
"context"
"encoding/json"
"math/big"
"net/http"
"testing"
"time"

"github.com/KyberNetwork/tradelogs/pkg/rpcnode"
"github.com/KyberNetwork/tradelogs/pkg/tracecall"
ethereum "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/test-go/testify/require"
)

const rpcURL = ""

func TestFetchEvent(t *testing.T) {
t.Skip("Need to add the rpc url that enables the trace call JSON-RPC")
rpcClient, err := rpcnode.NewClient(http.DefaultClient, rpcURL)
if err != nil {
panic(err)
}
traceCalls := tracecall.NewCache(rpcClient)
p := MustNewParser(traceCalls)
require.Equal(t, p.abi.Events[TradeEvent].ID, common.HexToHash("0xadd7095becdaa725f0f33243630938c861b0bba83dfd217d4055701aa768ec2e"))
client, err := ethclient.Dial(rpcURL)
require.NoError(t, err)
logs, err := client.FilterLogs(context.Background(), ethereum.FilterQuery{
BlockHash: nil,
FromBlock: big.NewInt(20009519),
ToBlock: big.NewInt(20009519),
Addresses: nil,
Topics: [][]common.Hash{
{
common.HexToHash("0xadd7095becdaa725f0f33243630938c861b0bba83dfd217d4055701aa768ec2e"),
},
},
})
require.NoError(t, err)
d, err := json.Marshal(logs)
require.NoError(t, err)
t.Log(string(d))
}

func TestParseEvent(t *testing.T) {
t.Skip("Need to add the rpc url that enables the trace call JSON-RPC")
eventRaw := `[{"address":"0xbbbbbbb520d69a9775e85b458c58c648259fad5f","topics":["0xadd7095becdaa725f0f33243630938c861b0bba83dfd217d4055701aa768ec2e","0x00000000000000000000000000000000bb6e24300f0812800000000000000000"],"data":"0x","blockNumber":"0x131522f","transactionHash":"0x1ced3e62f6e8083901b3d9365947f53edd28cf7901f79b25a9c8161f7b242b2c","transactionIndex":"0x3c","blockHash":"0xc41f37ec02be129d81f9f81527d52b37e00b2368a9ef418eda14f640662a600a","logIndex":"0xe3","removed":false}]`
events := []types.Log{}
err := json.Unmarshal([]byte(eventRaw), &events)
require.NoError(t, err)
rpcClient, err := rpcnode.NewClient(http.DefaultClient, rpcURL)
if err != nil {
panic(err)
}
traceCalls := tracecall.NewCache(rpcClient)
p := MustNewParser(traceCalls)
for _, event := range events {
log, err := p.Parse(event, uint64(time.Now().Unix()))
require.NoError(t, err)
require.Equal(t, log.EventHash, p.eventHash)
t.Log(log.Maker)
t.Log(log.MakerToken)
t.Log(log.MakerTokenAmount)
t.Log(log.Taker)
t.Log(log.TakerToken)
t.Log(log.TakerTokenAmount)
}
}
1 change: 1 addition & 0 deletions pkg/parser/bebop/gen.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
abigen --abi=abi.json --pkg=bebop --out=bebop.go -type Bebop
175 changes: 175 additions & 0 deletions pkg/parser/bebop/parser.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
package bebop

import (
"encoding/json"
"errors"
"math/big"
"strings"

"github.com/KyberNetwork/tradelogs/internal/types"
"github.com/KyberNetwork/tradelogs/pkg/decoder"
"github.com/KyberNetwork/tradelogs/pkg/parser"
"github.com/KyberNetwork/tradelogs/pkg/storage"
"github.com/KyberNetwork/tradelogs/pkg/tracecall"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
ethereumTypes "github.com/ethereum/go-ethereum/core/types"
)

const (
TradeEvent = "BebopOrder"
OrderParam = "order"
)

var (
ErrTradeTopic = errors.New("invalid trade topic")
ErrNotFoundTraceCall = errors.New("not found trace call")
)

type SingleOrder struct {
Expiry *big.Int `json:"expiry"`
TakerAddress string `json:"taker_address"`
MakerAddress string `json:"maker_address"`
MakerNonce *big.Int `json:"maker_nonce"`
TakerToken string `json:"taker_token"`
MakerToken string `json:"maker_token"`
TakerAmount *big.Int `json:"taker_amount"`
MakerAmount *big.Int `json:"maker_amount"`
Receiver string `json:"receiver"`
PackedCommands *big.Int `json:"packed_commands"`
Flags *big.Int `json:"flags"`
}

type Parser struct {
abi *abi.ABI
ps *BebopFilterer
eventHash string
traceCalls *tracecall.Cache
}

func MustNewParser(tracecall *tracecall.Cache) *Parser {
ps, err := NewBebopFilterer(common.Address{}, nil)
if err != nil {
panic(err)
}
ab, err := abi.JSON(strings.NewReader(BebopMetaData.ABI))
if err != nil {
panic(err)
}
event, ok := ab.Events[TradeEvent]
if !ok {
panic("no such event: " + TradeEvent)
}
return &Parser{
ps: ps,
abi: &ab,
eventHash: event.ID.String(),
traceCalls: tracecall,
}
}

func (p *Parser) Topics() []string {
return []string{
p.eventHash,
}
}

func (p *Parser) Parse(log ethereumTypes.Log, blockTime uint64) (storage.TradeLog, error) {
if len(log.Topics) > 0 && log.Topics[0].Hex() != p.eventHash {
return storage.TradeLog{}, ErrTradeTopic
}
o, err := p.ps.ParseBebopOrder(log)
if err != nil {
return storage.TradeLog{}, err
}
order := storage.TradeLog{
OrderHash: o.EventId.String(),
Maker: log.Address.Hex(),
ContractAddress: o.Raw.Address.String(),
BlockNumber: o.Raw.BlockNumber,
TxHash: o.Raw.TxHash.String(),
LogIndex: uint64(o.Raw.Index),
Timestamp: blockTime * 1000,
EventHash: p.eventHash,
}
return p.parseTraceCall(order)
}

func (p *Parser) parseTraceCall(order storage.TradeLog) (storage.TradeLog, error) {
traceCall, err := p.traceCalls.GetTraceCall(order.TxHash)
if err != nil {
return order, err
}

order, err = p.searchTradeLog(order, traceCall)
if err != nil {
return order, err
}

return order, nil
}

func (p *Parser) searchTradeLog(order storage.TradeLog, traceCall types.CallFrame) (storage.TradeLog, error) {
if p.checkBebopTrade(traceCall) {
return p.ParseFromInternalCall(order, traceCall)
}

for _, subCall := range traceCall.Calls {
tradeLog, err := p.searchTradeLog(order, subCall)
if err == nil {
return tradeLog, nil
}
}
return order, ErrNotFoundTraceCall
}

func (p *Parser) checkBebopTrade(traceCall types.CallFrame) bool {
for _, eventLog := range traceCall.Logs {
if len(eventLog.Topics) == 0 {
continue
}
if !strings.EqualFold(eventLog.Topics[0].String(), p.eventHash) {
continue
}
return true
}
return false
}

func (p *Parser) ParseFromInternalCall(order storage.TradeLog, internalCall types.CallFrame) (storage.TradeLog, error) {
contractCall, err := decoder.Decode(p.abi, internalCall.Input)
if err != nil {
return order, err
}

for _, param := range contractCall.Params {
if param.Name != OrderParam {
continue
}
var rfqOrder SingleOrder
bytes, err := json.Marshal(param.Value)
if err != nil {
return order, err
}

if err := json.Unmarshal(bytes, &rfqOrder); err != nil {
return order, err
}
order.MakerToken = rfqOrder.MakerToken
order.TakerToken = rfqOrder.TakerToken
order.Maker = rfqOrder.MakerAddress
order.Taker = rfqOrder.TakerAddress
order.MakerTokenAmount = rfqOrder.MakerAmount.String()
order.TakerTokenAmount = rfqOrder.TakerAmount.String()
}

return order, nil
}

func (p *Parser) Exchange() string {
return parser.ExBebop
}

func (p *Parser) UseTraceCall() bool {
return true
}
1 change: 1 addition & 0 deletions pkg/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const (
ExParaswapTaker = "paraswap_taker"
ExUniswapX = "uniswapx"
ExNative = "native"
ExBebop = "bebop"
)

type Parser interface {
Expand Down

0 comments on commit 3235dd2

Please sign in to comment.