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

Support for OPStack #23

Merged
merged 21 commits into from
Apr 22, 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
5 changes: 5 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
.git*
.env*
Dockerfile
docker-bake.hcl
LICENSE
*.md
*.proto
readme/
tmp/
22 changes: 16 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,16 +115,13 @@ jobs:
uses: actions/checkout@v2

- name: Setup QEMU
id: qemu
uses: docker/setup-qemu-action@v1
with:
platforms: amd64,arm64
uses: docker/setup-qemu-action@v3

- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v3

- name: Login to GitHub Container Registry
uses: docker/login-action@v1
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
Expand All @@ -137,3 +134,16 @@ jobs:
platforms: linux/amd64,linux/arm64
push: true
tags: ghcr.io/${{ github.repository }}/verse-verifier:${{ github.ref_name }}

- name: Build and Push
uses: docker/bake-action@v4
env:
REGISTRY: ghcr.io
REPOSITORY: ${{ github.repository }}
GIT_COMMIT: ${{ github.sha }}
GIT_VERSION: ${{ github.ref_name }}
IMAGE_TAGS: ${{ github.ref_name }}
with:
files: docker-bake.hcl
set: '*.platform=linux/amd64,linux/arm64'
push: true
17 changes: 11 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# builder
FROM golang:1.18-alpine as builder
FROM golang:1.18.10-bullseye as builder

RUN apk add --no-cache gcc musl-dev linux-headers git
RUN apt update && apt install -y git ca-certificates

ADD . /build
WORKDIR /build
Expand All @@ -10,10 +10,15 @@ ENV CGO_ENABLED=1
RUN go build -a -o oasvlfy -tags netgo -installsuffix netgo --ldflags='-s -w -extldflags "-static"' -buildvcs=false

# runner
FROM alpine:3.17

RUN apk add --no-cache ca-certificates

FROM debian:11.9-slim
COPY --from=builder /build/oasvlfy /usr/local/bin/oasvlfy
COPY --from=builder /etc/ssl /etc/ssl
COPY --from=builder /usr/share/ca-certificates /usr/share/ca-certificates

ENTRYPOINT ["/usr/local/bin/oasvlfy"]

# Add some metadata labels to help programatic image consumption
ARG COMMIT=""
ARG VERSION=""

LABEL commit="$COMMIT" version="$VERSION"
3 changes: 2 additions & 1 deletion beacon/beacon_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/oasysgames/oasys-optimism-verifier/config"
"github.com/oasysgames/oasys-optimism-verifier/testhelper"
httphelper "github.com/oasysgames/oasys-optimism-verifier/testhelper/http"
"github.com/stretchr/testify/suite"
)

Expand All @@ -28,7 +29,7 @@ func (s *BeaconWorkerTestSuite) TestBeaconWorker() {
)

