Skip to content

Commit

Permalink
Network tests: refactor config to allow for HA
Browse files Browse the repository at this point in the history
  • Loading branch information
BedrockSquirrel committed Mar 21, 2024
1 parent 2b17a1e commit 9aaf02e
Show file tree
Hide file tree
Showing 19 changed files with 131 additions and 102 deletions.
20 changes: 2 additions & 18 deletions integration/networktest/env/dev_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,28 +61,12 @@ func awaitHealthStatus(rpcAddress string, timeout time.Duration) error {
}, retry.NewTimeoutStrategy(timeout, 200*time.Millisecond))
}

func LocalDevNetwork(opts ...LocalNetworkOption) networktest.Environment {
config := &LocalNetworkConfig{}
for _, opt := range opts {
opt(config)
}
return &devNetworkEnv{inMemDevNetwork: devnetwork.DefaultDevNetwork(config.TenGatewayEnabled)}
func LocalDevNetwork(opts ...devnetwork.TenConfigOption) networktest.Environment {
return &devNetworkEnv{inMemDevNetwork: devnetwork.LocalDevNetwork(opts...)}
}

// LocalNetworkLiveL1 creates a local network that points to a live running L1.
// Note: seqWallet and validatorWallets need funds. seqWallet is used to deploy the L1 contracts
func LocalNetworkLiveL1(seqWallet wallet.Wallet, validatorWallets []wallet.Wallet, l1RPCURLs []string) networktest.Environment {
return &devNetworkEnv{inMemDevNetwork: devnetwork.LiveL1DevNetwork(seqWallet, validatorWallets, l1RPCURLs)}
}

type LocalNetworkConfig struct {
TenGatewayEnabled bool
}

type LocalNetworkOption func(*LocalNetworkConfig)

func WithTenGateway() LocalNetworkOption {
return func(c *LocalNetworkConfig) {
c.TenGatewayEnabled = true
}
}
3 changes: 2 additions & 1 deletion integration/networktest/tests/gateway/gateway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/ten-protocol/go-ten/integration/networktest"
"github.com/ten-protocol/go-ten/integration/networktest/actions"
"github.com/ten-protocol/go-ten/integration/networktest/env"
"github.com/ten-protocol/go-ten/integration/simulation/devnetwork"
)

