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

init services/explorer #174

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@
[submodule "packages/contracts/lib/forge-std"]
path = packages/contracts/lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "services/explorer/external/contracts/synapse-contracts"]
path = services/explorer/external/contracts/synapse-contracts
url = https://github.com/synapsecns/synapse-contracts
2 changes: 2 additions & 0 deletions services/explorer/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
external/synapse-contracts/
Copy link
Contributor

Choose a reason for hiding this comment

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

oh - I see. I'm guessing the symbolic link loops exists b/c you're ignoring the submodule here so on a fresh clone, the gitmodule doesn't actually get put here. Would remove this - gitmodules won't commit the history for this submodule anyway

sandbox/
36 changes: 36 additions & 0 deletions services/explorer/.goreleaser.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
project_name: explorer

monorepo:
tag_prefix: services/explorer/
dir: services/explorer/

builds:
- skip: true

# add a source archive at release time
source:
enabled: true

# Archives
archives:
- format: tar.gz
wrap_in_directory: true
format_overrides:
- goos: windows
format: zip
name_template: '{{.ProjectName}}-{{.Version}}_{{.Os}}_{{.Arch}}'
replacements:
amd64: x86_64
arm64: ARM64
darwin: macOS
linux: Linux
windows: Windows
files:
- README.md

checksum:
name_template: checksums.txt

# Add a changelog
changelog:
sort: asc
1 change: 1 addition & 0 deletions services/explorer/Makefile
4 changes: 4 additions & 0 deletions services/explorer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Explorer

