Skip to content

Commit

Permalink
Testnets: grant sequencer enclaveID permission on L1
Browse files Browse the repository at this point in the history
  • Loading branch information
BedrockSquirrel committed Dec 9, 2024
1 parent 99c6f58 commit bcaf1d1
Show file tree
Hide file tree
Showing 8 changed files with 157 additions and 37 deletions.
34 changes: 33 additions & 1 deletion .github/workflows/manual-deploy-testnet-l2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -359,11 +359,43 @@ jobs:
-postgres_db_host=postgres://tenuser:${{ secrets.TEN_POSTGRES_USER_PWD }}@postgres-ten-${{ github.event.inputs.testnet_type }}.postgres.database.azure.com:5432/ \
start'
check-obscuro-is-healthy:
grant-sequencer-enclaves:
needs:
- build
- deploy
runs-on: ubuntu-latest
environment:
name: ${{ github.event.inputs.testnet_type }}
steps:
- uses: actions/checkout@v4

- name: 'Grant permission to sequencer enclave(s)'
id: grantSequencerPermission
shell: bash
run: |
go run ./testnet/launcher/l1grantsequencers/cmd \
-l1_http_url=${{ secrets.L1_HTTP_URL }} \
-private_key=${{ secrets.ACCOUNT_PK_WORKER }} \
-management_contract_addr=${{ needs.build.outputs.MGMT_CONTRACT_ADDR }} \
-docker_image=${{ vars.L2_HARDHATDEPLOYER_DOCKER_BUILD_TAG }} \
-sequencer_url=http://obscuronode-0-${{ github.event.inputs.testnet_type }}.uksouth.cloudapp.azure.com:10000
- name: 'Save sequencer permissioning container logs'
run: |
docker logs `docker ps -aqf "name=grant-sequencers"` > grant-sequencers.out 2>&1
- name: 'Upload sequencer permissioning container logs'
uses: actions/upload-artifact@v4
with:
name: grant-sequencers
path: |
grant-sequencers.out
retention-days: 7

check-obscuro-is-healthy:
needs:
- grant-sequencer-enclaves
runs-on: ubuntu-latest
environment:
name: ${{ github.event.inputs.testnet_type }}
steps:
Expand Down
10 changes: 6 additions & 4 deletions contracts/scripts/sequencer/001_grant_sequencers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,14 @@ const grantSequencerStatus = async function (mgmtContractAddr: string, enclaveID
}
};

