Skip to content

Commit 08eac81

Browse files
authored
Merge pull request #43 from powerloom/feat/rpc-helper
Feat/rpc helper
2 parents 5e847b8 + d960dfe commit 08eac81

File tree

11 files changed

+266
-121
lines changed

11 files changed

+266
-121
lines changed

config/settings.go

Lines changed: 113 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ import (
66
"os"
77
"strconv"
88
"strings"
9+
"time"
10+
11+
rpchelper "github.com/powerloom/go-rpc-helper"
12+
"github.com/powerloom/go-rpc-helper/reporting"
913

1014
"github.com/ethereum/go-ethereum/common"
1115
)
@@ -18,6 +22,15 @@ type DataMarketMigrationEntry struct {
1822
}
1923

2024
type Settings struct {
25+
// RPC Helper Configuration
26+
RPCNodes []string `json:"rpc_nodes"`
27+
ArchiveRPCNodes []string `json:"archive_rpc_nodes"`
28+
MaxRetries int `json:"max_retries"`
29+
RetryDelayMs int `json:"retry_delay_ms"`
30+
MaxRetryDelayS int `json:"max_retry_delay_s"`
31+
RequestTimeoutS int `json:"request_timeout_s"`
32+
33+
// Legacy fields (keeping for backward compatibility during transition)
2134
ClientUrl string
2235
ContractAddress string
2336
RedisHost string
@@ -53,17 +66,57 @@ type Settings struct {
5366
}
5467

5568
func LoadConfig() {
69+
// Parse RPC nodes from environment variable
70+
rpcNodesStr := getEnv("RPC_NODES", "[]")
71+
var rpcNodes []string
72+
err := json.Unmarshal([]byte(rpcNodesStr), &rpcNodes)
73+
if err != nil {
74+
log.Fatalf("Failed to parse RPC_NODES environment variable: %v", err)
75+
}
76+
if len(rpcNodes) == 0 {
77+
// Fallback to legacy PROST_RPC_URL for backward compatibility
78+
legacyRPCURL := getEnv("PROST_RPC_URL", "")
79+
if legacyRPCURL != "" {
80+
rpcNodes = []string{legacyRPCURL}
81+
} else {
82+
log.Fatalf("RPC_NODES environment variable has an empty array and no PROST_RPC_URL fallback")
83+
}
84+
}
85+
86+
// Clean quotes from RPC node URLs
87+
for i, url := range rpcNodes {
88+
rpcNodes[i] = strings.Trim(url, "\"")
89+
}
90+
91+
// Parse archive RPC nodes from environment variable (optional)
92+
archiveRPCNodesStr := getEnv("ARCHIVE_RPC_NODES", "[]")
93+
var archiveRPCNodes []string
94+
err = json.Unmarshal([]byte(archiveRPCNodesStr), &archiveRPCNodes)
95+
if err != nil {
96+
log.Fatalf("Failed to parse ARCHIVE_RPC_NODES environment variable: %v", err)
97+
}
98+
99+
// Clean quotes from archive RPC node URLs
100+
for i, url := range archiveRPCNodes {
101+
archiveRPCNodes[i] = strings.Trim(url, "\"")
102+
}
103+
56104
dataMarketAddresses := getEnv("DATA_MARKET_ADDRESSES", "[]")
57105
dataMarketAddressesList := []string{}
58106

59-
err := json.Unmarshal([]byte(dataMarketAddresses), &dataMarketAddressesList)
107+
err = json.Unmarshal([]byte(dataMarketAddresses), &dataMarketAddressesList)
60108
if err != nil {
61109
log.Fatalf("Failed to parse DATA_MARKET_ADDRESSES environment variable: %v", err)
62110
}
63111
if len(dataMarketAddressesList) == 0 {
64112
log.Fatalf("DATA_MARKET_ADDRESSES environment variable has an empty array")
65113
}
66114

115+
// Clean quotes from data market addresses
116+
for i, addr := range dataMarketAddressesList {
117+
dataMarketAddressesList[i] = strings.Trim(addr, "\"")
118+
}
119+
67120
periodicEligibleCountAlerts, periodicEligibleCountAlertsErr := strconv.ParseBool(getEnv("PERIODIC_ELIGIBLE_COUNT_ALERTS", "true"))
68121
if periodicEligibleCountAlertsErr != nil {
69122
log.Fatalf("Failed to parse PERIODIC_ELIGIBLE_COUNT_ALERTS environment variable: %v", periodicEligibleCountAlertsErr)
@@ -93,8 +146,17 @@ func LoadConfig() {
93146
}
94147

95148
config := Settings{
149+
// RPC Helper Configuration
150+
RPCNodes: rpcNodes,
151+
ArchiveRPCNodes: archiveRPCNodes,
152+
MaxRetries: getEnvInt("RPC_MAX_RETRIES", 3),
153+
RetryDelayMs: getEnvInt("RPC_RETRY_DELAY_MS", 500),
154+
MaxRetryDelayS: getEnvInt("RPC_MAX_RETRY_DELAY_S", 30),
155+
RequestTimeoutS: getEnvInt("RPC_REQUEST_TIMEOUT_S", 30),
156+
157+
// Legacy configuration (keeping for backward compatibility)
96158
ClientUrl: getEnv("PROST_RPC_URL", ""),
97-
ContractAddress: getEnv("PROTOCOL_STATE_CONTRACT", ""),
159+
ContractAddress: strings.Trim(getEnv("PROTOCOL_STATE_CONTRACT", ""), "\""),
98160
RedisHost: getEnv("REDIS_HOST", ""),
99161
RedisPort: getEnv("REDIS_PORT", ""),
100162
RedisDB: getEnv("REDIS_DB", ""),
@@ -224,3 +286,52 @@ func getEnv(key, defaultValue string) string {
224286
}
225287
return value
226288
}
289+
290+
func getEnvInt(key string, defaultValue int) int {
291+
value := getEnv(key, "")
292+
if value == "" {
293+
return defaultValue
294+
}
295+
intValue, err := strconv.Atoi(value)
296+
if err != nil {
297+
log.Fatalf("Failed to parse %s environment variable: %v", key, err)
298+
}
299+
return intValue
300+
}
301+
302+
func (s *Settings) ToRPCConfig() *rpchelper.RPCConfig {
303+
config := &rpchelper.RPCConfig{
304+
Nodes: func() []rpchelper.NodeConfig {
305+
var nodes []rpchelper.NodeConfig
306+
for _, url := range s.RPCNodes {
307+
nodes = append(nodes, rpchelper.NodeConfig{URL: url})
308+
}
309+
return nodes
310+
}(),
311+
ArchiveNodes: func() []rpchelper.NodeConfig {
312+
var nodes []rpchelper.NodeConfig
313+
for _, url := range s.ArchiveRPCNodes {
314+
nodes = append(nodes, rpchelper.NodeConfig{URL: url})
315+
}
316+
return nodes
317+
}(),
318+
MaxRetries: s.MaxRetries,
319+
RetryDelay: time.Duration(s.RetryDelayMs) * time.Millisecond,
320+
MaxRetryDelay: time.Duration(s.MaxRetryDelayS) * time.Second,
321+
RequestTimeout: time.Duration(s.RequestTimeoutS) * time.Second,
322+
}
323+
324+
// Configure webhook if SlackReportingUrl is provided
325+
if s.SlackReportingUrl != "" {
326+
log.Printf("Configuring webhook alerts with URL: %s", s.SlackReportingUrl)
327+
config.WebhookConfig = &reporting.WebhookConfig{
328+
URL: s.SlackReportingUrl,
329+
Timeout: 30 * time.Second,
330+
Retries: 3,
331+
}
332+
} else {
333+
log.Printf("No webhook URL configured - SLACK_REPORTING_URL environment variable not set")
334+
}
335+
336+
return config
337+
}

go.mod

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
module submission-sequencer-collector
22

3-
go 1.23
3+
go 1.23.0
4+
5+
toolchain go1.23.4
46

57
require (
68
github.com/ethereum/go-ethereum v1.14.7
79
github.com/gorilla/handlers v1.5.2
10+
github.com/powerloom/go-rpc-helper v1.0.5-0.20250726065922-28883c22bd97
811
github.com/sirupsen/logrus v1.9.3
9-
github.com/stretchr/testify v1.9.0
12+
github.com/stretchr/testify v1.10.0
1013
github.com/swaggo/swag v1.16.4
1114
google.golang.org/protobuf v1.34.2
1215
)
1316

1417
require (
1518
github.com/KyleBanks/depth v1.2.1 // indirect
1619
github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 // indirect
20+
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
1721
github.com/cespare/xxhash/v2 v2.3.0 // indirect
1822
github.com/davecgh/go-spew v1.1.1 // indirect
1923
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
@@ -61,9 +65,9 @@ require (
6165
github.com/swaggo/http-swagger v1.3.4
6266
github.com/tklauser/go-sysconf v0.3.14 // indirect
6367
github.com/tklauser/numcpus v0.9.0 // indirect
64-
golang.org/x/crypto v0.28.0 // indirect
68+
golang.org/x/crypto v0.35.0 // indirect
6569
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect
66-
golang.org/x/sys v0.26.0 // indirect
70+
golang.org/x/sys v0.30.0 // indirect
6771
rsc.io/tmplfunc v0.0.3 // indirect
6872
)
6973

go.sum

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ github.com/bits-and-blooms/bitset v1.14.3 h1:Gd2c8lSNf9pKXom5JtD7AaKO8o7fGQ2LtFj
1818
github.com/bits-and-blooms/bitset v1.14.3/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
1919
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
2020
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
21+
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
22+
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
2123
github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk=
2224
github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
2325
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
@@ -156,6 +158,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
156158
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
157159
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
158160
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
161+
github.com/powerloom/go-rpc-helper v1.0.5-0.20250726065922-28883c22bd97 h1:znQ7p+uicav29JDXALd/bOnDSv+Wg5b4uXRZpwjizbs=
162+
github.com/powerloom/go-rpc-helper v1.0.5-0.20250726065922-28883c22bd97/go.mod h1:RxQj0kBBezXUWdH3j7rCXcDLXNwVlElT31qCKPNUFUI=
159163
github.com/prometheus/client_golang v1.12.0 h1:C+UIj/QWtmqY13Arb8kwMt5j34/0Z2iKamrJ+ryC0Gg=
160164
github.com/prometheus/client_golang v1.12.0/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
161165
github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a h1:CmF68hwI0XsOQ5UwlBopMi2Ow4Pbg32akc4KIVCOm+Y=
@@ -180,8 +184,8 @@ github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobt
180184
github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg=
181185
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
182186
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
183-
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
184-
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
187+
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
188+
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
185189
github.com/supranational/blst v0.3.13 h1:AYeSxdOMacwu7FBmpfloBz5pbFXDmJL33RuwnKtmTjk=
186190
github.com/supranational/blst v0.3.13/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw=
187191
github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE=
@@ -209,8 +213,8 @@ github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo
209213
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
210214
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
211215
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
212-
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
213-
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
216+
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
217+
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
214218
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY=
215219
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8=
216220
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
@@ -235,17 +239,17 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
235239
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
236240
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
237241
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
238-
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
239-
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
242+
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
243+
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
240244
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
241245
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
242246
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
243247
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
244248
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
245249
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
246250
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
247-
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
248-
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
251+
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
252+
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
249253
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
250254
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
251255
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

pkgs/constants.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ const (
1414
HandleDayTransition = "SequencerEventCollector: HandleDayTransition"
1515
TriggerBatchPreparation = "SequencerEventCollector: TriggerBatchPreparation"
1616
CheckAndTriggerBatchPreparation = "SequencerEventCollector: CheckAndTriggerBatchPreparation"
17-
MustQuery = "SequencerEventCollector: MustQuery"
1817
)
1918

2019
// General Key Constants

pkgs/prost/cleanup.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ func CleanupSubmissionDumpForAllSlots(parentCtx context.Context, dataMarketAddr
113113
log.Errorf("Failed to parse node count %s: %v", nodeCountStr, err)
114114
return err
115115
}
116+
// TODO: remove unnecessary cleanup since this key is not used anymore
116117
for slotId := 1; slotId <= nodeCount; slotId++ {
117118
log.Debugf("Cleaning up old submission dump for slot %d for data market %s", slotId, dataMarketAddr)
118119
keyPattern := fmt.Sprintf("snapshotter:%s:*:%d.slot_submissions", strings.ToLower(dataMarketAddr), slotId)

0 commit comments

Comments
 (0)