var _transferAmount = big.NewInt(100_000_000)
Expand All @@ -23,7 +24,7 @@ func TestGatewayHappyPath(t *testing.T) {
networktest.Run(
"gateway-happy-path",
t,
env.LocalDevNetwork(env.WithTenGateway()),
env.LocalDevNetwork(devnetwork.WithGateway()),
actions.Series(
&actions.CreateTestUser{UserID: 0, UseGateway: true},
&actions.CreateTestUser{UserID: 1, UseGateway: true},
Expand Down
3 changes: 2 additions & 1 deletion integration/networktest/tests/helpful/smoke_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"testing"

"github.com/ten-protocol/go-ten/integration/networktest/actions"
"github.com/ten-protocol/go-ten/integration/simulation/devnetwork"

"github.com/ten-protocol/go-ten/integration/networktest"
"github.com/ten-protocol/go-ten/integration/networktest/env"
Expand All @@ -19,7 +20,7 @@ func TestExecuteNativeFundsTransfer(t *testing.T) {
networktest.Run(
"native-funds-smoketest",
t,
env.LocalDevNetwork(),
env.LocalDevNetwork(devnetwork.WithGateway()),
actions.Series(
&actions.CreateTestUser{UserID: 0},
&actions.CreateTestUser{UserID: 1},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/ten-protocol/go-ten/integration/common/testlog"
"github.com/ten-protocol/go-ten/integration/networktest"
"github.com/ten-protocol/go-ten/integration/networktest/env"
"github.com/ten-protocol/go-ten/integration/simulation/devnetwork"
)

const (
Expand All @@ -31,7 +32,7 @@ const (
func TestRunLocalNetwork(t *testing.T) {
networktest.TestOnlyRunsInIDE(t)
networktest.EnsureTestLogsSetUp("local-geth-network")
networkConnector, cleanUp, err := env.LocalDevNetwork(env.WithTenGateway()).Prepare()
networkConnector, cleanUp, err := env.LocalDevNetwork(devnetwork.WithGateway()).Prepare()
if err != nil {
t.Fatal(err)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package nodescenario
91 changes: 61 additions & 30 deletions integration/simulation/devnetwork/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"time"

"github.com/ethereum/go-ethereum/common"

"github.com/ethereum/go-ethereum/crypto"
"github.com/ten-protocol/go-ten/go/enclave/genesis"
"github.com/ten-protocol/go-ten/go/wallet"
Expand All @@ -25,40 +24,67 @@ type L1Config struct {
AvgBlockDuration time.Duration
}

// ObscuroConfig tells the L2 node operators how to configure the nodes
type ObscuroConfig struct {
type TenConfigOption func(*TenConfig) // option pattern - typically used as overrides to DefaultTenConfig

// TenConfig describes the L2 network configuration we want to spin up
type TenConfig struct {
PortStart int
InitNumValidators int
BatchInterval time.Duration
RollupInterval time.Duration
L1BlockTime time.Duration
SequencerID common.Address
NumNodes int
TenGatewayEnabled bool
NumSeqEnclaves int

// these are typically set based on the L1 network and wallet setup provided
L1BlockTime time.Duration
SequencerID common.Address
}

// DefaultDevNetwork provides an off-the-shelf default config for a sim network
func DefaultDevNetwork(tenGateway bool) *InMemDevNetwork {
numNodes := 4 // Default sim currently uses 4 L1 nodes. Obscuro nodes: 1 seq, 3 validators
networkWallets := params.NewSimWallets(0, numNodes, integration.EthereumChainID, integration.TenChainID)
func DefaultTenConfig() *TenConfig {
return &TenConfig{
PortStart: integration.StartPortNetworkTests,
NumNodes: 4,
InitNumValidators: 3,
BatchInterval: 1 * time.Second,
RollupInterval: 10 * time.Second,
TenGatewayEnabled: false,
NumSeqEnclaves: 1, // increase for HA simulation
}
}

func LocalDevNetwork(tenConfigOpts ...TenConfigOption) *InMemDevNetwork {
tenConfig := DefaultTenConfig()
for _, opt := range tenConfigOpts {
opt(tenConfig)
}

// 1 wallet per node
nodeOpL1Wallets := params.NewSimWallets(0, tenConfig.NumNodes, integration.EthereumChainID, integration.TenChainID)
l1Config := &L1Config{
PortStart: integration.StartPortNetworkTests,
NumNodes: 4,
NumNodes: tenConfig.NumNodes, // we'll have 1 L1 node per L2 node
AvgBlockDuration: 1 * time.Second,
}
l1Network := NewGethNetwork(networkWallets, l1Config)
l1Network := NewGethNetwork(nodeOpL1Wallets, l1Config)

return NewInMemDevNetwork(tenConfig, l1Network, nodeOpL1Wallets)
}

// NewInMemDevNetwork provides an off-the-shelf default config for a sim network
// tenConfig - the requirements of the L2 network we are spinning up
// l1Network - the L1 network we are running the L2 network on
// nodeOpL1Wallets - the funded wallets for the node operators on the L1 network (expecting 1 per node)
func NewInMemDevNetwork(tenConfig *TenConfig, l1Network L1Network, nodeOpL1Wallets *params.SimWallets) *InMemDevNetwork {
// update tenConfig references to be consistent with the L1 setup
tenConfig.L1BlockTime = l1Network.GetBlockTime()
tenConfig.SequencerID = nodeOpL1Wallets.NodeWallets[0].Address() // sequencer wallet address is its ID for now

return &InMemDevNetwork{
networkWallets: networkWallets,
networkWallets: nodeOpL1Wallets,
l1Network: l1Network,
obscuroConfig: ObscuroConfig{
PortStart: integration.StartPortNetworkTests,
InitNumValidators: 3,
BatchInterval: 1 * time.Second,
RollupInterval: 10 * time.Second,
L1BlockTime: 15 * time.Second,
SequencerID: networkWallets.NodeWallets[0].Address(),
},
tenGatewayEnabled: tenGateway,
faucetLock: sync.Mutex{},
tenConfig: tenConfig,
faucetLock: sync.Mutex{},
}
}

Expand Down Expand Up @@ -91,13 +117,18 @@ func LiveL1DevNetwork(seqWallet wallet.Wallet, validatorWallets []wallet.Wallet,
logger: testlog.Logger(),
networkWallets: networkWallets,
l1Network: l1Network,
obscuroConfig: ObscuroConfig{
PortStart: integration.StartPortNetworkTests,
InitNumValidators: len(validatorWallets),
BatchInterval: 5 * time.Second,
RollupInterval: 3 * time.Minute,
L1BlockTime: 15 * time.Second,
SequencerID: seqWallet.Address(),
},
tenConfig: DefaultTenConfig(),
}
}

func WithGateway() TenConfigOption {
return func(tc *TenConfig) {
tc.TenGatewayEnabled = true
}
}

func WithHASequencer() TenConfigOption {
return func(tc *TenConfig) {
tc.NumSeqEnclaves = 2
}
}
38 changes: 18 additions & 20 deletions integration/simulation/devnetwork/dev_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,21 +52,19 @@ type InMemDevNetwork struct {
// When Obscuro network has been initialised on the L1 network, this will be populated
// - if reconnecting to an existing network it needs to be populated when initialising this object
// - if it is nil when `Start()` is called then Obscuro contracts will be deployed on the L1
l1SetupData *params.L1SetupData
l1SetupData *params.L1TenData

obscuroConfig ObscuroConfig
obscuroSequencer *InMemNodeOperator
obscuroValidators []*InMemNodeOperator
tenConfig *TenConfig
tenSequencer *InMemNodeOperator
tenValidators []*InMemNodeOperator
tenGatewayContainer *container.WalletExtensionContainer

tenGatewayEnabled bool

faucet userwallet.User
faucetLock sync.Mutex
}

func (s *InMemDevNetwork) GetGatewayURL() (string, error) {
if !s.tenGatewayEnabled {
if !s.tenConfig.TenGatewayEnabled {
return "", fmt.Errorf("ten gateway not enabled")
}
return fmt.Sprintf("http://localhost:%d", _gwHTTPPort), nil
Expand Down Expand Up @@ -123,15 +121,15 @@ func (s *InMemDevNetwork) GetL1Client() (ethadapter.EthClient, error) {
}

func (s *InMemDevNetwork) GetSequencerNode() networktest.NodeOperator {
return s.obscuroSequencer
return s.tenSequencer
}

func (s *InMemDevNetwork) GetValidatorNode(i int) networktest.NodeOperator {
return s.obscuroValidators[i]
return s.tenValidators[i]
}

func (s *InMemDevNetwork) NumValidators() int {
return len(s.obscuroValidators)
return len(s.tenValidators)
}

func (s *InMemDevNetwork) Start() {
Expand All @@ -148,7 +146,7 @@ func (s *InMemDevNetwork) Start() {
fmt.Println("Starting obscuro nodes")
s.startNodes()

if s.tenGatewayEnabled {
if s.tenConfig.TenGatewayEnabled {
s.startTenGateway()
}
// sleep to allow the nodes to start
Expand All @@ -160,22 +158,22 @@ func (s *InMemDevNetwork) GetGatewayClient() (ethadapter.EthClient, error) {
}

func (s *InMemDevNetwork) startNodes() {
if s.obscuroSequencer == nil {
// initialise node operators
s.obscuroSequencer = NewInMemNodeOperator(0, s.obscuroConfig, common.Sequencer, s.l1SetupData, s.l1Network.GetClient(0), s.networkWallets.NodeWallets[0], s.logger)
for i := 1; i <= s.obscuroConfig.InitNumValidators; i++ {
if s.tenSequencer == nil {
// initialise node operators (sequencer is node 0, validators are 1..N)
s.tenSequencer = NewInMemNodeOperator(0, s.tenConfig, common.Sequencer, s.l1SetupData, s.l1Network.GetClient(0), s.networkWallets.NodeWallets[0], s.logger)
for i := 1; i <= s.tenConfig.InitNumValidators; i++ {
l1Client := s.l1Network.GetClient(i % s.l1Network.NumNodes())
s.obscuroValidators = append(s.obscuroValidators, NewInMemNodeOperator(i, s.obscuroConfig, common.Validator, s.l1SetupData, l1Client, s.networkWallets.NodeWallets[i], s.logger))
s.tenValidators = append(s.tenValidators, NewInMemNodeOperator(i, s.tenConfig, common.Validator, s.l1SetupData, l1Client, s.networkWallets.NodeWallets[i], s.logger))
}
}

go func() {
err := s.obscuroSequencer.Start()
err := s.tenSequencer.Start()
if err != nil {
panic(err)
}
}()
for _, v := range s.obscuroValidators {
for _, v := range s.tenValidators {
go func(v networktest.NodeOperator) {
err := v.Start()
if err != nil {
Expand Down Expand Up @@ -218,7 +216,7 @@ func (s *InMemDevNetwork) startTenGateway() {
}

func (s *InMemDevNetwork) CleanUp() {
for _, v := range s.obscuroValidators {
for _, v := range s.tenValidators {
go func(v networktest.NodeOperator) {
err := v.Stop()
if err != nil {
Expand All @@ -227,7 +225,7 @@ func (s *InMemDevNetwork) CleanUp() {
}(v)
}
go func() {
err := s.obscuroSequencer.Stop()
err := s.tenSequencer.Stop()
if err != nil {
fmt.Println("failed to stop sequencer", err.Error())
}
Expand Down
5 changes: 5 additions & 0 deletions integration/simulation/devnetwork/geth_l1.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package devnetwork

import (
"fmt"
"time"

"github.com/ten-protocol/go-ten/integration"

Expand Down Expand Up @@ -51,3 +52,7 @@ func (g *gethDockerNetwork) NumNodes() int {
func (g *gethDockerNetwork) GetClient(_ int) ethadapter.EthClient {
return g.l1Clients[0]
}

func (g *gethDockerNetwork) GetBlockTime() time.Duration {
return g.l1Config.AvgBlockDuration
}
3 changes: 3 additions & 0 deletions integration/simulation/devnetwork/l1_network.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package devnetwork

import (
"time"

"github.com/ten-protocol/go-ten/go/ethadapter"
)

Expand All @@ -12,4 +14,5 @@ type L1Network interface {
CleanUp() // shut down nodes if required, clean up connections
NumNodes() int
GetClient(i int) ethadapter.EthClient
GetBlockTime() time.Duration // expected interval between blocks
}
5 changes: 5 additions & 0 deletions integration/simulation/devnetwork/live_l1.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
type liveL1Network struct {
deployWallet wallet.Wallet // wallet that can deploy to the live L1 network
rpcURLs []string
blockTime time.Duration // expected interval between blocks

clients []ethadapter.EthClient
seqWallet wallet.Wallet
Expand Down Expand Up @@ -51,6 +52,10 @@ func (l *liveL1Network) GetClient(i int) ethadapter.EthClient {
return l.clients[i%len(l.clients)]
}

func (l *liveL1Network) GetBlockTime() time.Duration {
return l.blockTime
}

func (l *liveL1Network) prepareClients() {
l.clients = make([]ethadapter.EthClient, len(l.rpcURLs))
for i, addr := range l.rpcURLs {
Expand Down
9 changes: 4 additions & 5 deletions integration/simulation/devnetwork/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ import (
// Note: InMemNodeOperator will panic when things go wrong, we want to fail fast in sims and avoid verbose error handling in usage
type InMemNodeOperator struct {
operatorIdx int
config ObscuroConfig
config *TenConfig
nodeType common.NodeType
l1Data *params.L1SetupData
l1Data *params.L1TenData
l1Client ethadapter.EthClient
logger gethlog.Logger

Expand Down Expand Up @@ -126,8 +126,7 @@ func (n *InMemNodeOperator) createHostContainer() *hostcontainer.HostContainer {
MessageBusAddress: n.l1Data.MessageBusAddr,
L1ChainID: integration.EthereumChainID,
ObscuroChainID: integration.TenChainID,
L1StartHash: n.l1Data.ObscuroStartBlock,
SequencerID: n.config.SequencerID,
L1StartHash: n.l1Data.TenStartBlock,
UseInMemoryDB: false,
LevelDBPath: n.hostDBFilepath,
DebugNamespaceEnabled: true,
Expand Down Expand Up @@ -233,7 +232,7 @@ func (n *InMemNodeOperator) StopEnclave() error {
return nil
}

func NewInMemNodeOperator(operatorIdx int, config ObscuroConfig, nodeType common.NodeType, l1Data *params.L1SetupData,
func NewInMemNodeOperator(operatorIdx int, config *TenConfig, nodeType common.NodeType, l1Data *params.L1TenData,
l1Client ethadapter.EthClient, l1Wallet wallet.Wallet, logger gethlog.Logger,
) *InMemNodeOperator {
// todo (@matt) - put sqlite and levelDB storage in the same temp dir
Expand Down
Loading

0 comments on commit 9aaf02e

Please sign in to comment.