Skip to content

Commit 759fac9

Browse files
authored
Merge pull request #10 from oasisprotocol/rube/heartbeat-block
heartbeat block
2 parents 5c1d5ff + c9451c8 commit 759fac9

11 files changed

Lines changed: 572 additions & 82 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ celerybeat.pid
104104
# Environments
105105
.env
106106
.env.production
107+
.env.test
107108
.venv
108109
env/
109110
venv/

compose.local.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ services:
33
build:
44
context: .
55
dockerfile: Dockerfile
6-
image: ghcr.io/rube-de/rofl-header-oracle:latest
6+
image: ghcr.io/oasisprotocol/rofl-header-oracle:latest
77
platform: linux/amd64
88
container_name: rofl_header_oracle
99
entrypoint: /bin/sh -c 'uv run python -m rofl_oracle --local'

compose.yaml

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ services:
33
build:
44
context: .
55
dockerfile: Dockerfile
6-
image: ghcr.io/rube-de/rofl-header-oracle:latest
6+
image: ghcr.io/oasisprotocol/rofl-header-oracle:latest
77
platform: linux/amd64
88
container_name: rofl_header_oracle
99
ports:
@@ -13,32 +13,32 @@ services:
1313
PYTHONUNBUFFERED: 1 # Disable output buffering for immediate log visibility
1414

1515
# Common configuration (all modes)
16-
SOURCE_RPC_URL: ${SOURCE_RPC_URL:-https://ethereum.publicnode.com}
17-
TARGET_RPC_URL: ${TARGET_RPC_URL:-https://testnet.sapphire.oasis.io}
18-
ROFL_ADAPTER_ADDRESS: ${ROFL_ADAPTER_ADDRESS:-} # Required - ROFLAdapter contract address
19-
REQUEST_TIMEOUT: ${REQUEST_TIMEOUT:-30} # HTTP request timeout in seconds
20-
RETRY_COUNT: ${RETRY_COUNT:-3} # Number of retry attempts
16+
SOURCE_RPC_URL: ${SOURCE_RPC_URL}
17+
TARGET_RPC_URL: ${TARGET_RPC_URL}
18+
ROFL_ADAPTER_ADDRESS: ${ROFL_ADAPTER_ADDRESS} # Required - ROFLAdapter contract address
19+
REQUEST_TIMEOUT: ${REQUEST_TIMEOUT} # HTTP request timeout in seconds
20+
RETRY_COUNT: ${RETRY_COUNT} # Number of retry attempts
2121

2222
# Oracle mode: event_listener, push, watcher, or token_watcher
2323
ORACLE_MODE: ${ORACLE_MODE:-event_listener}
2424

2525
# Logging configuration
26-
LOG_LEVEL: ${LOG_LEVEL:-INFO} # DEBUG, INFO, WARNING, ERROR, CRITICAL
27-
JSON_LOGS: ${JSON_LOGS:-false} # Enable JSON-formatted structured logging
26+
LOG_LEVEL: ${LOG_LEVEL} # DEBUG, INFO, WARNING, ERROR, CRITICAL
27+
JSON_LOGS: ${JSON_LOGS} # Enable JSON-formatted structured logging
2828

2929
# Event Listener Mode Configuration (ORACLE_MODE=event_listener)
30-
SOURCE_CONTRACT_ADDRESS: ${SOURCE_CONTRACT_ADDRESS:-} # Required for event_listener mode
31-
POLLING_INTERVAL: ${POLLING_INTERVAL:-12} # Seconds between event checks
32-
LOOKBACK_BLOCKS: ${LOOKBACK_BLOCKS:-100} # Blocks to look back on startup
30+
SOURCE_CONTRACT_ADDRESS: ${SOURCE_CONTRACT_ADDRESS} # Required for event_listener mode
31+
POLLING_INTERVAL: ${POLLING_INTERVAL} # Seconds between event checks
32+
LOOKBACK_BLOCKS: ${LOOKBACK_BLOCKS} # Blocks to look back on startup
3333

3434
# Push Mode Configuration (ORACLE_MODE=push)
35-
PUSH_INTERVAL: ${PUSH_INTERVAL:-60} # Seconds between block pushes
36-
PUSH_BATCH_SIZE: ${PUSH_BATCH_SIZE:-20} # Max blocks to push per iteration
35+
PUSH_INTERVAL: ${PUSH_INTERVAL} # Seconds between block pushes
36+
PUSH_BATCH_SIZE: ${PUSH_BATCH_SIZE} # Max blocks to push per iteration
3737

3838
# Watcher Mode Configuration (ORACLE_MODE=watcher)
3939
WATCH_ADDRESSES: ${WATCH_ADDRESSES:-} # Required for watcher mode - comma-separated addresses
40-
SCAN_INTERVAL: ${SCAN_INTERVAL:-60} # Seconds between scanning for interactions
41-
WATCHER_BATCH_SIZE: ${WATCHER_BATCH_SIZE:-50} # Max blocks to scan per iteration
40+
SCAN_INTERVAL: ${SCAN_INTERVAL} # Seconds between scanning for interactions
41+
WATCHER_BATCH_SIZE: ${WATCHER_BATCH_SIZE} # Max blocks to scan per iteration
4242
ENABLE_INTERNAL_TX_DETECTION: ${ENABLE_INTERNAL_TX_DETECTION:-false} # Requires archive node with debug API
4343

4444
# Token Watcher Mode Configuration (ORACLE_MODE=token_watcher)

contracts/hardhat.config.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ const config: HardhatUserConfig = {
6565
url: configVariable("SAPPHIRE_MAINNET_RPC_URL"),
6666
accounts: [configVariable("SAPPHIRE_PRIVATE_KEY")],
6767
},
68+
base: {
69+
type: "http",
70+
chainType: "l1",
71+
url: configVariable("BASE_RPC_URL"),
72+
accounts: [configVariable("BASE_PRIVATE_KEY")],
73+
},
6874
},
6975
};
7076

