Skip to content

Commit

Permalink
test(e2e): add netman and staging (#196)
Browse files Browse the repository at this point in the history
Adds staging network to e2e framework. Also re-introduces netman to
manage deploying and keys.

task: none
  • Loading branch information
corverroos authored Jan 30, 2024
1 parent ceed962 commit 2817968
Show file tree
Hide file tree
Showing 25 changed files with 737 additions and 251 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ devnet-stop: ## Stops devnet1 containers (alias for MANIFEST=devnet1 make e2e-st
e2e-run: ## Run specific e2e manifest (MANIFEST=single, MANIFEST=simple, etc). Note container remain running after the test.
@if [ -z "$(MANIFEST)" ]; then echo "⚠️ Please specify a manifest: MANIFEST=simple make e2e-run" && exit 1; fi
@echo "Using MANIFEST=$(MANIFEST)"
@go run github.com/omni-network/omni/test/e2e/runner -f test/e2e/manifests/$(MANIFEST).toml -p
@go run github.com/omni-network/omni/test/e2e/runner -f test/e2e/manifests/$(MANIFEST).toml

.PHONY: e2e-logs
e2e-logs: ## Print the docker logs of previously ran e2e manifest (single, simple, etc).
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go 1.21.5

require (
entgo.io/ent v0.12.5
github.com/BurntSushi/toml v1.3.2
github.com/bufbuild/buf v1.29.0
github.com/charmbracelet/log v0.3.1
github.com/cometbft/cometbft v0.38.5
Expand Down Expand Up @@ -40,7 +41,6 @@ require (
connectrpc.com/connect v1.14.0 // indirect
connectrpc.com/otelconnect v0.7.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/BurntSushi/toml v1.3.2 // indirect
github.com/DataDog/zstd v1.4.5 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/StackExchange/wmi v1.2.1 // indirect
Expand Down
3 changes: 3 additions & 0 deletions halo/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
FROM scratch

# Install ca-certificates (for https to rollups)
COPY --from=alpine:latest /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/

COPY halo /app

# Mount home directory at /halo
Expand Down
2 changes: 1 addition & 1 deletion halo/app/simnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func maybeSetupSimnetRelayer(ctx context.Context, network netconf.Network, cmtNo

cprov := cprovider.NewABCIProvider(rpclocal.New(cmtNode))

return relayer.StartRelayer(ctx, cprov, network.ChainIDs(), xprovider, relayer.CreateSubmissions, simnetSender{})
return relayer.StartRelayer(ctx, cprov, network, xprovider, relayer.CreateSubmissions, simnetSender{})
}

var _ relayer.Sender = simnetSender{}
Expand Down
3 changes: 3 additions & 0 deletions relayer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
FROM scratch

# Install ca-certificates (for https to rollups)
COPY --from=alpine:latest /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/

# Copy relayer binary and rename to /app
COPY relayer /app

Expand Down
2 changes: 1 addition & 1 deletion relayer/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func Run(ctx context.Context, cfg Config) error {

err = StartRelayer(ctx,
cprovider.NewABCIProvider(tmClient),
network.ChainIDs(),
network,
xprovider.New(network, rpcClientPerChain),
CreateSubmissions,
sender)
Expand Down
13 changes: 7 additions & 6 deletions relayer/app/relayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/omni-network/omni/lib/cchain"
"github.com/omni-network/omni/lib/errors"
"github.com/omni-network/omni/lib/log"
"github.com/omni-network/omni/lib/netconf"
"github.com/omni-network/omni/lib/xchain"
)

Expand All @@ -15,13 +16,13 @@ import (
func StartRelayer(
ctx context.Context,
cProvider cchain.Provider,
chainIDs []uint64,
network netconf.Network,
xClient xchain.Provider,
creator CreateFunc,
sender Sender,
) error {
// Get the last submitted cursors for each chain.
cursors, initialOffsets, err := getSubmittedCursors(ctx, chainIDs, xClient)
cursors, initialOffsets, err := getSubmittedCursors(ctx, network.ChainIDs(), xClient)
if err != nil {
return err
}
Expand Down Expand Up @@ -80,7 +81,7 @@ func StartRelayer(
}

// Subscribe to attestations for each chain.
for chainID, fromHeight := range FromHeights(cursors, chainIDs) {
for chainID, fromHeight := range FromHeights(cursors, network.Chains) {
cProvider.Subscribe(ctx, chainID, fromHeight, callback)
}

Expand Down Expand Up @@ -145,11 +146,11 @@ func filterMsgs(msgs []xchain.Msg, offsets map[xchain.StreamID]uint64, streamID
return res
}

func FromHeights(cursors []xchain.StreamCursor, chainIDs []uint64) map[uint64]uint64 {
func FromHeights(cursors []xchain.StreamCursor, chains []netconf.Chain) map[uint64]uint64 {
res := make(map[uint64]uint64)

for _, chainID := range chainIDs {
res[chainID] = 0
for _, chain := range chains {
res[chain.ID] = chain.DeployHeight
}

// sort cursors by decreasing SourceBlockHeight, so we start streaming from minimum height per source chain
Expand Down
50 changes: 33 additions & 17 deletions relayer/app/relayer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ package relayer_test

import (
"context"
"reflect"
"testing"

"github.com/omni-network/omni/lib/cchain"
"github.com/omni-network/omni/lib/netconf"
"github.com/omni-network/omni/lib/xchain"
relayer "github.com/omni-network/omni/relayer/app"

Expand Down Expand Up @@ -98,8 +98,12 @@ func Test_StartRelayer(t *testing.T) {
},
}

allChains := []uint64{srcChain, destChainA, destChainB}
err := relayer.StartRelayer(ctx, mockProvider, allChains, mockXClient, mockCreateFunc, mockSender)
network := netconf.Network{Chains: []netconf.Chain{
{ID: srcChain},
{ID: destChainA},
{ID: destChainB},
}}
err := relayer.StartRelayer(ctx, mockProvider, network, mockXClient, mockCreateFunc, mockSender)
require.NoError(t, err)

// Verify responses
Expand Down Expand Up @@ -132,36 +136,49 @@ func Test_StartRelayer(t *testing.T) {
func Test_FromHeights(t *testing.T) {
t.Parallel()
type args struct {
cursors []xchain.StreamCursor
chainIDs []uint64
cursors []xchain.StreamCursor
chains []netconf.Chain
}
tests := []struct {
name string
args args
want map[uint64]uint64
}{
{
name: "", args: args{
name: "1", args: args{
cursors: []xchain.StreamCursor{
{StreamID: xchain.StreamID{SourceChainID: 1, DestChainID: 2}, Offset: 100, SourceBlockHeight: 200},
{StreamID: xchain.StreamID{SourceChainID: 2, DestChainID: 3}, Offset: 150, SourceBlockHeight: 250},
{StreamID: xchain.StreamID{SourceChainID: 1, DestChainID: 2}, SourceBlockHeight: 200},
{StreamID: xchain.StreamID{SourceChainID: 2, DestChainID: 3}, SourceBlockHeight: 250},
},
chainIDs: []uint64{1, 2, 3},
chains: []netconf.Chain{{ID: 1}, {ID: 2}, {ID: 3}},
}, want: map[uint64]uint64{
1: 200,
2: 250,
3: 0,
},
},
{
name: "", args: args{
name: "2", args: args{
cursors: []xchain.StreamCursor{
{StreamID: xchain.StreamID{SourceChainID: 1, DestChainID: 2}, Offset: 100, SourceBlockHeight: 200},
{StreamID: xchain.StreamID{SourceChainID: 1, DestChainID: 3}, Offset: 150, SourceBlockHeight: 0},
{StreamID: xchain.StreamID{SourceChainID: 1, DestChainID: 3}, SourceBlockHeight: 200},
{StreamID: xchain.StreamID{SourceChainID: 2, DestChainID: 3}, SourceBlockHeight: 100},
},
chainIDs: []uint64{1, 3},
chains: []netconf.Chain{{ID: 1}, {ID: 2, DeployHeight: 55}, {ID: 3}},
}, want: map[uint64]uint64{
1: 0,
1: 200,
2: 100,
3: 0,
},
},
{
name: "3", args: args{
cursors: []xchain.StreamCursor{
{StreamID: xchain.StreamID{SourceChainID: 1, DestChainID: 2}, SourceBlockHeight: 200},
},
chains: []netconf.Chain{{ID: 1}, {ID: 2, DeployHeight: 55}, {ID: 3}},
}, want: map[uint64]uint64{
1: 200,
2: 55,
3: 0,
},
},
Expand All @@ -170,9 +187,8 @@ func Test_FromHeights(t *testing.T) {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
if got := relayer.FromHeights(tt.args.cursors, tt.args.chainIDs); !reflect.DeepEqual(got, tt.want) {
t.Errorf("fromHeights() = %v, want %v", got, tt.want)
}
got := relayer.FromHeights(tt.args.cursors, tt.args.chains)
require.Equal(t, tt.want, got)
})
}
}
Expand Down
6 changes: 6 additions & 0 deletions test/e2e/manifests/staging.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
network="staging"

[node.validator01]
[node.validator02]
[node.validator03]
[node.validator04]
96 changes: 6 additions & 90 deletions test/e2e/runner/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,95 +2,16 @@ package main

import (
"context"
"math/big"
"strings"
"time"

"github.com/omni-network/omni/contracts/bindings"
"github.com/omni-network/omni/lib/errors"
"github.com/omni-network/omni/lib/log"
"github.com/omni-network/omni/lib/netconf"
"github.com/omni-network/omni/test/e2e/runner/netman"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
)

const (
// privKeyHex0 of pre-funded anvil account 0.
privKeyHex0 = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
// privKeyHex1 of pre-funded anvil account 1.
privKeyHex1 = "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d"
)

type Portal struct {
Chain netconf.Chain
Client *ethclient.Client
Contract *bindings.OmniPortal
}

func DeployContracts(ctx context.Context, network netconf.Network) (map[uint64]Portal, error) {
log.Info(ctx, "Deploying portal contracts")

resp := make(map[uint64]Portal)
for _, chain := range network.Chains {
ethClient, err := ethclient.Dial(chain.RPCURL)
if err != nil {
return nil, errors.Wrap(err, "dial chain")
}

txOpts, err := newTxOpts(ctx, privKeyHex0, chain.ID)
if err != nil {
return nil, err
}

addr, _, _, err := bindings.DeployOmniPortal(txOpts, ethClient)
if err != nil {
return nil, errors.Wrap(err, "deploy portal")
} else if addr.Hex() != chain.PortalAddress {
return nil, errors.New("portal address mismatch",
"chain", chain.Name,
"expect", chain.PortalAddress,
"actual", addr.Hex(),
)
}

contract, err := bindings.NewOmniPortal(addr, ethClient)
if err != nil {
return nil, errors.Wrap(err, "create portal contract")
}

resp[chain.ID] = Portal{
Chain: chain,
Client: ethClient,
Contract: contract,
}
}

return resp, nil
}

func newTxOpts(ctx context.Context, privKeyHex string, chainID uint64) (*bind.TransactOpts, error) {
pk, err := crypto.HexToECDSA(strings.TrimPrefix(privKeyHex, "0x"))
if err != nil {
return nil, errors.Wrap(err, "parse private key")
}

txOpts, err := bind.NewKeyedTransactorWithChainID(
pk,
big.NewInt(int64(chainID)),
)
if err != nil {
return nil, errors.Wrap(err, "keyed tx ops")
}

txOpts.Context = ctx

return txOpts, nil
}

func StartSendingXMsgs(ctx context.Context, portals map[uint64]Portal) error {
func StartSendingXMsgs(ctx context.Context, portals map[uint64]netman.Portal) error {
log.Info(ctx, "Generating cross chain messages async")
go func() {
for ctx.Err() == nil {
Expand All @@ -101,15 +22,15 @@ func StartSendingXMsgs(ctx context.Context, portals map[uint64]Portal) error {
log.Error(ctx, "Failed to send xmsgs, giving up", err)
return
}
time.Sleep(time.Millisecond * 500)
time.Sleep(time.Millisecond * 1000)
}
}()

return nil
}

// SendXMsgs sends one xmsg from every chain to every other chain.
func SendXMsgs(ctx context.Context, portals map[uint64]Portal) error {
func SendXMsgs(ctx context.Context, portals map[uint64]netman.Portal) error {
for _, from := range portals {
for _, to := range portals {
if from.Chain.ID == to.Chain.ID {
Expand All @@ -126,13 +47,8 @@ func SendXMsgs(ctx context.Context, portals map[uint64]Portal) error {
}

// xcall sends a ethereum transaction to the portal contract, triggering a xcall.
func xcall(ctx context.Context, from Portal, destChainID uint64) error {
txOpts, err := newTxOpts(ctx, privKeyHex0, from.Chain.ID)
if err != nil {
return err
}

_, err = from.Contract.Xcall(txOpts, destChainID, common.Address{}, nil)
func xcall(ctx context.Context, from netman.Portal, destChainID uint64) error {
_, err := from.Contract.Xcall(from.TxOpts(ctx), destChainID, common.Address{}, nil)
if err != nil {
return errors.Wrap(err, "xcall",
"sourc_chain", from.Chain.ID,
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/runner/docker/compose.yaml.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ services:
e2e: true
container_name: chain_a
image: ghcr.io/foundry-rs/foundry:latest
entrypoint: ['anvil','--host','0.0.0.0','--chain-id','100','--block-time','1']
entrypoint: ['anvil','--host','0.0.0.0','--chain-id','100','--block-time','1', "--silent"]
ports:
- "6545:8545"
- "6546:8546"
Expand Down
Loading

0 comments on commit 2817968

Please sign in to comment.