Skip to content

Commit 833f8c4

Browse files
committed
chain, store: Adapt to different serialization forms for a block
1 parent 8f2eaf9 commit 833f8c4

File tree

2 files changed

+40
-2
lines changed

2 files changed

+40
-2
lines changed

chain/ethereum/src/chain.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,23 @@ impl Block for BlockFinality {
419419
}
420420

421421
fn data(&self) -> Result<json::Value, json::Error> {
422+
// The serialization here very delicately depends on how the
423+
// `ChainStore`'s `blocks` and `ancestor_block` return the data we
424+
// store here. This should be fixed in a better way to ensure we
425+
// serialize/deserialize appropriately.
426+
//
427+
// Commit #d62e9846 inadvertently introduced a variation in how
428+
// chain stores store ethereum blocks in that they now sometimes
429+
// store an `EthereumBlock` that has a `block` field with a
430+
// `LightEthereumBlock`, and sometimes they just store the
431+
// `LightEthereumBlock` directly. That causes issues because the
432+
// code reading from the chain store always expects the JSON data to
433+
// have the form of an `EthereumBlock`.
434+
//
435+
// The serialization here will subtly use different formats because
436+
// it serializes objects of different types.
437+
//
438+
// see also 7736e440-4c6b-11ec-8c4d-b42e99f52061
422439
match self {
423440
BlockFinality::Final(block) => json::to_value(block),
424441
BlockFinality::NonFinal(block) => json::to_value(&block.ethereum_block),

store/postgres/src/chain_store.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -486,12 +486,19 @@ mod data {
486486
) -> Result<Vec<json::Value>, Error> {
487487
use diesel::dsl::any;
488488

489+
// We need to deal with chain stores where some entries have a
490+
// toplevel 'block' field and others directly contain what would
491+
// be in the 'block' field. Make sure we return the contents of
492+
// the 'block' field if it exists, otherwise assume the whole
493+
// Json object is what should be in 'block'
494+
//
495+
// see also 7736e440-4c6b-11ec-8c4d-b42e99f52061
489496
match self {
490497
Storage::Shared => {
491498
use public::ethereum_blocks as b;
492499

493500
b::table
494-
.select(sql::<Jsonb>("data -> 'block'"))
501+
.select(sql::<Jsonb>("coalesce(data -> 'block', data)"))
495502
.filter(b::network_name.eq(chain))
496503
.filter(b::hash.eq(any(Vec::from_iter(
497504
hashes.into_iter().map(|h| format!("{:x}", h)),
@@ -500,7 +507,7 @@ mod data {
500507
}
501508
Storage::Private(Schema { blocks, .. }) => blocks
502509
.table()
503-
.select(sql::<Jsonb>("data -> 'block'"))
510+
.select(sql::<Jsonb>("coalesce(data -> 'block', data)"))
504511
.filter(
505512
blocks
506513
.hash()
@@ -835,6 +842,20 @@ mod data {
835842
}
836843
};
837844

845+
// We need to deal with chain stores where some entries have a
846+
// toplevel 'blocks' field and others directly contain what
847+
// would be in the 'blocks' field. Make sure the value we return
848+
// has a 'block' entry
849+
//
850+
// see also 7736e440-4c6b-11ec-8c4d-b42e99f52061
851+
let data = {
852+
use graph::prelude::serde_json::json;
853+
854+
data.map(|data| match data.get("block") {
855+
Some(_) => data,
856+
None => json!({ "block": data, "transaction_receipts": [] }),
857+
})
858+
};
838859
Ok(data)
839860
}
840861

0 commit comments

Comments
 (0)