Skip to content

Commit 1f0e170

Browse files
committed
Merge branch 'main' into tt-1717_tt-1719_tt-1724-function-docs
2 parents 43525a1 + 74a4a66 commit 1f0e170

File tree

36 files changed

+2949
-70
lines changed

36 files changed

+2949
-70
lines changed

.github/workflows/generate-go-docs.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ jobs:
110110
- name: Generate go docs for changed projects
111111
shell: bash
112112
env:
113-
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
113+
OPENAI_API_KEY: ${{ secrets.OPENAI_DOC_GEN_API_KEY }}
114114
run: |
115115
# Add go binary to PATH
116116
PATH=$PATH:$(go env GOPATH)/bin

.github/workflows/k8s-e2e.yaml

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
name: (k8s package) E2E tests
2-
# disabling for now, as they always fail
3-
#on:
4-
# pull_request:
2+
on:
3+
pull_request:
54

65
concurrency:
76
group: e2e-tests-k8s-${{ github.ref }}
@@ -74,7 +73,7 @@ jobs:
7473
- name: Load Nix
7574
run: nix develop -c sh -c "cd lib &&go mod download"
7675
- name: Setup environment
77-
uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/setup-run-tests-environment@d2f9642bcc24a73400568756f24b72c188ac7a9a # v2.3.31
76+
uses: smartcontractkit/.github/actions/ctf-setup-run-tests-environment@49cb1613e96c9ce17f7290e4dabd38f43aa9bd4d # [email protected]
7877
with:
7978
go_mod_path: go.mod
8079
QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }}
@@ -84,7 +83,7 @@ jobs:
8483
- name: Run Tests
8584
env:
8685
LOCAL_CHARTS: true
87-
uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@d2f9642bcc24a73400568756f24b72c188ac7a9a # v2.3.31
86+
uses: smartcontractkit/.github/actions/ctf-run-tests@b8731364b119e88983e94b0c4da87fc27ddb41b8 # [email protected]
8887
with:
8988
cl_repo: ${{ env.CHAINLINK_IMAGE }}
9089
cl_image_tag: ${{ env.CHAINLINK_VERSION }}
@@ -97,7 +96,6 @@ jobs:
9796
go_mod_path: go.mod
9897
QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }}
9998
QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }}
100-
QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }}
10199
run_setup: false
102100
- name: Upload test log
103101
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3

book/src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
- [Debug Loki errors](./libs/wasp/how-to/debug_loki_errors.md)
8282
- [Havoc](./libs/havoc.md)
8383
- [K8s Test Runner](k8s-test-runner/k8s-test-runner.md)
84+
- [Sentinel](./libs/sentinel.md)
8485

8586
---
8687

book/src/libs/sentinel.md

