|
| 1 | +# Token Data Observer |
| 2 | + |
| 3 | +This package implements an observer for fetching token data from offchain locations. The primary use case for this data is 3rd party attestation services (CCTP/USDC, LBTC), but in theory it could be used to fetch any token data for unknown use cases. |
| 4 | + |
| 5 | +The observer provides two primary functions: |
| 6 | +* Observe(ctx, messages) (observations, error) |
| 7 | +* IsTokenSupported(sourceSelector, msgTokenTransfer) bool |
| 8 | + |
| 9 | +The OCR plugin simply calls **Observe** and includes token data in the final report as necessary. |
| 10 | + |
| 11 | +# Architecture |
| 12 | + |
| 13 | +The **TokenDataObserver** is built by composing many parts which all implement the same two interfaces: |
| 14 | +* **TokenDataObserver** |
| 15 | +* **AttestionClient** |
| 16 | + |
| 17 | +We'll go into detail on each of these components, but first, here is a diagram which shows how everything is assembled for the **Execute** plugin: |
| 18 | +```mermaid |
| 19 | +graph TD |
| 20 | + subgraph A[BackgroundTokenDataObserver] |
| 21 | + direction LR |
| 22 | + subgraph B[CompositeTokenDataObserver] |
| 23 | + subgraph C[USDCTokenDataObserver] |
| 24 | + subgraph C1[CompositeUSDCTokenDataReader] |
| 25 | + C1a[EVMUSDC TokenDataReader] |
| 26 | + C1b[SolanaUSDC TokenDataReader] |
| 27 | + end |
| 28 | + C2["Observed [USDCAttestationClient]"] |
| 29 | + end |
| 30 | + subgraph D[LBTCTokenDataObserver] |
| 31 | + D1[LBTC TokenDataReader] |
| 32 | + D2["Observed [LBTCAttestationClient]"] |
| 33 | + end |
| 34 | + end |
| 35 | + end |
| 36 | +``` |
| 37 | + |
| 38 | +## Composite Token Data Observer |
| 39 | + |
| 40 | +In order to support multiple token types, a special **compositeTokenDataObserver** exists to dispatch calls to token specific Observers. At a high level it holds a slice of **TokenDataObserver** objects and calls **Observe** on each of them. Results from all observers are merged together to return a single response. |
| 41 | + |
| 42 | +Configuration for which tokens are supported is done using data stored in the **Home Chain**. See **NewConfigBasedCompositeObservers** for the logic which initializes token specific observers. The actual configuration if found at **pluginconfig/token.go** in the **TokenDataObserverConfig** struct. |
| 43 | + |
| 44 | +## Token Specific Observers |
| 45 | + |
| 46 | +Token specific observers (USDC, LBTC) are initialized as part of the **compositeTokenDataObserver**. They implement the same **TokenDataObserver** as everything else but have token specific logic. |
| 47 | + |
| 48 | +To add a new token, you would create a new package in this directory and implement the interface. |
| 49 | + |
| 50 | +## Attestation Client & Metrics |
| 51 | + |
| 52 | +The **AttestationClient** interface is a small wrapper for an http client. It is only used by the token specific observers and should have a token specific implementation. The main purpose of this interface is to be wrapped by an **ObservedAttestationClient**, which logs prometheus metrics. |
| 53 | + |
| 54 | +## Background Processing & Caching |
| 55 | + |
| 56 | +Data fetching happens as a background task. This is done to avoid latency introduced by calling 3rd party services. The **backgroundObserver** object implements the same **TokenDataObserver** and wraps the **compositeTokenDataObserver**. Instead of calling the real **Observe** function immediately, it manages a cache and only returns cached data. Any messages which had not been cached previously are sent to a queue where a background task will call the **Observe** function and add results to the cache. In future rounds, the data will be cached for immediate retrieval. |
0 commit comments