Skip to content

Commit ae66751

Browse files
committed
chain, graph: Fix block ptr ext parsing bug
1 parent d1109ac commit ae66751

File tree

4 files changed

+74
-38
lines changed

4 files changed

+74
-38
lines changed

chain/ethereum/src/ethereum_adapter.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1707,7 +1707,7 @@ impl EthereumAdapterTrait for EthereumAdapter {
17071707
chain_store: Arc<dyn ChainStore>,
17081708
block_numbers: HashSet<BlockNumber>,
17091709
) -> Box<dyn Stream<Item = Arc<BlockPtrExt>, Error = Error> + Send> {
1710-
let blocks_map: BTreeMap<i32, Vec<json::Value>> = chain_store
1710+
let blocks_map = chain_store
17111711
.cheap_clone()
17121712
.block_ptrs_by_numbers(block_numbers.iter().map(|&b| b.into()).collect::<Vec<_>>())
17131713
.await
@@ -1721,7 +1721,7 @@ impl EthereumAdapterTrait for EthereumAdapter {
17211721
.into_iter()
17221722
.filter_map(|(_number, values)| {
17231723
if values.len() == 1 {
1724-
json::from_value(values[0].clone()).ok()
1724+
Arc::new(values[0].clone()).into()
17251725
} else {
17261726
None
17271727
}

graph/src/blockchain/types.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,21 @@ impl TryFrom<(Option<H256>, Option<U64>, H256, U256)> for BlockPtrExt {
482482
})
483483
}
484484
}
485+
486+
impl TryFrom<(H256, i32, H256, U256)> for BlockPtrExt {
487+
type Error = anyhow::Error;
488+
489+
fn try_from(tuple: (H256, i32, H256, U256)) -> Result<Self, Self::Error> {
490+
let (hash, block_number, parent_hash, timestamp) = tuple;
491+
492+
Ok(BlockPtrExt {
493+
hash: hash.into(),
494+
number: block_number,
495+
parent_hash: parent_hash.into(),
496+
timestamp,
497+
})
498+
}
499+
}
485500
impl From<BlockPtrExt> for H256 {
486501
fn from(ptr: BlockPtrExt) -> Self {
487502
ptr.hash_as_h256()

graph/src/components/store/traits.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use web3::types::{Address, H256};
77

88
use super::*;
99
use crate::blockchain::block_stream::{EntityWithType, FirehoseCursor};
10-
use crate::blockchain::{BlockTime, ChainIdentifier};
10+
use crate::blockchain::{BlockPtrExt, BlockTime, ChainIdentifier};
1111
use crate::components::metrics::stopwatch::StopwatchMetrics;
1212
use crate::components::server::index_node::VersionInfo;
1313
use crate::components::subgraph::SubgraphVersionSwitchingMode;
@@ -526,7 +526,7 @@ pub trait ChainStore: Send + Sync + 'static {
526526
async fn block_ptrs_by_numbers(
527527
self: Arc<Self>,
528528
numbers: Vec<BlockNumber>,
529-
) -> Result<BTreeMap<BlockNumber, Vec<serde_json::Value>>, Error>;
529+
) -> Result<BTreeMap<BlockNumber, Vec<BlockPtrExt>>, Error>;
530530

531531
/// Get the `offset`th ancestor of `block_hash`, where offset=0 means the block matching
532532
/// `block_hash` and offset=1 means its parent. If `root` is passed, short-circuit upon finding

store/postgres/src/chain_store.rs

Lines changed: 55 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use anyhow::anyhow;
12
use diesel::pg::PgConnection;
23
use diesel::prelude::*;
34
use diesel::r2d2::{ConnectionManager, PooledConnection};
@@ -21,9 +22,9 @@ use std::{
2122
sync::Arc,
2223
};
2324

24-
use graph::blockchain::{Block, BlockHash, ChainIdentifier};
25+
use graph::blockchain::{Block, BlockHash, BlockPtrExt, ChainIdentifier};
2526
use graph::cheap_clone::CheapClone;
26-
use graph::prelude::web3::types::H256;
27+
use graph::prelude::web3::types::{H256, U256};
2728
use graph::prelude::{
2829
async_trait, serde_json as json, transaction_receipt::LightTransactionReceipt, BlockNumber,
2930
BlockPtr, CachedEthereumCall, CancelableError, ChainStore as ChainStoreTrait, Error,
@@ -53,6 +54,14 @@ impl JsonBlock {
5354
data,
5455
}
5556
}
57+
58+
fn timestamp(&self) -> Option<U256> {
59+
self.data
60+
.as_ref()
61+
.and_then(|data| data.get("timestamp"))
62+
.and_then(|ts| ts.as_str())
63+
.and_then(|ts| U256::from_dec_str(ts).ok())
64+
}
5665
}
5766

5867
/// Tables in the 'public' database schema that store chain-specific data
@@ -1949,6 +1958,20 @@ impl ChainStore {
19491958
}
19501959
}
19511960

