Skip to content

Commit

Permalink
Merge branch 'develop' into BCF-2612-ChainReader-Next
Browse files Browse the repository at this point in the history
  • Loading branch information
nolag committed Jan 22, 2024
2 parents 40bb712 + f0543e6 commit d4c0b69
Show file tree
Hide file tree
Showing 12 changed files with 364 additions and 23 deletions.
1 change: 1 addition & 0 deletions .github/workflows/automation-benchmark-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ on:
- SEPOLIA
- BASE_GOERLI
- ARBITRUM_SEPOLIA
- LINEA_GOERLI
TestInputs:
description: TestInputs
required: false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,20 @@ spec:
selector:
matchLabels:
app: {{ $.Release.Name }}-db
# Used for testing.
# havoc-component-group and havoc-network-group are used by "havoc" chaos testing tool
havoc-component-group: db
havoc-network-group: db
instance: {{ $cfg.name }}-db
release: {{ $.Release.Name }}
template:
metadata:
labels:
app: {{ $.Release.Name }}-db
# Used for testing.
# havoc-component-group and havoc-network-group are used by "havoc" chaos testing tool
havoc-component-group: db
havoc-network-group: db
instance: {{ $cfg.name }}-db
release: {{ $.Release.Name }}
{{- range $key, $value := $.Values.labels }}
Expand Down
25 changes: 19 additions & 6 deletions charts/chainlink-cluster/templates/chainlink-node-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,39 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ $.Release.Name }}-{{ $cfg.name }}
name: {{ if eq $index 0 }}{{ $.Release.Name }}-{{ $cfg.name }}-bootstrap{{ else }}{{ $.Release.Name }}-{{ $cfg.name }}{{ end }}
spec:
strategy:
# Need to recreate the pod to deal with lease lock held by old pod.
type: Recreate
selector:
matchLabels:
app: {{ $.Release.Name }}
# Used for testing.
# havoc-component-group and havoc-network-group are used by "havoc" chaos testing tool
{{ if eq $index 0 }}{{ else }}
havoc-component-group: node
{{ end }}
{{ if eq $index 0 }}{{ else }}
havoc-network-group: {{ if gt $index 2 }}"1"{{ else }}"2"{{ end }}
{{ end }}
instance: {{ $cfg.name }}
release: {{ $.Release.Name }}
template:
metadata:
labels:
app: {{ $.Release.Name }}
# Used for testing.
# havoc-component-group and havoc-network-group are used by "havoc" chaos testing tool
{{ if eq $index 0 }}{{ else }}
havoc-component-group: node
{{ end }}
{{ if eq $index 0 }}{{ else }}
havoc-network-group: {{ if gt $index 2 }}"1"{{ else }}"2"{{ end }}
{{ end }}

