From eff70df7098df87b1266ff85f66b73d65f500014 Mon Sep 17 00:00:00 2001 From: Noah Gundotra Date: Thu, 16 Jan 2025 23:56:31 -0500 Subject: [PATCH] Revert "Add Ix Cards for Ed25519 Precompile" (#438) Reverts solana-foundation/explorer#437 --- .../ed25519/Ed25519DetailsCard.tsx | 162 ------------------ .../__tests__/Ed25519DetailsCard.test.tsx | 131 -------------- app/components/instruction/ed25519/types.ts | 15 -- .../transaction/InstructionsSection.tsx | 5 - 4 files changed, 313 deletions(-) delete mode 100644 app/components/instruction/ed25519/Ed25519DetailsCard.tsx delete mode 100644 app/components/instruction/ed25519/__tests__/Ed25519DetailsCard.test.tsx delete mode 100644 app/components/instruction/ed25519/types.ts diff --git a/app/components/instruction/ed25519/Ed25519DetailsCard.tsx b/app/components/instruction/ed25519/Ed25519DetailsCard.tsx deleted file mode 100644 index ec845f63..00000000 --- a/app/components/instruction/ed25519/Ed25519DetailsCard.tsx +++ /dev/null @@ -1,162 +0,0 @@ -import { - ParsedTransaction, - PartiallyDecodedInstruction, - PublicKey, - SignatureResult, - TransactionInstruction, -} from '@solana/web3.js'; -import bs58 from 'bs58'; -import React from 'react'; - -import { Address } from '../../common/Address'; -import { Copyable } from '../../common/Copyable'; -import { InstructionCard } from '../InstructionCard'; -import { PROGRAM_ID as ED25519_PROGRAM_ID } from './types'; - -type DetailsProps = { - tx: ParsedTransaction; - ix: TransactionInstruction; - index: number; - result: SignatureResult; - innerCards?: JSX.Element[]; - childIndex?: number; -}; - -interface Ed25519SignatureOffsets { - signatureOffset: number; // offset to ed25519 signature of 64 bytes - signatureInstructionIndex: number; // instruction index to find signature - publicKeyOffset: number; // offset to public key of 32 bytes - publicKeyInstructionIndex: number; // instruction index to find public key - messageDataOffset: number; // offset to start of message data - messageDataSize: number; // size of message data - messageInstructionIndex: number; // index of instruction data to get message data -} - -// See https://docs.anza.xyz/runtime/programs/#ed25519-program -function decodeEd25519Instruction(data: Buffer): Ed25519SignatureOffsets[] { - const count = data.readUInt8(0); - const offsets: Ed25519SignatureOffsets[] = []; - - let cursor = 2; // Skip count and padding byte - - for (let i = 0; i < count; i++) { - const offset: Ed25519SignatureOffsets = { - messageDataOffset: data.readUInt16LE(cursor + 8), - messageDataSize: data.readUInt16LE(cursor + 10), - messageInstructionIndex: data.readUInt16LE(cursor + 12), - publicKeyInstructionIndex: data.readUInt16LE(cursor + 6), - publicKeyOffset: data.readUInt16LE(cursor + 4), - signatureInstructionIndex: data.readUInt16LE(cursor + 2), - signatureOffset: data.readUInt16LE(cursor), - }; - offsets.push(offset); - cursor += 14; // Number of bytes in one Ed25519SignatureOffsets struct - } - - return offsets; -} - -export function Ed25519DetailsCard(props: DetailsProps) { - const { tx, ix, index, result, innerCards, childIndex } = props; - - const offsets = decodeEd25519Instruction(ix.data); - - return ( - - - Program - -
- - - - {offsets.map((offset, index) => { - const signatureIx = tx.message.instructions[ - offset.signatureInstructionIndex - ] as PartiallyDecodedInstruction; - const signature = signatureIx.data.slice(offset.signatureOffset, offset.signatureOffset + 64); - - const pubkeyIx = tx.message.instructions[ - offset.publicKeyInstructionIndex - ] as PartiallyDecodedInstruction; - const pubkey = bs58.decode(pubkeyIx.data).slice(offset.publicKeyOffset, offset.publicKeyOffset + 32); - - const messageIx = tx.message.instructions[ - offset.messageInstructionIndex - ] as PartiallyDecodedInstruction; - const message = messageIx.data.slice( - offset.messageDataOffset, - offset.messageDataOffset + offset.messageDataSize - ); - - return ( - - - - Signature #{index + 1} - - - - Signature Reference - - Instruction {offset.signatureInstructionIndex}, Offset {offset.signatureOffset} - - - - Signature - - - {Buffer.from(signature).toString('base64')} - - - - - Public Key Reference - - Instruction {offset.publicKeyInstructionIndex}, Offset {offset.publicKeyOffset} - - - - Public Key - -
- - - - Message Reference - - Instruction {offset.messageInstructionIndex}, Offset {offset.messageDataOffset}, Size{' '} - {offset.messageDataSize} - - - - Message - - - {Buffer.from(message).toString('base64')} - - - - - ); - })} - - ); -} diff --git a/app/components/instruction/ed25519/__tests__/Ed25519DetailsCard.test.tsx b/app/components/instruction/ed25519/__tests__/Ed25519DetailsCard.test.tsx deleted file mode 100644 index 218490a0..00000000 --- a/app/components/instruction/ed25519/__tests__/Ed25519DetailsCard.test.tsx +++ /dev/null @@ -1,131 +0,0 @@ -import { ParsedTransaction, PublicKey } from '@solana/web3.js'; -import { render, screen } from '@testing-library/react'; -import bs58 from 'bs58'; - -import { Ed25519DetailsCard } from '../Ed25519DetailsCard'; - -// Mock the dependencies -jest.mock('../../../common/Address', () => ({ - Address: ({ pubkey, alignRight, link }: { pubkey: PublicKey; alignRight?: boolean; link?: boolean }) => ( -
- {pubkey.toBase58()} -
- ), -})); - -jest.mock('../../../common/Copyable', () => ({ - Copyable: ({ text, children }: { text: string; children: React.ReactNode }) => ( -
- {children} -
- ), -})); - -jest.mock('../../InstructionCard', () => ({ - InstructionCard: ({ children, title }: { children: React.ReactNode; title: string }) => ( -
-
{title}
- - {children} -
-
- ), -})); - -describe('Ed25519DetailsCard', () => { - const defaultProps = { - childIndex: undefined, - index: 0, - innerCards: undefined, - result: { err: null }, - }; - - it('renders basic Ed25519 verification instruction with single signature', () => { - // 56JcSVYUPr8hdg8q2bfDhiPm5W9XQtr45VEevK9ye6Ec7DcyvD9CvnDgUoQhL3eQEmz32RRtLcaRdU9xyaDyCLiT (devnet) - - // Example of single signature verification - const ed25519x = { - data: Buffer.from('01000c0001004c0001006e008a000100', 'hex'), - keys: [], - programId: new PublicKey('Ed25519SigVerify111111111111111111111111111'), - }; - const programIx = { - data: bs58.encode( - Buffer.from( - '3259784efe0f688cec00000037d6acf4b3c9628b3485f398ed7baa20c37c4dff8ebee937456adea100d27c923e097cb0f41c9ff752efc7ed06db3c28bcf867f3ca203cde9222e72d1e93d503395311d51c1b87fd56c3b5872d1041111e51f399b12d291d981a0ea3834072958a00303030313031303034303432306630303030303030303030303030303030303030303030303030303031303030303030303030303030303030303031633830313939353235653733313730303030303030313330646465643337313730303030303030303030633866373165313530303030303030303334373337303431353433343533343830303030', - 'hex' - ) - ), - keys: [ - { - isSigner: false, - isWritable: false, - pubkey: new PublicKey('5zpq7DvB6UdFFvpmBPspGPNfUGoBRRCE2HHg5u3gxcsN'), - }, - { - isSigner: false, - isWritable: true, - pubkey: new PublicKey('UT4Qz3caSmEKEUmzQLxANRVxdZpcmdGJQ9bukQnxhRb'), - }, - { - isSigner: false, - isWritable: true, - pubkey: new PublicKey('fxDKmzDYgHBmuzzgtnGzEwJsUZRL9oceLS1Sg1ytwCj'), - }, - { - isSigner: false, - isWritable: true, - pubkey: new PublicKey('95Lgwzkf2P5Kbu2cubAwEvmWN3kjeS9njy6gLxQQ7rps'), - }, - { - isSigner: true, - isWritable: true, - pubkey: new PublicKey('4rmhwytmKH1XsgGAUyUUH7U64HS5FtT6gM8HGKAfwcFE'), - }, - // Ignore other keys in this ix for this test - ].map(meta => ({ - ...meta, - pubkey: meta.pubkey.toBase58(), - })), - programId: new PublicKey('dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH'), - }; - - // Very annoying thing about ed25519 is that all of its ix data has to reference - // other outer instructions - const tx = { - message: { - accountKeys: [], - instructions: [ed25519x, programIx], - recentBlockhash: '11111111111111111111111111111111', - }, - signatures: [], - } as unknown as ParsedTransaction; - - render(); - - const card = screen.getByTestId('instruction-card'); - - // Check title - expect(card).toHaveTextContent('Ed25519: Verify Signature'); - - // Check signature details - expect(card).toHaveTextContent('Signature #1'); - expect(card).toHaveTextContent('Signature Reference'); - expect(card).toHaveTextContent('Instruction 1, Offset 12'); - expect(card).toHaveTextContent( - 'UkJHZjY1ZHVSWUI4Q1Z3QXZUTTlGdThFNWlVNXpyZFQybnhoYjhzOVBpdlNzcHJZUVRyOHByRmZaVHNtVVV4Vg==' - ); - - // Check public key details - expect(card).toHaveTextContent('Public Key Reference'); - expect(card).toHaveTextContent('Instruction 1, Offset 76'); - expect(card).toHaveTextContent('4rmhwytmKH1XsgGAUyUUH7U64HS5FtT6gM8HGKAfwcFE'); - - // Check message details - expect(card).toHaveTextContent('Message Reference'); - expect(card).toHaveTextContent('Instruction 1, Offset 110, Size 138'); - expect(card).toHaveTextContent( - 'Q1Z4RTlQZ1NIa29XbnluQUM2MkdZMnNnanVCSGtEdXZGOU5BVng2MlY2V0xFQlR2Y0pWUTdzWWY0RG9jQlg4am1CTjFqNXRUTERwTlp2Vzc5eE5wU0xKUDJnb3RGNW1pWWprQ2JMb1NRaWhRWEw2OXlvMmgyeTIxZTc4WEJ0cXFVSmdCbk1YUnhN' - ); - }); -}); diff --git a/app/components/instruction/ed25519/types.ts b/app/components/instruction/ed25519/types.ts deleted file mode 100644 index 0fa52e25..00000000 --- a/app/components/instruction/ed25519/types.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { PublicKey, TransactionInstruction } from '@solana/web3.js'; -import { PublicKeyFromString } from '@validators/pubkey'; -import { Infer, type } from 'superstruct'; - -const PROGRAM_ADDRESS = 'Ed25519SigVerify111111111111111111111111111'; -export const PROGRAM_ID = new PublicKey(PROGRAM_ADDRESS); - -export type Ed25519Info = Infer; -export const Ed25519Info = type({ - account: PublicKeyFromString, -}); - -export function isEd25519Instruction(instruction: TransactionInstruction): boolean { - return PROGRAM_ADDRESS === instruction.programId.toBase58(); -} diff --git a/app/components/transaction/InstructionsSection.tsx b/app/components/transaction/InstructionsSection.tsx index 3b689187..e0851ec8 100644 --- a/app/components/transaction/InstructionsSection.tsx +++ b/app/components/transaction/InstructionsSection.tsx @@ -43,8 +43,6 @@ import React from 'react'; import { ErrorBoundary } from 'react-error-boundary'; import AnchorDetailsCard from '../instruction/AnchorDetailsCard'; -import { Ed25519DetailsCard } from '../instruction/ed25519/Ed25519DetailsCard'; -import { isEd25519Instruction } from '../instruction/ed25519/types'; import { LighthouseDetailsCard } from '../instruction/lighthouse/LighthouseDetailsCard'; import { isLighthouseInstruction } from '../instruction/lighthouse/types'; import { isMangoInstruction } from '../instruction/mango/types'; @@ -168,7 +166,6 @@ function InstructionCard({ const key = `${index}-${childIndex}`; const { program: anchorProgram } = useAnchorProgram(ix.programId.toString(), url); - console.log('ix', ix); if ('parsed' in ix) { const props = { childIndex, @@ -222,8 +219,6 @@ function InstructionCard({ if (isAddressLookupTableInstruction(transactionIx)) { return ; - } else if (isEd25519Instruction(transactionIx)) { - return ; } else if (isMangoInstruction(transactionIx)) { return ; } else if (isSerumInstruction(transactionIx)) {