const args = process.argv.slice(2);
if (args.length !== 2) {
throw new Error("Required arguments: <mgmtContractAddr> <enclaveIDs>");
const mgmtContractAddr = process.env.MGMT_CONTRACT_ADDRESS;
const enclaveIDs = process.env.ENCLAVE_IDS;

if (!mgmtContractAddr || !enclaveIDs) {
console.error("Missing required environment variables: MGMT_CONTRACT_ADDRESS and ENCLAVE_IDS.");
process.exit(1);
}

const [mgmtContractAddr, enclaveIDs] = args as [string, string];
grantSequencerStatus(mgmtContractAddr, enclaveIDs)
.then(() => process.exit(0))
.catch((error) => {
Expand Down
34 changes: 6 additions & 28 deletions testnet/launcher/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package launcher

import (
"fmt"
"strings"
"time"

"github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -138,6 +137,11 @@ func (t *Testnet) Start() error {
return fmt.Errorf("unable to configure the l2 contract deployer - %w", err)
}

err = t.grantSequencerStatus(networkConfig.ManagementContractAddress)
if err != nil {
return fmt.Errorf("failed to grant sequencer status: %w", err)
}

err = l2ContractDeployer.Start()
if err != nil {
return fmt.Errorf("unable to start the l2 contract deployer - %w", err)
Expand All @@ -149,11 +153,6 @@ func (t *Testnet) Start() error {
}
fmt.Println("L2 Contracts were successfully deployed...")

err = t.grantSequencerStatus(networkConfig.ManagementContractAddress)
if err != nil {
return fmt.Errorf("failed to grant sequencer status: %w", err)
}

faucetPort := 99
faucetInst, err := faucet.NewDockerFaucet(
faucet.NewFaucetConfig(
Expand Down Expand Up @@ -304,35 +303,14 @@ func waitForHealthyNode(port int) error { // todo: hook the cfg
func (t *Testnet) grantSequencerStatus(mgmtContractAddr string) error {
// fetch enclaveIDs
hostURL := fmt.Sprintf("http://localhost:%d", 80)
client, err := rpc.NewNetworkClient(hostURL)
if err != nil {
return fmt.Errorf("failed to create network client: %w", err)
}
defer client.Stop()

obsClient := obsclient.NewObsClient(client)
health, err := obsClient.Health()
if err != nil {
return fmt.Errorf("failed to get health status: %w", err)
}

if len(health.Enclaves) == 0 {
return fmt.Errorf("could not retrieve enclave IDs from health endpoint")
}

var enclaveIDs []string
for _, status := range health.Enclaves {
enclaveIDs = append(enclaveIDs, status.EnclaveID.String())
}
enclaveIDsStr := strings.Join(enclaveIDs, ",")

l1grantsequencers, err := l1gs.NewGrantSequencers(
l1gs.NewGrantSequencerConfig(
l1gs.WithL1HTTPURL("http://eth2network:8025"),
l1gs.WithPrivateKey("f52e5418e349dccdda29b6ac8b0abe6576bb7713886aa85abea6181ba731f9bb"),
l1gs.WithDockerImage(t.cfg.contractDeployerDockerImage),
l1gs.WithMgmtContractAddress(mgmtContractAddr),
l1gs.WithEnclaveIDs(enclaveIDsStr),
l1gs.WithSequencerURL(hostURL),
),
)
if err != nil {
Expand Down
3 changes: 3 additions & 0 deletions testnet/launcher/l1grantsequencers/cmd/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ type L1GrantSequencersConfigCLI struct {
mgmtContractAddress string
enclaveIDs string
dockerImage string
sequencerURL string
}

// ParseConfigCLI returns a NodeConfigCLI based the cli params and defaults.
Expand All @@ -23,13 +24,15 @@ func ParseConfigCLI() *L1GrantSequencersConfigCLI {
mgmtContractAddress := flag.String(mgmtContractAddressFlag, "", flagUsageMap[mgmtContractAddressFlag])
enclaveIDs := flag.String(enclaveIDsFlag, "", flagUsageMap[enclaveIDsFlag])
dockerImage := flag.String(dockerImageFlag, "testnetobscuronet.azurecr.io/obscuronet/hardhatdeployer:latest", flagUsageMap[dockerImageFlag])
sequencerURL := flag.String(sequencerURLFlag, "", flagUsageMap[sequencerURLFlag])
flag.Parse()

cfg.l1HTTPURL = *l1HTTPURL
cfg.privateKey = *privateKey
cfg.mgmtContractAddress = *mgmtContractAddress
cfg.enclaveIDs = *enclaveIDs
cfg.dockerImage = *dockerImage
cfg.sequencerURL = *sequencerURL

return cfg
}
6 changes: 4 additions & 2 deletions testnet/launcher/l1grantsequencers/cmd/cli_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ package main
const (
l1HTTPURLFlag = "l1_http_url"
privateKeyFlag = "private_key"
mgmtContractAddressFlag = "mgmt_contract_address"
mgmtContractAddressFlag = "management_contract_addr"
enclaveIDsFlag = "enclave_ids"
dockerImageFlag = "docker_image"
contractsEnvFileFlag = "contracts_env_file"
sequencerURLFlag = "sequencer_url"
)

// Returns a map of the flag usages.
Expand All @@ -17,8 +18,9 @@ func getFlagUsageMap() map[string]string {
l1HTTPURLFlag: "Layer 1 network http RPC addr",
privateKeyFlag: "L1 and L2 private key used in the node",
mgmtContractAddressFlag: "L1 management contract address",
enclaveIDsFlag: "List of enclave public keys",
enclaveIDsFlag: "List of enclave public keys to grant sequencer role",
dockerImageFlag: "Docker image to run",
contractsEnvFileFlag: "If set, it will write the contract addresses to the file",
sequencerURLFlag: "Sequencer RPC URL to fetch enclave IDs (required if enclaveIDs are not provided)",
}
}
7 changes: 7 additions & 0 deletions testnet/launcher/l1grantsequencers/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ func main() {
l1gs.WithDockerImage(cliConfig.dockerImage),
l1gs.WithMgmtContractAddress(cliConfig.mgmtContractAddress),
l1gs.WithEnclaveIDs(cliConfig.enclaveIDs),
l1gs.WithSequencerURL(cliConfig.sequencerURL),
),
)
if err != nil {
Expand All @@ -30,5 +31,11 @@ func main() {
os.Exit(1)
}

err = l1grantsequencers.WaitForFinish()
if err != nil {
fmt.Println("unexpected error waiting for grant sequnecer permission script to finish - %w", err)
os.Exit(1)
}
fmt.Println("L1 Sequencer permissions were successfully granted...")
os.Exit(0)
}
8 changes: 8 additions & 0 deletions testnet/launcher/l1grantsequencers/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ type Config struct {
mgmtContractAddress string
enclaveIDs string
dockerImage string
sequencerURL string

// debugEnabled bool
}

Expand Down Expand Up @@ -53,6 +55,12 @@ func WithDockerImage(s string) Option {
}
}

func WithSequencerURL(s string) Option {
return func(c *Config) {
c.sequencerURL = s
}
}

//func WithDebugEnabled(b bool) Option {
// return func(c *Config) {
// c.debugEnabled = b
Expand Down
92 changes: 90 additions & 2 deletions testnet/launcher/l1grantsequencers/docker.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
package l1grantsequencers

import (
"bytes"
"context"
"fmt"
"io"
"strings"
"time"

"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"github.com/ten-protocol/go-ten/go/common/docker"
"github.com/ten-protocol/go-ten/go/obsclient"
"github.com/ten-protocol/go-ten/go/rpc"
)

type GrantSequencers struct {
Expand All @@ -18,14 +27,25 @@ func NewGrantSequencers(cfg *Config) (*GrantSequencers, error) {
}

func (s *GrantSequencers) Start() error {
var enclaveIDs string
var err error
if s.cfg.enclaveIDs != "" {
enclaveIDs = s.cfg.enclaveIDs
} else if s.cfg.sequencerURL != "" {
enclaveIDs, err = fetchEnclaveIDs(s.cfg.sequencerURL)
if err != nil {
return err
}
} else {
return fmt.Errorf("enclaveIDs or sequencerURL must be provided")
}
cmds := []string{
"npx",
"hardhat",
"run",
"--network",
"layer1",
"scripts/sequencer/001_grant_sequencers.ts",
s.cfg.mgmtContractAddress,
s.cfg.enclaveIDs,
}

envs := map[string]string{
Expand All @@ -37,8 +57,12 @@ func (s *GrantSequencers) Start() error {
"accounts": [ "%s" ]
}
}`, s.cfg.l1HTTPURL, s.cfg.privateKey),
"MGMT_CONTRACT_ADDRESS": s.cfg.mgmtContractAddress,
"ENCLAVE_IDS": enclaveIDs,
}

fmt.Printf("Starting grant sequencer script. MgntContractAddress: %s, EnclaveIDs: %s\n", s.cfg.mgmtContractAddress, enclaveIDs)

containerID, err := docker.StartNewContainer(
"grant-sequencers",
s.cfg.dockerImage,
Expand All @@ -55,3 +79,67 @@ func (s *GrantSequencers) Start() error {
s.containerID = containerID
return nil
}

func (s *GrantSequencers) WaitForFinish() error {
cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil {
return fmt.Errorf("failed to create docker client: %w", err)
}
defer cli.Close()

// make sure the container has finished execution
err = docker.WaitForContainerToFinish(s.containerID, 15*time.Minute)
if err != nil {
fmt.Println("Error waiting for container to finish: ", err)
s.PrintLogs(cli)
return err
}

return nil
}

func fetchEnclaveIDs(url string) (string, error) {
// fetch enclaveIDs
client, err := rpc.NewNetworkClient(url)
if err != nil {
return "", fmt.Errorf("failed to create network client (%s): %w", url, err)
}
defer client.Stop()

obsClient := obsclient.NewObsClient(client)
health, err := obsClient.Health()
if err != nil {
return "", fmt.Errorf("failed to get health status: %w", err)
}

if len(health.Enclaves) == 0 {
return "", fmt.Errorf("could not retrieve enclave IDs from health endpoint - no enclaves found")
}

var enclaveIDs []string
for _, status := range health.Enclaves {
enclaveIDs = append(enclaveIDs, status.EnclaveID.String())
}
return strings.Join(enclaveIDs, ","), nil
}

func (s *GrantSequencers) PrintLogs(cli *client.Client) {
logsOptions := types.ContainerLogsOptions{
ShowStdout: true,
ShowStderr: true,
}

// Read the container logs
out, err := cli.ContainerLogs(context.Background(), s.containerID, logsOptions)
if err != nil {
fmt.Printf("Error printing out container %s logs... %v\n", s.containerID, err)
}
defer out.Close()

var buf bytes.Buffer
_, err = io.Copy(&buf, out)
if err != nil {
fmt.Printf("Error getting logs for container %s\n", s.containerID)
}
fmt.Println(buf.String())
}

0 comments on commit bcaf1d1

Please sign in to comment.