SSZ web api for decoding input data (#2473)

* first pass ssz server for decoding deposit input data

* fix decoding

* revert viz change on helper

* add image target

* use /api prefix, add deployment for cluster

* fix lint
This commit is contained in:
Preston Van Loon
2019-05-03 01:11:54 -04:00
committed by Raul Jordan
parent 7007a9e8fa
commit 9fb5bbd662
4 changed files with 224 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
kind: Deployment
apiVersion: apps/v1
metadata:
name: ssz-server
namespace: beacon-chain
labels:
app: beacon-chain
component: ssz-server
version: v1
spec:
replicas: 2
selector:
matchLabels:
app: beacon-chain
component: ssz-server
version: v1
template:
metadata:
labels:
app: beacon-chain
component: ssz-server
version: v1
spec:
priorityClassName: production-priority
containers:
- name: site
image: gcr.io/prysmaticlabs/prysm/ssz-server:latest
livenessProbe:
httpGet:
path: /healthz
port: 4000
resources:
requests:
cpu: "100m"
ports:
- containerPort: 4000
name: http
---
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
name: ssz-server
namespace: beacon-chain
spec:
scaleTargetRef:
apiVersion: extensions/v1beta1
kind: Deployment
name: ssz-server
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
targetAverageUtilization: 80
---
kind: Service
apiVersion: v1
metadata:
name: ssz-server
namespace: beacon-chain
spec:
selector:
app: beacon-chain
component: ssz-server
ports:
- port: 4000
targetPort: 4000
name: http
type: ClusterIP

View File

@@ -100,6 +100,16 @@ spec:
gateways:
- prylabs-wildcard-gateway
http:
- match:
- uri:
prefix: /ssz
rewrite:
uri: /api
route:
- destination:
port:
number: 4000
host: ssz-server.beacon-chain.svc.cluster.local
- match:
- uri:
prefix: /

View File

@@ -0,0 +1,48 @@
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
load("@io_bazel_rules_docker//go:image.bzl", "go_image")
load("@io_bazel_rules_docker//container:container.bzl", "container_push")
go_library(
name = "go_default_library",
srcs = ["main.go"],
importpath = "github.com/prysmaticlabs/prysm/tools/ssz-server",
visibility = ["//visibility:private"],
deps = [
"//proto/beacon/p2p/v1:go_default_library",
"//shared/ssz:go_default_library",
],
)
go_binary(
name = "ssz-server",
embed = [":go_default_library"],
visibility = ["//visibility:public"],
)
go_image(
name = "image",
srcs = ["main.go"],
importpath = "github.com/prysmaticlabs/prysm/tools/ssz-server",
visibility = ["//visibility:private"],
static = "on",
tags = ["manual"],
goarch = "amd64",
goos = "linux",
deps = [
"//proto/beacon/p2p/v1:go_default_library",
"//shared/ssz:go_default_library",
],
race = "off",
pure = "on",
)
container_push(
name = "push_image",
format = "Docker",
image = ":image",
registry = "gcr.io",
repository = "prysmaticlabs/prysm/ssz-server",
tag = "latest",
tags = ["manual"],
visibility = ["//visibility:private"],
)

96
tools/ssz-server/main.go Normal file
View File

@@ -0,0 +1,96 @@
// This binary is a simple ssz deserializer REST API endpoint for the testnet
// frontend to decode the deposit data for the user.
// This should be removed after https://github.com/prysmaticlabs/prysm-testnet-site/issues/37
// is resolved.
package main
import (
"bytes"
"encoding/hex"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/ssz"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/healthz", healthz)
mux.HandleFunc("/api/decodeDepositData", decodeDepositData)
log.Println("Starting on port 4000")
if err := http.ListenAndServe(":4000", mux); err != nil {
log.Fatalf("Failed to start server %v", err)
}
}
func healthz(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}
type deserializationRequest struct {
Data string `json:"data"`
}
func decodeDepositData(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
data, err := ioutil.ReadAll(r.Body)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Printf("Failed to read request body: %v\n", err)
return
}
requestData := &deserializationRequest{}
if err := json.Unmarshal(data, requestData); err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Printf("Unable to unmarshal JSON: %v\n", err)
return
}
if len(requestData.Data) < 2 {
w.WriteHeader(http.StatusBadRequest)
return
}
encodedData, err := hex.DecodeString(requestData.Data[2:])
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
_, err = fmt.Fprintf(w, "Failed to decode hex string")
if err != nil {
log.Printf("Failed to write data to client: %v\n", err)
}
return
}
di := &pb.DepositInput{}
if err := ssz.Decode(bytes.NewReader(encodedData), di); err != nil {
w.WriteHeader(http.StatusInternalServerError)
_, err := fmt.Fprintf(w, "Failed to decode SSZ data: %v", err)
if err != nil {
log.Printf("Failed to write data to client: %v\n", err)
}
return
}
b, err := json.Marshal(di)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
log.Printf("Failed to marshal deposit data: %v\n", err)
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
_, err = w.Write(b)
if err != nil {
log.Printf("Failed to write data to client: %v\n", err)
}
}