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

[LocalNet] Add Path to LocalNet #879

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from
2 changes: 2 additions & 0 deletions .github/workflows-helpers/run-e2e-test-job-template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ spec:
value: /root/.poktroll
- name: APPGATE_SERVER_URL
value: http://${NAMESPACE}-appgate-server:80
- name: PATH_URL
value: http://${NAMESPACE}-path:80
- name: GATEWAY_URL
value: http://${NAMESPACE}-gateway:80
volumeMounts:
Expand Down
59 changes: 58 additions & 1 deletion Tiltfile
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,15 @@ localnet_config_defaults = {
"rest": {
"enabled": True,
},
"path_gateways": {
"count": 1,
},
# By default, we use the `helm_repo` function below to point to the remote repository
# but can update it to the locally cloned repo for testing & development
"helm_chart_local_repo": {"enabled": False, "path": "../helm-charts"},
# By default, we use a pre-built PATH image, but can update it to use a local
# repo instead.
"path_local_repo": {"enabled": False, "path": "../path"},
}
localnet_config_file = read_yaml(localnet_config_path, default=localnet_config_defaults)
# Initial empty config
Expand All @@ -73,7 +79,8 @@ if (localnet_config_file != localnet_config) or (not os.path.exists(localnet_con
print("Updating " + localnet_config_path + " with defaults")
local("cat - > " + localnet_config_path, stdin=encode_yaml(localnet_config))

# Configure helm chart reference. If using a local repo, set the path to the local repo; otherwise, use our own helm repo.
# Configure helm chart reference.
# If using a local repo, set the path to the local repo; otherwise, use our own helm repo.
helm_repo("pokt-network", "https://pokt-network.github.io/helm-charts/")
chart_prefix = "pokt-network/"
if localnet_config["helm_chart_local_repo"]["enabled"]:
Expand All @@ -82,6 +89,14 @@ if localnet_config["helm_chart_local_repo"]["enabled"]:
print("Using local helm chart repo " + helm_chart_local_repo)
chart_prefix = helm_chart_local_repo + "/charts/"

# Configure PATH reference.
# If using a local repo, set the path to the local repo; otherwise, use our own helm repo.
# path_repo("pokt-network", "https://pokt-network.github.io/helm-charts/")
path_local_repo = ""
if localnet_config["path_local_repo"]["enabled"]:
path_local_repo = localnet_config["path_local_repo"]["path"]
hot_reload_dirs.append(path_local_repo)
print("Using local PATH repo " + path_local_repo)

# Observability
print("Observability enabled: " + str(localnet_config["observability"]["enabled"]))
Expand Down Expand Up @@ -341,6 +356,45 @@ for x in range(localnet_config["gateways"]["count"]):
],
)

# Provision PATH Gateway
# Build the Docker image with Tilt (local build)
docker_build("path-gateway-local", path_local_repo)

# TODO_IN_THIS_PR(@okdas): Move configs to values and add helm charts for PATH

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[linter-name (fail-on-found)] reported by reviewdog 🐶
# TODO_IN_THIS_PR(@okdas): Move configs to values and add helm charts for PATH

path_deployment_yaml = str(read_file("./localnet/kubernetes/path-local.yaml", "r"))
actor_number = 0
# Loop to configure and apply multiple PATH gateway deployments
for x in range(localnet_config["path_gateways"]["count"]):
actor_number += 1

# Create the ConfigMap for each gateway instance
configmap_create(
"path-config" + str(actor_number), from_file="localnet/kubernetes/path-config-" + str(actor_number) + ".yaml"
)

# Format the YAML deployment with the actor number and port
formatted_path_deployment_yaml = path_deployment_yaml.format(actor_number=actor_number, port=2999 + actor_number)

# Apply the deployment to Kubernetes using Tilt
k8s_yaml(blob(formatted_path_deployment_yaml))
k8s_resource(
"path-gateway" + str(actor_number),
labels=["gateways"],
resource_deps=["validator"],
# TODO_IMPROVE(, @HebertCL): Update this once PATH has grafana dashboards
# links=[
# link(
# "http://localhost:3003/d/path/protocol-path?orgId=1&refresh=5s&var-path=gateway"
# + str(actor_number),
# "Grafana dashboard",
# ),
# ],
# TODO_IMPROVE(@HebertCL): Add port forwards to grafana, pprof, like the other resources
port_forwards=[str(2999 + actor_number) + ":3000"],
)


