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

fix: http response field parsing #52

Merged
merged 4 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
27 changes: 13 additions & 14 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ var initCmd = &cobra.Command{
log.Fatalf("failed to unmarshal config: %v", err)
}

// if bot key dir doesn't exist, create it
if _, err := os.Stat(cfg.Bots.KeyringDir); os.IsNotExist(err) {
if err := os.MkdirAll(cfg.Bots.KeyringDir, 0o755); err != nil {
log.Fatalf("failed to create bot key directory: %v", err)
// if fulfiller key dir doesn't exist, create it
if _, err := os.Stat(cfg.Fulfillers.KeyringDir); os.IsNotExist(err) {
if err := os.MkdirAll(cfg.Fulfillers.KeyringDir, 0o755); err != nil {
log.Fatalf("failed to create fulfiller key directory: %v", err)
}
}

Expand Down Expand Up @@ -94,8 +94,8 @@ var startCmd = &cobra.Command{
log.Fatalf("failed to create order client: %v", err)
}

if cfg.Bots.NumberOfBots == 0 {
log.Println("no bots to start")
if cfg.Fulfillers.Scale == 0 {
log.Println("no fulfillers to start")
return
}

Expand Down Expand Up @@ -125,11 +125,11 @@ func buildLogger(logLevel string) (*zap.Logger, error) {

var scaleCmd = &cobra.Command{
Use: "scale [count]",
Short: "scale bot count",
Long: `scale the number of bot accounts that fulfill the eibc orders`,
Short: "scale fulfiller count",
Long: `scale the number of accounts that fulfill demand orders`,
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
newBotCount, err := strconv.Atoi(args[0])
newFulfillerCount, err := strconv.Atoi(args[0])
if err != nil {
return
}
Expand All @@ -148,21 +148,21 @@ var scaleCmd = &cobra.Command{
return
}

err = utils.UpdateViperConfig("bots.number_of_bots", newBotCount, viper.ConfigFileUsed())
err = utils.UpdateViperConfig("fulfillers.scale", newFulfillerCount, viper.ConfigFileUsed())
if err != nil {
return
}

fmt.Printf(
"bot count successfully scaled to %d, please restart the eibc process if it's running\n",
newBotCount,
"fulfiller count successfully scaled to %d, please restart the eibc process if it's running\n",
newFulfillerCount,
)
},
}

var versionCmd = &cobra.Command{
Use: "version",
Short: "Print the version of roller",
Short: "Print the version of eibc-client",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println(version.BuildVersion)
},
Expand All @@ -173,7 +173,6 @@ func init() {
RootCmd.AddCommand(initCmd)
RootCmd.AddCommand(startCmd)
RootCmd.AddCommand(scaleCmd)

RootCmd.AddCommand(versionCmd)

cobra.OnInitialize(config.InitConfig)
Expand Down
22 changes: 11 additions & 11 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type Config struct {
Rollapps map[string]RollappConfig `mapstructure:"rollapps"`

Operator OperatorConfig `mapstructure:"operator"`
Bots BotConfig `mapstructure:"bots"`
Fulfillers FulfillerConfig `mapstructure:"fulfillers"`
Validation ValidationConfig `mapstructure:"validation"`

LogLevel string `mapstructure:"log_level"`
Expand All @@ -34,13 +34,13 @@ type GasConfig struct {
Fees string `mapstructure:"fees"`
}

type BotConfig struct {
NumberOfBots int `mapstructure:"number_of_bots"`
type FulfillerConfig struct {
Scale int `mapstructure:"scale"`
OperatorAddress string `mapstructure:"operator_address"`
PolicyAddress string `mapstructure:"policy_address"`
KeyringBackend cosmosaccount.KeyringBackend `mapstructure:"keyring_backend"`
KeyringDir string `mapstructure:"keyring_dir"`
MaxOrdersPerTx int `mapstructure:"max_orders_per_tx"`
BatchSize int `mapstructure:"batch_size"`
}

type OperatorConfig struct {
Expand Down Expand Up @@ -70,11 +70,11 @@ const (
defaultGasFees = "3000000000000000" + defaultHubDenom
testKeyringBackend = "test"

BotNamePrefix = "bot-"
FulfillerNamePrefix = "bot-"
defaultOperatorAccountName = "client"
defaultOperatorGroupID = 1
defaultOperatorMinFeeShare = 0.1
defaultNumberOfBots = 30
defaultFulfillerScale = 30
NewOrderBufferSize = 100
defaultMaxOrdersPerTx = 10
defaultOrderRefreshInterval = 30 * time.Second
Expand Down Expand Up @@ -118,11 +118,11 @@ func InitConfig() {
viper.SetDefault("operator.group_id", defaultOperatorGroupID)
viper.SetDefault("operator.min_fee_share", defaultOperatorMinFeeShare)

viper.SetDefault("bots.keyring_backend", testKeyringBackend)
viper.SetDefault("bots.keyring_dir", defaultHomeDir)
viper.SetDefault("bots.number_of_bots", defaultNumberOfBots)
viper.SetDefault("bots.max_orders_per_tx", defaultMaxOrdersPerTx)
viper.SetDefault("bots.policy_address", "<your-policy-address>")
viper.SetDefault("fulfillers.keyring_backend", testKeyringBackend)
viper.SetDefault("fulfillers.keyring_dir", defaultHomeDir)
viper.SetDefault("fulfillers.scale", defaultFulfillerScale)
viper.SetDefault("fulfillers.max_orders_per_tx", defaultMaxOrdersPerTx)
viper.SetDefault("fulfillers.policy_address", "<your-policy-address>")

viper.SetDefault("validation.fallback_level", defaultValidationFallbackLevel)
viper.SetDefault("validation.validation_wait_time", defaultValidationWaitTime)
Expand Down
45 changes: 22 additions & 23 deletions eibc/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,11 @@ import (
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/cosmos/cosmos-sdk/x/feegrant"
"github.com/cosmos/cosmos-sdk/x/group"
"github.com/dymensionxyz/cosmosclient/cosmosclient"
"github.com/google/uuid"
"go.uber.org/zap"
"google.golang.org/grpc/status"

"github.com/dymensionxyz/cosmosclient/cosmosclient"

"github.com/dymensionxyz/eibc-client/config"
)

Expand All @@ -45,15 +44,15 @@ func addAccount(client cosmosclient.Client, name string) (string, error) {
return address.String(), nil
}

func getBotAccounts(client cosmosclient.Client) (accs []account, err error) {
func getFulfillerAccounts(client cosmosclient.Client) (accs []account, err error) {
var accounts []account
accounts, err = listAccounts(client)
if err != nil {
return
}

for _, acc := range accounts {
if !strings.HasPrefix(acc.Name, config.BotNamePrefix) {
if !strings.HasPrefix(acc.Name, config.FulfillerNamePrefix) {
continue
}
accs = append(accs, acc)
Expand Down Expand Up @@ -83,15 +82,15 @@ func listAccounts(client cosmosclient.Client) ([]account, error) {
return accounts, nil
}

func createBotAccounts(client cosmosclient.Client, count int) (accs []account, err error) {
func createFulfillerAccounts(client cosmosclient.Client, count int) (accs []account, err error) {
for range count {
botName := fmt.Sprintf("%s%s", config.BotNamePrefix, uuid.New().String()[0:5])
addr, err := addAccount(client, botName)
fulfillerName := fmt.Sprintf("%s%s", config.FulfillerNamePrefix, uuid.New().String()[0:5])
addr, err := addAccount(client, fulfillerName)
if err != nil {
return nil, fmt.Errorf("failed to create account: %w", err)
}
acc := account{
Name: botName,
Name: fulfillerName,
Address: addr,
}
accs = append(accs, acc)
Expand Down Expand Up @@ -155,38 +154,38 @@ func waitForTx(client cosmosClient, txHash string) (*tx.GetTxResponse, error) {
}
}

func addBotAccounts(numBots int, clientConfig config.ClientConfig, logger *zap.Logger) ([]account, error) {
cosmosClient, err := cosmosclient.New(config.GetCosmosClientOptions(clientConfig)...)
func addFulfillerAccounts(scale int, clientConfig config.ClientConfig, logger *zap.Logger) ([]account, error) {
cClient, err := cosmosclient.New(config.GetCosmosClientOptions(clientConfig)...)
if err != nil {
return nil, fmt.Errorf("failed to create cosmos client for bot: %w", err)
return nil, fmt.Errorf("failed to create cosmos client for fulfiller: %w", err)
}

accs, err := getBotAccounts(cosmosClient)
accs, err := getFulfillerAccounts(cClient)
if err != nil {
return nil, fmt.Errorf("failed to get bot accounts: %w", err)
return nil, fmt.Errorf("failed to get fulfiller accounts: %w", err)
}

numFoundBots := len(accs)
numFoundFulfillers := len(accs)

botsAccountsToCreate := max(0, numBots) - numFoundBots
if botsAccountsToCreate > 0 {
logger.Info("creating bot accounts", zap.Int("accounts", botsAccountsToCreate))
fulfillersAccountsToCreate := max(0, scale) - numFoundFulfillers
if fulfillersAccountsToCreate > 0 {
logger.Info("creating fulfiller accounts", zap.Int("accounts", fulfillersAccountsToCreate))
}

newAccs, err := createBotAccounts(cosmosClient, botsAccountsToCreate)
newAccs, err := createFulfillerAccounts(cClient, fulfillersAccountsToCreate)
if err != nil {
return nil, fmt.Errorf("failed to create bot accounts: %w", err)
return nil, fmt.Errorf("failed to create fulfiller accounts: %w", err)
}

accs = slices.Concat(accs, newAccs)

if len(accs) < numBots {
return nil, fmt.Errorf("expected %d bot accounts, got %d", numBots, len(accs))
if len(accs) < scale {
return nil, fmt.Errorf("expected %d fulfiller accounts, got %d", scale, len(accs))
}
return accs, nil
}

func addBotsToGroup(operatorName, operatorAddress string, groupID int, client cosmosclient.Client, newAccs []account) error {
func addFulfillersToGroup(operatorName, operatorAddress string, groupID int, client cosmosclient.Client, newAccs []account) error {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

Expand Down Expand Up @@ -311,7 +310,7 @@ func hasFeeGranted(client cosmosClient, granterAddr, granteeAddr string) (bool,
return false, nil
}

func addFeeGrantToBot(client cosmosClient, fromName string, granterAddr sdk.AccAddress, granteeAddr ...sdk.AccAddress) error {
func addFeeGrantToFulfiller(client cosmosClient, fromName string, granterAddr sdk.AccAddress, granteeAddr ...sdk.AccAddress) error {
msgs := make([]sdk.Msg, 0, len(granteeAddr))
for _, addr := range granteeAddr {
msg, err := feegrant.NewMsgGrantAllowance(
Expand Down
84 changes: 80 additions & 4 deletions eibc/lp.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@ package eibc

import (
"context"
"fmt"
"sync"
"time"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/cosmos/cosmos-sdk/x/authz"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/cosmos/gogoproto/proto"
"go.uber.org/zap"

"github.com/dymensionxyz/eibc-client/types"
)

type lp struct {
Expand All @@ -31,6 +36,12 @@ func (l *lp) hasBalance(amount sdk.Coins) bool {
return l.spendableBalance().IsAllGTE(amount)
}

func (l *lp) getBalance() sdk.Coins {
l.bmu.Lock()
defer l.bmu.Unlock()
return l.balance
}

func (l *lp) setBalance(balance sdk.Coins) {
l.bmu.Lock()
defer l.bmu.Unlock()
Expand All @@ -57,6 +68,7 @@ func (l *lp) releaseFunds(amount sdk.Coins) {
func (l *lp) debitReservedFunds(amount sdk.Coins) {
l.bmu.Lock()
defer l.bmu.Unlock()

var fail bool
l.reservedFunds, fail = l.reservedFunds.SafeSub(amount...)
if fail {
Expand All @@ -76,11 +88,75 @@ func (l *lp) spendableBalance() sdk.Coins {
return l.balance.Sub(l.reservedFunds...)
}

func (or *orderTracker) loadLPs(ctx context.Context) error {
grants, err := or.getLPGrants(ctx, &authz.QueryGranteeGrantsRequest{
Grantee: or.policyAddress,
})
if err != nil {
return fmt.Errorf("failed to get LP grants: %w", err)
}

or.lpmu.Lock()
defer or.lpmu.Unlock()

for _, grant := range grants.Grants {
if grant.Authorization == nil {
continue
}

g := new(types.FulfillOrderAuthorization)
if err = proto.Unmarshal(grant.Authorization.Value, g); err != nil {
return fmt.Errorf("failed to unmarshal grant: %w", err)
}

resp, err := or.getBalances(ctx, &banktypes.QuerySpendableBalancesRequest{
Address: grant.Granter,
})
if err != nil {
return fmt.Errorf("failed to get LP balances: %w", err)
}

lp := &lp{
address: grant.Granter,
rollapps: make(map[string]rollappCriteria),
balance: resp.Balances,
}

for _, rollapp := range g.Rollapps {
// check the operator fee is the minimum for what the operator wants
if rollapp.OperatorFeeShare.Dec.LT(or.minOperatorFeeShare) {
continue
}

denoms := make(map[string]bool)
for _, denom := range rollapp.Denoms {
denoms[denom] = true
}
lp.rollapps[rollapp.RollappId] = rollappCriteria{
rollappID: rollapp.RollappId,
denoms: denoms,
maxPrice: rollapp.MaxPrice,
minFeePercentage: rollapp.MinLpFeePercentage.Dec,
operatorFeeShare: rollapp.OperatorFeeShare.Dec,
settlementValidated: rollapp.SettlementValidated,
}
}

if len(lp.rollapps) == 0 {
continue
}

or.lps[grant.Granter] = lp
}

return nil
}

func (or *orderTracker) releaseAllReservedOrdersFunds(demandOrder ...*demandOrder) {
for _, order := range demandOrder {
or.lpmu.Lock()
if lp, ok := or.lps[order.lpAddress]; ok {
lp.releaseFunds(order.amount)
lp.releaseFunds(order.price)
}
or.lpmu.Unlock()
}
Expand All @@ -90,7 +166,7 @@ func (or *orderTracker) debitAllReservedOrdersFunds(demandOrder ...*demandOrder)
for _, order := range demandOrder {
or.lpmu.Lock()
if lp, ok := or.lps[order.lpAddress]; ok {
lp.debitReservedFunds(order.amount)
lp.debitReservedFunds(order.price)
}
or.lpmu.Unlock()
}
Expand All @@ -110,7 +186,7 @@ func (or *orderTracker) balanceRefresher(ctx context.Context) {

func (or *orderTracker) refreshBalances(ctx context.Context) {
for _, lp := range or.lps {
resp, err := or.getBalances(ctx, &types.QuerySpendableBalancesRequest{
resp, err := or.getBalances(ctx, &banktypes.QuerySpendableBalancesRequest{
Address: lp.address,
})
if err != nil {
Expand Down
Loading
Loading