Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace ethjs-query with @metamask/eth-query #129

Merged
merged 1 commit into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,10 @@
"pify": "^5.0.0"
},
"devDependencies": {
"@ethereumjs/util": "^8.1.0",
"@lavamoat/allow-scripts": "^2.5.1",
"@metamask/auto-changelog": "^3.3.0",
"@metamask/eth-json-rpc-middleware": "^12.0.0",
"eth-block-tracker": "^8.0.0",
"ethjs-query": "^0.3.8",
"ganache-core": "^2.13.2",
"sinon": "^15.2.0",
"tape": "^5.7.0"
Expand Down Expand Up @@ -59,7 +57,8 @@
"ganache-core>websocket>bufferutil": false,
"ganache-core>websocket>utf-8-validate": false,
"ganache-core>ethereumjs-util>ethereum-cryptography>keccak": false,
"ganache-core>ethereumjs-util>ethereum-cryptography>secp256k1": false
"ganache-core>ethereumjs-util>ethereum-cryptography>secp256k1": false,
"ganache-core>web3-provider-engine>eth-block-tracker>json-rpc-engine>babelify>babel-core>babel-runtime>core-js": false
}
}
}
96 changes: 72 additions & 24 deletions test/ganache.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
const test = require('tape')
const ethUtil = require('@ethereumjs/util')
const {
createTestSetup,
asyncTest,
Expand All @@ -9,50 +8,74 @@ const {
test('LogFilter - basic', asyncTest(async (t) => {

const tools = createTestSetup()
const eth = tools.query
const { sendAsync } = tools

// deploy log-echo contract
const coinbase = await eth.coinbase()
const coinbase = await sendAsync({ method: 'eth_coinbase' })
const { contractAddress } = await deployLogEchoContract({ tools, from: coinbase })
t.ok(contractAddress, 'got deployed contract address')

// create filter
const blockNumber = (await eth.blockNumber()).toNumber()
const blockNumber = await sendAsync({ method: 'eth_blockNumber' })
const targetTopic = '0xaabbcce106361d4f6cd9098051596d565c1dbf7bc20b4c3acb3aaa4204aabbcc'
const filterParams = { address: contractAddress, topics: [targetTopic], fromBlock: blockNumber, toBlock: 'latest' }
const filterId = ethUtil.intToHex((await eth.newFilter(filterParams)).toNumber())
const filterId = await sendAsync({
method: 'eth_newFilter',
params: {
address: contractAddress,
topics: [targetTopic],
fromBlock: blockNumber,
toBlock: 'latest'
}
})
t.ok(filterId, `got filter id: ${filterId} (${typeof filterId})`)

// trigger filter
const triggeringTxHash = await eth.sendTransaction({ from: coinbase, to: contractAddress, data: targetTopic })
const triggeringTxHash = await sendAsync({
method: 'eth_sendTransaction',
params: {
from: coinbase,
to: contractAddress,
data: targetTopic
}
})
await tools.trackNextBlock()
// check filter
const filterChanges = await eth.getFilterChanges(filterId)
const filterChanges = await sendAsync({
method: 'eth_getFilterChanges',
params: [filterId]
})
t.equal(filterChanges.length, 1, 'only one matched filter')
const matchingFilter = filterChanges[0]
t.equal(matchingFilter.transactionHash, triggeringTxHash, 'tx hash should match')
t.equal(matchingFilter.topics.length, 1, 'emitted a single log topic')
const matchedTopic = matchingFilter.topics[0]
t.equal(matchedTopic, targetTopic, 'topic matches expected')

await eth.uninstallFilter(filterId)
await sendAsync({ method: 'eth_uninstallFilter', params: [filterId] })
}))

test('LogFilter - multiple blocks', asyncTest(async (t) => {

const tools = createTestSetup()
const eth = tools.query
const { sendAsync } = tools

// deploy log-echo contract
const coinbase = await eth.coinbase()
const coinbase = await sendAsync({ method: 'eth_coinbase' })
const { contractAddress } = await deployLogEchoContract({ tools, from: coinbase })
t.ok(contractAddress, 'got deployed contract address')

// create filter
const blockNumber = (await eth.blockNumber()).toNumber()
const blockNumber = await sendAsync({ method: 'eth_blockNumber' })
const targetTopic = '0x112233e106361d4f6cd9098051596d565c1dbf7bc20b4c3acb3aaa4204112233'
const filterParams = { address: contractAddress, topics: [targetTopic], fromBlock: blockNumber, toBlock: 'latest' }
const filterId = ethUtil.intToHex((await eth.newFilter(filterParams)).toNumber())
const filterId = await sendAsync({
method: 'eth_newFilter',
params: {
address: contractAddress,
topics: [targetTopic],
fromBlock: blockNumber,
toBlock: 'latest'
}
})
t.ok(filterId, `got filter id: ${filterId} (${typeof filterId})`)

// await multiple blocks
Expand All @@ -64,7 +87,14 @@ test('LogFilter - multiple blocks', asyncTest(async (t) => {
await tools.trackNextBlock()

// trigger filter
const triggeringTxHash = await eth.sendTransaction({ from: coinbase, to: contractAddress, data: targetTopic })
const triggeringTxHash = await sendAsync({
method: 'eth_sendTransaction',
params: {
from: coinbase,
to: contractAddress,
data: targetTopic
}
})
await tools.trackNextBlock()

// await multiple blocks
Expand All @@ -74,44 +104,56 @@ test('LogFilter - multiple blocks', asyncTest(async (t) => {
await tools.trackNextBlock()

// check filter
const filterChanges = await eth.getFilterChanges(filterId)
const filterChanges = await sendAsync({
method: 'eth_getFilterChanges',
params: [filterId]
})
t.equal(filterChanges.length, 1, 'only one matched filter')
const matchingFilter = filterChanges[0]
t.equal(matchingFilter.transactionHash, triggeringTxHash, 'tx hash should match')
t.equal(matchingFilter.topics.length, 1, 'emitted a single log topic')
const matchedTopic = matchingFilter.topics[0]
t.equal(matchedTopic, targetTopic, 'topic matches expected')

await eth.uninstallFilter(filterId)
await sendAsync({ method: 'eth_uninstallFilter', params: [filterId] })
}))

test('BlockFilter - basic', asyncTest(async (t) => {

const tools = createTestSetup()
const eth = tools.query
const { sendAsync } = tools

// await first block
await tools.trackNextBlock()

// create filter
const filterId = ethUtil.intToHex((await eth.newBlockFilter()).toNumber())
const filterId = await sendAsync({ method: 'eth_newBlockFilter', })
t.ok(filterId, `got filter id: ${filterId} (${typeof filterId})`)

// check filter
const filterChanges1 = await eth.getFilterChanges(filterId)
const filterChanges1 = await sendAsync({
method: 'eth_getFilterChanges',
params: [filterId]
})
t.equal(filterChanges1.length, 0, 'no matched filters yet')

// await one block
await tools.forceNextBlock()
await tools.trackNextBlock()

// check filter
const filterChanges2 = await eth.getFilterChanges(filterId)
const filterChanges2 = await sendAsync({
method: 'eth_getFilterChanges',
params: [filterId]
})
t.equal(filterChanges2.length, 1, 'only one matched filter')
const matchingFilter1 = filterChanges2[0]
t.equal(matchingFilter1.length, 2 + 32 * 2, 'result is correct length for block hash')
// check filter
const filterChanges3 = await eth.getFilterChanges(filterId)
const filterChanges3 = await sendAsync({
method: 'eth_getFilterChanges',
params: [filterId]
})
t.equal(filterChanges3.length, 0, 'matched filters reset')

// await two blocks
Expand All @@ -121,13 +163,19 @@ test('BlockFilter - basic', asyncTest(async (t) => {
await tools.trackNextBlock()

// check filter
const filterChanges4 = await eth.getFilterChanges(filterId)
const filterChanges4 = await sendAsync({
method: 'eth_getFilterChanges',
params: [filterId]
})
t.equal(filterChanges4.length, 2, 'two matched filter')
const matchingFilter2 = filterChanges4[0]
const matchingFilter3 = filterChanges4[1]
t.equal(matchingFilter2.length, 2 + 32 * 2, 'result is correct length for block hash')
t.equal(matchingFilter3.length, 2 + 32 * 2, 'result is correct length for block hash')
t.notEqual(matchingFilter2, matchingFilter3, 'hashes are different')

await eth.uninstallFilter(filterId)
await sendAsync({
method: 'eth_uninstallFilter',
params: [filterId]
})
}))
2 changes: 1 addition & 1 deletion test/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
process.on('unhandledRejection', function(err){
process.on('unhandledRejection', function (err) {
throw err
})

Expand Down
28 changes: 18 additions & 10 deletions test/subscriptions.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
const test = require('tape')
const {
createTestSetup,
createPayload,
asyncTest,
timeout,
deployLogEchoContract,
Expand All @@ -10,11 +9,8 @@ const {
test('subscriptions - newHeads', asyncTest(async (t) => {

const tools = createTestSetup()
const eth = tools.query
const subs = tools.subs

const { blockTracker } = tools

// await first block
await tools.forceNextBlock()
await tools.trackNextBlock()
Expand Down Expand Up @@ -57,11 +53,10 @@ test('subscriptions - newHeads', asyncTest(async (t) => {
test('subscriptions - log', asyncTest(async (t) => {

const tools = createTestSetup()
const eth = tools.query
const { query, subs, blockTracker } = tools
const { sendAsync, subs, blockTracker } = tools

// deploy log-echo contract
const coinbase = await query.coinbase()
const coinbase = await sendAsync({ method: 'eth_coinbase' })
const { contractAddress } = await deployLogEchoContract({ tools, from: coinbase })
t.ok(contractAddress, 'got deployed contract address')
// deploy secondary "wrong" log contract
Expand All @@ -84,15 +79,28 @@ test('subscriptions - log', asyncTest(async (t) => {
t.equal(typeof subId, 'string', `got sub id as hex string (${typeof subId})`)

// trigger matching log
const triggeringTxHash = await query.sendTransaction({ from: coinbase, to: contractAddress, data: targetTopic })
const triggeringTxHash = await sendAsync({
method: 'eth_sendTransaction',
params: { from: coinbase, to: contractAddress, data: targetTopic }
})
await tools.trackNextBlock()

// trigger non-matching log
await query.sendTransaction({ from: coinbase, to: contractAddress, data: wrongTopic })
await sendAsync({
method: 'eth_sendTransaction',
params: {
from: coinbase,
to: contractAddress,
data: wrongTopic
}
})
await tools.trackNextBlock()

// trigger non-matching contract
await query.sendTransaction({ from: coinbase, to: wrongContractAddress, data: targetTopic })
await sendAsync({
method: 'eth_sendTransaction',
params: { from: coinbase, to: wrongContractAddress, data: targetTopic }
})
await tools.trackNextBlock()

// wait for subscription results to update
Expand Down
34 changes: 22 additions & 12 deletions test/util.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const EventEmitter = require('events')
const { PollingBlockTracker } = require('eth-block-tracker')
const EthQuery = require('ethjs-query')
const EthQuery = require('@metamask/eth-query')
const { JsonRpcEngine } = require('@metamask/json-rpc-engine')
const { providerAsMiddleware } = require('@metamask/eth-json-rpc-middleware')
const { providerFromEngine } = require('@metamask/eth-json-rpc-provider')
Expand All @@ -19,7 +19,7 @@ module.exports = {
deployLogEchoContract,
}

function createTestSetup () {
function createTestSetup() {
// raw data source
const { ganacheProvider, forceNextBlock } = createEngineFromGanacheCore()
// create block trackerfilterId
Expand All @@ -31,6 +31,7 @@ function createTestSetup () {
const engine = new JsonRpcEngine()
const provider = providerFromEngine(engine)
const query = new EthQuery(provider)
const sendAsync = pify(query.sendAsync.bind(query));
// add filter middleware
engine.push(createFilterMiddleware({ blockTracker, provider }))
// add subscription middleware
Expand All @@ -43,7 +44,7 @@ function createTestSetup () {
// subs helper
const subs = createSubsHelper({ provider })

return { ganacheProvider, forceNextBlock, engine, provider, query, subs, blockTracker, trackNextBlock }
return { ganacheProvider, forceNextBlock, engine, provider, sendAsync, subs, blockTracker, trackNextBlock }

async function trackNextBlock() {
return new Promise((resolve) => blockTracker.once('latest', resolve))
Expand All @@ -59,7 +60,7 @@ function createSubsHelper({ provider }) {
}

function createSubGenerator({ subType, provider }) {
return pify(function() {
return pify(function () {
const args = [].slice.call(arguments)
const cb = args.pop()
args.unshift(subType)
Expand Down Expand Up @@ -98,7 +99,7 @@ function createNewSub({ id, provider }) {
}
}

function createEngineFromGanacheCore () {
function createEngineFromGanacheCore() {
const ganacheProvider = GanacheCore.provider()
return { ganacheProvider, forceNextBlock }

Expand All @@ -108,7 +109,7 @@ function createEngineFromGanacheCore () {
}
}

function createEngineFromTestBlockMiddleware () {
function createEngineFromTestBlockMiddleware() {
const engine = new JsonRpcEngine()
const testBlockSource = new TestBlockMiddleware()
engine.push(testBlockSource.createMiddleware())
Expand All @@ -119,8 +120,8 @@ function createPayload(payload) {
return Object.assign({ id: 1, jsonrpc: '2.0', params: [] }, payload)
}

function asyncTest(asyncTestFn){
return async function(t) {
function asyncTest(asyncTestFn) {
return async function (t) {
try {
await asyncTestFn(t)
t.end()
Expand All @@ -135,12 +136,21 @@ function timeout(duration) {
}


async function deployLogEchoContract({ tools, from }){
async function deployLogEchoContract({ tools, from }) {
// https://github.com/kumavis/eth-needlepoint/blob/master/examples/emit-log.js
const eth = tools.query
const deployTxHash = await eth.sendTransaction({ from, data: '0x600e600c600039600e6000f336600060003760005160206000a1' })
const { sendAsync } = tools;
const deployTxHash = await sendAsync({
method: 'eth_sendTransaction',
params: {
from,
data: '0x600e600c600039600e6000f336600060003760005160206000a1'
}
})
await tools.trackNextBlock()
const deployTxRx = await eth.getTransactionReceipt(deployTxHash)
const deployTxRx = await sendAsync({
method: 'eth_getTransactionReceipt',
params: [deployTxHash]
})
const contractAddress = deployTxRx.contractAddress
return {
deployTxHash,
Expand Down
Loading
Loading