-
Notifications
You must be signed in to change notification settings - Fork 782
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
Kick ethers
off the block
#2633
Changes from all commits
9c32c76
650fb3f
d177332
a21a116
d99e6b1
0b45f5d
5032c1d
65d63d9
1dc1fcf
8bd0129
4dce10c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
import { Chain, Common, Hardfork } from '@ethereumjs/common' | ||
import { randomBytes } from 'crypto' | ||
import * as tape from 'tape' | ||
import * as td from 'testdouble' | ||
|
||
import { blockFromRpc } from '../src/from-rpc' | ||
import { blockHeaderFromRpc } from '../src/header-from-rpc' | ||
|
@@ -185,13 +187,39 @@ tape('[fromRPC] - Alchemy/Infura API block responses', (t) => { | |
|
||
tape('[fromEthersProvider]', async (t) => { | ||
const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.London }) | ||
const provider = new MockProvider() | ||
const provider = new MockProvider() // mimics some properties of an Ethers JsonRPCProvider | ||
|
||
const fakeFetch = async (_url: string, req: any) => { | ||
if ( | ||
req.method === 'eth_getBlockByHash' && | ||
req.params[0] === '0x1850b014065b23d804ecf71a8a4691d076ca87c2e6fb8fe81ee20a4d8e884c24' | ||
) { | ||
const block = await import(`./testdata/infura15571241wtxns.json`) | ||
return block | ||
} else { | ||
return null // Infura returns null if no block is found | ||
} | ||
} | ||
|
||
const providerUtils = require('@ethereumjs/util/dist/provider') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this needs to be required in such a strange way? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have to get a concrete reference to the function I want to stub using |
||
td.replace<any>(providerUtils, 'fetchFromProvider', fakeFetch) | ||
|
||
const blockHash = '0x1850b014065b23d804ecf71a8a4691d076ca87c2e6fb8fe81ee20a4d8e884c24' | ||
const block = await Block.fromEthersProvider(provider, blockHash, { common }) | ||
t.equal( | ||
'0x' + block.hash().toString('hex'), | ||
blockHash, | ||
'assembled a block from blockdata from a provider' | ||
) | ||
try { | ||
await Block.fromEthersProvider(provider, '0x' + randomBytes(32).toString('hex'), {}) | ||
t.fail('should throw') | ||
} catch (err: any) { | ||
t.ok( | ||
err.message.includes('No block data returned from provider'), | ||
'returned correct error message' | ||
) | ||
} | ||
td.reset() | ||
t.end() | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,5 @@ | ||
import { ethers } from 'ethers' | ||
|
||
export class MockProvider extends ethers.providers.JsonRpcProvider { | ||
send = async (method: string, params: Array<any>) => { | ||
switch (method) { | ||
case 'eth_getBlockByHash': | ||
return this.getBlockValues(params as any) | ||
case 'eth_chainId': // Always pretends to be mainnet | ||
return 1 | ||
default: | ||
throw new Error(`method ${method} not implemented`) | ||
} | ||
} | ||
|
||
private getBlockValues = async (_params: any) => { | ||
const block = await import(`./testdata/infura15571241wtxns.json`) | ||
return block | ||
export class MockProvider { | ||
connection = { | ||
url: 'http://localhost', | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so the provider is essentially being stripped out. not sure if this is the right approach as the provider might be providing some wrapper functionality (like proof seeking and verification)
May be we can later revisit this on how to best interface a provider
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where would a provider do proof verification? We could put cleanly define the provider interface (at least for the minimal functions we'd need to call) I supposed but that feels like more work than it's worth and very brittle if
ethers
orweb3js
(if we support that provider type too in the future) ever change their API. At the end of the day, we're just making an HTTP call to some remote RPC provider to get the json blob back for the blob or the tx. But, that said, happy to discuss further. We need to add a todo on the breaking release to rename thefromEthersProvider
functions anyway.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we eventually test for the Ethers import to work (in a try/catch block) and only do this stripping out as a fallback solution? Then we might somewhat have best of both worlds.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess we could but all we were doing before was calling the
provider.send
method which is just abstracting a raw JSON RPC call. Here again, we weren't using any provider-specific functionality, just a simple wrapper around HTTP requests. As such, I'm not sure what we gain since we'd have to blindly call the provider and hope nothing in the API has changed. I don't think what I've done in this PR is any worse than that.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, good reasoning, then let's merge here.
I would now plan a round of "normal" releases for sometime mid next week, will prepare release notes next Monday or so.