contracts/tasks/deploy-rofl-adapter.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,14 @@ export const deployRoflAdapter = task("deploy:rofl-adapter", "Deploy the ROFLAda
2525
.addOption({
2626
name: "roflAppId",
2727
description: "ROFL app ID in bech32 format (e.g., rofl1qrct2u3sap98mx462lzwy7za86ajgaaxkvs79x88)",
28-
defaultValue: "rofl1qrct2u3sap98mx462lzwy7za86ajgaaxkvs79x88",
28+
defaultValue: "rofl1qz5h592w87uyftlrht388g3rkf58s5z7n53w5xh0", // mainnet
29+
// defaultValue: "rofl1qrct2u3sap98mx462lzwy7za86ajgaaxkvs79x88", // testnet
2930
})
3031
.addOption({
3132
name: "sourceChainId",
3233
description: "Chain ID of the source chain (e.g., 11155111 for Sepolia)",
33-
defaultValue: "11155111",
34+
defaultValue: "8453", // base
35+
// defaultValue: "11155111", // sepolia
3436
})
3537
.addFlag({
3638
name: "verify",

rofl-dev.yaml

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
name: rofl-header-oracle
2+
version: 0.1.0
3+
tee: tdx
4+
kind: container
5+
resources:
6+
memory: 4096
7+
cpus: 2
8+
storage:
9+
kind: disk-persistent
10+
size: 10000
11+
artifacts:
12+
firmware: https://github.com/oasisprotocol/oasis-boot/releases/download/v0.6.2/ovmf.tdx.fd#db47100a7d6a0c1f6983be224137c3f8d7cb09b63bb1c7a5ee7829d8e994a42f
13+
kernel: https://github.com/oasisprotocol/oasis-boot/releases/download/v0.6.2/stage1.bin#e5d4d654ca1fa2c388bf64b23fc6e67815893fc7cb8b7cfee253d87963f54973
14+
stage2: https://github.com/oasisprotocol/oasis-boot/releases/download/v0.6.2/stage2-podman.tar.bz2#b2ea2a0ca769b6b2d64e3f0c577ee9c08f0bb81a6e33ed5b15b2a7e50ef9a09f
15+
container:
16+
runtime: https://github.com/oasisprotocol/oasis-sdk/releases/download/rofl-containers%2Fv0.8.5/rofl-containers#b63e85b33d37f1c762aef85125617d87d79763c3fe3f30815301f0f9fe57179d
17+
compose: compose.yaml
18+
deployments:
19+
default:
20+
app_id: rofl1qrct2u3sap98mx462lzwy7za86ajgaaxkvs79x88
21+
network: testnet
22+
paratime: sapphire
23+
admin: myaccount
24+
trust_root:
25+
height: 29520076
26+
hash: f00ebd495ebcebe0c19832974f65e75fce5a2a6eca3569691ca5a7b83c27f862
27+
policy:
28+
quotes:
29+
pcs:
30+
tcb_validity_period: 30
31+
min_tcb_evaluation_data_number: 18
32+
tdx: {}
33+
enclaves:
34+
- id: wxQAwRK/Jm7eKBMMjyHEAXbjchiZsIz5TQ7PzRs0nuAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
35+
- id: uUkpAYcj6nScA4HdXKRGPruq3aYuua6Eh/uGeOQoQCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
36+
endorsements:
37+
- any: {}
38+
fees: endorsing_node
39+
max_expiration: 3
40+
secrets:
41+
- name: ENABLE_INTERNAL_TX_DETECTION
42+
value: pGJwa1ggSCD8Yhlq5on3u+0wEX254uU1woO6YevQxTxkqlCBkn1kbmFtZVgs331yEuLqLrhDhDBup3U5UbncHhb3/m4HTsiUwTP38JzbIHPE4twYrm0a6Ohlbm9uY2VPMM6Q6t9WQXpdOIBI8R8ZZXZhbHVlVXbMIasTY0WvY4Vd7BrQN/TdwgKk4A==
43+
- name: JSON_LOGS
44+
value: pGJwa1ggvhEDLI5jD5HMhXPbtx/ShYgM/RGsjUhZWCKszF9J7mRkbmFtZVgZTyomWre4aEzMA7sYQVQDrkRvcBJUEIJa+2Vub25jZU8C2weIg3+lCvlzJFir1DZldmFsdWVVdWVba/lncYLyyQFwfNdEvqRoBv0M
45+
- name: LOG_LEVEL
46+
value: pGJwa1gg0npr4br1ruTrtTeBN9F/n57LM0ufsZsE6zNgmzZUFj1kbmFtZVgZIB4PRKhFuJOg8yWvAIn88q8YpvlShkzp0mVub25jZU/lbmwidbVFcw4X6RjKji1ldmFsdWVU+nvGDrJGI3hr+QoANFT02h0I00s=
47+
- name: LOOKBACK_BLOCKS
48+
value: pGJwa1ggV/zaiDi6lnwBFBGq57ChsInqdU7EKAaCWx2ngnCqAEpkbmFtZVgfr1NpuvHpSiBx7vIHKudMf0177jPiCZxOZIYVo0c5umVub25jZU9l+D7GP9sL4igR6bxp6dZldmFsdWVRl5D/MnnO2fI/BfIc422fR/s=
49+
- name: ORACLE_MODE
50+
value: pGJwa1ggX4BWf3+E5ekiK4EVEiCjO9j/6dEcjzAHqUSGDs7UNBBkbmFtZVgbg2cvhjVDF7X3Ljv8o4wJl0pUQ8xpBxOuQe/CZW5vbmNlTzbCK3PhUddVBZ+GrL0bX2V2YWx1ZVfE+GSpjkY+Lc+6tWubzZAkJoV8LWv34Q==
51+
- name: REQUEST_TIMEOUT
52+
value: pGJwa1gg6Bb2JY3MfBBNbCjuOKCFSMqq7BwduLfHcCrwPeQl4X5kbmFtZVgfPf9Lce0zHK66t3HRSmtODqr9yzEEDIucXFq7YxR56GVub25jZU+BZDC0vamhvl5iSTBhmC9ldmFsdWVS1rTidbLAEUql1mwhGXSCzv0l
53+
- name: RETRY_COUNT
54+
value: pGJwa1ggOKNeNGvAOr1Nt8sW8Md/C+W7Mj9rLesU/WU2VO6zGGRkbmFtZVgbBcw498KWMEvoJex82V1P3UHaQjhpgx6pIB2KZW5vbmNlTzCGV1dos/ySSiAWfXVoOGV2YWx1ZVH9IC9AFhQi/HSXvUBeo7gTxA==
55+
- name: ROFL_ADAPTER_ADDRESS
56+
value: pGJwa1ggYsDsCACXt7OKJpuKjNyS73aD77jnUj+RzH1sZmPRD1VkbmFtZVgkF+eZRCUIvMGm9Il/gMCVYBqNIss5VphvLnFQcPIYpFGyxgFxZW5vbmNlT/C1qWTURwEkLbiiyEdGd2V2YWx1ZVg6Pa35yuoGrD0sSdY+QOYgCV6CM/KcC0EF77DIzW07qDfoIuaU0VBopdl36QlPld1Oq3vyPCxVlqDPYA==
57+
- name: SCAN_INTERVAL
58+
value: pGJwa1ggS3JwcqmjBflbNZ1tDZA1uGdyVNv2zX9z2nDtn+ur301kbmFtZVgdYak16b7oFf3aodC2YAAr7wU+bnqLR+33H3xoYvNlbm9uY2VPE0zYPvBFa1/rIilFkDaGZXZhbHVlUjFtvo88ZWO3lNwOMHvsFVYdpg==
59+
- name: SOURCE_RPC_URL
60+
value: pGJwa1ggW53Ygoz4T28CEpXLLOM/dgfJmbEb9/M032IhycJsGxFkbmFtZVgep692EbtvuE0S82EzlZFSUFmTmInztw6PqpeOybhaZW5vbmNlT1tdPrq8JsjSYrZEdO1WRWV2YWx1ZVhVi60hGAZH2gfaBty22H+6YaF5WW4NAYTJ/9l6+VpAEdHxIjE2/vXgpzFAXj9LSwKRsc0yk1iOAefMQRex6K6slNrtNFydltjam0W/bI1P6pme1RCgTg==
61+
- name: TARGET_RPC_URL
62+
value: pGJwa1gg3aTFHrNWfLCw5H3J1TxA4bYfJV6pqZ+dCKvGqUkijWNkbmFtZVgeXs9X9jO8ljPBtEByVMKRcbuwbu9O1LsSREg0K9RKZW5vbmNlT/XaNVGhzcWB/OGiOdZ0G2V2YWx1ZVgxKWJ0oVd/k+v8MbRa2ZtkVGzU+TFV2Rr9SFT9zVIs//WrGyA7djSEXi6VsZsEpevwwg==
63+
- name: WATCHER_BATCH_SIZE
64+
value: pGJwa1ggImj9pLX8glDr0Ngd6HNVI7lrXPaEYWp0gzPAsLmEBztkbmFtZVgidb5i2nu0QQttCrM+uQUu1z3z36if0cUGgvIvlTiK04VWZ2Vub25jZU9JyhlZJjUQ0xXLr0TL/MxldmFsdWVSgmyqPRM2yFEvzOoWEm0xEisd
65+
- name: WATCH_ADDRESSES
66+
value: pGJwa1ggz0xk6zewqQgi7LKZ41wnyj9x+dlKHIZ2Z7jl45AKrD1kbmFtZVgfIx4owNH9rq0aj0+Zqkh4ICQ5N6dmP5w/BtrpXrBsgWVub25jZU82ocss2/553iynvf+cHe5ldmFsdWVYOlVvt3lQluNdNAbOi1NpZf5dvefICW1VbVkVR5yIiEjGYndaKb1WKxhBKFuvBoV57xMIoUszOKAlAD4=

rofl.yaml

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ version: 0.1.0
33
tee: tdx
44
kind: container
55
resources:
6-
memory: 4096
7-
cpus: 2
6+
memory: 2048
7+
cpus: 1
88
storage:
99
kind: disk-persistent
10-
size: 10000
10+
size: 1000
1111
artifacts:
1212
firmware: https://github.com/oasisprotocol/oasis-boot/releases/download/v0.6.2/ovmf.tdx.fd#db47100a7d6a0c1f6983be224137c3f8d7cb09b63bb1c7a5ee7829d8e994a42f
1313
kernel: https://github.com/oasisprotocol/oasis-boot/releases/download/v0.6.2/stage1.bin#e5d4d654ca1fa2c388bf64b23fc6e67815893fc7cb8b7cfee253d87963f54973
@@ -17,50 +17,56 @@ artifacts:
1717
compose: compose.yaml
1818
deployments:
1919
default:
20-
app_id: rofl1qrct2u3sap98mx462lzwy7za86ajgaaxkvs79x88
21-
network: testnet
20+
app_id: rofl1qz5h592w87uyftlrht388g3rkf58s5z7n53w5xh0
21+
network: mainnet
2222
paratime: sapphire
23-
admin: myaccount
23+
admin: paymaster
24+
oci_repository: rofl.sh/a49767f8-f27b-4f03-ae78-f30171bcbbd2:1765396217
2425
trust_root:
25-
height: 29520076
26-
hash: f00ebd495ebcebe0c19832974f65e75fce5a2a6eca3569691ca5a7b83c27f862
26+
height: 27683851
27+
hash: 32de51c51980859a16a593943c3db853d1e387e80c5b65c4370a8897826479dd
2728
policy:
2829
quotes:
2930
pcs:
3031
tcb_validity_period: 30
3132
min_tcb_evaluation_data_number: 18
3233
tdx: {}
3334
enclaves:
34-
- id: wxQAwRK/Jm7eKBMMjyHEAXbjchiZsIz5TQ7PzRs0nuAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
35-
- id: uUkpAYcj6nScA4HdXKRGPruq3aYuua6Eh/uGeOQoQCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
35+
- id: 47YJdKGT4gRY5UvJEiv3Y/u/SAaS+7Dw8plcH/xntV4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
36+
- id: mbii+uP+Xqyf1xl72lJ0m1/GHcE418NeWWkTbXDDpAsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
3637
endorsements:
3738
- any: {}
3839
fees: endorsing_node
3940
max_expiration: 3
4041
secrets:
4142
- name: ENABLE_INTERNAL_TX_DETECTION
42-
value: pGJwa1ggK+IfpbNPVRCG0LCLlzuRXIaY/ch2EeGJRcLqaQQTnEdkbmFtZVgsMVwyL/5/4+rl1XafBmFWMOqkZK0WP1se4lCBM1lkliHDgEw1hwWVhXIf9tllbm9uY2VPcONjIAKQ1Utud6BFptNlZXZhbHVlVT7l6K+wW3PmoX3407mM+MoBC4ZxSw==
43+
value: pGJwa1ggk7KPIsfxOTlkY/JgSrT2St+srjsvapD4mkzFauo+fRdkbmFtZVgsS5M1T3fwHcV9i5BZDEeaT6zhObtWj/VU4Ix2svHnyJ81aoS40zLDC/XquUZlbm9uY2VPKdKGk8AqhrJcafGT229jZXZhbHVlVafQZn9qGFWcNzxLmo88tcn8jxWzWQ==
4344
- name: JSON_LOGS
44-
value: pGJwa1ggFfR70IpOjGiRAExTXgD9lgoHEd81+bneP6bzyHY+zBBkbmFtZVgZwaAr0mabOA0lYdLaHEsVEAYJepHXLjQZCWVub25jZU9ovA0XhUAsowlfJe/z0UBldmFsdWVVj0gi3i2aeTOiKpGcLxEyps6TjG7h
45+
value: pGJwa1ggzHmwyRNNcgKjjexA1E7VygpEExKOtXzDg0Wa5+acTnZkbmFtZVgZB55Jsvv6Jr6Mn+xvGMp1QYczfDRyZ7Uu8GVub25jZU9CXDWuX/OBgk0vZLzpnxJldmFsdWVV9PHLlI8QHogIlg5BXW7HN53D+CPS
4546
- name: LOG_LEVEL
46-
value: pGJwa1ggfzB2xxUZx6oLGQHRF67hbhG6EkHjVb5ypjHfRYAuiyBkbmFtZVgZKsLNUSSV8z1p4gib5sCLapKOHbN7nSJ422Vub25jZU+GlIoIOrJh/uTJu+54tatldmFsdWVUYbHULbpFMUOuRSUNnC/+anHTRSg=
47+
value: pGJwa1ggC3PoxrjwrdjjEa3hBBM/1df+CeaU55zKoNbPqtGykjZkbmFtZVgZXeP52bWz/NYUDZCx9ZlwLrCI2T+Dt7iQTWVub25jZU+1rNIcpCxoVirE9Ach2hpldmFsdWVUzUPRVi4a1WYgtzQ5rkXN/L5CWQY=
4748
- name: LOOKBACK_BLOCKS
48-
value: pGJwa1ggFc9JYiw7mF1Rgencr5qK6RfXB+mI2vrYi/tV27nboi9kbmFtZVgfoM+/XwmEW/Gt/zdJqkDTtmU/VyrDvzqjzQuEvqBZy2Vub25jZU/BkD9qj5FF4jGR/9GsFdVldmFsdWVR5e9W2emyip1qYLVHT7o1oyg=
49+
value: pGJwa1gg45kGrmd+Tdv0BhQBeeuJ2WvkUdP68S7Fjav7FOisJBtkbmFtZVgfK+yFlLgRnycTSTsZWc0xC4JV/SbdCILj9urgt2fSTGVub25jZU96ItbiIpDbXnTCZR1nSF5ldmFsdWVREoXW9O6Nlku/8qQyDkFJSMY=
4950
- name: ORACLE_MODE
50-
value: pGJwa1ggTuTbTmL8zZ2JUZruYFU7MSWbNGNp4VIBlwFFx7PKyD9kbmFtZVgb9do0QKbQXRiy2jGV4Iy6lTjTEn4itFU3cJAAZW5vbmNlT/HXUkNyOBFtwAM/mmqUhGV2YWx1ZVfxRyn1GQINE9hkPCJg9JjrZTSng4DjHw==
51+
value: pGJwa1ggfXQs0d0eB0cZhEG0ctDAL0jZhfIclPAFtsz6iLJJGnpkbmFtZVgbdPRxl3TWlkd9HesGKg3TXFXdfd54fG4bqcVLZW5vbmNlT7MYNSrElCAXGRKGIInqK2V2YWx1ZVcgKhDazH6z9VPuTs6tROTXrO3Pqeo0UQ==
5152
- name: REQUEST_TIMEOUT
52-
value: pGJwa1gge9KJvKXzD/I8DHHTzG3XuAvAIwDCfu5pUo6rJrlnQiBkbmFtZVgfuRpEc9qbApXT0rCBvgAWDBq3/2WC0xIPdF3RjYOfImVub25jZU/Ebv7u8E2l++QoTlqyeM1ldmFsdWVS6Kj95a2/B5eUX6lR/NzQztkN
53+
value: pGJwa1ggvT5icjVaRr1I/ACekONMltplpylNn90OB1gQB5jTyQpkbmFtZVgfNVa8sEWZR5G6UvIf89zmsgJICcCnv5GJkdOXivY752Vub25jZU8vcQmNPfD9793FgIGpPvBldmFsdWVSOPOXTZG8NI2s2O/tb086S2J7
5354
- name: RETRY_COUNT
54-
value: pGJwa1ggTXAHArzApCiF3PYq4xnmgcyjhMas845ymOY+aalcz0NkbmFtZVgbijvcsZD2btb2Om5UmYgKutbv192JVxeeJ/mjZW5vbmNlT2c/DO25OiywnqwNH5Bm82V2YWx1ZVF7LPF2HN+AmIWDBYAEKGr7HQ==
55+
value: pGJwa1ggWsQ0rDhTg7yJygE1Tai4k9RgfrkXJxdwwBPhaCk03j5kbmFtZVgbzcHhLCdCu0tq2JRJDJ2uzM+6neIqHrNRPnRnZW5vbmNlTwIfTafuMVF5mGcT2JQ7UmV2YWx1ZVFnWh7KARGIyT8kk0X9CRWnLQ==
5556
- name: ROFL_ADAPTER_ADDRESS
56-
value: pGJwa1ggqKgjI8Kl85oW3VhgJiqoPxym1h992J6MlX3aHX4NwmJkbmFtZVgkG6nDSpxZ7Cl7k3CEGrtH2ZYKxy4Wu0a9HL3PNBlforz7WiRsZW5vbmNlTz8VZHb48XOpzd/nRJUEvWV2YWx1ZVg6ycPBTgyTJR8C0fVV8822waJVl6ax6rEFnI7d3Sops9cFj/b9xjUncT+FlyFFS/NFjciL0grWrQaiPw==
57+
value: pGJwa1ggmQbQpe53XKCSCUGu8YDRAquQiXrOg9Ig/Wfex89++RVkbmFtZVgk8W2oNqB5S9YLCxzh6PUvrYNZttU/jEOITT0BNND1qKKbuDZfZW5vbmNlT1pN1NPbzo1EUjL30B9eVmV2YWx1ZVg60rp66OXmYj8TrejJ1SMV4reBiltpzqN0gCvInj05C+5v/kTxtgzjcazvKIYzGwwKmX9iVp7zKxJM1w==
5758
- name: SCAN_INTERVAL
58-
value: pGJwa1gggX/Ve+bFd4+Sw43elSNMAQtSZKMHCGmO8wn3gEq7p15kbmFtZVgdFzkI3p8FHJWNbuoo8Uojta8ZrcA7pkFVATDSZX9lbm9uY2VPIr1d3zI+uS3iAP7D+gEpZXZhbHVlUnYy1Kla9cnpKFj8fJG2LTuWWA==
59+
value: pGJwa1ggAAqxCmS4DLcc8Q8nilt0DHhGGKrJelT2Squ1Lu24LAhkbmFtZVgds7BZ7nyL4KGzhAtL+fHOHujrRNZjOb4iN23PF9Zlbm9uY2VPUEhz+WfBbn1HJkwcsVWuZXZhbHVlUkPDS+/sTvmAJx6h+tpn2Dq5rQ==
5960
- name: SOURCE_RPC_URL
60-
value: pGJwa1gg0+OwPX8U8xq+kD47OE+MWlwwd9nWkEKrAsMqWn2dIzdkbmFtZVgeJfMMdxSJ0uWcD4WL9IB6gkkI3RodT8hpC4Iie2s6ZW5vbmNlT51PCs1G+B2xV+TrCSrbymV2YWx1ZVhVi1ZnKCRguLNQ4qlGzKDaBD/cJOagISlfzFIF5oQUVYdDlFQPn6QmNu0zZa1geOiL0V7Q9MUAX851tpsUUOMSPEgdNY5FD0xlAYNNdCsydASKMZDetA==
61+
value: pGJwa1gg0My+HGbGtvLIJ8e9r6VrEqc7TClTEKWtKhFXo9tCljxkbmFtZVgeQkkoOlv07LS78RP3Kzd/bQCyC7+/HUg4YcHxMoueZW5vbmNlT6SeYcf2KAo5mRa5hL+TQWV2YWx1ZVhWVJ69/WY333tehDyi8LGBxkANzsoHzEC6DoWp8ETl+qm8ZiZLzriOjwkdmx0ZLnm8qUC7+CojVTXVw8jKyUAYdGJEsIy9D4sIHz9MnDvCdQnIauIk0C8=
6162
- name: TARGET_RPC_URL
62-
value: pGJwa1ggrya4WQJPZ87rxIGO7AB4j98huInSdGDq8HMJxwcKYSdkbmFtZVgex7Zh+5jSMfw9ZH2XcJZHJ6vg8WwgMdfjOkLnLJnYZW5vbmNlT4nK+3sqbfy5G0HmPIABPWV2YWx1ZVgx/v1H1n8Tt6T/IBJbRcg2PDfZAC0GmCLHI58t4s9jMNH6ZQJHkGNOvOWZjxQXMfGl9Q==
63+
value: pGJwa1ggfznY/mDYqJ9xwryNqBdRYzajW4/NmTBtVDfvVu0cGypkbmFtZVgeRPAJtHyXcIZFg60fhL9yldG4r6uUMGTqJXH905PSZW5vbmNlT0MeKeQYd7kgDSRNO58q5mV2YWx1ZVgpE52YefI30MF8DWM/VFAsVCwznJq2gJndbMW0SqrsSvQvp/UzZRWlC/U=
6364
- name: WATCHER_BATCH_SIZE
64-
value: pGJwa1gg9/kr4FnMFLwewmK7uCWqg2sSkuUXpfylFHzGhkBC9wtkbmFtZVgigbBwaiSqqKbyW5l3DaccI3s4jLuYz2YpKCaARnFKrgg2t2Vub25jZU8HkOq+FA7MDHbDP9maJrlldmFsdWVS2Rr/wszulJr7+zMwUjLZll6F
65+
value: pGJwa1ggNMYXQVK2cU8NMwCdMt3aPklR0ewiwF5hhsTrAuoiKG5kbmFtZVgi2OGAAev1bjY4l40NZMAfxp2DGvlurXZVmpK93HxcwI0EEGVub25jZU9S/SPrStTmTNxvErfrBwhldmFsdWVS2F87LYCvd21wRCwzukL+TK2Z
6566
- name: WATCH_ADDRESSES
66-
value: pGJwa1ggRamOhTxrYRIFGxWYcs61dC0f9aNDLwLHga8DqjT3omJkbmFtZVgfctENMjOPmoNG5v80FE1vO1TVuix1iB43ZVhaN/+eH2Vub25jZU8on45PiEHvWgAv45IUOGJldmFsdWVYOtEpkjuW1fWOUwvGF7FDmJvZMQRNufT9dQEGKVSpnI/W4plaN5biWCblp397JSFGg+zlIEHNqATWT9c=
67+
value: pGJwa1ggnFJoaPX8iHlldespD8/6JvjqA0Eao3+WzpKaB8jKdWlkbmFtZVgfQX/PI6ED+ZhkTVlU9n9p83+NJagfBRk7IqDIOtXWAmVub25jZU8L+rdkWLUUVJmMz3uIRH9ldmFsdWVYOq9t+Z1h7BIEU71gFXuguXMrcNDQlqgCDBubIDnYTQBU3YVOG/CjRzEH+GwkZkABmEp4uJcJkG7mgt0=
68+
machines:
69+
default:
70+
provider: oasis1qzc8pldvm8vm3duvdrj63wgvkw34y9ucfcxzetqr
71+
offer: medium
72+
id: 000000000000006a

rofl_oracle/config.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,13 +134,15 @@ class WatcherModeConfig:
134134
:cvar batch_size: Maximum blocks to scan per iteration (env: WATCHER_BATCH_SIZE)
135135
:cvar lookback_blocks: Number of blocks to look back on startup (env: LOOKBACK_BLOCKS)
136136
:cvar enable_internal_tx_detection: Enable internal transaction detection (env: ENABLE_INTERNAL_TX_DETECTION)
137+
:cvar heartbeat_interval_seconds: Seconds between heartbeat submissions when no activity (env: HEARTBEAT_INTERVAL_SECONDS)
137138
"""
138139

139140
watch_addresses: list[str]
140141
scan_interval: int
141142
batch_size: int = 50
142143
lookback_blocks: int = 100
143144
enable_internal_tx_detection: bool = False
145+
heartbeat_interval_seconds: int = 3600
144146

145147
def __post_init__(self) -> None:
146148
"""Validate watcher configuration."""
@@ -171,6 +173,15 @@ def __post_init__(self) -> None:
171173
f"Lookback blocks too high (max 1000), got {self.lookback_blocks}"
172174
)
173175

176+
if self.heartbeat_interval_seconds <= 0:
177+
raise ValueError(
178+
f"Heartbeat interval must be positive, got {self.heartbeat_interval_seconds}"
179+
)
180+
if self.heartbeat_interval_seconds > 86400:
181+
raise ValueError(
182+
f"Heartbeat interval too high (max 86400s/24h), got {self.heartbeat_interval_seconds}"
183+
)
184+
174185
if self.watch_addresses is None or len(self.watch_addresses) == 0:
175186
raise ValueError("Watcher mode requires at least one watch address")
176187

@@ -517,6 +528,9 @@ def from_env(cls, local_mode: bool = False) -> "OracleConfig":
517528
"ENABLE_INTERNAL_TX_DETECTION", "false"
518529
).lower()
519530
in ("true", "1", "yes"),
531+
heartbeat_interval_seconds=int(
532+
os.environ.get("HEARTBEAT_INTERVAL_SECONDS", "3600")
533+
),
520534
)
521535
else: # OracleMode.TOKEN_WATCHER
522536
token_addresses_str = os.environ.get("TOKEN_ADDRESSES", "")
@@ -623,6 +637,9 @@ def log_config(self) -> None:
623637
logger.info(
624638
f" Lookback Blocks: {self.mode_config.lookback_blocks}"
625639
)
640+
logger.info(
641+
f" Heartbeat Interval: {self.mode_config.heartbeat_interval_seconds} seconds"
642+
)
626643
logger.info(
627644
f" Internal TX Detection: {'ENABLED' if self.mode_config.enable_internal_tx_detection else 'DISABLED'}"
628645
)

0 commit comments

Comments
 (0)