# Provision Validators
k8s_resource(
"validator",
labels=["pocket_network"],
Expand All @@ -359,8 +413,10 @@ k8s_resource(
],
)

# Provision anvil (test Ethereum) service nodes
k8s_resource("anvil", labels=["data_nodes"], port_forwards=["8547"])

# Provision ollama (LLM) service nodes
if localnet_config["ollama"]["enabled"]:
print("Ollama enabled: " + str(localnet_config["ollama"]["enabled"]))

Expand All @@ -379,6 +435,7 @@ if localnet_config["ollama"]["enabled"]:
resource_deps=["ollama"],
)

# Provision RESTful (not JSON-RPC) test service nodes
if localnet_config["rest"]["enabled"]:
print("REST enabled: " + str(localnet_config["rest"]["enabled"]))
deployment_create("rest", image="davarski/go-rest-api-demo")
Expand Down
2 changes: 1 addition & 1 deletion api/poktroll/supplier/tx.pulsar.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 11 additions & 9 deletions config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -170,21 +170,23 @@ genesis:
amount: "100000000" # 100 POKT
denom: upokt
applicationList:
- address: pokt1mrqt5f7qh8uxs27cjm9t7v9e74a9vvdnq5jva4
delegatee_gateway_addresses: []
- address: pokt1mrqt5f7qh8uxs27cjm9t7v9e74a9vvdnq5jva4 # app1
delegatee_gateway_addresses: [
pokt15vzxjqklzjtlz7lahe8z2dfe9nm5vxwwmscne4, # gateway1
]
service_configs:
- service_id: anvil
- service_id: "anvil"
- service_id: rest
- service_id: ollama
stake:
# NB: This value should be exactly 1upokt smaller than the value in
# `supplier1_stake_config.yaml` so that the stake command causes a state change.
amount: "100000068" # ~100 POKT
denom: upokt
- address: pokt1ad28jdap2zfanjd7hpkh984yveney6k9a42man
- address: pokt1ad28jdap2zfanjd7hpkh984yveney6k9a42man # apptiny
delegatee_gateway_addresses: []
service_configs:
- service_id: anvil
- service_id: "anvil"
- service_id: rest
- service_id: ollama
stake:
Expand All @@ -202,7 +204,7 @@ genesis:
- owner_address: pokt19a3t4yunp0dlpfjrp7qwnzwlrzd5fzs2gjaaaj
operator_address: pokt19a3t4yunp0dlpfjrp7qwnzwlrzd5fzs2gjaaaj
services:
- service_id: anvil
- service_id: "anvil"
endpoints:
- configs: []
rpc_type: JSON_RPC
Expand Down Expand Up @@ -235,8 +237,8 @@ genesis:
params:
# TODO_MAINNET: Determine realistic amount for minimum gateway stake amount.
min_stake:
amount: "1000000" # 1 POKT
denom: upokt
amount: "1000000" # 1 POKT
denom: upokt
gatewayList:
- address: pokt15vzxjqklzjtlz7lahe8z2dfe9nm5vxwwmscne4
stake:
Expand All @@ -250,7 +252,7 @@ genesis:
amount: "1000000000"
denom: upokt
serviceList:
- id: anvil
- id: "anvil"
name: "anvil"
compute_units_per_relay: 1
owner_address: pokt1cwnu460557x0z78jv3hhc7356hhkrgc86c87q5
Expand Down
10 changes: 9 additions & 1 deletion e2e/tests/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ var (
keyRingFlag = "--keyring-backend=test"
chainIdFlag = "--chain-id=poktroll"
appGateServerUrl = "http://localhost:42069" // Keeping localhost by default because that is how we run the tests on our machines locally
pathUrl = "localhost:3000" // Keeping localhost by default because that is how we run the tests on our machines locally
)

