synapsecns/sanguine

View on GitHub
services/omnirpc/cmd/commands.go

Summary

Maintainability
A
0 mins
Test Coverage
package cmd

import (
    "fmt"
    "os"
    "time"

    "github.com/synapsecns/sanguine/core/metrics"
    "github.com/synapsecns/sanguine/services/omnirpc/modules/confirmedtofinalized"
    "github.com/synapsecns/sanguine/services/omnirpc/modules/harmonyproxy"
    "github.com/synapsecns/sanguine/services/omnirpc/modules/receiptsbackup"

    "github.com/phayes/freeport"
    "github.com/synapsecns/sanguine/core"
    rpcConfig "github.com/synapsecns/sanguine/services/omnirpc/config"
    "github.com/synapsecns/sanguine/services/omnirpc/debug"
    "github.com/synapsecns/sanguine/services/omnirpc/proxy"
    "github.com/synapsecns/sanguine/services/omnirpc/rpcinfo"
    "github.com/urfave/cli/v2"
)

var latencyCommand = &cli.Command{
    Name:  "check-latency",
    Usage: "checks latency for all rpc endpoints known for a chain id",
    Flags: []cli.Flag{chainIDFlag},
    Action: func(c *cli.Context) error {
        rConfig, err := rpcConfig.GetPublicRPCConfig()
        if err != nil {
            return fmt.Errorf("could not get rpc map: %w", err)
        }

        chainConfig, ok := rConfig.Chains[uint32(c.Int(chainIDFlag.Name))]
        if !ok {
            return fmt.Errorf("could not get chain config for chain %d", c.Int(chainIDFlag.Name))
        }

        res := rpcinfo.GetRPCLatency(c.Context, time.Second*5, chainConfig.RPCs, metrics.Get())
        DisplayLatency(res)

        return nil
    },
}

var chainListCommand = &cli.Command{
    Name:  "chainlist-server",
    Usage: "runs a chainlist proxy server",
    Flags: []cli.Flag{portFlag},
    Action: func(c *cli.Context) error {
        // Create a large heap allocation of 10 GiB
        // See: https://blog.twitch.tv/en/2019/04/10/go-memory-ballast-how-i-learnt-to-stop-worrying-and-love-the-heap/
        _ = make([]byte, 10<<30)

        rConfig, err := rpcConfig.GetPublicRPCConfig()
        if err != nil {
            return fmt.Errorf("could not get rpc map: %w", err)
        }

        if c.Int(portFlag.Name) != 0 {
            rConfig.Port = uint16(c.Int(portFlag.Name))
        }

        if rConfig.Port == 0 {
            rConfig.Port = uint16(freeport.GetPort())
        }

        server := proxy.NewProxy(rConfig, metrics.Get())

        server.Run(c.Context)

        return nil
    },
}

var publicConfigCommand = &cli.Command{
    Name:  "public-config",
    Usage: "output a public config file from chainlist.org",
    Flags: []cli.Flag{outputFlag},
    Action: func(c *cli.Context) error {
        rConfig, err := rpcConfig.GetPublicRPCConfig()
        if err != nil {
            return fmt.Errorf("could not get rpc map: %w", err)
        }

        output, err := rConfig.Marshall()
        if err != nil {
            return fmt.Errorf("could not get rpc map: %w", err)
        }

        outputConfig, err := os.Create(core.ExpandOrReturnPath(c.String(outputFlag.Name)))
        if err != nil {
            return fmt.Errorf("could not create config file: %w", err)
        }

        defer func() {
            _ = outputConfig.Close()
        }()

        _, err = outputConfig.Write(output)
        if err != nil {
            return fmt.Errorf("could not write to file: %w", err)
        }

        fmt.Printf("written to %s \n", c.String(outputFlag.Name))
        return nil
    },
}

var serverCommand = &cli.Command{
    Name:  "server",
    Usage: "run a server from a config",
    Flags: []cli.Flag{
        configFlag,
        portFlag,
    },
    Action: func(c *cli.Context) error {
        // Create a large heap allocation of 10 GiB
        // See: https://blog.twitch.tv/en/2019/04/10/go-memory-ballast-how-i-learnt-to-stop-worrying-and-love-the-heap/
        _ = make([]byte, 10<<30)

        fileContents, err := os.ReadFile(core.ExpandOrReturnPath(c.String(configFlag.Name)))
        if err != nil {
            return fmt.Errorf("could not read file %s: %w", c.String(configFlag.Name), err)
        }
        rConfig, err := rpcConfig.UnmarshallConfig(fileContents)
        if err != nil {
            return fmt.Errorf("could not unmarshall config: %w", err)
        }

        if c.Int(portFlag.Name) != 0 {
            rConfig.Port = uint16(c.Int(portFlag.Name))
        }

        if rConfig.Port == 0 {
            rConfig.Port = uint16(freeport.GetPort())
        }

        server := proxy.NewProxy(rConfig, metrics.Get())

        server.Run(c.Context)

        return nil
    },
}

var debugResponse = &cli.Command{
    Name:  "debug-response",
    Usage: "used for debugging responses and finding diff between rpcs",
    Flags: []cli.Flag{
        fileFlag,
    },
    Action: func(c *cli.Context) error {
        diffFile, err := os.ReadFile(c.String(fileFlag.Name))
        if err != nil {
            return fmt.Errorf("could not read file: %w", err)
        }
        //nolint:wrapcheck
        return debug.HashDiff(diffFile)
    },
}

// latestRewrite rewrites latest block numbers for a single rpc url.
var latestRewrite = &cli.Command{
    Name:  "latest-rewrite",
    Usage: "A simple rpc proxy for one-off integration tests. Rewrites block queries that use \"latest\" to \"finalized\"",
    Flags: []cli.Flag{
        rpcFlag,
        portFlag,
        maxSubmitAhead,
        chainIDFlag,
    },
    Action: func(c *cli.Context) error {
        simpleProxy := confirmedtofinalized.NewProxy(c.String(rpcFlag.Name), metrics.Get(), c.Int(portFlag.Name), c.Int(maxSubmitAhead.Name), c.Int(chainIDFlag.Name))

        err := simpleProxy.Run(c.Context)
        if err != nil {
            return fmt.Errorf("return err: %w", err)
        }
        return nil
    },
}

var harmonyProxy = &cli.Command{
    Name:  "harmony-confirm",
    Usage: "An experimental harmony confirmation client",
    Flags: []cli.Flag{
        rpcFlag,
        portFlag,
    },
    Action: func(c *cli.Context) error {
        simpleProxy := harmonyproxy.NewHarmonyProxy(c.String(rpcFlag.Name), metrics.Get(), c.Int(portFlag.Name))

        err := simpleProxy.Run(c.Context)
        if err != nil {
            return fmt.Errorf("return err: %w", err)
        }
        return nil
    },
}

var receiptsProxy = &cli.Command{
    Name:  "receipts-backup",
    Usage: "A rpc proxy for using backup RPC with hanging receipt requests",
    Flags: []cli.Flag{
        rpcFlag,
        backupRPCFlag,
        portFlag,
        chainIDFlag,
        recieptsTimeoutFlag,
    },
    Action: func(c *cli.Context) error {
        simpleProxy := receiptsbackup.NewProxy(c.String(rpcFlag.Name), c.String(backupRPCFlag.Name), c.Duration(recieptsTimeoutFlag.Name), metrics.Get(), c.Int(portFlag.Name), c.Int(chainIDFlag.Name))

        err := simpleProxy.Run(c.Context)
        if err != nil {
            return fmt.Errorf("return err: %w", err)
        }
        return nil
    },
}