Skip to content

Commit f85769f

Browse files
authored
feat: add bitcoin support (#911)
1 parent a7359e3 commit f85769f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+3252
-223
lines changed

Cargo.lock

Lines changed: 282 additions & 97 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ u5c = ["utxorpc", "futures"]
2121
mithril = ["mithril-client"]
2222
hydra = ["tungstenite", "tokio-tungstenite", "futures-util", "bytes"]
2323
eth = ["futures-util"]
24+
btc = ["bitcoind-async-client", "corepc-types"]
2425
# elasticsearch = auto feature flag
2526
# kafka = auto feature flag
2627

@@ -83,9 +84,11 @@ tokio-tungstenite = { version = "0.24.0", optional = true }
8384
futures-util = { version = "0.3", optional = true }
8485
bytes = { version = "1.7.2", optional = true }
8586
zmq = { version = "0.10.0", optional = true }
87+
bitcoind-async-client = { version = "0.6.0", optional = true }
88+
corepc-types = { version = "0.10.1", optional = true }
8689

8790
# TODO(p): add feature
88-
alloy = { version = "1.0.30", features = ["full"] }
91+
alloy = { version = "1.0.38", features = ["full"] }
8992

9093
[dev-dependencies]
9194
goldenfile = "1.7.3"

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ The data pipeline is implemented by the [Gasket](https://github.com/construkts/g
3939

4040
### CLI to Watch Live Transactions
4141

42-
You can run `oura watch <socket>` to print TX data into the terminal from the tip of a local or remote node. It can be useful as a debugging tool for developers or if you're just curious to see what's going on in the network (for example, to see airdrops as they happen or oracles posting new information).
42+
You can run `oura watch cardano <socket>` to print Cardano transaction data into the terminal from the tip of a local or remote node, or `oura watch bitcoin <rpc_host>` to watch Bitcoin blockchain events. These commands are useful as debugging tools for developers or if you're just curious to see what's going on in the network (for example, to see airdrops as they happen or oracles posting new information).
4343

4444
### As a Bridge to Other Persistence Mechanisms
4545

@@ -80,6 +80,7 @@ Oura is in its essence just a pipeline for processing events. Each stage of the
8080
- Hydra
8181
- Mithril
8282
- Utxorpc
83+
- Bitcoin
8384
- Sinks
8485
- AWS Lambda
8586
- AWS S3

docs/v3/advanced/_meta.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
label: Advanced Features
2+
order: 70
3+
collapsed: true
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
---
2+
title: Custom networks
3+
---
4+
5+
Instructions on how to configure Oura for connecting to a custom network (aka: other than mainnet / preprod / preview).
6+
7+
## Context
8+
9+
Oura requires certain information about the chain it is reading from. In a way, this is similar to the json config files required to run the Cardano node. These values are used for procedures such as encoding bech32 addresses, computing wall-clock time for blocks, etc.
10+
11+
Since `mainnet`, `testnet`, `preprod` and `preview` are well-known, heavily used networks, Oura hardcodes these values as part of the binary release so that the user is spared from having to manually specify them. On the other hand, custom networks require the user to configure these values manually for Oura to establish a connection.
12+
13+
## Feature
14+
15+
By adding a `[chain]` section in the daemon configuration file, users can provide the information required by Oura to connect to a custom network.
16+
17+
The `[chain]` section has the following propoerties:
18+
19+
| Name | DataType | Description |
20+
| :------------------- | :------- | :------------------------------------------------------------ |
21+
| type | string | types of network (mainnet, testnet, preprod, preview, custom) |
22+
| magic | integer | the network number |
23+
| byron_epoch_length | integer | the length (in seconds) of a Byron epoch in this network |
24+
| byron_slot_length | integer | the length (in seconds) of a Byron slot in this network |
25+
| byron_known_slot | integer | the slot of a Byron block known to exist in this network |
26+
| byron_known_hash | string | the hash of the known Byron block |
27+
| byron_known_time | integer | the unix timestamp of the known Byron block |
28+
| shelley_epoch_length | integer | the length (in seconds) of a Shelley epoch in this network |
29+
| shelley_slot_length | integer | the length (in seconds) of a Shelley slot in this network |
30+
| shelley_known_slot | integer | the slot of a Shelley block known to exist in this network |
31+
| shelley_known_hash | String | the hash of the known Shelley block |
32+
| shelley_known_time | integer | the unix timestamp of the known Shelley block |
33+
34+
## Examples
35+
36+
### Chain information for mainnet
37+
38+
This example configuration shows the values for mainnet. Since testnet values are hardcoded as part of Oura's release, users are not required to input these exact values anywhere, but it serves as a good example of what the configuration looks like.
39+
40+
```toml
41+
[chain]
42+
type = "custom"
43+
magic = 764824073
44+
byron_epoch_length = 432000
45+
byron_slot_length = 20
46+
byron_known_slot = 0
47+
byron_known_time = 1506203091
48+
byron_known_hash = "f0f7892b5c333cffc4b3c4344de48af4cc63f55e44936196f365a9ef2244134f"
49+
shelley_epoch_length = 432000
50+
shelley_slot_length = 1
51+
shelley_known_slot = 4492800
52+
shelley_known_hash = "aa83acbf5904c0edfe4d79b3689d3d00fcfc553cf360fd2229b98d464c28e9de"
53+
shelley_known_time = 1596059091
54+
```
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
title: Finalize Options
3+
---
4+
5+
Advanced options for instructing Oura to stop on a chain point. If you'd like it to only sync a specific section of the chain, you can also instruct oura to stop syncing when it reaches a specific block hash by defining a `[finalize]` config.
6+
7+
## Configuration
8+
9+
To modify the default behavior the daemon mode uses, a section named `[finalize]` needs to be added to the `daemon.toml` file.
10+
11+
```toml
12+
[finalize]
13+
until_hash = <BlockHash>
14+
max_block_slot = <SlotNumber>
15+
```
16+
17+
## Examples
18+
19+
The following example show how to configure Oura to stop sync on Byron era
20+
21+
```toml
22+
[finalize]
23+
until_hash = "aa83acbf5904c0edfe4d79b3689d3d00fcfc553cf360fd2229b98d464c28e9de"
24+
```
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
---
2+
title: Intersect Options
3+
---
4+
5+
Advanced options for instructing Oura from which point in the chain to start reading from.
6+
7+
## Feature
8+
9+
When running in daemon mode, Oura provides 4 different strategies for finding the intersection point within the chain sync process.
10+
11+
- `Tip`: Oura will start reading from the current tip of the chain.
12+
- `Origin`: Oura will start reading from the beginning of the chain.
13+
- `Point`: Oura will start reading from a particular point [slot, hash] in the chain.
14+
- `Breadcrumbs`: Oura will start reading from a some points [[slot, hash],[slot, hash]] in the chain.
15+
16+
The default strategy use by Oura is `Tip`, unless an alternative option is specified via configuration.
17+
18+
You can also define a finalizing point by providing a block hash at which oura will stop reading from the the chain and exit gracefully.
19+
20+
## Configuration
21+
22+
To modify the default behaviour used by the daemon mode, a section named `[intersect]` needs to be added in the `daemon.toml` file.
23+
24+
```toml
25+
[intersect]
26+
type = <Type>
27+
value = <Value>
28+
```
29+
30+
- `type`: Defines which strategy to use. Valid values are `Origin`, `Tip`, `Point`, `Breadcrumbs`. Default value is `Tip`.
31+
- `value`: Either a point or an array of points to be used as argument for the selected strategy.
32+
33+
## Examples
34+
35+
The following example show how to configure Oura to use a intersection point.
36+
37+
```toml
38+
[intersect]
39+
type = "Point"
40+
value = [
41+
4493860,
42+
"ce7f821d2140419fea1a7900cf71b0c0a0e94afbb1f814a6717cff071c3b6afc",
43+
]
44+
```
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
---
2+
title: Pipeline Metrics
3+
---
4+
5+
The _metrics_ features allows operators to track the progress and performance of long-running Oura sessions.
6+
7+
## Context
8+
9+
Some use-cases require Oura to be running either continuosuly or for prolonged periods of time. Keeping a sink updated in real-time requires 24/7 operation. Dumping historical chain-data from origin might take several hours.
10+
11+
These scenarios require an understanding of the internal state of the pipeline to facilitate monitoring and troubleshooting of the system. In a data-processing pipeline such as this, two important aspects need to observable: progress and performance.
12+
13+
## Feature
14+
15+
Oura provides an optional `/metrics` HTTP endpoint that uses Prometheus format to expose real-time opertional metrics of the pipeline. Each stage (source / sink) is responsible for notifying their progress as they process each event. This notifications are then aggregated via counters & gauges and exposed via HTTP using the well-known Prometheus encoding.
16+
17+
The following metrics are available:
18+
19+
- `chain_tip`: the last detected tip of the chain (height)
20+
- `rollback_count`: number of rollback events occurred
21+
- `source_current_slot`: last slot processed by the source of the pipeline
22+
- `source_current_height`: last height (block #) processed by the source of the pipeline
23+
- `source_event_count`: number of events processed by the source of the pipeline
24+
- `sink_current_slot`: last slot processed by the sink of the pipeline
25+
- `sink_event_count`: number of events processed by the sink of the pipeline
26+
27+
## Configuration
28+
29+
The _metrics_ feature is a configurable setting available when running in daemon mode. A top level `[metrics]` section of the daemon toml file controls the feature:
30+
31+
```toml
32+
# daemon.toml file
33+
34+
[metrics]
35+
address = "0.0.0.0:9186"
36+
endpoint = "/metrics"
37+
```
38+
39+
- `[metrics]` section needs to be present to enable the feature. Absence of the section will not expose any HTTP endpoints.
40+
- `address`: The address at which the HTTP server will be listening for request. Expected format is `<ip>:<port>`. Use the IP value `0.0.0.0` to allow connections on any of the available IP address of the network interface. Default value is `0.0.0.0:9186`.
41+
- `endpoint`: The path at which the metrics will be exposed. Default value is `/metrics`.
42+
43+
## Usage
44+
45+
Once enabled, a quick method to check the metrics output is to navigate to the HTTP endpoint using any common browser. A local instance of Oura with metrics enabled on port `9186` can be accessed by opening the URL http://localhost:9186
46+
47+
An output similar to the following should be shown by the browser:
48+
49+
```
50+
# HELP chain_tip the last detected tip of the chain (height)
51+
# TYPE chain_tip gauge
52+
chain_tip 6935733
53+
# HELP rollback_count number of rollback events occurred
54+
# TYPE rollback_count counter
55+
rollback_count 1
56+
# HELP sink_current_slot last slot processed by the sink of the pipeline
57+
# TYPE sink_current_slot gauge
58+
sink_current_slot 2839340
59+
# HELP sink_event_count number of events processed by the sink of the pipeline
60+
# TYPE sink_event_count counter
61+
sink_event_count 2277714
62+
# HELP source_current_height last height (block #) processed by the source of the pipeline
63+
# TYPE source_current_height gauge
64+
source_current_height 2837810
65+
# HELP source_current_slot last slot processed by the source of the pipeline
66+
# TYPE source_current_slot gauge
67+
source_current_slot 2839340
68+
# HELP source_event_count number of events processed by the source of the pipeline
69+
# TYPE source_event_count counter
70+
source_event_count 2277715
71+
```
72+
73+
Regardless of the above mechanism, the inteded approach for tracking Oura's metrics is to use a monitoring infrastructure compatible with Prometheus format. Setting up and managing the monitoring stack is outside the scope of Oura. If you don't have any infrastructure in place, we recommend checking out some of the more commons stacks:
74+
75+
- Prometheus Server + Grafana
76+
- Metricbeat + Elasticsearch + Kibana
77+
- Telegraf + InfluxDB + Chronograf
78+

docs/v3/advanced/retry_policy.mdx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
title: Retry Policy
3+
---
4+
5+
Advanced options for instructing Oura how to deal with failed attempts.
6+
7+
## Configuration
8+
9+
To modify the default behavior, a section named `[retries]` needs to be added to the `daemon.toml` file.
10+
11+
```toml
12+
[retries]
13+
max_retries = 3
14+
backoff_unit_sec = 10
15+
backoff_factor = 3
16+
max_backoff_sec = 10
17+
dismissible = true
18+
```
19+
20+
- `max_retries`: the max number of retries before failing the whole pipeline.
21+
- `backoff_unit_sec`: the delay expressed in seconds between each retry.
22+
- `backoff_factor`: the amount to increase the backoff delay after each attempt.
23+
- `max_backoff_sec`: the longest possible delay in seconds.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---
2+
title: Stateful Cursor
3+
---
4+
5+
The _cursor_ feature provides a mechanism to persist the "position" of the processing pipeline to make it resilient to restarts.
6+
7+
## Context
8+
9+
When running in daemon mode, a restart of the process will make Oura start crawling from the initially configured point. This default behavior can be problematic depending on the use-case of the operator.
10+
11+
An scenario where continuous "coverage" of all the processed blocks is important (eg: building a stateful view of the chain), it's prohibitive to have "gaps" while procesing. If Oura is configure to start from the "tip" of the chain, a restart of the process might miss some blocks during the bootstrap procedure.
12+
13+
A valid workaround to the above problem is to configure Oura to start from a fixed point in the chain. If a restart occurs, the pipeline will re-process the blocks, ensuring that each block was processed at least once. When working with sinks that implement idempotency when processing an event, receiving data from the same block multiple times should not impose a problem.
14+
15+
Although valid, the workaround described above is very inefficient. If the fixed point at which the pipeline starts is too far behind, catching up could take several hours, wasting time and resource.
16+
17+
## Feature
18+
19+
Oura implements an optional stateful cursor that receives notifications from the sink stage of the pipeline to continuously track the current position of the chain. At certain checkpoints (every 10 secs by default), the position is persisted onto the file system at a configurable location.
20+
21+
Assuming that a restart occurs and the cursor feature is enabled, the process will attempt to locate and load the persisted value and instruct the source stage to begin reading chain data from the last known position.
22+
23+
## Configuration
24+
25+
The _cursor_ feature is a configurable setting available when running in daemon mode. A top level `[cursor]` section of the daemon toml file controls the feature:
26+
27+
```toml
28+
[cursor]
29+
type = "File"
30+
path = "/var/oura/cursor"
31+
```
32+
33+
- `[cursor]`: The presence of this section in the toml file indicates Oura to enable the _cursor_ feature.
34+
- `type`: The type of persistence backend to use for storing the state of the cursor. The only available option at the moment is `File`, which stores the cursor in the file system.
35+
- `path`: The location of the cursor file within the file system. Default value is `var/oura/cursor`.

0 commit comments

Comments
 (0)