Add address resolution support to trace tool
This commit is contained in:
parent
d2ae5f07fd
commit
c4615e47bf
|
@ -127,7 +127,7 @@ const Transaction: React.FC = () => {
|
||||||
/>
|
/>
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/tx/:txhash/trace" exact>
|
<Route path="/tx/:txhash/trace" exact>
|
||||||
<Trace txData={txData} />
|
<Trace txData={txData} resolvedAddresses={resolvedAddresses} />
|
||||||
</Route>
|
</Route>
|
||||||
</Switch>
|
</Switch>
|
||||||
</React.Suspense>
|
</React.Suspense>
|
||||||
|
|
|
@ -2,17 +2,19 @@ import React, { useContext } from "react";
|
||||||
import AddressHighlighter from "../components/AddressHighlighter";
|
import AddressHighlighter from "../components/AddressHighlighter";
|
||||||
import DecoratedAddressLink from "../components/DecoratedAddressLink";
|
import DecoratedAddressLink from "../components/DecoratedAddressLink";
|
||||||
import ContentFrame from "../ContentFrame";
|
import ContentFrame from "../ContentFrame";
|
||||||
|
import TraceItem from "./TraceItem";
|
||||||
import { TransactionData } from "../types";
|
import { TransactionData } from "../types";
|
||||||
import { useBatch4Bytes } from "../use4Bytes";
|
import { useBatch4Bytes } from "../use4Bytes";
|
||||||
import { useTraceTransaction, useUniqueSignatures } from "../useErigonHooks";
|
import { useTraceTransaction, useUniqueSignatures } from "../useErigonHooks";
|
||||||
import { RuntimeContext } from "../useRuntime";
|
import { RuntimeContext } from "../useRuntime";
|
||||||
import TraceItem from "./TraceItem";
|
import { ResolvedAddresses } from "../api/address-resolver";
|
||||||
|
|
||||||
type TraceProps = {
|
type TraceProps = {
|
||||||
txData: TransactionData;
|
txData: TransactionData;
|
||||||
|
resolvedAddresses: ResolvedAddresses | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Trace: React.FC<TraceProps> = ({ txData }) => {
|
const Trace: React.FC<TraceProps> = ({ txData, resolvedAddresses }) => {
|
||||||
const { provider } = useContext(RuntimeContext);
|
const { provider } = useContext(RuntimeContext);
|
||||||
const traces = useTraceTransaction(provider, txData.transactionHash);
|
const traces = useTraceTransaction(provider, txData.transactionHash);
|
||||||
const uniqueSignatures = useUniqueSignatures(traces);
|
const uniqueSignatures = useUniqueSignatures(traces);
|
||||||
|
@ -28,6 +30,7 @@ const Trace: React.FC<TraceProps> = ({ txData }) => {
|
||||||
miner={txData.from === txData.confirmedData?.miner}
|
miner={txData.from === txData.confirmedData?.miner}
|
||||||
txFrom
|
txFrom
|
||||||
txTo={txData.from === txData.to}
|
txTo={txData.from === txData.to}
|
||||||
|
resolvedAddresses={resolvedAddresses}
|
||||||
/>
|
/>
|
||||||
</AddressHighlighter>
|
</AddressHighlighter>
|
||||||
</div>
|
</div>
|
||||||
|
@ -41,6 +44,7 @@ const Trace: React.FC<TraceProps> = ({ txData }) => {
|
||||||
txData={txData}
|
txData={txData}
|
||||||
last={i === a.length - 1}
|
last={i === a.length - 1}
|
||||||
fourBytesMap={sigMap}
|
fourBytesMap={sigMap}
|
||||||
|
resolvedAddresses={resolvedAddresses}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -6,12 +6,14 @@ import FunctionSignature from "./FunctionSignature";
|
||||||
import { TransactionData } from "../types";
|
import { TransactionData } from "../types";
|
||||||
import { extract4Bytes, FourBytesEntry } from "../use4Bytes";
|
import { extract4Bytes, FourBytesEntry } from "../use4Bytes";
|
||||||
import { TraceGroup } from "../useErigonHooks";
|
import { TraceGroup } from "../useErigonHooks";
|
||||||
|
import { ResolvedAddresses } from "../api/address-resolver";
|
||||||
|
|
||||||
type TraceItemProps = {
|
type TraceItemProps = {
|
||||||
t: TraceGroup;
|
t: TraceGroup;
|
||||||
txData: TransactionData;
|
txData: TransactionData;
|
||||||
last: boolean;
|
last: boolean;
|
||||||
fourBytesMap: Record<string, FourBytesEntry | null | undefined>;
|
fourBytesMap: Record<string, FourBytesEntry | null | undefined>;
|
||||||
|
resolvedAddresses: ResolvedAddresses | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
const TraceItem: React.FC<TraceItemProps> = ({
|
const TraceItem: React.FC<TraceItemProps> = ({
|
||||||
|
@ -19,6 +21,7 @@ const TraceItem: React.FC<TraceItemProps> = ({
|
||||||
txData,
|
txData,
|
||||||
last,
|
last,
|
||||||
fourBytesMap,
|
fourBytesMap,
|
||||||
|
resolvedAddresses,
|
||||||
}) => {
|
}) => {
|
||||||
const raw4Bytes = extract4Bytes(t.input);
|
const raw4Bytes = extract4Bytes(t.input);
|
||||||
const sigText =
|
const sigText =
|
||||||
|
@ -42,6 +45,7 @@ const TraceItem: React.FC<TraceItemProps> = ({
|
||||||
miner={t.to === txData.confirmedData?.miner}
|
miner={t.to === txData.confirmedData?.miner}
|
||||||
txFrom={t.to === txData.from}
|
txFrom={t.to === txData.from}
|
||||||
txTo={t.to === txData.to}
|
txTo={t.to === txData.to}
|
||||||
|
resolvedAddresses={resolvedAddresses}
|
||||||
/>
|
/>
|
||||||
</AddressHighlighter>
|
</AddressHighlighter>
|
||||||
</span>
|
</span>
|
||||||
|
@ -66,6 +70,7 @@ const TraceItem: React.FC<TraceItemProps> = ({
|
||||||
txData={txData}
|
txData={txData}
|
||||||
last={i === a.length - 1}
|
last={i === a.length - 1}
|
||||||
fourBytesMap={fourBytesMap}
|
fourBytesMap={fourBytesMap}
|
||||||
|
resolvedAddresses={resolvedAddresses}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { useState, useEffect, useRef } from "react";
|
||||||
import { JsonRpcProvider } from "@ethersproject/providers";
|
import { JsonRpcProvider } from "@ethersproject/providers";
|
||||||
import { ProcessedTransaction, TransactionData } from "./types";
|
import { ProcessedTransaction, TransactionData } from "./types";
|
||||||
import { batchPopulate, ResolvedAddresses } from "./api/address-resolver";
|
import { batchPopulate, ResolvedAddresses } from "./api/address-resolver";
|
||||||
|
import { TraceGroup } from "./useErigonHooks";
|
||||||
|
|
||||||
export type AddressCollector = () => string[];
|
export type AddressCollector = () => string[];
|
||||||
|
|
||||||
|
@ -61,6 +62,31 @@ export const transactionDataCollector =
|
||||||
return Array.from(uniqueAddresses);
|
return Array.from(uniqueAddresses);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const tracesCollector =
|
||||||
|
(traces: TraceGroup[] | undefined): AddressCollector =>
|
||||||
|
() => {
|
||||||
|
if (traces === undefined) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const uniqueAddresses = new Set<string>();
|
||||||
|
let searchTraces = [...traces];
|
||||||
|
while (searchTraces.length > 0) {
|
||||||
|
const nextSearch: TraceGroup[] = [];
|
||||||
|
|
||||||
|
for (const g of searchTraces) {
|
||||||
|
uniqueAddresses.add(g.from);
|
||||||
|
uniqueAddresses.add(g.to);
|
||||||
|
if (g.children) {
|
||||||
|
nextSearch.push(...g.children);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
searchTraces = nextSearch;
|
||||||
|
}
|
||||||
|
return Array.from(uniqueAddresses);
|
||||||
|
};
|
||||||
|
|
||||||
export const useResolvedAddresses = (
|
export const useResolvedAddresses = (
|
||||||
provider: JsonRpcProvider | undefined,
|
provider: JsonRpcProvider | undefined,
|
||||||
addrCollector: AddressCollector
|
addrCollector: AddressCollector
|
||||||
|
|
Loading…
Reference in New Issue