func init() {
Expand All @@ -75,6 +76,11 @@ func init() {
if url := os.Getenv("APPGATE_SERVER_URL"); url != "" {
appGateServerUrl = url
}

// If "APPGATE_SERVER_URL" envar is present, use it for pathUrl
if url := os.Getenv("PATH_URL"); url != "" {
pathUrl = url
}
}

func TestMain(m *testing.M) {
Expand Down Expand Up @@ -463,7 +469,9 @@ func (s *suite) TheApplicationSendsTheSupplierASuccessfulRequestForServiceWithPa
method = "GET"
}

res, err := s.pocketd.RunCurlWithRetry(appGateServerUrl, serviceId, method, path, requestData, 5)
// TODO_IN_THIS_PR: Figure out a plan for deprecating appGateServerUrl in a followup (cleaner) PR

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[linter-name (fail-on-found)] reported by reviewdog 🐶
// TODO_IN_THIS_PR: Figure out a plan for deprecating appGateServerUrl in a followup (cleaner) PR

// res, err := s.pocketd.RunCurlWithRetry(appGateServerUrl, serviceId, method, path, requestData, 5)
res, err := s.pocketd.RunCurlWithRetry(pathUrl, serviceId, method, path, requestData, 5)
require.NoError(s, err, "error sending relay request from app %q to supplier %q for service %q", appName, supplierOperatorName, serviceId)

var jsonContent json.RawMessage
Expand Down
36 changes: 27 additions & 9 deletions e2e/tests/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,16 @@ var (
defaultAppGateServerURL = os.Getenv("APPGATE_SERVER")
// defaultDebugOutput provides verbose output on manipulations with binaries (cli command, stdout, stderr)
defaultDebugOutput = os.Getenv("E2E_DEBUG_OUTPUT")
// serviceIdToAliasMap maps service IDs to their respective aliases
// This is useful for gateway operators that map static on-chain names
// to semantic, easier to understand, off-chain names.
serviceIdToAliasMap = map[string]string{
"anvil": "anvil",
}
)

const ()

func isVerbose() bool {
return defaultDebugOutput == "true"
}
Expand Down Expand Up @@ -172,13 +180,8 @@ func (p *pocketdBin) runPocketCmd(args ...string) (*commandResult, error) {

// runCurlPostCmd is a helper to run a command using the local pocketd binary with the flags provided
func (p *pocketdBin) runCurlCmd(rpcUrl, service, method, path, data string, args ...string) (*commandResult, error) {
// Ensure that if a path is provided, it starts with a "/".
// This is required for RESTful APIs that use a path to identify resources.
// For JSON-RPC APIs, the resource path should be empty, so empty paths are allowed.
if len(path) > 0 && path[0] != '/' {
path = "/" + path
}
urlStr := fmt.Sprintf("%s/%s%s", rpcUrl, service, path)
serviceAlias := serviceIdToAliasMap[service]
urlStr := formatURLString(serviceAlias, rpcUrl, path)
base := []string{
"-v", // verbose output
"-sS", // silent with error
Expand All @@ -190,8 +193,7 @@ func (p *pocketdBin) runCurlCmd(rpcUrl, service, method, path, data string, args
if method == "POST" {
base = append(base, "--data", data)
} else if len(data) > 0 {
fmt.Println(fmt.Sprintf("WARN: data provided but not being included in the %s request", method))

fmt.Printf("WARN: data provided but not being included in the %s request", method)
}
args = append(base, args...)
commandStr := "curl " + strings.Join(args, " ") // Create a string representation of the command
Expand Down Expand Up @@ -220,3 +222,19 @@ func (p *pocketdBin) runCurlCmd(rpcUrl, service, method, path, data string, args

return r, err
}

// formatURLString returns RESTful or JSON-RPC API endpoint URL depending
// on the parameters provided.
func formatURLString(serviceAlias, rpcUrl, path string) string {
// For JSON-RPC APIs, the path should be empty
if len(path) == 0 {
return fmt.Sprintf("http://%s.%s/v1", serviceAlias, rpcUrl)
}

// For RESTful APIs, the path should not be empty.
// We remove the leading / to make the format string below easier to read.
if path[0] == '/' {
path = path[1:]
}
return fmt.Sprintf("http://%s.%s/v1/%s", serviceAlias, rpcUrl, path)
}
17 changes: 17 additions & 0 deletions localnet/kubernetes/path-config-1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
shannon_config:
full_node_config:
rpc_url: tcp://validator-poktroll-validator:26657
grpc_config:
host_port: validator-poktroll-validator:9090
insecure: true
# TODO: Allow sovereign soverign apps to sign their own relay requests.

Check warning on line 7 in localnet/kubernetes/path-config-1.yaml

View workflow job for this annotation

GitHub Actions / misspell

[misspell] localnet/kubernetes/path-config-1.yaml#L7

"soverign" is a misspelling of "sovereign"
Raw output
./localnet/kubernetes/path-config-1.yaml:7:28: "soverign" is a misspelling of "sovereign"
gateway_address: pokt15vzxjqklzjtlz7lahe8z2dfe9nm5vxwwmscne4 # gateway1
gateway_private_key: cf09805c952fa999e9a63a9f434147b0a5abfd10f268879694c6b5a70e1ae177
# TODO: Populate delegated_app_addres ses from on-chain records.

Check warning on line 10 in localnet/kubernetes/path-config-1.yaml

View workflow job for this annotation

GitHub Actions / misspell

[misspell] localnet/kubernetes/path-config-1.yaml#L10

"addres" is a misspelling of "address"
Raw output
./localnet/kubernetes/path-config-1.yaml:10:35: "addres" is a misspelling of "address"
delegated_app_addresses:
- pokt1mrqt5f7qh8uxs27cjm9t7v9e74a9vvdnq5jva4 # app1

services:
# Path needs 0021 service ID to handle EVM relays.
"anvil":
alias: anvil
14 changes: 14 additions & 0 deletions localnet/kubernetes/path-config-2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
shannon_config:
full_node_config:
rpc_url: tcp://validator-poktroll-validator:26657
grpc_config:
host_port: validator-poktroll-validator:9090
insecure: true
gateway_address: pokt15w3fhfyc0lttv7r585e2ncpf6t2kl9uh8rsnyz # gateway2
gateway_private_key: 177ba43cec962ea407f71da9c3994ba685708e82d5d7a6d7da3268e74119bf88
delegated_app_addresses:
- pokt1mrqt5f7qh8uxs27cjm9t7v9e74a9vvdnq5jva4 # app1

services:
"anvil":
alias: anvil
14 changes: 14 additions & 0 deletions localnet/kubernetes/path-config-3.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
shannon_config:
full_node_config:
rpc_url: tcp://validator-poktroll-validator:26657
grpc_config:
host_port: validator-poktroll-validator:9090
insecure: true
gateway_address: pokt1zhmkkd0rh788mc9prfq0m2h88t9ge0j83gnxya # gateway3
gateway_private_key: f73b6f7f0b9c99603c7eeddbf1c419c6f6bbc241f3798e3e4c8da9769ca81c26
delegated_app_addresses:
- pokt1mrqt5f7qh8uxs27cjm9t7v9e74a9vvdnq5jva4 # app3

services:
"anvil":
alias: anvil
45 changes: 45 additions & 0 deletions localnet/kubernetes/path-local.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: path-gateway{actor_number}
spec:
replicas: 1
selector:
matchLabels:
app: path-gateway{actor_number}
template:
metadata:
labels:
app: path-gateway{actor_number}
spec:
containers:
- name: path-gateway
image: path-gateway-local:latest # Local image tag
imagePullPolicy: Never # Ensure Kubernetes uses local image
ports:
- containerPort: 3000
volumeMounts:
- name: path-config{actor_number}
mountPath: /app/.config.yaml
subPath: .config.yaml
volumes:
- name: path-config{actor_number}
configMap:
name: path-config{actor_number}
items:
- key: path-config-{actor_number}.yaml
path: .config.yaml
---
apiVersion: v1
kind: Service
metadata:
name: path-gateway{actor_number}
spec:
selector:
app: path-gateway{actor_number}
ports:
- protocol: TCP
name: rpc
port: {port}
targetPort: 3000
Loading
Loading