Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BE-586 | Claimbot #524

Merged
merged 39 commits into from
Nov 3, 2024
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
cd919d6
BE-586 | Claimbot prototype
deividaspetraitis Oct 4, 2024
25746a1
BE-586 | WIP
deividaspetraitis Oct 7, 2024
801f9f4
BE-586 | WIP
deividaspetraitis Oct 8, 2024
53dc4b8
BE-595 | Clean up
deividaspetraitis Oct 9, 2024
d349b3f
BE-586 | Add docs
deividaspetraitis Oct 10, 2024
dbc37ec
BE-586 | Clean up
deividaspetraitis Oct 10, 2024
a629788
BE-586 | Add docs
deividaspetraitis Oct 10, 2024
3d1c9b6
BE-596 | Tests init
deividaspetraitis Oct 11, 2024
c548460
BE-586 | Add tests for slices, orderbook packages
deividaspetraitis Oct 14, 2024
f37ac1d
BE-586 | claimbot/tx tests
deividaspetraitis Oct 14, 2024
ad494d3
BE-586 | claimbot/order.go tests
deividaspetraitis Oct 14, 2024
ac10250
BE-586 | Requested changes
deividaspetraitis Oct 15, 2024
b7e3e6c
Merge remote-tracking branch 'upstream/v26.x' into BE-586
deividaspetraitis Oct 15, 2024
0183cce
BE-586 | Process block orderbooks, tests
deividaspetraitis Oct 16, 2024
f139b10
Merge remote-tracking branch 'upstream/v26.x' into BE-586
deividaspetraitis Oct 17, 2024
54d41bd
BE-586 | Requested changes
deividaspetraitis Oct 17, 2024
92ee4b2
BE-586 | Config update
deividaspetraitis Oct 17, 2024
5a93a63
Merge remote-tracking branch 'upstream/v26.x' into BE-586
deividaspetraitis Oct 22, 2024
811bfac
BE-586 | OrderBookClient use slices.Split for pagination
deividaspetraitis Oct 22, 2024
f2084e0
BE-586 | Clean up
deividaspetraitis Oct 22, 2024
54a4d82
Merge remote-tracking branch 'upstream/v26.x' into BE-586
deividaspetraitis Oct 22, 2024
6bc4139
BE-586 | Fix fillbot docker-compose
deividaspetraitis Oct 22, 2024
89df2a6
BE-586 | Docs, docker compose fixes
deividaspetraitis Oct 24, 2024
a94eea3
Merge remote-tracking branch 'upstream/v26.x' into BE-586
deividaspetraitis Oct 25, 2024
46cf981
Merge remote-tracking branch 'upstream/v26.x' into BE-586
deividaspetraitis Oct 25, 2024
3c90eb8
BE-586 | Run fillbot via docker-compose
deividaspetraitis Oct 25, 2024
3e2d513
BE-586 | Run claimbot via docker-compose, clean up
deividaspetraitis Oct 25, 2024
0ff913b
BE-586 | Cleanup
deividaspetraitis Oct 25, 2024
fc39dd7
BE-586 | Named logger
deividaspetraitis Oct 28, 2024
3216bb1
BE-586 | Requested changes
deividaspetraitis Oct 28, 2024
b1ecbf4
BE-586 | Logging failing tx
deividaspetraitis Oct 28, 2024
8a8ef15
BE-586 | Increase gas adjustment
deividaspetraitis Oct 28, 2024
adb286c
BE-586 | Error logging fix
deividaspetraitis Oct 28, 2024
d298179
BE-586 | Trace name update
deividaspetraitis Oct 29, 2024
131ba9e
BE-586 | Requested changes #1
deividaspetraitis Oct 30, 2024
172b2ad
BE-586 | Requested changes #2
deividaspetraitis Oct 30, 2024
d11fbf2
BE-586 | Sequence number update
deividaspetraitis Oct 30, 2024
beee769
BE-586 | added tests
deividaspetraitis Oct 31, 2024
2593bc0
BE-586 | Suggested improvements
deividaspetraitis Oct 31, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -243,11 +243,25 @@ orderbook-fillbot-start:
./ingest/usecase/plugins/orderbook/fillbot/create_copy_config.sh
cd ./ingest/usecase/plugins/orderbook/fillbot && docker compose up -d
cd ../../../../
echo "Order Book Filler Bot Started"
echo "Orderbook Fill Bot Started"
sleep 10 && osmosisd status
sleep 10 && docker logs -f osmosis-sqs

orderbook-fillbot-stop:
cd ./ingest/usecase/plugins/orderbook/fillbot && docker compose down
cd ../../../../
echo "Order Book Filler Bot Stopped"
echo "Orderbook Fill Bot Stopped"


