Skip to content

Commit 687c834

Browse files
committed
Listen to real stream events
1 parent 85d13bb commit 687c834

File tree

11 files changed

+896
-202
lines changed

11 files changed

+896
-202
lines changed

Cargo.lock

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

firefly-cardanoconnect/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ aide = { version = "0.13", features = ["axum"] }
99
anyhow = "1"
1010
async-trait = "0.1"
1111
axum = { version = "0.7", features = ["ws"] }
12+
blockfrost = "1"
1213
clap = { version = "4", features = ["derive"] }
1314
chrono = "0.4"
1415
dashmap = "6"

firefly-cardanoconnect/src/blockchain.rs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::path::PathBuf;
22

33
use crate::{
4-
config::CardanoConnectConfig,
4+
config::{CardanoConnectConfig, Secret},
55
streams::{BlockInfo, BlockReference},
66
};
77
use anyhow::{bail, Result};
@@ -19,8 +19,10 @@ mod n2c;
1919
#[serde(rename_all = "camelCase")]
2020
pub struct BlockchainConfig {
2121
pub socket: PathBuf,
22+
pub blockfrost_key: Option<Secret<String>>,
2223
pub network: Option<Network>,
2324
pub network_magic: Option<u64>,
25+
pub genesis_hash: Option<String>,
2426
pub era: u16,
2527
}
2628

@@ -43,6 +45,16 @@ impl BlockchainConfig {
4345
Network::Mainnet => 764824073,
4446
}
4547
}
48+
fn genesis_hash(&self) -> &str {
49+
if let Some(hash) = &self.genesis_hash {
50+
return hash;
51+
}
52+
match self.network.unwrap_or(Network::Mainnet) {
53+
Network::PreProd => "f28f1c1280ea0d32f8cd3143e268650d6c1a8e221522ce4a7d20d62fc09783e1",
54+
Network::Preview => "83de1d7302569ad56cf9139a41e2e11346d4cb4a31c00142557b6ab3fa550761",
55+
Network::Mainnet => "5f20df933584822601f9e3f8c024eb5eb252fe8cefb24d1317dc3d432e940ebb",
56+
}
57+
}
4658
}
4759

