-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7ded3f9
commit 5f60353
Showing
10 changed files
with
446 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
99 changes: 99 additions & 0 deletions
99
src/serve/minibf/routes/blocks/hash_or_number/addresses.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
use itertools::Itertools; | ||
use pallas::ledger::traverse::MultiEraBlock; | ||
use rocket::{get, http::Status, State}; | ||
use serde::{Deserialize, Serialize}; | ||
use std::collections::HashMap; | ||
|
||
use crate::{ | ||
state::LedgerStore, | ||
wal::{redb::WalStore, ReadUtils, WalReader}, | ||
}; | ||
|
||
#[derive(Debug, Clone, Serialize, Deserialize, Default)] | ||
pub struct BlockAddress { | ||
address: String, | ||
transactions: Vec<BlockAddressTx>, | ||
} | ||
|
||
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq, Hash)] | ||
pub struct BlockAddressTx { | ||
tx_hash: String, | ||
} | ||
|
||
#[get("/blocks/<hash_or_number>/addresses", rank = 2)] | ||
pub fn route( | ||
hash_or_number: String, | ||
wal: &State<WalStore>, | ||
ledger: &State<LedgerStore>, | ||
) -> Result<rocket::serde::json::Json<Vec<BlockAddress>>, Status> { | ||
let maybe_raw = wal | ||
.crawl_from(None) | ||
.map_err(|_| Status::ServiceUnavailable)? | ||
.into_blocks() | ||
.find(|maybe_raw| match maybe_raw { | ||
Some(raw) => match MultiEraBlock::decode(&raw.body) { | ||
Ok(block) => { | ||
block.hash().to_string() == hash_or_number | ||
|| block.number().to_string() == hash_or_number | ||
} | ||
Err(_) => false, | ||
}, | ||
None => false, | ||
}); | ||
|
||
match maybe_raw { | ||
Some(Some(raw)) => { | ||
let block = MultiEraBlock::decode(&raw.body).map_err(|_| Status::ServiceUnavailable)?; | ||
let mut addresses = HashMap::new(); | ||
|
||
for tx in block.txs() { | ||
// Handle inputs | ||
let utxos = ledger | ||
.get_utxos(tx.inputs().iter().map(Into::into).collect()) | ||
.map_err(|_| Status::ServiceUnavailable)?; | ||
|
||
for (_, eracbor) in utxos { | ||
let parsed = | ||
pallas::ledger::traverse::MultiEraOutput::decode(eracbor.0, &eracbor.1) | ||
.map_err(|_| Status::InternalServerError)?; | ||
let address = parsed | ||
.address() | ||
.map_err(|_| Status::ServiceUnavailable)? | ||
.to_bech32() | ||
.map_err(|_| Status::ServiceUnavailable)?; | ||
let tx_hash = tx.hash().to_string(); | ||
addresses | ||
.entry(address.to_string()) | ||
.or_insert_with(Vec::new) | ||
.push(BlockAddressTx { tx_hash }); | ||
} | ||
|
||
// Handle outputs | ||
for output in tx.outputs() { | ||
let address = output | ||
.address() | ||
.map_err(|_| Status::ServiceUnavailable)? | ||
.to_bech32() | ||
.map_err(|_| Status::ServiceUnavailable)?; | ||
let tx_hash = tx.hash().to_string(); | ||
addresses | ||
.entry(address.to_string()) | ||
.or_insert_with(Vec::new) | ||
.push(BlockAddressTx { tx_hash }); | ||
} | ||
} | ||
|
||
Ok(rocket::serde::json::Json( | ||
addresses | ||
.into_iter() | ||
.sorted_by_key(|(address, _)| address.clone()) | ||
.map(|(address, transactions)| BlockAddress { | ||
address, | ||
transactions: transactions.into_iter().unique().collect(), | ||
}) | ||
.collect(), | ||
)) | ||
} | ||
_ => Err(Status::NotFound), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
use pallas::ledger::traverse::wellknown::GenesisValues; | ||
use rocket::{get, http::Status, State}; | ||
use std::sync::Arc; | ||
|
||
use crate::{ledger::pparams::Genesis, wal::redb::WalStore}; | ||
|
||
use super::Block; | ||
|
||
pub mod addresses; | ||
pub mod next; | ||
pub mod previous; | ||
pub mod txs; | ||
|
||
#[get("/blocks/<hash_or_number>", rank = 2)] | ||
pub fn route( | ||
hash_or_number: String, | ||
genesis: &State<Arc<Genesis>>, | ||
wal: &State<WalStore>, | ||
) -> Result<rocket::serde::json::Json<Block>, Status> { | ||
let Some(magic) = genesis.shelley.network_magic else { | ||
return Err(Status::ServiceUnavailable); | ||
}; | ||
|
||
let Some(values) = GenesisValues::from_magic(magic as u64) else { | ||
return Err(Status::ServiceUnavailable); | ||
}; | ||
|
||
let block = Block::find_in_wal(wal, &hash_or_number, &values)?; | ||
match block { | ||
Some(block) => Ok(rocket::serde::json::Json(block)), | ||
None => Err(Status::NotFound), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
use pallas::ledger::traverse::{wellknown::GenesisValues, MultiEraBlock}; | ||
use rocket::{get, http::Status, State}; | ||
use std::sync::Arc; | ||
|
||
use crate::{ | ||
ledger::pparams::Genesis, | ||
wal::{redb::WalStore, ReadUtils, WalReader}, | ||
}; | ||
|
||
use super::Block; | ||
|
||
#[get("/blocks/<hash_or_number>/next", rank = 2)] | ||
pub fn route( | ||
hash_or_number: String, | ||
genesis: &State<Arc<Genesis>>, | ||
wal: &State<WalStore>, | ||
) -> Result<rocket::serde::json::Json<Block>, Status> { | ||
let Some(magic) = genesis.shelley.network_magic else { | ||
return Err(Status::ServiceUnavailable); | ||
}; | ||
|
||
let Some(values) = GenesisValues::from_magic(magic as u64) else { | ||
return Err(Status::ServiceUnavailable); | ||
}; | ||
|
||
let iterator = wal | ||
.crawl_from(None) | ||
.map_err(|_| Status::ServiceUnavailable)? | ||
.into_blocks(); | ||
|
||
let mut prev = None; | ||
for raw in iterator.flatten() { | ||
let block = MultiEraBlock::decode(&raw.body).map_err(|_| Status::ServiceUnavailable)?; | ||
if block.hash().to_string() == hash_or_number | ||
|| block.number().to_string() == hash_or_number | ||
{ | ||
break; | ||
} else { | ||
prev = Some(raw.hash.to_string()); | ||
} | ||
} | ||
match prev { | ||
Some(block) => { | ||
match Block::find_in_wal(wal, &block, &values) | ||
.map_err(|_| Status::ServiceUnavailable)? | ||
{ | ||
Some(block) => Ok(rocket::serde::json::Json(block)), | ||
None => Err(Status::NotFound), | ||
} | ||
} | ||
None => Err(Status::NotFound), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
use pallas::ledger::traverse::{wellknown::GenesisValues, MultiEraBlock}; | ||
use rocket::{get, http::Status, State}; | ||
use std::sync::Arc; | ||
|
||
use crate::{ | ||
ledger::pparams::Genesis, | ||
wal::{redb::WalStore, ReadUtils, WalReader}, | ||
}; | ||
|
||
use super::Block; | ||
|
||
#[get("/blocks/<hash_or_number>/previous", rank = 2)] | ||
pub fn route( | ||
hash_or_number: String, | ||
genesis: &State<Arc<Genesis>>, | ||
wal: &State<WalStore>, | ||
) -> Result<rocket::serde::json::Json<Block>, Status> { | ||
let Some(magic) = genesis.shelley.network_magic else { | ||
return Err(Status::ServiceUnavailable); | ||
}; | ||
|
||
let Some(values) = GenesisValues::from_magic(magic as u64) else { | ||
return Err(Status::ServiceUnavailable); | ||
}; | ||
|
||
// Reversed iterator | ||
let iterator = wal | ||
.crawl_from(None) | ||
.map_err(|_| Status::ServiceUnavailable)? | ||
.rev() | ||
.into_blocks(); | ||
|
||
let mut next = None; | ||
for raw in iterator.flatten() { | ||
let block = MultiEraBlock::decode(&raw.body).map_err(|_| Status::ServiceUnavailable)?; | ||
if block.hash().to_string() == hash_or_number | ||
|| block.number().to_string() == hash_or_number | ||
{ | ||
break; | ||
} else { | ||
next = Some(raw.hash.to_string()); | ||
} | ||
} | ||
match next { | ||
Some(block) => { | ||
match Block::find_in_wal(wal, &block, &values) | ||
.map_err(|_| Status::ServiceUnavailable)? | ||
{ | ||
Some(block) => Ok(rocket::serde::json::Json(block)), | ||
None => Err(Status::NotFound), | ||
} | ||
} | ||
None => Err(Status::NotFound), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
use pallas::ledger::traverse::MultiEraBlock; | ||
use rocket::{get, http::Status, State}; | ||
|
||
use crate::wal::{redb::WalStore, ReadUtils, WalReader}; | ||
|
||
#[get("/blocks/<hash_or_number>/txs", rank = 2)] | ||
pub fn route( | ||
hash_or_number: String, | ||
wal: &State<WalStore>, | ||
) -> Result<rocket::serde::json::Json<Vec<String>>, Status> { | ||
let maybe_raw = wal | ||
.crawl_from(None) | ||
.map_err(|_| Status::ServiceUnavailable)? | ||
.into_blocks() | ||
.find(|maybe_raw| match maybe_raw { | ||
Some(raw) => match MultiEraBlock::decode(&raw.body) { | ||
Ok(block) => { | ||
block.hash().to_string() == hash_or_number | ||
|| block.number().to_string() == hash_or_number | ||
} | ||
Err(_) => false, | ||
}, | ||
None => false, | ||
}); | ||
|
||
match maybe_raw { | ||
Some(Some(raw)) => { | ||
let block = MultiEraBlock::decode(&raw.body).map_err(|_| Status::ServiceUnavailable)?; | ||
Ok(rocket::serde::json::Json( | ||
block.txs().iter().map(|tx| tx.hash().to_string()).collect(), | ||
)) | ||
} | ||
_ => Err(Status::NotFound), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.