Highlight flashbot-like txs inside blocks

This commit is contained in:
Willian Mitsuda 2021-07-05 00:34:40 -03:00
parent 6dc6e63b95
commit 1b32f4e888
4 changed files with 80 additions and 29 deletions

View File

@ -11,7 +11,7 @@ import ResultHeader from "./search/ResultHeader";
import PendingResults from "./search/PendingResults"; import PendingResults from "./search/PendingResults";
import TransactionItem from "./search/TransactionItem"; import TransactionItem from "./search/TransactionItem";
import BlockLink from "./components/BlockLink"; import BlockLink from "./components/BlockLink";
import { ProcessedTransaction } from "./types"; import { ProcessedTransaction, Transfer } from "./types";
import { PAGE_SIZE } from "./params"; import { PAGE_SIZE } from "./params";
import { useFeeToggler } from "./search/useFeeToggler"; import { useFeeToggler } from "./search/useFeeToggler";
import { useENSCache } from "./useReverseCache"; import { useENSCache } from "./useReverseCache";
@ -49,28 +49,51 @@ const BlockTransactions: React.FC = () => {
]); ]);
document.title = `Block #${_block.number} Transactions | Otterscan`; document.title = `Block #${_block.number} Transactions | Otterscan`;
setTxs( const responses = _block.transactions
_block.transactions .map((t, i): ProcessedTransaction => {
.map((t, i) => { return {
return { blockNumber: blockNumber.toNumber(),
blockNumber: blockNumber.toNumber(), timestamp: _block.timestamp,
timestamp: _block.timestamp, miner: _block.miner,
miner: _block.miner, idx: i,
idx: i, hash: t.hash,
hash: t.hash, from: t.from,
from: t.from, to: t.to,
to: t.to, value: t.value,
value: t.value, fee: provider.formatter
fee: provider.formatter .bigNumber(_receipts[i].gasUsed)
.bigNumber(_receipts[i].gasUsed) .mul(t.gasPrice!),
.mul(t.gasPrice!), gasPrice: t.gasPrice!,
gasPrice: t.gasPrice!, data: t.data,
data: t.data, status: provider.formatter.number(_receipts[i].status),
status: provider.formatter.number(_receipts[i].status), };
}; })
}) .reverse();
.reverse()
const internalChecks = await Promise.all(
responses.map(async (res) => {
const r = await provider.send("ots_getTransactionTransfers", [
res.hash,
]);
for (const t of r) {
if (
res.miner &&
(res.miner === ethers.utils.getAddress(t.from) ||
res.miner === ethers.utils.getAddress(t.to))
) {
return true;
}
}
return false;
})
); );
for (let i = 0; i < responses.length; i++) {
if (internalChecks[i]) {
responses[i].internalMinerInteraction = true;
}
}
setTxs(responses);
}; };
readBlock(); readBlock();
}, [blockNumber]); }, [blockNumber]);

View File

@ -1,6 +1,9 @@
import React from "react"; import React from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faLongArrowAltRight } from "@fortawesome/free-solid-svg-icons"; import {
faCoins,
faLongArrowAltRight,
} from "@fortawesome/free-solid-svg-icons";
export enum Direction { export enum Direction {
IN, IN,
@ -9,12 +12,18 @@ export enum Direction {
INTERNAL, INTERNAL,
} }
export enum Flags {
MINER,
}
type TransactionDirectionProps = { type TransactionDirectionProps = {
direction?: Direction; direction?: Direction;
flags?: Flags;
}; };
const TransactionDirection: React.FC<TransactionDirectionProps> = ({ const TransactionDirection: React.FC<TransactionDirectionProps> = ({
direction, direction,
flags,
}) => { }) => {
let bgColor = "bg-green-50"; let bgColor = "bg-green-50";
let fgColor = "text-green-500"; let fgColor = "text-green-500";
@ -34,6 +43,11 @@ const TransactionDirection: React.FC<TransactionDirectionProps> = ({
msg = "INT"; msg = "INT";
} }
if (flags === Flags.MINER) {
bgColor = "bg-yellow-50";
fgColor = "text-yellow-400";
}
return ( return (
<span <span
className={`${bgColor} ${fgColor} ${ className={`${bgColor} ${fgColor} ${
@ -42,10 +56,14 @@ const TransactionDirection: React.FC<TransactionDirectionProps> = ({
: "w-5 h-5 rounded-full flex justify-center items-center" : "w-5 h-5 rounded-full flex justify-center items-center"
} text-xs font-bold`} } text-xs font-bold`}
> >
{msg ?? ( {flags === Flags.MINER ? (
<span> <FontAwesomeIcon icon={faCoins} size="1x" />
<FontAwesomeIcon icon={faLongArrowAltRight} /> ) : (
</span> msg ?? (
<span>
<FontAwesomeIcon icon={faLongArrowAltRight} />
</span>
)
)} )}
</span> </span>
); );

View File

@ -11,6 +11,7 @@ import AddressOrENSName from "../components/AddressOrENSName";
import TimestampAge from "../components/TimestampAge"; import TimestampAge from "../components/TimestampAge";
import TransactionDirection, { import TransactionDirection, {
Direction, Direction,
Flags,
} from "../components/TransactionDirection"; } from "../components/TransactionDirection";
import TransactionValue from "../components/TransactionValue"; import TransactionValue from "../components/TransactionValue";
import { ENSReverseCache, ProcessedTransaction } from "../types"; import { ENSReverseCache, ProcessedTransaction } from "../types";
@ -45,9 +46,14 @@ const TransactionItem: React.FC<TransactionItemProps> = ({
const ensFrom = ensCache && tx.from && ensCache[tx.from]; const ensFrom = ensCache && tx.from && ensCache[tx.from];
const ensTo = ensCache && tx.to && ensCache[tx.to]; const ensTo = ensCache && tx.to && ensCache[tx.to];
const flash = tx.gasPrice.isZero() && tx.internalMinerInteraction;
return ( return (
<div className="grid grid-cols-12 gap-x-1 items-baseline text-sm border-t border-gray-200 hover:bg-gray-100 px-2 py-3"> <div
className={`grid grid-cols-12 gap-x-1 items-baseline text-sm border-t border-gray-200 hover:bg-gray-100 ${
flash ? "bg-yellow-100" : ""
} px-2 py-3`}
>
<div className="col-span-2 flex space-x-1 items-baseline"> <div className="col-span-2 flex space-x-1 items-baseline">
{tx.status === 0 && ( {tx.status === 0 && (
<span className="text-red-600" title="Transaction reverted"> <span className="text-red-600" title="Transaction reverted">
@ -81,7 +87,10 @@ const TransactionItem: React.FC<TransactionItemProps> = ({
)} )}
</span> </span>
<span> <span>
<TransactionDirection direction={direction} /> <TransactionDirection
direction={direction}
flags={tx.internalMinerInteraction ? Flags.MINER : undefined}
/>
</span> </span>
</span> </span>
<span className="col-span-2 truncate" title={tx.to}> <span className="col-span-2 truncate" title={tx.to}>

View File

@ -8,6 +8,7 @@ export type ProcessedTransaction = {
hash: string; hash: string;
from?: string; from?: string;
to?: string; to?: string;
internalMinerInteraction?: boolean;
value: BigNumber; value: BigNumber;
fee: BigNumber; fee: BigNumber;
gasPrice: BigNumber; gasPrice: BigNumber;