4860
enum ClientImpl {
@@ -52,6 +64,7 @@ enum ClientImpl {
5264

5365
pub struct BlockchainClient {
5466
client: ClientImpl,
67+
genesis_hash: String,
5568
era: u16,
5669
}
5770

@@ -60,25 +73,38 @@ impl BlockchainClient {
6073
let blockchain = &config.connector.blockchain;
6174

6275
let n2c = {
63-
let client = NodeToClient::new(&blockchain.socket, blockchain.magic()).await?;
76+
let client = NodeToClient::new(
77+
&blockchain.socket,
78+
blockchain.magic(),
79+
blockchain.genesis_hash(),
80+
blockchain.blockfrost_key.as_ref(),
81+
)
82+
.await?;
6483
RwLock::new(client)
6584
};
6685

6786
Ok(Self {
6887
client: ClientImpl::NodeToClient(n2c),
88+
genesis_hash: blockchain.genesis_hash().to_string(),
6989
era: blockchain.era,
7090
})
7191
}
7292

7393
#[allow(unused)]
7494
pub fn mock() -> Self {
7595
let mock_chain = MockChain::new(3000);
96+
let genesis_hash = mock_chain.genesis_hash();
7697
Self {
7798
client: ClientImpl::Mock(mock_chain),
99+
genesis_hash,
78100
era: 0,
79101
}
80102
}
81103

104+
pub fn genesis_hash(&self) -> String {
105+
self.genesis_hash.clone()
106+
}
107+
82108
pub async fn submit(&self, transaction: Tx) -> Result<String> {
83109
match &self.client {
84110
ClientImpl::Mock(_) => bail!("mock transaction submission not implemented"),

firefly-cardanoconnect/src/blockchain/mocks.rs

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,14 @@ impl ChainSyncClient for MockChainSync {
3333
}
3434

3535
// what are you waiting for?
36-
let requested_block_number = match &self.consumer_tip {
37-
BlockReference::Origin => 0,
38-
BlockReference::Point(number, _) => *number + 1,
36+
let next_index = match &self.consumer_tip {
37+
BlockReference::Origin => Some(1),
38+
BlockReference::Point(_, hash) => self.chain.indexes.get(hash).map(|i| *i + 1),
3939
};
4040

4141
// if we have it, give it
42-
if let Some(info) = chain.get(requested_block_number as usize) {
43-
self.consumer_tip =
44-
BlockReference::Point(requested_block_number, info.block_hash.clone());
42+
if let Some(info) = next_index.and_then(|i| chain.get(i)) {
43+
self.consumer_tip = BlockReference::Point(info.block_slot, info.block_hash.clone());
4544
return Ok(RequestNextResponse::RollForward(info.clone(), tip));
4645
}
4746

@@ -58,9 +57,9 @@ impl ChainSyncClient for MockChainSync {
5857
let chain = self.chain.read_lock().await;
5958
let intersect = points.iter().find_map(|point| match point {
6059
BlockReference::Origin => chain.first(),
61-
BlockReference::Point(number, hash) => chain
62-
.get(*number as usize)
63-
.filter(|b| b.block_hash == *hash),
60+
BlockReference::Point(_, hash) => {
61+
self.chain.indexes.get(hash).and_then(|i| chain.get(*i))
62+
}
6463
});
6564
self.consumer_tip = intersect.map(|b| b.as_reference()).unwrap_or_default();
6665
let tip = chain.last().map(|b| b.as_reference()).unwrap_or_default();
@@ -77,29 +76,42 @@ impl ChainSyncClient for MockChainSync {
7776
pub struct MockChain {
7877
// the real implementation of course won't be in memory
7978
chain: Arc<RwLock<Vec<BlockInfo>>>,
79+
indexes: Arc<DashMap<String, usize>>,
8080
new_block: Arc<Notify>,
8181
rolled_back: Arc<DashMap<BlockReference, BlockReference>>,
8282
}
8383

8484
impl MockChain {
8585
pub fn new(initial_height: usize) -> Self {
8686
let chain = Arc::new(RwLock::new(vec![]));
87+
let indexes = Arc::new(DashMap::new());
8788
let new_block = Arc::new(Notify::new());
8889
let rolled_back = Arc::new(DashMap::new());
8990
tokio::spawn(Self::generate(
9091
chain.clone(),
92+
indexes.clone(),
9193
new_block.clone(),
9294
rolled_back.clone(),
9395
initial_height,
9496
));
9597

9698
Self {
9799
chain,
100+
indexes,
98101
new_block,
99102
rolled_back,
100103
}
101104
}
102105

106+
pub fn genesis_hash(&self) -> String {
107+
self.chain
108+
.blocking_read()
109+
.first()
110+
.unwrap()
111+
.block_hash
112+
.clone()
113+
}
114+
103115
pub fn sync(&self) -> MockChainSync {
104116
MockChainSync {
105117
chain: self.clone(),
@@ -130,11 +142,13 @@ impl MockChain {
130142
pub async fn request_block(&self, block_ref: &BlockReference) -> Result<Option<BlockInfo>> {
131143
match block_ref {
132144
BlockReference::Origin => Ok(None),
133-
BlockReference::Point(number, hash) => {
145+
BlockReference::Point(slot, hash) => {
134146
let chain = self.chain.read().await;
135147
Ok(chain
136-
.get(*number as usize)
137-
.filter(|b| b.block_hash == *hash)
148+
.iter()
149+
.rev()
150+
.find(|b| b.block_hash == *hash)
151+
.filter(|b| b.block_slot == *slot)
138152
.cloned())
139153
}
140154
}
@@ -143,6 +157,7 @@ impl MockChain {
143157
// TODO: roll back sometimes
144158
async fn generate(
145159
chain: Arc<RwLock<Vec<BlockInfo>>>,
160+
indexes: Arc<DashMap<String, usize>>,
146161
new_block: Arc<Notify>,
147162
_rolled_back: Arc<DashMap<BlockReference, BlockReference>>,
148163
initial_height: usize,
@@ -151,33 +166,39 @@ impl MockChain {
151166
{
152167
let mut lock = chain.write().await;
153168
for _ in 0..initial_height {
154-
Self::generate_block(&mut rng, &mut lock);
169+
Self::generate_block(&mut rng, &mut lock, &indexes);
155170
}
156171
}
157172
loop {
158173
time::sleep(Duration::from_secs(1)).await;
159174
let mut lock = chain.write().await;
160-
Self::generate_block(&mut rng, &mut lock);
175+
Self::generate_block(&mut rng, &mut lock, &indexes);
161176
new_block.notify_waiters();
162177
}
163178
}
164179

165-
fn generate_block(rng: &mut ChaChaRng, chain: &mut Vec<BlockInfo>) {
166-
let (block_number, parent_hash) = match chain.last() {
167-
Some(block) => (block.block_number + 1, block.block_hash.clone()),
168-
None => (0, "".into()),
180+
fn generate_block(
181+
rng: &mut ChaChaRng,
182+
chain: &mut Vec<BlockInfo>,
183+
indexes: &DashMap<String, usize>,
184+
) {
185+
let (block_height, parent_hash) = match chain.last() {
186+
Some(block) => (Some(chain.len() as u64), Some(block.block_hash.clone())),
187+
None => (None, None),
169188
};
170189

171190
let mut transaction_hashes = vec![];
172191
for _ in 0..rng.gen_range(0..10) {
173192
transaction_hashes.push(Self::generate_hash(rng));
174193
}
175194
let block = BlockInfo {
176-
block_number,
195+
block_height,
196+
block_slot: block_height,
177197
block_hash: Self::generate_hash(rng),
178198
parent_hash,
179199
transaction_hashes,
180200
};
201+
indexes.insert(block.block_hash.clone(), chain.len());
181202
chain.push(block);
182203
}
183204

0 commit comments

Comments
 (0)