// setup test client
client := testhelper.NewTestHTTPClient(func(req *http.Request) *http.Response {
client := httphelper.NewTestHTTPClient(func(req *http.Request) *http.Response {
url = req.URL.String()
data, _ = io.ReadAll(req.Body)

Expand Down
196 changes: 196 additions & 0 deletions cmd/config_loader.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
package cmd

import (
"io/ioutil"
"strings"

"github.com/oasysgames/oasys-optimism-verifier/config"
"github.com/spf13/cobra"
)

const (
fileConfigFlag = "config"
)

type configLoader struct {
cmd *cobra.Command

// from file
fromFile string

// from cli
fromCli bool
cfg *config.Config
verse struct {
use bool
verse config.Verse
scc, l2oo string
}
verifier struct {
use bool
wallet config.Wallet
}
submitter struct {
use bool
wallet config.Wallet
targets []uint
}
}

type argConfigFlagGroup struct {
name string
flags map[string]func(name string)
}

func argConfigFlag[T any](
ptr *T,
flagSetFn func(ptr *T, name string, defVal T, help string),
help string,
) func(name string) {
return func(name string) {
flagSetFn(ptr, name, *ptr, help)
}
}

func mustNewConfigLoader(cmd *cobra.Command) *configLoader {
cfg := config.MustNewDefaultConfig()
opts := &configLoader{cmd: cmd, cfg: cfg}
f := cmd.PersistentFlags()

// add flag for load configuration from the file
f.StringVar(&opts.fromFile, fileConfigFlag, "", "Load config from the file")

// add flags for load configuration from command line arguments
argGroups := []*argConfigFlagGroup{
{
name: "",
flags: map[string]func(name string){
"cli": argConfigFlag(&opts.fromCli, f.BoolVar, "Load config from command line arguments"),
"datastore": argConfigFlag(&cfg.Datastore, f.StringVar, "Datastore directory path"),
"keystore": argConfigFlag(&cfg.Keystore, f.StringVar, "Private keys directory path"),
},
},
{
name: "hub",
flags: map[string]func(name string){
"chain_id": argConfigFlag(&cfg.HubLayer.ChainID, f.Uint64Var, "Chain ID of the Hub-Layer"),
"rpc": argConfigFlag(&cfg.HubLayer.RPC, f.StringVar, "RPC of the Hub-Layer(HTTP or WebSocket)"),
},
},
{
name: "p2p",
flags: map[string]func(name string){
"listens": argConfigFlag(&cfg.P2P.Listens, f.StringSliceVar, "libp2p multi-addresses to listen"),
"bootnodes": argConfigFlag(&cfg.P2P.Bootnodes, f.StringSliceVar, "Initial node list"),
"append_announce": argConfigFlag(&cfg.P2P.AppendAnnounce, f.StringSliceVar, "Additional multi-addresses to advertise"),
"no_announce": argConfigFlag(&cfg.P2P.NoAnnounce, f.StringSliceVar, "Multi-addresses not advertised"),
"connection_filter": argConfigFlag(&cfg.P2P.ConnectionFilter, f.StringSliceVar, "Multi-addresses that filter dial or receive connections"),
},
},
{
name: "verse",
flags: map[string]func(name string){
"": argConfigFlag(&opts.verse.use, f.BoolVar, "Use static verse setting"),
"chain_id": argConfigFlag(&opts.verse.verse.ChainID, f.Uint64Var, "Chain ID of the Verse-Layer"),
"rpc": argConfigFlag(&opts.verse.verse.RPC, f.StringVar, "RPC of the Verse-Layer(HTTP or WebSocket)"),
"scc": argConfigFlag(&opts.verse.scc, f.StringVar, "Address of the StateCommitmentChain"),
"l2oo": argConfigFlag(&opts.verse.l2oo, f.StringVar, "Address of the L2OutputOracle"),
"discovery": argConfigFlag(&cfg.VerseLayer.Discovery.Endpoint, f.StringVar, "URL of the Verse-Layer list json"),
},
},
{
name: "verifier",
flags: map[string]func(name string){
"": argConfigFlag(&opts.verifier.use, f.BoolVar, "Enable the verifier feature"),
"wallet.address": argConfigFlag(&opts.verifier.wallet.Address, f.StringVar, "Address of the verifier wallet"),
"wallet.password": argConfigFlag(&opts.verifier.wallet.Password, f.StringVar, "Password file of the verifier wallet"),
"wallet.plain": argConfigFlag(&opts.verifier.wallet.Plain, f.StringVar, "Plaintext private key of the verifier wallet"),
},
},
{
name: "submitter",
flags: map[string]func(name string){
"": argConfigFlag(&opts.submitter.use, f.BoolVar, "Enable the submitter feature"),
"confirmations": argConfigFlag(&cfg.Submitter.Confirmations, f.IntVar, "Number of confirmation blocks for transaction receipt"),
"scc-verifier-address": argConfigFlag(&cfg.Submitter.SCCVerifierAddress, f.StringVar, "Address of the OasysStateCommitmentChainVerifier contract.."),
"l2oo-verifier-address": argConfigFlag(&cfg.Submitter.L2OOVerifierAddress, f.StringVar, "Address of the OasysL2OutputOracleVerifier contract"),
"multicall-address": argConfigFlag(&cfg.Submitter.MulticallAddress, f.StringVar, "Address of the Multicall contract"),
"targets": argConfigFlag(&opts.submitter.targets, f.UintSliceVar, "List of Chain IDs to submit"),
"wallet.address": argConfigFlag(&opts.submitter.wallet.Address, f.StringVar, "Address of the submitter wallet"),
"wallet.password": argConfigFlag(&opts.submitter.wallet.Password, f.StringVar, "Password file of the submitter wallet"),
"wallet.plain": argConfigFlag(&opts.submitter.wallet.Plain, f.StringVar, "Plaintext private key of the submitter wallet"),
},
},
}
for _, ag := range argGroups {
parts := []string{fileConfigFlag}
if ag.name != "" {
parts = append(parts, ag.name)
}
for name, flagSetFn := range ag.flags {
parts := parts
if name != "" {
parts = append(parts, name)
}
flagSetFn(strings.Join(parts, "."))
}
}

return opts
}

func (opts *configLoader) load() (*config.Config, error) {
// load config from the file
if !opts.fromCli {
path, err := opts.cmd.Flags().GetString(fileConfigFlag)
if err != nil {
return nil, err
}

input, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}

conf, err := config.NewConfig(input)
if err != nil {
return nil, err
}

return conf, nil
}

// load config from command line arguments
opts.cfg.Wallets = map[string]*config.Wallet{}
if opts.verse.use {
opts.verse.verse.L1Contracts = map[string]string{}
if opts.verse.scc != "" {
opts.verse.verse.L1Contracts[SCCName] = opts.verse.scc
}
if opts.verse.l2oo != "" {
opts.verse.verse.L1Contracts[L2OOName] = opts.verse.l2oo
}
opts.cfg.VerseLayer.Directs = []*config.Verse{&opts.verse.verse}
}

if opts.verifier.use {
opts.cfg.Wallets["verifier"] = &opts.verifier.wallet
opts.cfg.Verifier.Enable = true
opts.cfg.Verifier.Wallet = "verifier"
}

if opts.submitter.use {
opts.cfg.Wallets["submitter"] = &opts.submitter.wallet
opts.cfg.Submitter.Enable = true
for _, chainID := range opts.submitter.targets {
target := config.SubmitterTarget{ChainID: uint64(chainID), Wallet: "submitter"}
opts.cfg.Submitter.Targets = append(opts.cfg.Submitter.Targets, &target)
}
}

if err := config.Validate(opts.cfg); err != nil {
return nil, err
}

return opts.cfg, nil
}
Loading
Loading