Skip to content

Commit

Permalink
test(sdk): Use ethers v6 utils (#2886)
Browse files Browse the repository at this point in the history
Moved two Ethereum function selector utils from `FakeJsonRpcServer` to
test utils. These are soon needed in
#2883.

Also refactored methods (and one `FakeJsonRpcServer` usage) to use the
`id` utils from ethers
(https://github.com/ethers-io/ethers.js/blob/9e7e7f3e2f2d51019aaa782e6290e079c38332fb/src.ts/hash/id.ts#L16).
It does the same hash calculation as our implementation.

Note that the return value of the functions now includes the `0x`
prefix. It is therefore compatible e.g. with `ethers`
`FunctionFragment.getSelector()` method
(https://github.com/ethers-io/ethers.js/blob/9e7e7f3e2f2d51019aaa782e6290e079c38332fb/src.ts/abi/fragments.ts#L1449).
  • Loading branch information
teogeb authored Nov 18, 2024
1 parent 2a40642 commit 1e4dac3
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 17 deletions.
21 changes: 8 additions & 13 deletions packages/sdk/test/test-utils/FakeJsonRpcServer.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { AbiCoder, keccak256, toUtf8Bytes } from 'ethers'
import { AbiCoder, id } from 'ethers'
import { once } from 'events'
import express, { Request, Response } from 'express'
import { Server } from 'http'
import { intersection, isArray } from 'lodash'
import { AddressInfo } from 'net'
import { promisify } from 'util'
import { formEthereumFunctionSelector, parseEthereumFunctionSelectorFromCallData } from './utils'

export const CHAIN_ID = 5555
const BLOCK_NUMBER = 123
Expand All @@ -14,12 +15,6 @@ const toHex = (val: number) => {
return '0x' + val.toString(16)
}

const getLabelHash = (methodSignature: string) => keccak256(toUtf8Bytes(methodSignature))

const getContractMethodHash = (methodSignature: string) => getLabelHash(methodSignature).substring(2, 10)

const getEventTopicHash = (eventSignature: string) => getLabelHash(eventSignature)

export interface JsonRpcRequest {
id: string
method: string
Expand Down Expand Up @@ -88,17 +83,17 @@ export class FakeJsonRpcServer {
return toHex(BLOCK_NUMBER)
} else if (request.method === 'eth_call') {
const data: string = request.params[0].data
const contractMethodHash = data.substring(2, 10)
if (contractMethodHash === getContractMethodHash('getPermissionsForUserId(string,bytes)')) {
const functionSelector = parseEthereumFunctionSelectorFromCallData(data)
if (functionSelector === formEthereumFunctionSelector('getPermissionsForUserId(string,bytes)')) {
// PermissionStructOutput: { canEdit: false, canDelete: false, publishExpiration: 0n, subscribeExpiration: 0n, canGrant: false }
return '0x' + '0'.repeat(320)
} else {
throw new Error(`Unknown contract method: ${contractMethodHash}, request: ${JSON.stringify(request)}`)
throw new Error(`Unknown contract method: ${functionSelector}, request: ${JSON.stringify(request)}`)
}
} else if (request.method === 'eth_getLogs') {
const topics = request.params[0].topics
const topicHash = getEventTopicHash('StreamCreated(string,string)')
if ((topics.length !== 1) || (topics[0] !== topicHash)) {
const topicId = id('StreamCreated(string,string)')
if ((topics.length !== 1) || (topics[0] !== topicId)) {
throw new Error('Not implemented')
}
if (request.params[0].toBlock !== 'latest') {
Expand All @@ -109,7 +104,7 @@ export class FakeJsonRpcServer {
const data = new AbiCoder().encode(['string', 'string'], [EVENT_STREAM_ID, JSON.stringify({ partitions: 1 })])
return [{
address: request.params[0].address,
topics: [topicHash],
topics: [topicId],
data,
blockNumber: toHex(BLOCK_NUMBER),
transactionHash: '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef',
Expand Down
18 changes: 14 additions & 4 deletions packages/sdk/test/test-utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ import {
DEFAULT_PARTITION_COUNT,
Logger,
MAX_PARTITION_COUNT,
merge,
StreamPartID,
StreamPartIDUtils,
until,
UserID,
merge,
utf8ToBinary,
wait,
until
wait
} from '@streamr/utils'
import crypto from 'crypto'
import { Wallet } from 'ethers'
import { id, Wallet } from 'ethers'
import { once } from 'events'
import express, { Request, Response } from 'express'
import { mock } from 'jest-mock-extended'
Expand Down Expand Up @@ -318,3 +318,13 @@ export const readUtf8ExampleIndirectly = async (): Promise<string> => {
})
})
}

const ETHEREUM_FUNCTION_SELECTOR_LENGTH = 10 // 0x + 4 bytes

export const formEthereumFunctionSelector = (methodSignature: string): string => {
return id(methodSignature).substring(0, ETHEREUM_FUNCTION_SELECTOR_LENGTH)
}

export const parseEthereumFunctionSelectorFromCallData = (data: string): string => {
return data.substring(0, ETHEREUM_FUNCTION_SELECTOR_LENGTH)
}

0 comments on commit 1e4dac3

Please sign in to comment.