Skip to content

Commit

Permalink
feat: decode Optimism blobs (#529)
Browse files Browse the repository at this point in the history
* feat: add optimism-decoder package

* feat: Add error handling for undefined bytes in utils.ts

* feat: added download.ts script + refactor

* feat: Added saveFilesToDB

* chore: Update npm scripts for saveFilesToDB

* chore: update pnpm-lock.yaml

* chore: Update pnpm-lock.yaml and package.json dependencies

* chore: Add decoded transaction fields to transaction page

* Update packages/optimism-decoder/src/decoder.ts

Co-authored-by: Francisco Jiménez Aguilera <franjimenezaguilera@gmail.com>

* add TODO issue links

* refactor: move commands to its own package

* fix: blob-decoder package import

* pnpm lock

* fix migration

* chore: update turbo

* op:generate-import-csv

* add summary

* Refactor transaction page to display decoded transaction data

* chore: Add links to etherscan in the optimism decoded blob data

* chore: bump turbo

* chore: update turbo commands to v2

* Revert "chore: update turbo commands to v2"

This reverts commit b58c63f.

* Revert "chore: bump turbo"

This reverts commit 441efd2.

* Revert "chore: update turbo"

This reverts commit 9a6ea15.

* test: check for `decodedFields`

* chore: resolve lint warnings

* chore: add changeset

* test(db): fix tests

---------

Co-authored-by: Luis Herasme <luis.alberto.herasme.cuevas@gmail.com>
Co-authored-by: Francisco Jiménez Aguilera <franjimenezaguilera@gmail.com>
Co-authored-by: PJColombo <paulo.colombo@pm.me>
  • Loading branch information
4 people authored Oct 24, 2024
1 parent 5a4a662 commit 78468dd
Show file tree
Hide file tree
Showing 30 changed files with 1,264 additions and 11 deletions.
6 changes: 6 additions & 0 deletions .changeset/hot-badgers-hammer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@blobscan/api": minor
"@blobscan/web": minor
---

Displayed Optimism decoded blob data
5 changes: 5 additions & 0 deletions .changeset/smart-toys-agree.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@blobscan/db": minor
---

Added `decodedFields` JSON field for storing decoded-blob-related data
14 changes: 7 additions & 7 deletions apps/docs/src/app/docs/codebase-overview/page.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@ Here you can find all the shared packages used by the apps:
| [`@blobscan/blob-storage-manager`](https://github.com/Blobscan/blobscan/tree/next/packages/blob-storage-manager) | Orchestrates the storage/retrieval of blobs in/from different storage providers. Currently it supports [Google Cloud Storage](https://cloud.google.com/storage), [Swarm](https://www.ethswarm.org), PostgreSQL database and filesystem. |
| [`@blobscan/dayjs`](https://github.com/Blobscan/blobscan/tree/next/packages/dayjs) |  Extended [Day.js](https://day.js.org/) with plugins. |
| [`@blobscan/db`](https://github.com/Blobscan/blobscan/tree/next/packages/db) | Prisma schema and a Prisma client with [extensions](https://www.prisma.io/docs/concepts/components/prisma-client/client-extensions) containing custom methods queries. |
| [`@blobscan/logger`](https://github.com/Blobscan/blobscan/tree/next/packages/logger) |  Shared logger utilities. |
| |
|  [`@blobscan/open-telemetry`](https://github.com/Blobscan/blobscan/tree/next/packages/open-telemetry) | [Otel](https://opentelemetry.io/) configuration and sdk setup. |
| [`@blobscan/test`](https://github.com/Blobscan/blobscan/tree/next/packages/test) |  Shared test utilities and fixtures. |
|  [`@blobscan/zod`](https://github.com/Blobscan/blobscan/tree/next/packages/zod) |  Shared [Zod](https://zod.dev) schemas and utilities. |
|  [`@blobscan/eth-format`](https://github.com/Blobscan/blobscan/tree/next/packages/eth-format) |  Provides utility functions for handling Ethereum value conversions and formatting. |
|  [`@blobscan/rollups`](https://github.com/Blobscan/blobscan/tree/next/packages/rollups) |  A utility that provides a comprehensive list of all rollups and their associated addresses supported by Blobscan, along with functions to retrieve them easily. |
| [`@blobscan/logger`](https://github.com/Blobscan/blobscan/tree/next/packages/logger) | Shared logger utilities. |
| [`@blobscan/optimism-decoder`](https://github.com/Blobscan/blobscan/tree/next/packages/optimism-decoder) | Optimism blobs decoder. |
| [`@blobscan/open-telemetry`](https://github.com/Blobscan/blobscan/tree/next/packages/open-telemetry) | [Otel](https://opentelemetry.io/) configuration and sdk setup. |
| [`@blobscan/test`](https://github.com/Blobscan/blobscan/tree/next/packages/test) | Shared test utilities and fixtures. |
| [`@blobscan/zod`](https://github.com/Blobscan/blobscan/tree/next/packages/zod) | Shared [Zod](https://zod.dev) schemas and utilities. |
| [`@blobscan/eth-format`](https://github.com/Blobscan/blobscan/tree/next/packages/eth-format) | Provides utility functions for handling Ethereum value conversions and formatting. |
| [`@blobscan/rollups`](https://github.com/Blobscan/blobscan/tree/next/packages/rollups) | A utility that provides a comprehensive list of all rollups and their associated addresses supported by Blobscan, along with functions to retrieve them easily. |

### Tooling

Expand Down
88 changes: 88 additions & 0 deletions apps/web/src/pages/tx/[hash].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import { useMemo } from "react";
import type { NextPage } from "next";
import { useRouter } from "next/router";

import { parseDecodedData } from "~/utils/decoded-transaction";
import { RollupBadge } from "~/components/Badges/RollupBadge";
import { Card } from "~/components/Cards/Card";
import { BlobCard } from "~/components/Cards/SurfaceCards/BlobCard";
import { Copyable, CopyToClipboard } from "~/components/CopyToClipboard";
import { StandardEtherUnitDisplay } from "~/components/Displays/StandardEtherUnitDisplay";
import { InfoGrid } from "~/components/InfoGrid";
import { DetailsLayout } from "~/components/Layouts/DetailsLayout";
import type { DetailsLayoutProps } from "~/components/Layouts/DetailsLayout";
import { Link } from "~/components/Link";
Expand Down Expand Up @@ -227,6 +229,11 @@ const Tx: NextPage = () => {
);
}

const decodedData =
rawTxData && rawTxData.decodedFields
? parseDecodedData(rawTxData.decodedFields)
: null;

return (
<>
<DetailsLayout
Expand All @@ -249,6 +256,87 @@ const Tx: NextPage = () => {
fields={detailsFields}
/>

{rawTxData && rawTxData.decodedFields && (
<Card header="Decoded transaction fields">
{decodedData && (
<div>
<InfoGrid
fields={[
{
name: "Timestamp since L2 genesis",
value: (
<div className="whitespace-break-spaces">
{formatTimestamp(decodedData.timestampSinceL2Genesis)}
</div>
),
},
{
name: "Last L1 origin number",
value: decodedData.lastL1OriginNumber,
},
{
name: "Parent L2 block hash",
value: (
<div className="flex items-center gap-2">
<Link
href={
"https://etherscan.io/block/" +
"0x" +
decodedData.parentL2BlockHash
}
>
{"0x" + decodedData.parentL2BlockHash}
</Link>
<CopyToClipboard
value={"0x" + decodedData.parentL2BlockHash}
label="Copy parent L2 block hash"
/>
</div>
),
},
{
name: "L1 origin block hash",
value: (
<div className="flex items-center gap-2">
<Link
href={
"https://etherscan.io/block/" +
"0x" +
decodedData.l1OriginBlockHash
}
>
{"0x" + decodedData.l1OriginBlockHash}
</Link>
<CopyToClipboard
value={"0x" + decodedData.l1OriginBlockHash}
label="Copy L1 origin block hash"
/>
</div>
),
},
{
name: "Number of L2 blocks",
value: decodedData.numberOfL2Blocks,
},
{
name: "Changed by L1 origin",
value: decodedData.changedByL1Origin,
},
{
name: "Total transactions",
value: decodedData.totalTxs,
},
{
name: "Contract creation transactions",
value: decodedData.contractCreationTxsNumber,
},
]}
/>
</div>
)}
</Card>
)}

<Card header={`Blobs ${tx ? `(${tx.blobs.length})` : ""}`}>
<div className="space-y-6">
{isLoading || !tx || !tx.blobs
Expand Down
32 changes: 32 additions & 0 deletions apps/web/src/utils/decoded-transaction.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { z } from "zod";

export const OptimismDecodedDataSchema = z.object({
timestampSinceL2Genesis: z.number(),
lastL1OriginNumber: z.number(),
parentL2BlockHash: z.string(),
l1OriginBlockHash: z.string(),
numberOfL2Blocks: z.number(),
changedByL1Origin: z.number(),
totalTxs: z.number(),
contractCreationTxsNumber: z.number(),
});

type OptimismDecodedData = z.infer<typeof OptimismDecodedDataSchema>;

export function parseDecodedData(data: string): OptimismDecodedData | null {
let json;

try {
json = JSON.parse(data);
} catch (error) {
return null;
}

const decoded = OptimismDecodedDataSchema.safeParse(json);

if (!decoded.success) {
return null;
}

return decoded.data;
}
1 change: 1 addition & 0 deletions docker-compose.local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ services:
- 5432:5432
volumes:
- postgres-data:/var/lib/postgresql/data
- /tmp:/tmp
environment:
- POSTGRES_USER=blobscan
- POSTGRES_DB=blobscan_dev
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"msw": "^2.3.1",
"prettier": "^2.8.8",
"prettier-plugin-tailwindcss": "^0.2.8",
"ts-node": "^10.9.1",
"ts-node": "^10.9.2",
"ts-node-dev": "^2.0.0",
"turbo": "^1.10.7",
"typescript": "^5.2.2",
Expand All @@ -65,4 +65,4 @@
"manypkg": {
"workspaceProtocool": "require"
}
}
}
1 change: 1 addition & 0 deletions packages/api/src/routers/indexer/indexData.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ export function createDBTransactions({
blobAsCalldataGasUsed: bigIntToDecimal(blobGasAsCalldataUsed),
rollup,
category,
decodedFields: null,
};
}
);
Expand Down
1 change: 1 addition & 0 deletions packages/api/src/routers/tx/common/selects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export const baseTransactionSelect =
blockNumber: true,
blockTimestamp: true,
index: true,
decodedFields: true,
});

export function createTransactionSelect(expands: Expands) {
Expand Down
2 changes: 2 additions & 0 deletions packages/api/src/routers/tx/common/serializers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const baseSerializedTransactionFieldsSchema = z.object({
.merge(serializedExpandedBlobDataSchema)
),
block: serializedExpandedBlockSchema.optional(),
decodedFields: z.string().optional(),
});

export const serializedTransactionSchema =
Expand Down Expand Up @@ -129,5 +130,6 @@ export function serializeTransaction(
return {
...serializedBaseTx,
...serializedAdditionalTx,
decodedFields: JSON.stringify(txQuery.decodedFields),
};
}
Loading

0 comments on commit 78468dd

Please sign in to comment.