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

PRT-XYZ Fix invalid parsing and add unit tests #298

Merged
merged 9 commits into from
Feb 14, 2023
Merged
6 changes: 2 additions & 4 deletions .github/workflows/protocol_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,8 @@ jobs:
######################################################
### Run protocol unitests
######################################################
- name: Run Lava Session Tests
run: go test ./protocol/lavasession/ -v
- name: Run Lava Chain Tracker Tests
run: go test ./protocol/chaintracker/ -v
- name: Run Lava Protocol Tests
run: go test ./protocol/... -v
- name: Run Lava Chain Proxy Tests
run: go test ./relayer/chainproxy/ -v
- name: Run Relayer Metrics Unit Tests
Expand Down
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ require (
require (
cosmossdk.io/api v0.2.5
github.com/CosmWasm/wasmvm v1.2.0
github.com/CosmosContracts/juno v1.0.2
github.com/coniks-sys/coniks-go v0.0.0-20180722014011-11acf4819b71
github.com/cosmos/cosmos-proto v1.0.0-alpha8
github.com/cosmos/gogoproto v1.4.3
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,6 @@ github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQ
github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4=
github.com/CosmWasm/wasmvm v1.2.0 h1:pNCp175id+r/dSa4Ii5zoTkmauOoeipkvepvEJM1bao=
github.com/CosmWasm/wasmvm v1.2.0/go.mod h1:OIhXFPi9BbcEL1USBj4OIrBTtSSds+9eEql56fsdyfE=
github.com/CosmosContracts/juno v1.0.2 h1:iMSc72BH5emXz3XbZbHaPSqAa4LGNVuyXRDrirMeAo8=
github.com/CosmosContracts/juno v1.0.2/go.mod h1:u9rHzjcjQmgSIRZdNl9XCOELdFyZDktiTqdDqHVFgWk=
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func GetTendermintRPCError(jsonError *rpcclient.JsonError) (*tenderminttypes.RPC
func ConvertErrorToRPCError(errString string, code int) *tenderminttypes.RPCError {
var rpcError *tenderminttypes.RPCError
unmarshalError := json.Unmarshal([]byte(errString), &rpcError)
if unmarshalError != nil {
if unmarshalError != nil || (rpcError.Data == "" && rpcError.Message == "") {
utils.LavaFormatWarning("Failed unmarshalling error tendermintrpc", unmarshalError, &map[string]string{"err": errString})
rpcError = &tenderminttypes.RPCError{
Code: code,
Expand Down
71 changes: 0 additions & 71 deletions protocol/chainlib/chainproxy/thirdparty/grpc_test.go

This file was deleted.

4 changes: 2 additions & 2 deletions protocol/chainlib/grpc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func TestGRPCChainParser_Spec(t *testing.T) {
Enabled: true,
ReliabilityThreshold: 10,
AllowedBlockLagForQosSync: 11,
AverageBlockTime: 12,
AverageBlockTime: 12000,
BlockDistanceForFinalizedData: 13,
BlocksInFinalizationProof: 14,
}
Expand All @@ -35,7 +35,7 @@ func TestGRPCChainParser_Spec(t *testing.T) {
allowedBlockLagForQosSync, averageBlockTime, blockDistanceForFinalizedData, blocksInFinalizationProof := apip.ChainBlockStats()

// convert block time
AverageBlockTime := time.Duration(apip.spec.AverageBlockTime) * time.Second
AverageBlockTime := time.Duration(apip.spec.AverageBlockTime) * time.Millisecond

// check that the spec was set correctly
assert.Equal(t, apip.spec.Enabled, enabled)
Expand Down
4 changes: 2 additions & 2 deletions protocol/chainlib/jsonRPC_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func TestJSONChainParser_Spec(t *testing.T) {
Enabled: true,
ReliabilityThreshold: 10,
AllowedBlockLagForQosSync: 11,
AverageBlockTime: 12,
AverageBlockTime: 12000,
BlockDistanceForFinalizedData: 13,
BlocksInFinalizationProof: 14,
}
Expand All @@ -36,7 +36,7 @@ func TestJSONChainParser_Spec(t *testing.T) {
allowedBlockLagForQosSync, averageBlockTime, blockDistanceForFinalizedData, blocksInFinalizationProof := apip.ChainBlockStats()

// convert block time
AverageBlockTime := time.Duration(apip.spec.AverageBlockTime) * time.Second
AverageBlockTime := time.Duration(apip.spec.AverageBlockTime) * time.Millisecond

// check that the spec was set correctly
assert.Equal(t, apip.spec.Enabled, enabled)
Expand Down
4 changes: 2 additions & 2 deletions protocol/chainlib/rest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func TestRestChainParser_Spec(t *testing.T) {
Enabled: true,
ReliabilityThreshold: 10,
AllowedBlockLagForQosSync: 11,
AverageBlockTime: 12,
AverageBlockTime: 12000,
BlockDistanceForFinalizedData: 13,
BlocksInFinalizationProof: 14,
}
Expand All @@ -35,7 +35,7 @@ func TestRestChainParser_Spec(t *testing.T) {
allowedBlockLagForQosSync, averageBlockTime, blockDistanceForFinalizedData, blocksInFinalizationProof := apip.ChainBlockStats()

// convert block time
AverageBlockTime := time.Duration(apip.spec.AverageBlockTime) * time.Second
AverageBlockTime := time.Duration(apip.spec.AverageBlockTime) * time.Millisecond

// check that the spec was set correctly
assert.Equal(t, apip.spec.Enabled, enabled)
Expand Down
4 changes: 2 additions & 2 deletions protocol/chainlib/tendermintRPC_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func TestTendermintChainParser_Spec(t *testing.T) {
Enabled: true,
ReliabilityThreshold: 10,
AllowedBlockLagForQosSync: 11,
AverageBlockTime: 12,
AverageBlockTime: 12000,
BlockDistanceForFinalizedData: 13,
BlocksInFinalizationProof: 14,
}
Expand All @@ -36,7 +36,7 @@ func TestTendermintChainParser_Spec(t *testing.T) {
allowedBlockLagForQosSync, averageBlockTime, blockDistanceForFinalizedData, blocksInFinalizationProof := apip.ChainBlockStats()

// convert block time
AverageBlockTime := time.Duration(apip.spec.AverageBlockTime) * time.Second
AverageBlockTime := time.Duration(apip.spec.AverageBlockTime) * time.Millisecond

// check that the spec was set correctly
assert.Equal(t, apip.spec.Enabled, enabled)
Expand Down
29 changes: 22 additions & 7 deletions protocol/common/rpcconsumerlogs.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package common

import (
"fmt"
"encoding/json"
"math/rand"
"os"
"strconv"

"github.com/gofiber/fiber/v2"
"github.com/gofiber/websocket/v2"
"github.com/joho/godotenv"
"github.com/lavanet/lava/relayer/metrics"
Expand Down Expand Up @@ -57,14 +58,23 @@ func (pl *RPCConsumerLogs) GetMessageSeed() string {

// Input will be masked with a random GUID if returnMaskedErrors is set to true
func (pl *RPCConsumerLogs) GetUniqueGuidResponseForError(responseError error, msgSeed string) string {
var ret string
ret = "Error GUID: " + msgSeed
utils.LavaFormatError("UniqueGuidResponseForError", responseError, &map[string]string{"msgSeed": msgSeed})
type ErrorData struct {
Error_GUID string `json:"Error_GUID"`
Error string `json:"Error,omitempty"`
}

data := ErrorData{
Error_GUID: msgSeed,
}
if ReturnMaskedErrors == "false" {
ret += fmt.Sprintf(", Error: %v", responseError)
data.Error = responseError.Error()
}

return ret
utils.LavaFormatError("UniqueGuidResponseForError", responseError, &map[string]string{"msgSeed": msgSeed})

ret, _ := json.Marshal(data)

return string(ret)
}

// Websocket healthy disconnections throw "websocket: close 1005 (no status)" error,
Expand All @@ -76,7 +86,12 @@ func (pl *RPCConsumerLogs) AnalyzeWebSocketErrorAndWriteMessage(c *websocket.Con
return
}
pl.LogRequestAndResponse(rpcType+" ws msg", true, "ws", c.LocalAddr().String(), string(msg), "", msgSeed, err)
c.WriteMessage(mt, []byte("Error Received: "+pl.GetUniqueGuidResponseForError(err, msgSeed)))

jsonResponse, _ := json.Marshal(fiber.Map{
"Error_Received": pl.GetUniqueGuidResponseForError(err, msgSeed),
})

c.WriteMessage(mt, jsonResponse)
}
}

Expand Down
94 changes: 94 additions & 0 deletions protocol/common/rpcconsumerlogs_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package common
ranlavanet marked this conversation as resolved.
Show resolved Hide resolved

import (
"encoding/json"
"errors"
"testing"

"github.com/gofiber/fiber/v2"
"github.com/gofiber/websocket/v2"
websocket2 "github.com/gorilla/websocket"
"github.com/stretchr/testify/assert"
)

type WebSocketError struct {
ErrorReceived string `json:"Error_Received"`
}

type ErrorData struct {
GUID string `json:"Error_GUID"`
Error1 string `json:"Error"`
}

func TestGetUniqueGuidResponseForError(t *testing.T) {
plog, err := NewRPCConsumerLogs()
assert.Nil(t, err)

responseError := errors.New("response error")

errorMsg := plog.GetUniqueGuidResponseForError(responseError, "msgSeed")

errObject := &ErrorData{}

err = json.Unmarshal([]byte(errorMsg), errObject)
assert.Nil(t, err)
assert.Equal(t, errObject.GUID, "msgSeed")
assert.Equal(t, errObject.Error1, "response error")
}

func TestGetUniqueGuidResponseDeterministic(t *testing.T) {
plog, err := NewRPCConsumerLogs()
assert.Nil(t, err)

responseError := errors.New("response error")
errorMsg := plog.GetUniqueGuidResponseForError(responseError, "msgSeed")

for i := 1; i < 10000; i++ {
err := plog.GetUniqueGuidResponseForError(responseError, "msgSeed")

assert.Equal(t, err, errorMsg)
}
}

func TestAnalyzeWebSocketErrorAndWriteMessage(t *testing.T) {
app := fiber.New()

app.Get("/", websocket.New(func(c *websocket.Conn) {
mt, _, _ := c.ReadMessage()
plog, _ := NewRPCConsumerLogs()
responseError := errors.New("response error")
plog.AnalyzeWebSocketErrorAndWriteMessage(c, mt, responseError, "seed", []byte{}, "rpcType")
}))

go app.Listen("127.0.0.1:3000")
defer func() {
app.Shutdown()
}()

url := "ws://localhost:3000/"
dialer := &websocket2.Dialer{}
conn, _, err := dialer.Dial(url, nil)
if err != nil {
t.Fatalf("Error dialing websocket connection: %s", err)
}
defer conn.Close()

err = conn.WriteMessage(websocket.TextMessage, []byte("test"))
if err != nil {
t.Fatalf("Error writing message to websocket connection: %s", err)
}

_, response, err := conn.ReadMessage()
if err != nil {
t.Fatalf("Error reading message from websocket connection: %s", err)
}

errObject := &WebSocketError{}

err = json.Unmarshal(response, errObject)
assert.Nil(t, err)

errData := &ErrorData{}
err = json.Unmarshal([]byte(errObject.ErrorReceived), errData)
assert.Equal(t, errData.GUID, "seed")
}
32 changes: 25 additions & 7 deletions relayer/chainproxy/portalLogs.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package chainproxy

import (
"fmt"
"encoding/json"
"math/rand"
"os"
"strconv"
Expand Down Expand Up @@ -58,14 +58,23 @@ func (pl *PortalLogs) GetMessageSeed() string {

// Input will be masked with a random GUID if returnMaskedErrors is set to true
func (pl *PortalLogs) GetUniqueGuidResponseForError(responseError error, msgSeed string) string {
var ret string
ret = "Error GUID: " + msgSeed
utils.LavaFormatError("UniqueGuidResponseForError", responseError, &map[string]string{"msgSeed": msgSeed})
type ErrorData struct {
Error_GUID string `json:"Error_GUID"`
Error string `json:"Error,omitempty"`
}

data := ErrorData{
Error_GUID: msgSeed,
}
if ReturnMaskedErrors == "false" {
ret += fmt.Sprintf(", Error: %v", responseError)
data.Error = responseError.Error()
}

return ret
utils.LavaFormatError("UniqueGuidResponseForError", responseError, &map[string]string{"msgSeed": msgSeed})

ret, _ := json.Marshal(data)

return string(ret)
}

// Websocket healthy disconnections throw "websocket: close 1005 (no status)" error,
Expand All @@ -77,7 +86,16 @@ func (pl *PortalLogs) AnalyzeWebSocketErrorAndWriteMessage(c *websocket.Conn, mt
return
}
pl.LogRequestAndResponse(rpcType+" ws msg", true, "ws", c.LocalAddr().String(), string(msg), "", msgSeed, err)
c.WriteMessage(mt, []byte("Error Received: "+pl.GetUniqueGuidResponseForError(err, msgSeed)))

type ErrorResponse struct {
ErrorReceived string `json:"Error_Received"`
}

jsonResponse, _ := json.Marshal(ErrorResponse{
ErrorReceived: pl.GetUniqueGuidResponseForError(err, msgSeed),
})

c.WriteMessage(mt, jsonResponse)
}
}

Expand Down
2 changes: 1 addition & 1 deletion relayer/chainproxy/tendermintRPC.go
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ func getTendermintRPCError(jsonError *rpcclient.JsonError) (*tenderminttypes.RPC
func convertErrorToRPCError(errString string, code int) *tenderminttypes.RPCError {
var rpcError *tenderminttypes.RPCError
unmarshalError := json.Unmarshal([]byte(errString), &rpcError)
if unmarshalError != nil {
if unmarshalError != nil || (rpcError.Data == "" && rpcError.Message == "") {
utils.LavaFormatWarning("Failed unmarshalling error tendermintrpc", unmarshalError, &map[string]string{"err": errString})
rpcError = &tenderminttypes.RPCError{
Code: code,
Expand Down