ethers-rs
ethers-rs copied to clipboard
Object Safe Connections
This is the realization of the design proposed in #592.
Motivation
The current Transport
trait is not object-safe, meaning it is not easily possible to dynamically abstract over different connection types at runtime. It is also heavily entangled with the Middleware
trait, obscuring in some cases what happens, when API calls are made (or even, if API calls are made at all).
Solution
Rewrite Transport
trait and implementations to be object-safe, untangle Middleware
trait and move entirely to ethers-middleware
, making it optional for certain use-cases.
Issues to be Resolved by this PR
- #1154 - the rewritten
Provider
type will expose the Ethereum JSON-RPC in type-safe manner, with mostly a 1:1 mapping between RPC calls and exposed methods - #969 - with the new
Provider
API, thePendingTransaction
type could/should be made generic over owned & borrowed providers - #876 - this is already implemented, the signature is
async fn [Provider::]connect(url: &str) -> Result<Provider<Arc<dyn Connection>>, ProviderError>
- #592
Points of Contention
Some points I would like to discuss before moving forward on them:
- There is a bunch of types in
ethers-core
that only exist because of the structure of the JSON-RPC API, such asSyncStatus
(models the return type ofeth_syncing
) orBlockNumber
(allows calling certain methods with either a block number or a generic tag like "latest"). I would like to move all those types toethers_providers::types
. - The "meta-transport" implementations
Quorum
andReadWrite
. The latter in particular feels like something that could be easily handwritten by each user requiring such functionality and is not really worth the cost of maintaining it at a library level, but feel free to voice your concerns in the comments. Both could probably be "hackily" implemented asConnection
impls by inspecting the "raw" request strings and searching for method call names. - To me,
ethers-providers
should provide an API that fairly closely matches the Ethereum JSON-RPC API, sosend_raw_transaction
should just return a hash,get_block_by_number
/get_block_by_hash
should be distinct functions, etc. Convenience should be added on top of that at a higher level (i.e., for now, theMiddleware
trait). - For now, I've changed the name of the trait from
Transport
toConnection
, I feel like this better describes the concept being abstracted by it. I've also found it let me word doc comments less awkwardly and it more closely matches the terminology in the Ethereum API spec. Overall it may be undesirable to some, as it does lead to more API breakage I would think.
PR Checklist
- [x] Implemented new
Connection
&DuplexConnection
traits - [x] Implemented HTTP connection
- [x] Implemented IPC connection
- [ ] Implemented WS connection
- [ ] Implemented
Quorum
/ReadWrite
(discussion re potential removal?) - [ ] Implement full JSON-RPC API
- [ ] Moved
Middleware
trait toethers-middleware
- [ ] Moved types that are only RPC-related from
ethers-core
toethers-providers
(discussion?) - [ ] Merge with
ethers-providers
- [ ] Added Tests
- [ ] Added Documentation
- [ ] Updated the changelog