Skip to content

Commit

Permalink
Changes to support sepolia testing from IDE (#1527)
Browse files Browse the repository at this point in the history
  • Loading branch information
BedrockSquirrel authored Sep 15, 2023
1 parent 64a0c5e commit 8babe2e
Show file tree
Hide file tree
Showing 11 changed files with 62 additions and 46 deletions.
4 changes: 3 additions & 1 deletion go/ethadapter/geth_rpc_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,9 @@ func (e *gethRPCClient) ReconnectIfClosed() error {

// Alive tests the client
func (e *gethRPCClient) Alive() bool {
_, err := e.client.BlockNumber(context.Background())
ctx, cancel := context.WithTimeout(context.Background(), e.timeout)
defer cancel()
_, err := e.client.BlockNumber(ctx)
if err != nil {
e.logger.Error("Unable to fetch BlockNumber rpc endpoint - client connection is in error state")
return false
Expand Down
7 changes: 3 additions & 4 deletions go/host/enclave/guardian.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,6 @@ func (g *Guardian) provideSecret() error {
// instead of requesting a secret, we generate one and broadcast it
return g.generateAndBroadcastSecret()
}
g.logger.Info("Requesting secret.")
att, err := g.enclaveClient.Attestation()
if err != nil {
return fmt.Errorf("could not retrieve attestation from enclave. Cause: %w", err)
Expand Down Expand Up @@ -301,7 +300,7 @@ func (g *Guardian) provideSecret() error {
}

func (g *Guardian) generateAndBroadcastSecret() error {
g.logger.Info("Node is genesis node. Broadcasting secret.")
g.logger.Info("Node is genesis node. Publishing secret to L1 management contract.")
// Create the shared secret and submit it to the management contract for storage
attestation, err := g.enclaveClient.Attestation()
if err != nil {
Expand All @@ -318,9 +317,9 @@ func (g *Guardian) generateAndBroadcastSecret() error {

err = g.sl.L1Publisher().InitializeSecret(attestation, secret)
if err != nil {
return errors.Wrap(err, "failed to initialise enclave secret")
return errors.Wrap(err, "failed to publish generated enclave secret")
}
g.logger.Info("Node is genesis node. Secret was broadcast.")
g.logger.Info("Node is genesis node. Secret generation was published to L1.")
g.state.OnSecretProvided()
return nil
}
Expand Down
8 changes: 4 additions & 4 deletions integration/networktest/env/dev_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ func (d *devNetworkEnv) Prepare() (networktest.NetworkConnector, func(), error)
}

func awaitNodesAvailable(nc networktest.NetworkConnector) error {
err := awaitHealthStatus(nc.GetSequencerNode().HostRPCAddress(), 30*time.Second)
err := awaitHealthStatus(nc.GetSequencerNode().HostRPCAddress(), 60*time.Second)
if err != nil {
return err
}
for i := 0; i < nc.NumValidators(); i++ {
err := awaitHealthStatus(nc.GetValidatorNode(i).HostRPCAddress(), 30*time.Second)
err := awaitHealthStatus(nc.GetValidatorNode(i).HostRPCAddress(), 60*time.Second)
if err != nil {
return err
}
Expand Down Expand Up @@ -67,6 +67,6 @@ func LocalDevNetwork() networktest.Environment {

// 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, l1RPCAddress string) networktest.Environment {
return &devNetworkEnv{inMemDevNetwork: devnetwork.LiveL1DevNetwork(seqWallet, validatorWallets, l1RPCAddress)}
func LocalNetworkLiveL1(seqWallet wallet.Wallet, validatorWallets []wallet.Wallet, l1RPCURLs []string) networktest.Environment {
return &devNetworkEnv{inMemDevNetwork: devnetwork.LiveL1DevNetwork(seqWallet, validatorWallets, l1RPCURLs)}
}
5 changes: 3 additions & 2 deletions integration/networktest/env/network_setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ func DevTestnet() networktest.Environment {
return &testnetEnv{connector}
}

// LongRunningLocalNetwork is a local network, the l1WSURL is optional (can be empty string), only required if testing L1 interactions
func LongRunningLocalNetwork(l1WSURL string) networktest.Environment {
connector := NewTestnetConnectorWithFaucetAccount(
"http://127.0.0.1:37800",
[]string{"http://127.0.0.1:37801", "http://127.0.0.1:37802"},
"ws://127.0.0.1:37900",
[]string{"ws://127.0.0.1:37901"},
genesis.TestnetPrefundedPK,
l1WSURL,
)
Expand Down
2 changes: 1 addition & 1 deletion integration/networktest/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func Run(testName string, t *testing.T, env Environment, action Action) {
if err != nil {
t.Fatal(err)
}
time.Sleep(2 * time.Second) // allow time for latest test transactions to propagate todo (@matt) consider how to configure this sleep
time.Sleep(20 * time.Second) // allow time for latest test transactions to propagate todo (@matt) make network speeds readable from env to configure this
fmt.Println("Verifying test:", testName)
err = action.Verify(ctx, network)
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@ import (
const (
_sepoliaChainID = 11155111

// To run Sepolia network: update these details with a websocket RPC address and funded PKs
_sepoliaRPCAddress = "wss://sepolia.infura.io/ws/v3/<api-key>"
SepoliaRPCAddress1 = "wss://sepolia.infura.io/ws/v3/<api-key>" // seq
SepoliaRPCAddress2 = "wss://sepolia.infura.io/ws/v3/<api-key>" // val
SepoliaRPCAddress3 = "wss://sepolia.infura.io/ws/v3/<api-key>" // tester

_sepoliaSequencerPK = "<pk>" // account 0x<acc>
_sepoliaValidator1PK = "<pk>" // account 0x<acc>

)

func TestRunLocalNetwork(t *testing.T) {
Expand All @@ -45,14 +46,14 @@ func TestRunLocalNetworkAgainstSepolia(t *testing.T) {
networktest.EnsureTestLogsSetUp("local-sepolia-network")

l1DeployerWallet := wallet.NewInMemoryWalletFromConfig(_sepoliaSequencerPK, _sepoliaChainID, testlog.Logger())
checkBalance("sequencer", l1DeployerWallet, _sepoliaRPCAddress)
checkBalance("sequencer", l1DeployerWallet, SepoliaRPCAddress1)

val1Wallet := wallet.NewInMemoryWalletFromConfig(_sepoliaValidator1PK, _sepoliaChainID, testlog.Logger())
checkBalance("validator1", val1Wallet, _sepoliaRPCAddress)
checkBalance("validator1", val1Wallet, SepoliaRPCAddress2)

validatorWallets := []wallet.Wallet{val1Wallet}
networktest.EnsureTestLogsSetUp("local-network-live-l1")
networkConnector, cleanUp, err := env.LocalNetworkLiveL1(l1DeployerWallet, validatorWallets, _sepoliaRPCAddress).Prepare()
networkConnector, cleanUp, err := env.LocalNetworkLiveL1(l1DeployerWallet, validatorWallets, []string{SepoliaRPCAddress1, SepoliaRPCAddress2}).Prepare()
if err != nil {
t.Fatal(err)
}
Expand Down
2 changes: 1 addition & 1 deletion integration/networktest/userwallet/userwallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (

const (
_maxReceiptWaitTime = 30 * time.Second
_receiptPollInterval = 1 * time.Second
_receiptPollInterval = 1 * time.Second // todo (@matt) this should be configured using network timings provided by env
)

// UserWallet implements wallet.Wallet so it can be used with the original Wallet code.
Expand Down
11 changes: 9 additions & 2 deletions integration/simulation/devnetwork/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"sync"
"time"

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

"github.com/ethereum/go-ethereum/crypto"
"github.com/obscuronet/go-obscuro/go/enclave/genesis"
"github.com/obscuronet/go-obscuro/go/wallet"
Expand All @@ -30,6 +32,7 @@ type ObscuroConfig struct {
BatchInterval time.Duration
RollupInterval time.Duration
L1BlockTime time.Duration
SequencerID common.Address
}

// DefaultDevNetwork provides an off-the-shelf default config for a sim network
Expand All @@ -52,12 +55,15 @@ func DefaultDevNetwork() *InMemDevNetwork {
BatchInterval: 1 * time.Second,
RollupInterval: 10 * time.Second,
L1BlockTime: 15 * time.Second,
SequencerID: networkWallets.NodeWallets[0].Address(),
},
faucetLock: sync.Mutex{},
}
}

func LiveL1DevNetwork(seqWallet wallet.Wallet, validatorWallets []wallet.Wallet, rpcAddress string) *InMemDevNetwork {
// LiveL1DevNetwork provides a local obscuro network running on a live L1
// Caller should provide a wallet per node and ideally an RPC URL per node (may not be necessary but can avoid conflicts, e.g. Infura seems to require an API key per connection)
func LiveL1DevNetwork(seqWallet wallet.Wallet, validatorWallets []wallet.Wallet, rpcURLs []string) *InMemDevNetwork {
// setup the host and deployer wallets to be the prefunded wallets

// create the L2 faucet wallet
Expand All @@ -77,7 +83,7 @@ func LiveL1DevNetwork(seqWallet wallet.Wallet, validatorWallets []wallet.Wallet,
deployWallet: seqWallet, // use the same wallet for deploying the contracts
seqWallet: seqWallet,
validatorWallets: validatorWallets,
rpcAddress: rpcAddress,
rpcURLs: rpcURLs,
}

return &InMemDevNetwork{
Expand All @@ -90,6 +96,7 @@ func LiveL1DevNetwork(seqWallet wallet.Wallet, validatorWallets []wallet.Wallet,
BatchInterval: 5 * time.Second,
RollupInterval: 3 * time.Minute,
L1BlockTime: 15 * time.Second,
SequencerID: seqWallet.Address(),
},
}
}
30 changes: 19 additions & 11 deletions integration/simulation/devnetwork/live_l1.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,27 @@ import (

type liveL1Network struct {
deployWallet wallet.Wallet // wallet that can deploy to the live L1 network
rpcAddress string
rpcURLs []string

client ethadapter.EthClient
clients []ethadapter.EthClient
seqWallet wallet.Wallet
validatorWallets []wallet.Wallet
}

func (l *liveL1Network) Prepare() {
// nothing to do really, sanity check the L1 connection
logger := testlog.Logger()
client, err := ethadapter.NewEthClientFromURL(l.rpcAddress, 20*time.Second, common.HexToAddress("0x0"), logger)
if err != nil {
panic("unable to create live L1 eth client, err=" + err.Error())
}
l.client = client
l.prepareClients()
client := l.GetClient(0)
blockNum, err := client.BlockNumber()
if err != nil {
panic(fmt.Sprintf("unable to fetch head block number for live L1 network, rpc=%s err=%s",
l.rpcAddress, err))
l.rpcURLs[0], err))
}
fmt.Println("Connected to L1 successfully", "currHeight", blockNum)
logger.Info("Connected to L1 successfully", "currHeight", blockNum)

nonce, err := l.client.Nonce(l.deployWallet.Address())
nonce, err := client.Nonce(l.deployWallet.Address())
if err != nil {
panic(err)
}
Expand All @@ -50,6 +47,17 @@ func (l *liveL1Network) NumNodes() int {
return 1
}

func (l *liveL1Network) GetClient(_ int) ethadapter.EthClient {
return l.client
func (l *liveL1Network) GetClient(i int) ethadapter.EthClient {
return l.clients[i%len(l.clients)]
}

func (l *liveL1Network) prepareClients() {
l.clients = make([]ethadapter.EthClient, len(l.rpcURLs))
for i, addr := range l.rpcURLs {
client, err := ethadapter.NewEthClientFromURL(addr, 20*time.Second, common.HexToAddress("0x0"), testlog.Logger())
if err != nil {
panic(fmt.Sprintf("unable to create live L1 eth client, addr=%s err=%s", addr, err))
}
l.clients[i] = client
}
}
21 changes: 9 additions & 12 deletions integration/simulation/devnetwork/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"math/big"
"os"

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

"github.com/obscuronet/go-obscuro/go/host/l1"

"github.com/obscuronet/go-obscuro/go/host"
Expand All @@ -13,7 +15,6 @@ import (

"github.com/obscuronet/go-obscuro/go/ethadapter/mgmtcontractlib"

gethcommon "github.com/ethereum/go-ethereum/common"
gethlog "github.com/ethereum/go-ethereum/log"
"github.com/obscuronet/go-obscuro/go/common"
"github.com/obscuronet/go-obscuro/go/common/log"
Expand Down Expand Up @@ -106,7 +107,7 @@ func (n *InMemNodeOperator) createHostContainer() *hostcontainer.HostContainer {
p2pAddr := fmt.Sprintf("%s:%d", network.Localhost, p2pPort)

hostConfig := &config.HostConfig{
ID: getHostID(n.operatorIdx),
ID: n.l1Wallet.Address(),
IsGenesis: n.nodeType == common.Sequencer,
NodeType: n.nodeType,
HasClientRPCHTTP: true,
Expand All @@ -124,7 +125,7 @@ func (n *InMemNodeOperator) createHostContainer() *hostcontainer.HostContainer {
L1ChainID: integration.EthereumChainID,
ObscuroChainID: integration.ObscuroChainID,
L1StartHash: n.l1Data.ObscuroStartBlock,
SequencerID: getHostID(0),
SequencerID: n.config.SequencerID,
UseInMemoryDB: false,
LevelDBPath: n.hostDBFilepath,
DebugNamespaceEnabled: true,
Expand All @@ -133,32 +134,32 @@ func (n *InMemNodeOperator) createHostContainer() *hostcontainer.HostContainer {
L1BlockTime: n.config.L1BlockTime,
}

hostLogger := testlog.Logger().New(log.NodeIDKey, n.operatorIdx, log.CmpKey, log.HostCmp)
hostLogger := testlog.Logger().New(log.NodeIDKey, n.l1Wallet.Address(), log.CmpKey, log.HostCmp)

// create a socket P2P layer
p2pLogger := hostLogger.New(log.CmpKey, log.P2PCmp)
svcLocator := host.NewServicesRegistry(n.logger)
nodeP2p := p2p.NewSocketP2PLayer(hostConfig, svcLocator, p2pLogger, nil)
// create an enclave client

enclaveClient := enclaverpc.NewClient(hostConfig, testlog.Logger().New(log.NodeIDKey, n.operatorIdx))
enclaveClient := enclaverpc.NewClient(hostConfig, testlog.Logger().New(log.NodeIDKey, n.l1Wallet.Address()))
rpcServer := clientrpc.NewServer(hostConfig, n.logger)
mgmtContractLib := mgmtcontractlib.NewMgmtContractLib(&hostConfig.ManagementContractAddress, n.logger)
l1Repo := l1.NewL1Repository(n.l1Client, []gethcommon.Address{hostConfig.ManagementContractAddress, hostConfig.MessageBusAddress}, n.logger)
return hostcontainer.NewHostContainer(hostConfig, svcLocator, nodeP2p, n.l1Client, l1Repo, enclaveClient, mgmtContractLib, n.l1Wallet, rpcServer, hostLogger, metrics.New(false, 0, n.logger))
}

func (n *InMemNodeOperator) createEnclaveContainer() *enclavecontainer.EnclaveContainer {
enclaveLogger := testlog.Logger().New(log.NodeIDKey, n.operatorIdx, log.CmpKey, log.EnclaveCmp)
enclaveLogger := testlog.Logger().New(log.NodeIDKey, n.l1Wallet.Address(), log.CmpKey, log.EnclaveCmp)
enclavePort := n.config.PortStart + integration.DefaultEnclaveOffset + n.operatorIdx
enclaveAddr := fmt.Sprintf("%s:%d", network.Localhost, enclavePort)

hostPort := n.config.PortStart + integration.DefaultHostP2pOffset + n.operatorIdx
hostAddr := fmt.Sprintf("%s:%d", network.Localhost, hostPort)

enclaveConfig := &config.EnclaveConfig{
HostID: getHostID(n.operatorIdx),
SequencerID: getHostID(0),
HostID: n.l1Wallet.Address(),
SequencerID: n.config.SequencerID,
HostAddress: hostAddr,
Address: enclaveAddr,
NodeType: n.nodeType,
Expand Down Expand Up @@ -241,7 +242,3 @@ func NewInMemNodeOperator(operatorIdx int, config ObscuroConfig, nodeType common
hostDBFilepath: levelDBPath,
}
}

func getHostID(nodeIdx int) gethcommon.Address {
return gethcommon.BigToAddress(big.NewInt(int64(nodeIdx)))
}
5 changes: 3 additions & 2 deletions integration/simulation/network/geth_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ func DeployContract(workerClient ethadapter.EthClient, w wallet.Wallet, contract

var start time.Time
var receipt *types.Receipt
// todo (@matt) these timings should be driven by the L2 batch times and L1 block times
for start = time.Now(); time.Since(start) < 80*time.Second; time.Sleep(2 * time.Second) {
receipt, err = workerClient.TransactionReceipt(signedTx.Hash())
if err == nil && receipt != nil {
Expand All @@ -191,10 +192,10 @@ func DeployContract(workerClient ethadapter.EthClient, w wallet.Wallet, contract
return receipt, nil
}

testlog.Logger().Info(fmt.Sprintf("Contract deploy tx has not been mined into a block after %s...", time.Since(start)))
testlog.Logger().Info(fmt.Sprintf("Contract deploy tx (%s) has not been mined into a block after %s...", signedTx.Hash(), time.Since(start)))
}

return nil, fmt.Errorf("failed to mine contract deploy tx into a block after %s. Aborting", time.Since(start))
return nil, fmt.Errorf("failed to mine contract deploy tx (%s) into a block after %s. Aborting", signedTx.Hash(), time.Since(start))
}

func CreateEthClientConnection(id int64, port uint) ethadapter.EthClient {
Expand Down

0 comments on commit 8babe2e

Please sign in to comment.