rocket-pool / smartnode

The CLI package for Rocket Pool smart nodes.
GNU General Public License v3.0
150 stars 112 forks source link

errors while trying to query BN on Oracle DAO node #690

Closed mendelskiv93 closed 3 weeks ago

mendelskiv93 commented 1 month ago

We are trying to get smartnode metrics by querying the Rocket Pool Metrics Exporter but it times out and fails when querying BN:

Oct 25 14:18:50 rocketpool-daemon[103870]: [Beacon Collector] Error getting sync duties: Could not get validator sync duties: HTTP status 400; response body: '{"code":400,"message":"Invalid validator's index value(s)","stacktraces":["Unable to deserialize data"]}'

it seems like malformed payload because it's an Oracle DAO node and has no validators.

{"lvl":"DBG","ts":"2024-10-25 10:18:53.410+00:00","msg":"Serving API request","topics":"beacnde","peer":"127.0.0.1:51932","meth":"POST","uri":"/eth/v1/validator/duties/sync/320640","path_params":"[(epoch, 320640)]","query_params":"[]","content_body":"(application/json, 4 bytes)"}
{"lvl":"DBG","ts":"2024-10-25 10:18:53.410+00:00","msg":"Failed to deserialize REST JSON data","topics":"rest_nimbusapi","err":"<data>(1, 1) '[' expected","data":"null"}

Payload is actually visible in dataand it is null (4 characters) which is not a valid input to that endpoint.

import results, stew/[assign2, base10, byteutils, endians2],
       serialization, json_serialization,
       json_serialization/std/[net, sets],
       json_serialization/stew/results as jsonSerializationResults

createJsonFlavor RestJson

proc testFoo() =
  let
    data = @[byte('n'), byte('u'), byte('l'), byte('l')]
    decoded =
      try:
        RestJson.decode(data, seq[string],
                        requireAllFields = true,
                        allowUnknownFields = true)
      except SerializationError as exc:
        echo "Failed to decode JSON data",
             ", error = ",
             exc.formatMsg("<data>"),
             ", data = ",
             string.fromBytes(data)
        return

when isMainModule:
  testFoo()

Based on reading the code, GetValidatorSyncDuties doesn't seem to use any kind of serialization framework, just manually constructing the query:https://github.com/rocket-pool/smartnode/blob/4969a80aa3910d7adcb3ab834561c11a2a796e6c/rocketpool/node/collectors/beacon-collector.go#L115-L119 https://github.com/rocket-pool/smartnode/blob/4969a80aa3910d7adcb3ab834561c11a2a796e6c/shared/services/beacon/client/std-http-client.go#L314-L318 and the code formatting the POST request does only json.Marshall: https://github.com/rocket-pool/smartnode/blob/4969a80aa3910d7adcb3ab834561c11a2a796e6c/rocketpool/node/collectors/beacon-collector.go#L115-L119 Which as far as I can tell is only serializing a Golang nil which should be null, 4 bytes from a payload.

package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    data, err := json.Marshal(nil)
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    fmt.Println(string(data)) // Output: null