Lines changed: 274 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,274 @@
1+
# Sentinel
2+
3+
**🚧 Beta Notice:** Sentinel is currently in **Beta** mode. The API is **subject to change**, and users are advised to stay updated with the latest releases and documentation.
4+
5+
## Table of Contents
6+
7+
- [Overview](#overview)
8+
- [Key Features](#key-features)
9+
- [System Architecture](#system-architecture)
10+
- [How Components Interact](#how-components-interact)
11+
- [Core Components](#core-components)
12+
- [Usage](#usage)
13+
- [Initialize Sentinel](#initialize-sentinel)
14+
- [Add a Chain](#add-a-chain)
15+
- [Subscribe to Events](#subscribe-to-events)
16+
- [Unsubscribe](#unsubscribe)
17+
- [Remove a Chain](#remove-a-chain)
18+
- [API Reference](#api-reference)
19+
- [Sentinel](#sentinel)
20+
- [Testing](#testing)
21+
- [Run Tests](#run-tests)
22+
23+
## Overview
24+
25+
Sentinel is a centralized orchestrator that manages multiple blockchain poller services, each responsible for a specific blockchain network (e.g., Ethereum, Optimism, Arbitrum). It provides a unified interface for subscribing to blockchain events, ensuring efficient log polling and event broadcasting to subscribers.
26+
27+
## Key Features
28+
29+
- **Multi-Chain Support**: Manage multiple blockchain networks concurrently.
30+
- **Event Broadcasting**: Relay blockchain events to subscribers via a thread-safe subscription system.
31+
- **Flexible Subscriptions**: Dynamically subscribe and unsubscribe to events based on addresses and topics.
32+
- **Graceful Lifecycle Management**: Start, stop, and clean up resources across services effortlessly.
33+
- **Comprehensive Testing**: Ensures reliability through extensive unit and integration tests.
34+
- **Scalable Architecture**: Designed to handle polling multiple chains with multiple users subscribed to multiple events.
35+
36+
## System Architecture
37+
38+
### How Components Interact
39+
40+
```mermaid
41+
graph TD
42+
Sentinel["Sentinel<br/>(Coordinator)"]
43+
44+
subgraph Ethereum
45+
ChainPollerSvc_Ethereum["ChainPollerSvc<br/>(Ethereum)"]
46+
ChainPoller_Ethereum["ChainPoller<br/>(Log Fetching)"]
47+
SubscriptionManager_Ethereum["Subscription Manager"]
48+
ChainPollerSvc_Ethereum --> ChainPoller_Ethereum
49+
ChainPollerSvc_Ethereum --> SubscriptionManager_Ethereum
50+
ChainPoller_Ethereum --> Blockchain_Ethereum["Blockchain<br/>(Ethereum)"]
51+
end
52+
53+
subgraph Polygon
54+
ChainPollerSvc_Polygon["ChainPollerSvc<br/>(Polygon)"]
55+
ChainPoller_Polygon["ChainPoller<br/>(Log Fetching)"]
56+
SubscriptionManager_Polygon["Subscription Manager"]
57+
ChainPollerSvc_Polygon --> ChainPoller_Polygon
58+
ChainPollerSvc_Polygon --> SubscriptionManager_Polygon
59+
ChainPoller_Polygon --> Blockchain_Polygon["Blockchain<br/>(Polygon)"]
60+
end
61+
62+
subgraph Arbitrum
63+
ChainPollerSvc_Arbitrum["ChainPollerSvc<br/>(Arbitrum)"]
64+
ChainPoller_Arbitrum["ChainPoller<br/>(Log Fetching)"]
65+
SubscriptionManager_Arbitrum["Subscription Manager"]
66+
ChainPollerSvc_Arbitrum --> ChainPoller_Arbitrum
67+
ChainPollerSvc_Arbitrum --> SubscriptionManager_Arbitrum
68+
ChainPoller_Arbitrum --> Blockchain_Arbitrum["Blockchain<br/>(Arbitrum)"]
69+
end
70+
71+
Sentinel --> Ethereum
72+
Sentinel --> Polygon
73+
Sentinel --> Arbitrum
74+
```
75+
76+
### Core Components
77+
78+
1. **Sentinel**:
79+
- **Role**: Central coordinator managing multiple `ChainPollerService` instances.
80+
- **Visibility**: External
81+
- **Responsibilities**:
82+
- Handles adding and removing blockchain chains.
83+
- Manages global subscriptions.
84+
- Orchestrates communication between components.
85+
86+
2. **ChainPollerService**:
87+
- **Role**: Manages the polling process for a specific blockchain.
88+
- **Visibility**: Internal
89+
- **Responsibilities**:
90+
- Polls blockchain logs based on filter queries.
91+
- Integrates internal `ChainPoller` and `SubscriptionManager`.
92+
- Broadcasts fetched logs to relevant subscribers.
93+
94+
3. **ChainPoller**:
95+
- **Role**: Fetches logs from blockchain networks.
96+
- **Visibility**: Internal
97+
- **Responsibilities**:
98+
- Interacts with the blockchain client to retrieve logs.
99+
- Processes filter queries to fetch relevant logs.
100+
101+
4. **SubscriptionManager**:
102+
- **Role**: Manages event subscriptions for a specific chain.
103+
- **Visibility**: Internal
104+
- **Responsibilities**:
105+
- Tracks subscriptions to blockchain events.
106+
- Ensures thread-safe management of subscribers.
107+
- Broadcasts logs to all relevant subscribers.
108+
109+
## Usage
110+
111+
### Initialize Sentinel
112+
113+
Set up a `Sentinel` instance:
114+
115+
```go
116+
package main
117+
118+
import (
119+
"github.com/rs/zerolog"
120+
"os"
121+
122+
"github.com/smartcontractkit/chainlink-testing-framework/sentinel"
123+
)
124+
125+
func main() {
126+
// Initialize logger
127+
logger := zerolog.New(os.Stdout).With().Timestamp().Logger()
128+
129+
// Initialize Sentinel
130+
sentinelCoordinator := sentinel.NewSentinel(sentinel.SentinelConfig{
131+
Logger: &logger,
132+
})
133+
defer sentinelCoordinator.Close()
134+
}
135+
```
136+
137+
### Add a Chain
138+
139+
Add a blockchain to monitor:
140+
141+
```go
142+
package main
143+
144+
import (
145+
"time"
146+
147+
"github.com/ethereum/go-ethereum/ethclient"
148+
"github.com/smartcontractkit/chainlink-testing-framework/sentinel/blockchain_client_wrapper"
149+
"github.com/smartcontractkit/chainlink-testing-framework/sentinel/sentinel"
150+
)
151+
152+
func main() {
153+
// Initialize logger and Sentinel as shown above
154+
155+
// Setup blockchain client (e.g., Geth)
156+
client, err := ethclient.Dial("https://mainnet.infura.io/v3/YOUR-PROJECT-ID")
157+
if err != nil {
158+
panic("Failed to connect to blockchain client: " + err.Error())
159+
}
160+
wrappedClient := blockchain_client_wrapper.NewGethClientWrapper(client)
161+
162+
// Add a new chain to Sentinel
163+
err = sentinelCoordinator.AddChain(sentinel.AddChainConfig{
164+
ChainID: 1, // Ethereum Mainnet
165+
PollInterval: 10 * time.Second,
166+
BlockchainClient: wrappedClient,
167+
})
168+
if err != nil {
169+
panic("Failed to add chain: " + err.Error())
170+
}
171+
}
172+
```
173+
174+
### Subscribe to Events
175+
176+
Subscribe to blockchain events:
177+
178+
```go
179+
package main
180+
181+
import (
182+
"fmt"
183+
184+
"github.com/ethereum/go-ethereum/common"
185+
"github.com/smartcontractkit/chainlink-testing-framework/sentinel/api"
186+
)
187+
188+
func main() {
189+
// Initialize logger, Sentinel, and add a chain as shown above
190+
191+
// Define the address and topic to subscribe to
192+
address := common.HexToAddress("0x1234567890abcdef1234567890abcdef12345678")
193+
topic := common.HexToHash("0xabcdefabcdefabcdefabcdefabcdefabcdefabcdef")
194+
195+
// Subscribe to the event
196+
logCh, err := sentinelCoordinator.Subscribe(1, address, topic)
197+
if err != nil {
198+
panic("Failed to subscribe: " + err.Error())
199+
}
200+
defer sentinelCoordinator.Unsubscribe(1, address, topic, logCh)
201+
202+
// Listen for logs in a separate goroutine
203+
go func() {
204+
for log := range logCh {
205+
fmt.Printf("Received log: %+v\n", log)
206+
}
207+
}()
208+
}
209+
```
210+
211+
### Unsubscribe
212+
213+
Unsubscribe from events:
214+
215+
```go
216+
package main
217+
218+
func main() {
219+
// Initialize logger, Sentinel, add a chain, and subscribe as shown above
220+
221+
// Assume logCh is the channel obtained from Subscribe
222+
err = sentinelCoordinator.Unsubscribe(1, address, topic, logCh)
223+
if err != nil {
224+
panic("Failed to unsubscribe: " + err.Error())
225+
}
226+
}
227+
```
228+
229+
### Remove a Chain
230+
231+
Remove a blockchain from monitoring:
232+
233+
```go
234+
package main
235+
236+
func main() {
237+
// Initialize logger, Sentinel, add a chain, and subscribe as shown above
238+
239+
// Remove the chain
240+
err = sentinelCoordinator.RemoveChain(1)
241+
if err != nil {
242+
panic("Failed to remove chain: " + err.Error())
243+
}
244+
}
245+
```
246+
247+
## API Reference
248+
249+
### Sentinel
250+
251+
- **`NewSentinel(config SentinelConfig) *Sentinel`**
252+
Initializes a new Sentinel instance.
253+
254+
- **`AddChain(config AddChainConfig) error`**
255+
Adds a new blockchain chain to Sentinel.
256+
257+
- **`RemoveChain(chainID int64) error`**
258+
Removes an existing chain from Sentinel.
259+
260+
- **`Subscribe(chainID int64, address common.Address, topic common.Hash) (chan api.Log, error)`**
261+
Subscribes to a specific event on a given chain.
262+
263+
- **`Unsubscribe(chainID int64, address common.Address, topic common.Hash, ch chan api.Log) error`**
264+
Unsubscribes from a specific event.
265+
266+
## Testing
267+
268+
### Run Tests
269+
270+
Run the comprehensive test suite using:
271+
272+
```bash
273+
go test -race ./... -v
274+
```

go.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ flowchart LR
2222
click chainlink-testing-framework/lib href "https://github.com/smartcontractkit/chainlink-testing-framework"
2323
chainlink-testing-framework/lib/grafana
2424
click chainlink-testing-framework/lib/grafana href "https://github.com/smartcontractkit/chainlink-testing-framework"
25+
chainlink-testing-framework/sentinel --> chainlink-testing-framework/lib
26+
click chainlink-testing-framework/sentinel href "https://github.com/smartcontractkit/chainlink-testing-framework"
2527
chainlink-testing-framework/seth --> seth
2628
click chainlink-testing-framework/seth href "https://github.com/smartcontractkit/chainlink-testing-framework"
2729
chainlink-testing-framework/tools/citool --> chainlink-testing-framework/lib
@@ -47,6 +49,7 @@ flowchart LR
4749
chainlink-testing-framework/havoc
4850
chainlink-testing-framework/lib
4951
chainlink-testing-framework/lib/grafana
52+
chainlink-testing-framework/sentinel
5053
chainlink-testing-framework/seth
5154
chainlink-testing-framework/tools/citool
5255
chainlink-testing-framework/tools/envresolve

lib/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,10 @@ k8s_test_e2e:
123123
go test ./k8s/e2e/local-runner -count 1 -test.parallel=12 -v $(args)
124124

125125
k8s_test_e2e_ci: go_mod
126-
go test ./k8s/e2e/local-runner -count 1 -test.parallel=14 -test.timeout=1h -json 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage
126+
CHAINLINK_USER_TEAM=TT go test ./k8s/e2e/local-runner -count 1 -test.parallel=14 -test.timeout=1h -json 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage
127127

128128
k8s_test_e2e_ci_remote_runner: go_mod
129-
go test ./k8s/e2e/remote-runner -count 1 -test.parallel=20 -test.timeout=1h -json 2>&1 | tee /tmp/remoterunnergotest.log | gotestloghelper -ci -singlepackage
129+
CHAINLINK_USER_TEAM=TT go test ./k8s/e2e/remote-runner -count 1 -test.parallel=20 -test.timeout=1h -json 2>&1 | tee /tmp/remoterunnergotest.log | gotestloghelper -ci -singlepackage
130130

131131
.PHONY: examples
132132
examples:

lib/k8s/e2e/common/test_common.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,22 @@ var (
3333
)
3434

3535
func GetTestEnvConfig(t *testing.T) *environment.Config {
36+
testType := "functional"
37+
product := "internal-k8s-test-runner"
38+
39+
nsLabels, err := environment.GetRequiredChainLinkNamespaceLabels(product, testType)
40+
require.NoError(t, err, "Error creating required chain.link labels for namespace")
41+
42+
workloadPodLabels, err := environment.GetRequiredChainLinkWorkloadAndPodLabels(product, testType)
43+
require.NoError(t, err, "Error creating required chain.link labels for workloads and pods")
44+
3645
return &environment.Config{
37-
NamespacePrefix: TestEnvType,
38-
Labels: []string{testSelector},
39-
Test: t,
46+
NamespacePrefix: TestEnvType,
47+
Test: t,
48+
Labels: nsLabels,
49+
WorkloadLabels: workloadPodLabels,
50+
PodLabels: workloadPodLabels,
51+
SkipRequiredChainLinkLabelsValidation: true,
4052
}
4153
}
4254

0 commit comments

Comments
 (0)