See [#167](https://github.com/synapsecns/sanguine/issues/167) to learn more.

28 changes: 28 additions & 0 deletions services/explorer/cmd/cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package cmd

import (
// used to embed markdown.
_ "embed"
"github.com/synapsecns/sanguine/core/commandline"
"github.com/urfave/cli/v2"
)

// Start starts the command line.
func Start(args []string) {
app := cli.NewApp()
app.Name = "explorer"
app.Description = "An indexer + API serving platform analytics"
app.Usage = "explorer help"
app.EnableBashCompletion = true

// commands
app.Commands = cli.Commands{infoCommand, backfillCommand, serverCommand}
Copy link
Contributor

Choose a reason for hiding this comment

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

nuke backfill/server- they don't exist yet

shellCommand := commandline.GenerateShellCommand(app.Commands)
app.Commands = append(app.Commands, shellCommand)
app.Action = shellCommand.Action

err := app.Run(args)
if err != nil {
panic(err)
}
}
22 changes: 22 additions & 0 deletions services/explorer/cmd/cmd.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Explorer

Explorer is an indexer and API serving platform analytics.

`./explorer placeholder`: A placeholder

## Directory Structure

<pre>
explorer
├── <a href="./cmd">cmd</a>: CLI
├── <a href="./config">config</a>: Config for the Explorer
├── <a href="./db">db</a>: Currently holds schema for db
├── <a href="./contracts">contracts</a>: Holds contracts generated via abigen
│ ├── <a href="./contracts/bridge">bridge</a>: SynapseBridge contract and more
│ ├── <a href="./contracts/bridgeconfig">bridgeconfig</a>: BridgeConfig contract and more
│ └── <a href="./contracts/swap">swap</a>: SwapFlashLoan contract and more
├── <a href="./internal">internal</a>: Workaround go-generate error, requiring file
└── <a href="./external">external</a>: External packages
└── └── <a href="./external/flattened-contracts">flattened-contracts</a>: Holds flattened contracts used by the /contracts generate.go files

</pre>
47 changes: 47 additions & 0 deletions services/explorer/cmd/commands.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package cmd

import (
// used to embed markdown.
_ "embed"
"fmt"
"os"

"github.com/hashicorp/consul/sdk/freeport"

markdown "github.com/MichaelMure/go-term-markdown"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/jftuga/termsize"
"github.com/synapsecns/sanguine/core/dbcommon"
"github.com/urfave/cli/v2"
)

//go:embed cmd.md
var help string

// infoCommand references the help info from the cmd.md file and presents it.
var infoCommand = &cli.Command{
Name: "info",
Description: "learn how to use explorer cli",
Action: func(c *cli.Context) error {
fmt.Println(string(markdown.Render(help, termsize.Width(), 6)))
return nil
},
}


//placeholder
var placeholderCommand = &cli.Command{
Name: "gm",
Description: "gm",
Usage: "gm",
Action: func(c *cli.Context) error {
fmt.Println("gm")
}
}

func init() {
ports := freeport.Get(1)
if len(ports) > 0 {
portFlag.Value = uint(ports[0])
}
}
2 changes: 2 additions & 0 deletions services/explorer/cmd/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Package cmd: CLI infra
package cmd
1 change: 1 addition & 0 deletions services/explorer/cmd/generate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package cmd
47 changes: 47 additions & 0 deletions services/explorer/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//parses the input config.yaml file
package config

import (
"fmt"

"github.com/davecgh/go-spew/spew"
"github.com/jftuga/ellipsis"
"gopkg.in/yaml.v3"
)

// Config holds the config for the chain.
type Config struct {
// chainID -> chainConfig
Chains map[uint32]ChainConfig `yaml:"chains"`
// Port is the port
Port uint16 `yaml:"port,omitempty"`
// RefreshInterval is the refresh interval of rpc latency
// expressed in seconds
RefreshInterval int `yaml:"refresh_interval,omitempty"`
}

// ChainConfig is the config for a single chain.
type ChainConfig struct {
// RPCS is a list of rpcs to use
RPCs []string `yaml:"rpcs"`
// Checks is how many rpcs must return the same result for it to be used. This does not apply to height/status based methods
Checks uint16 `yaml:"confirmations,omitempty"`
}

// UnmarshallConfig unmarshalls a config.
func UnmarshallConfig(input []byte) (cfg Config, err error) {
err = yaml.Unmarshal(input, &cfg)
if err != nil {
return Config{}, fmt.Errorf("could not unmarshall config %s: %w", ellipsis.Shorten(string(input), 30), err)
}
return cfg, nil
}

// Marshall a config to yaml.
func (c Config) Marshall() ([]byte, error) {
output, err := yaml.Marshal(c)
if err != nil {
return nil, fmt.Errorf("could not unmarshall config %s: %w", ellipsis.Shorten(spew.Sdump(c), 20), err)
}
return output, nil
}
75 changes: 75 additions & 0 deletions services/explorer/config/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package config_test

import (
"github.com/brianvoe/gofakeit/v6"
. "github.com/stretchr/testify/assert"
"github.com/synapsecns/sanguine/services/omnirpc/config"
Copy link
Contributor

Choose a reason for hiding this comment

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

should be testing explorer:

"github.com/synapsecns/sanguine/services/explorer/config"

"golang.org/x/exp/slices"
"testing"
)

func TestConfig(t *testing.T) {
testConfig := config.Config{
Chains: map[uint32]config.ChainConfig{
1: {
RPCs: []string{gofakeit.URL(), gofakeit.URL(), gofakeit.URL()},
Checks: gofakeit.Uint16(),
},
2: {
RPCs: []string{gofakeit.URL(), gofakeit.URL(), gofakeit.URL()},
Checks: gofakeit.Uint16(),
},
},
Port: gofakeit.Uint16(),
RefreshInterval: gofakeit.Second(),
}

out, err := testConfig.Marshall()
Nil(t, err)

unmarshalledConfig, err := config.UnmarshallConfig(out)
Nil(t, err)

Equal(t, testConfig, unmarshalledConfig)
}

func TestUnmarshallMarshall(t *testing.T) {
rpcConf, err := config.UnmarshallConfig([]byte(testYaml))
Nil(t, err)

True(t, slices.Contains(rpcConf.Chains[1].RPCs, "https://api.mycryptoapi.com/eth"))
True(t, slices.Contains(rpcConf.Chains[1].RPCs, "https://api.bitstack.com/v1/wNFxbiJyQsSeLrX8RRCHi7NpRxrlErZk/DjShIqLishPCTB9HiMkPHXjUM9CNM9Na/ETH/mainnet"))
True(t, slices.Contains(rpcConf.Chains[2].RPCs, "https://node.eggs.cool"))
}

const testYaml = `
chains:
0:
rpcs:
- https://rpc.kardiachain.io/
confirmations: 1
1:
rpcs:
- https://api.mycryptoapi.com/eth
- https://rpc.flashbots.net/
- https://eth-mainnet.gateway.pokt.network/v1/5f3453978e354ab992c4da79
- https://cloudflare-eth.com/
- https://mainnet-nethermind.blockscout.com/
- https://nodes.mewapi.io/rpc/eth
- https://main-rpc.linkpool.io/
- https://mainnet.eth.cloud.ava.do/
- https://ethereumnodelight.app.runonflux.io
- https://rpc.ankr.com/eth
- https://eth-rpc.gateway.pokt.network
- https://main-light.eth.linkpool.io
- https://eth-mainnet.public.blastapi.io
- http://18.211.207.34:8545
- https://eth-mainnet.nodereal.io/v1/1659dfb40aa24bbb8153a677b98064d7
- wss://eth-mainnet.nodereal.io/ws/v1/1659dfb40aa24bbb8153a677b98064d7
- https://api.bitstack.com/v1/wNFxbiJyQsSeLrX8RRCHi7NpRxrlErZk/DjShIqLishPCTB9HiMkPHXjUM9CNM9Na/ETH/mainnet
confirmations: 1
2:
rpcs:
- https://node.eggs.cool
- https://node.expanse.tech
confirmations: 1`
2 changes: 2 additions & 0 deletions services/explorer/config/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Package config: enables .yaml files to be passed and parsed to specify indexer behavior
package config
Loading