instance: {{ $cfg.name }}
release: {{ $.Release.Name }}
# Used for testing. Role value should either be: bootstrap or node.
# There should only be one "bootstrap" node, the rest should be "node".
# Here we set the first node to be bootstrap, the rest to be node.
role: {{ if eq $index 0 }}bootstrap{{ else }}node{{ end }}
{{- range $key, $value := $.Values.labels }}
{{ $key }}: {{ $value | quote }}
{{- end }}
Expand All @@ -43,7 +56,7 @@ spec:
{{- toYaml $.Values.chainlink.securityContext | nindent 12 }}
image: {{ default "public.ecr.aws/chainlink/chainlink" $cfg.image }}
imagePullPolicy: Always
command: ["bash", "-c", "while ! pg_isready -U postgres --host {{ $.Release.Name }}-db-{{ $cfg.name }} --port 5432; do echo \"waiting for database to start\"; sleep 1; done && chainlink -c /etc/node-secrets-volume/default.toml -c /etc/node-secrets-volume/overrides.toml -secrets /etc/node-secrets-volume/secrets.toml node start -d -p /etc/node-secrets-volume/node-password -a /etc/node-secrets-volume/apicredentials --vrfpassword=/etc/node-secrets-volume/apicredentials"]
command: [ "bash", "-c", "while ! pg_isready -U postgres --host {{ $.Release.Name }}-db-{{ $cfg.name }} --port 5432; do echo \"waiting for database to start\"; sleep 1; done && chainlink -c /etc/node-secrets-volume/default.toml -c /etc/node-secrets-volume/overrides.toml -secrets /etc/node-secrets-volume/secrets.toml node start -d -p /etc/node-secrets-volume/node-password -a /etc/node-secrets-volume/apicredentials --vrfpassword=/etc/node-secrets-volume/apicredentials" ]
ports:
- name: access
containerPort: {{ $.Values.chainlink.web_port }}
Expand Down
8 changes: 8 additions & 0 deletions charts/chainlink-cluster/templates/geth-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,19 @@ spec:
selector:
matchLabels:
app: geth
# Used for testing.
# havoc-component-group and havoc-network-group are used by "havoc" chaos testing tool
havoc-component-group: "blockchain"
havoc-network-group: "blockchain"
release: {{ .Release.Name }}
template:
metadata:
labels:
app: geth
# Used for testing.
# havoc-component-group and havoc-network-group are used by "havoc" chaos testing tool
havoc-component-group: "blockchain"
havoc-network-group: "blockchain"
release: {{ .Release.Name }}
annotations:
{{- range $key, $value := .Values.podAnnotations }}
Expand Down
6 changes: 2 additions & 4 deletions core/chains/legacyevm/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -474,15 +474,13 @@ func newEthClientFromCfg(cfg evmconfig.NodePool, noNewHeadsThreshold time.Durati
var sendonlys []commonclient.SendOnlyNode[*big.Int, evmclient.RPCCLient]
for i, node := range nodes {
if node.SendOnly != nil && *node.SendOnly {
name := fmt.Sprintf("eth-sendonly-rpc-%d", i)
rpc := evmclient.NewRPCClient(lggr, empty, (*url.URL)(node.HTTPURL), name, int32(i), chainID,
rpc := evmclient.NewRPCClient(lggr, empty, (*url.URL)(node.HTTPURL), *node.Name, int32(i), chainID,
commonclient.Secondary)
sendonly := commonclient.NewSendOnlyNode[*big.Int, evmclient.RPCCLient](lggr, (url.URL)(*node.HTTPURL),
*node.Name, chainID, rpc)
sendonlys = append(sendonlys, sendonly)
} else {
name := fmt.Sprintf("eth-primary-rpc-%d", i)
rpc := evmclient.NewRPCClient(lggr, (url.URL)(*node.WSURL), (*url.URL)(node.HTTPURL), name, int32(i),
rpc := evmclient.NewRPCClient(lggr, (url.URL)(*node.WSURL), (*url.URL)(node.HTTPURL), *node.Name, int32(i),
chainID, commonclient.Primary)
primaryNode := commonclient.NewNode[*big.Int, *evmtypes.Head, evmclient.RPCCLient](cfg, noNewHeadsThreshold,
lggr, (url.URL)(*node.WSURL), (*url.URL)(node.HTTPURL), *node.Name, int32(i), chainID, *node.Order,
Expand Down
39 changes: 39 additions & 0 deletions core/services/pipeline/internal/eautils/eautils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package eautils

import (
"encoding/json"
"net/http"
)

type AdapterStatus struct {
ErrorMessage *string `json:"errorMessage"`
Error any `json:"error"`
StatusCode *int `json:"statusCode"`
ProviderStatusCode *int `json:"providerStatusCode"`
}

func BestEffortExtractEAStatus(responseBytes []byte) (code int, ok bool) {
var status AdapterStatus
err := json.Unmarshal(responseBytes, &status)
if err != nil {
return 0, false
}

if status.StatusCode == nil {
return 0, false
}

if *status.StatusCode != http.StatusOK {
return *status.StatusCode, true
}

if status.ProviderStatusCode != nil && *status.ProviderStatusCode != http.StatusOK {
return *status.ProviderStatusCode, true
}

if status.Error != nil {
return http.StatusInternalServerError, true
}

return *status.StatusCode, true
}
61 changes: 61 additions & 0 deletions core/services/pipeline/internal/eautils/eautils_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package eautils

import (
"net/http"
"testing"

"github.com/stretchr/testify/assert"
)

func TestBestEffortExtractEAStatus(t *testing.T) {
tests := []struct {
name string
arg []byte
expectCode int
expectOk bool
}{
{
name: "invalid object",
arg: []byte(`{"error": "invalid json object" `),
expectCode: 0,
expectOk: false,
},
{
name: "no status code in object",
arg: []byte(`{}`),
expectCode: 0,
expectOk: false,
},
{
name: "invalid status code",
arg: []byte(`{"statusCode":400}`),
expectCode: http.StatusBadRequest,
expectOk: true,
},
{
name: "invalid provider status code",
arg: []byte(`{"statusCode":200, "providerStatusCode":500}`),
expectCode: http.StatusInternalServerError,
expectOk: true,
},
{
name: "valid statuses with error message",
arg: []byte(`{"statusCode":200, "providerStatusCode":200, "error": "unexpected error"}`),
expectCode: http.StatusInternalServerError,
expectOk: true,
},
{
name: "valid status code",
arg: []byte(`{"statusCode":200}`),
expectCode: http.StatusOK,
expectOk: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
code, ok := BestEffortExtractEAStatus(tt.arg)
assert.Equal(t, tt.expectCode, code)
assert.Equal(t, tt.expectOk, ok)
})
}
}
9 changes: 8 additions & 1 deletion core/services/pipeline/task.bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (

"github.com/smartcontractkit/chainlink/v2/core/bridges"
"github.com/smartcontractkit/chainlink/v2/core/logger"
"github.com/smartcontractkit/chainlink/v2/core/services/pipeline/internal/eautils"
)

// NOTE: These metrics generate a new label per bridge, this should be safe
Expand Down Expand Up @@ -167,7 +168,13 @@ func (t *BridgeTask) Run(ctx context.Context, lggr logger.Logger, vars Vars, inp

var cachedResponse bool
responseBytes, statusCode, headers, elapsed, err := makeHTTPRequest(requestCtx, lggr, "POST", url, reqHeaders, requestData, t.httpClient, t.config.DefaultHTTPLimit())
if err != nil {

// check for external adapter response object status
if code, ok := eautils.BestEffortExtractEAStatus(responseBytes); ok {
statusCode = code
}

if err != nil || statusCode != http.StatusOK {
promBridgeErrors.WithLabelValues(t.Name).Inc()
if cacheTTL == 0 {
return Result{Error: err}, RunInfo{IsRetryable: isRetryableHTTPError(statusCode, err)}
Expand Down
Loading

0 comments on commit d4c0b69

Please sign in to comment.