orderbook-claimbot-start:
./ingest/usecase/plugins/orderbook/fillbot/create_copy_config.sh
cd ./ingest/usecase/plugins/orderbook/claimbot && docker compose up -d
cd ../../../../
echo "Orderbook Claim Bot Started"
sleep 10 && osmosisd status
sleep 10 && docker logs -f osmosis-sqs

orderbook-claimbot-stop:
cd ./ingest/usecase/plugins/orderbook/claimbot && docker compose down
cd ../../../../
echo "Orderbook Claim Bot Stopped"
26 changes: 25 additions & 1 deletion app/sidecar_query_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (

ingestrpcdelivry "github.com/osmosis-labs/sqs/ingest/delivery/grpc"
ingestusecase "github.com/osmosis-labs/sqs/ingest/usecase"
orderbookclaimbot "github.com/osmosis-labs/sqs/ingest/usecase/plugins/orderbook/claimbot"
orderbookfillbot "github.com/osmosis-labs/sqs/ingest/usecase/plugins/orderbook/fillbot"
orderbookrepository "github.com/osmosis-labs/sqs/orderbook/repository"
orderbookusecase "github.com/osmosis-labs/sqs/orderbook/usecase"
Expand Down Expand Up @@ -271,7 +272,7 @@ func NewSideCarQueryServer(appCodec codec.Codec, config domain.Config, logger lo
if plugin.IsEnabled() {
var currentPlugin domain.EndBlockProcessPlugin

if plugin.GetName() == orderbookplugindomain.OrderBookPluginName {
if plugin.GetName() == orderbookplugindomain.OrderbookFillbotPlugin {
// Create keyring
keyring, err := keyring.New()
if err != nil {
Expand All @@ -282,6 +283,29 @@ func NewSideCarQueryServer(appCodec codec.Codec, config domain.Config, logger lo
currentPlugin = orderbookfillbot.New(poolsUseCase, routerUsecase, tokensUseCase, passthroughGRPCClient, orderBookAPIClient, keyring, defaultQuoteDenom, logger)
}

if plugin.GetName() == orderbookplugindomain.OrderbookClaimbotPlugin {
// Create keyring
keyring, err := keyring.New()
if err != nil {
return nil, err
}

logger.Info("Using keyring with address", zap.Stringer("address", keyring.GetAddress()))
currentPlugin, err = orderbookclaimbot.New(
keyring,
orderBookUseCase,
poolsUseCase,
orderBookRepository,
orderBookAPIClient,
logger,
config.ChainGRPCGatewayEndpoint,
config.ChainID,
)
deividaspetraitis marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, err
}
}

// Register the plugin with the ingest use case
ingestUseCase.RegisterEndBlockProcessPlugin(currentPlugin)
}
Expand Down
32 changes: 19 additions & 13 deletions config.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
{
"flight-record": {
"enabled": false
},
"otel": {
"enabled": false,
"environment": "sqs-dev"
},
"plugins": [
{
"name": "orderbook",
"enabled": false
}
]
"flight-record": {
"enabled": false
},
"otel": {
"enabled": false,
"environment": "sqs-dev"
},
"grpc-ingester": {
"plugins": [
{
"name": "orderbook-fillbot-plugin",
"enabled": false
},
{
"name": "orderbook-claimbot-plugin",
"enabled": false
}
]
}
Comment on lines +9 to +20
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider adding configuration parameters for fine-grained control.

The plugin configurations could benefit from additional parameters to control their behavior:

  • Threshold for considering orders as filled (currently hardcoded at 98%)
  • Concurrent order book processing settings
  • Rate limiting parameters

This would provide more flexibility in different environments without requiring code changes.

Example structure:

 {
   "name": "orderbook-claimbot-plugin",
   "enabled": false,
+  "settings": {
+    "fill_threshold_percentage": 98,
+    "max_concurrent_orderbooks": 1,
+    "rate_limit": {
+      "orders_per_second": 10,
+      "max_batch_size": 50
+    }
+  }
 }

Committable suggestion was skipped due to low confidence.

}
10 changes: 8 additions & 2 deletions domain/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,11 @@ var (
Plugins: []Plugin{
&OrderBookPluginConfig{
Enabled: false,
Name: orderbookplugindomain.OrderBookPluginName,
Name: orderbookplugindomain.OrderbookFillbotPlugin,
},
&OrderBookPluginConfig{
Enabled: false,
Name: orderbookplugindomain.OrderbookClaimbotPlugin,
},
},
},
Expand Down Expand Up @@ -377,7 +381,9 @@ func validateDynamicMinLiquidityCapDesc(values []DynamicMinLiquidityCapFilterEnt
// PluginFactory creates a Plugin instance based on the provided name.
func PluginFactory(name string) Plugin {
switch name {
case orderbookplugindomain.OrderBookPluginName:
case orderbookplugindomain.OrderbookFillbotPlugin:
return &OrderBookPluginConfig{}
case orderbookplugindomain.OrderbookClaimbotPlugin:
deividaspetraitis marked this conversation as resolved.
Show resolved Hide resolved
return &OrderBookPluginConfig{}
// Add cases for other plugins as needed
default:
Expand Down
5 changes: 3 additions & 2 deletions domain/orderbook/plugin/config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package orderbookplugindomain

// Orderbook plugin names
const (
// OrderBookPluginName is the name of the orderbook plugin.
OrderBookPluginName = "orderbook"
OrderbookFillbotPlugin = "orderbook-fillbot-plugin"
OrderbookClaimbotPlugin = "orderbook-claimbot-plugin"
)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
DD_API_KEY=YOUR_API_KEY
OSMOSIS_KEYRING_PATH=/root/.osmosisd/keyring-test
OSMOSIS_KEYRING_PASSWORD=test
OSMOSIS_KEYRING_KEY_NAME=local.info
OSMOSIS_KEYRING_KEY_NAME=local.info
69 changes: 69 additions & 0 deletions ingest/usecase/plugins/orderbook/claimbot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Orderbook Claimbot Plugin

The Orderbook Claimbot plugin is a plugin that claims filled order book orders.

It scans all active orders for each order book determining which orders have been filled and need to be claimed. At the moment order is said to be claimable if it is filled 98 percent or more. In order for an order book to be processed to claim its active orders it must be canonical as per SQS definition.


Such order book scanning and claiming is achieved by listening for new blocks and core logic is triggered at the end of each new block by calling Claimbot `ProcessEndBlock` method.

## Configuration

### Node

1. Initialize a fresh node with the `osmosisd` binary.
```bash
osmosisd init claim-bot --chain-id osmosis-1
```

2. Get latest snapshot from [here](https://snapshots.osmosis.zone/index.html)

3. Go to `$HOME/.osmosisd/config/app.toml` and set `osmosis-sqs.is-enabled` to true

4. Optionally, turn off any services from `app.toml` and `config.toml` that you don't need

### SQS

In `config.json`, set the plugin to enabled:

```json
"grpc-ingester":{
...
"plugins": [
{
"name": "orderbook-claimbot-plugin",
"enabled": true
}
]
},
```

Configure the key on a test keyring, and set the following environment variables:
deividaspetraitis marked this conversation as resolved.
Show resolved Hide resolved
```bash
OSMOSIS_KEYRING_PATH=/root/.osmosisd/keyring-test
OSMOSIS_KEYRING_PASSWORD=test
OSMOSIS_KEYRING_KEY_NAME=local.info
```
- Here, the key is named `local` and the keyring path is in the default `osmosisd` home directory.

To create your key:
```bash
osmosisd keys add local --keyring-backend test --recover

# Enter your mnemonic

# Confirm the key is created
osmosisd keys list --keyring-backend test
```

Note that the test keyring is not a secure approach but we opted-in for simplicity and speed
of PoC implementation. In the future, this can be improved to support multiple backends.

## Starting (via docker compose)

1. Ensure that the "Configuration" section is complete.
2. From project root, `cd` into `ingest/usecase/plugins/orderbook/claimbot`
3. Update `.env` with your environment variables.
4. Run `make orderbook-claimbot-start`
5. Run `osmosisd status` to check that the node is running and caught up to tip.
6. Curl `/healthcheck` to check that SQS is running `curl http://localhost:9092/healthcheck`
62 changes: 62 additions & 0 deletions ingest/usecase/plugins/orderbook/claimbot/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package claimbot

import (
"github.com/osmosis-labs/sqs/delivery/grpc"
authtypes "github.com/osmosis-labs/sqs/domain/cosmos/auth/types"
sqstx "github.com/osmosis-labs/sqs/domain/cosmos/tx"
"github.com/osmosis-labs/sqs/domain/keyring"
"github.com/osmosis-labs/sqs/domain/mvc"
orderbookdomain "github.com/osmosis-labs/sqs/domain/orderbook"
orderbookgrpcclientdomain "github.com/osmosis-labs/sqs/domain/orderbook/grpcclient"
"github.com/osmosis-labs/sqs/log"

txfeestypes "github.com/osmosis-labs/osmosis/v26/x/txfees/types"

txtypes "github.com/cosmos/cosmos-sdk/types/tx"
)

// Config is the configuration for the claimbot plugin
type Config struct {
Keyring keyring.Keyring
PoolsUseCase mvc.PoolsUsecase
OrderbookUsecase mvc.OrderBookUsecase
OrderbookRepository orderbookdomain.OrderBookRepository
deividaspetraitis marked this conversation as resolved.
Show resolved Hide resolved
OrderBookClient orderbookgrpcclientdomain.OrderBookClient
AccountQueryClient authtypes.QueryClient
TxfeesClient txfeestypes.QueryClient
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider abstracting all of the chain clients behind a struct

GasCalculator sqstx.GasCalculator
TxServiceClient txtypes.ServiceClient
ChainID string
Logger log.Logger
}
deividaspetraitis marked this conversation as resolved.
Show resolved Hide resolved

// NewConfig creates a new Config instance.
func NewConfig(
keyring keyring.Keyring,
orderbookusecase mvc.OrderBookUsecase,
poolsUseCase mvc.PoolsUsecase,
orderbookRepository orderbookdomain.OrderBookRepository,
orderBookClient orderbookgrpcclientdomain.OrderBookClient,
logger log.Logger,
chainGRPCGatewayEndpoint string,
chainID string,
) (*Config, error) {
grpcClient, err := grpc.NewClient(chainGRPCGatewayEndpoint)
if err != nil {
return nil, err
}

return &Config{
Keyring: keyring,
PoolsUseCase: poolsUseCase,
OrderbookUsecase: orderbookusecase,
OrderbookRepository: orderbookRepository,
OrderBookClient: orderBookClient,
AccountQueryClient: authtypes.NewQueryClient(grpcClient),
TxfeesClient: txfeestypes.NewQueryClient(grpcClient),
GasCalculator: sqstx.NewGasCalculator(grpcClient),
TxServiceClient: txtypes.NewServiceClient(grpcClient),
Logger: logger,
ChainID: chainID,
}, nil
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add input validation and consider connection management.

The constructor could be improved in several ways:

  1. Add validation for required parameters (e.g., non-nil checks)
  2. Consider connection pooling or separate clients for different services
  3. Add cleanup mechanism for the gRPC client

Consider adding validation and cleanup:

 func NewConfig(
     keyring keyring.Keyring,
     orderbookusecase mvc.OrderBookUsecase,
     poolsUseCase mvc.PoolsUsecase,
     orderbookRepository orderbookdomain.OrderBookRepository,
     orderBookClient orderbookgrpcclientdomain.OrderBookClient,
     logger log.Logger,
     chainGRPCGatewayEndpoint string,
     chainID string,
 ) (*Config, error) {
+    if keyring == nil || orderbookusecase == nil || poolsUseCase == nil ||
+        orderbookRepository == nil || orderBookClient == nil || logger == nil {
+        return nil, fmt.Errorf("all dependencies must be non-nil")
+    }
+    if chainGRPCGatewayEndpoint == "" || chainID == "" {
+        return nil, fmt.Errorf("chainGRPCGatewayEndpoint and chainID must not be empty")
+    }
+
     grpcClient, err := grpc.NewClient(chainGRPCGatewayEndpoint)
     if err != nil {
         return nil, err
     }
+
+    cfg := &Config{
+        Keyring:             keyring,
+        PoolsUseCase:        poolsUseCase,
+        OrderbookUsecase:    orderbookusecase,
+        OrderbookRepository: orderbookRepository,
+        OrderBookClient:     orderBookClient,
+        AccountQueryClient:  authtypes.NewQueryClient(grpcClient),
+        TxfeesClient:        txfeestypes.NewQueryClient(grpcClient),
+        GasCalculator:       sqstx.NewGasCalculator(grpcClient),
+        TxServiceClient:     txtypes.NewServiceClient(grpcClient),
+        Logger:              logger,
+        ChainID:            chainID,
+        MinimumFillPercentage: 0.98, // Default to 98% as mentioned in PR objectives
+    }
+
+    // Add cleanup method
+    runtime.SetFinalizer(cfg, func(c *Config) {
+        if conn, ok := grpcClient.(*grpc.ClientConn); ok {
+            _ = conn.Close()
+        }
+    })
+
-    return &Config{
-        Keyring:             keyring,
-        PoolsUseCase:        poolsUseCase,
-        OrderbookUsecase:    orderbookusecase,
-        OrderbookRepository: orderbookRepository,
-        OrderBookClient:     orderBookClient,
-        AccountQueryClient:  authtypes.NewQueryClient(grpcClient),
-        TxfeesClient:        txfeestypes.NewQueryClient(grpcClient),
-        GasCalculator:       sqstx.NewGasCalculator(grpcClient),
-        TxServiceClient:     txtypes.NewServiceClient(grpcClient),
-        Logger:              logger,
-        ChainID:             chainID,
-    }, nil
+    return cfg, nil

Committable suggestion was skipped due to low confidence.

Loading
Loading