1961+
fn json_block_to_block_ptr_ext(json_block: &JsonBlock) -> Result<BlockPtrExt, Error> {
1962+
let hash = json_block.ptr.hash.clone();
1963+
let number = json_block.ptr.number;
1964+
let parent_hash = json_block.parent_hash.clone();
1965+
1966+
let timestamp = json_block
1967+
.timestamp()
1968+
.ok_or_else(|| anyhow!("Timestamp is missing"))?;
1969+
1970+
let ptr = BlockPtrExt::try_from((hash.as_h256(), number, parent_hash.as_h256(), timestamp))
1971+
.map_err(|e| anyhow!("Failed to convert to BlockPtrExt: {}", e))?;
1972+
1973+
Ok(ptr)
1974+
}
19521975
#[async_trait]
19531976
impl ChainStoreTrait for ChainStore {
19541977
fn genesis_block_ptr(&self) -> Result<BlockPtr, Error> {
@@ -2145,23 +2168,11 @@ impl ChainStoreTrait for ChainStore {
21452168
async fn block_ptrs_by_numbers(
21462169
self: Arc<Self>,
21472170
numbers: Vec<BlockNumber>,
2148-
) -> Result<BTreeMap<BlockNumber, Vec<json::Value>>, Error> {
2149-
if ENV_VARS.store.disable_block_cache_for_lookup {
2150-
let values = self
2151-
.blocks_from_store_by_numbers(numbers)
2152-
.await?
2153-
.into_iter()
2154-
.map(|(num, blocks)| {
2155-
(
2156-
num,
2157-
blocks
2158-
.into_iter()
2159-
.filter_map(|block| block.data)
2160-
.collect::<Vec<_>>(),
2161-
)
2162-
})
2163-
.collect();
2164-
Ok(values)
2171+
) -> Result<BTreeMap<BlockNumber, Vec<BlockPtrExt>>, Error> {
2172+
let result = if ENV_VARS.store.disable_block_cache_for_lookup {
2173+
let values = self.blocks_from_store_by_numbers(numbers).await?;
2174+
2175+
values
21652176
} else {
21662177
let cached = self.recent_blocks_cache.get_block_ptrs_by_numbers(&numbers);
21672178

@@ -2209,16 +2220,28 @@ impl ChainStoreTrait for ChainStore {
22092220
.map(|(ptr, data)| (ptr.block_number(), vec![data]))
22102221
.collect::<BTreeMap<_, _>>();
22112222

2212-
let mut result: BTreeMap<BlockNumber, Vec<json::Value>> = cached_map;
2223+
let mut result = cached_map;
22132224
for (num, blocks) in stored {
2214-
result
2215-
.entry(num)
2216-
.or_default()
2217-
.extend(blocks.into_iter().filter_map(|block| block.data));
2225+
if !result.contains_key(&num) {
2226+
result.insert(num, blocks);
2227+
}
22182228
}
22192229

2220-
Ok(result)
2221-
}
2230+
result
2231+
};
2232+
2233+
let ptrs = result
2234+
.into_iter()
2235+
.map(|(num, blocks)| {
2236+
let ptrs = blocks
2237+
.into_iter()
2238+
.filter_map(|block| json_block_to_block_ptr_ext(&block).ok())
2239+
.collect();
2240+
(num, ptrs)
2241+
})
2242+
.collect();
2243+
2244+
Ok(ptrs)
22222245
}
22232246

22242247
async fn blocks(self: Arc<Self>, hashes: Vec<BlockHash>) -> Result<Vec<json::Value>, Error> {
@@ -2527,10 +2550,8 @@ mod recent_blocks_cache {
25272550
.and_then(|block| block.data.as_ref().map(|data| (&block.ptr, data)))
25282551
}
25292552

2530-
fn get_block_by_number(&self, number: BlockNumber) -> Option<(&BlockPtr, &json::Value)> {
2531-
self.blocks
2532-
.get(&number)
2533-
.and_then(|block| block.data.as_ref().map(|data| (&block.ptr, data)))
2553+
fn get_block_by_number(&self, number: BlockNumber) -> Option<&JsonBlock> {
2554+
self.blocks.get(&number)
25342555
}
25352556

25362557
fn get_ancestor(
@@ -2658,13 +2679,13 @@ mod recent_blocks_cache {
26582679
pub fn get_block_ptrs_by_numbers(
26592680
&self,
26602681
numbers: &[BlockNumber],
2661-
) -> Vec<(BlockPtr, json::Value)> {
2682+
) -> Vec<(BlockPtr, JsonBlock)> {
26622683
let inner = self.inner.read();
2663-
let mut blocks: Vec<(BlockPtr, json::Value)> = Vec::new();
2684+
let mut blocks: Vec<(BlockPtr, JsonBlock)> = Vec::new();
26642685

26652686
for &number in numbers {
2666-
if let Some((ptr, block)) = inner.get_block_by_number(number) {
2667-
blocks.push((ptr.clone(), block.clone()));
2687+
if let Some(block) = inner.get_block_by_number(number) {
2688+
blocks.push((block.ptr.clone(), block.clone()));
26682689
}
26692690
}
26702691

0 commit comments

Comments
 (0)