Ethers to Alloy Migration Guide
Rindexer released a breaking change for all Rust projects, which internally migrates from ethers to alloy.
This means that exposed types and primitives are now from Alloy rather than Ethers-rs; some methods have also been deprecated and this will require breaking changes to be implemented within any rindexer rust project.
The simple steps to take are as follows:
- Add
alloy
to yourCargo.toml
- Run
rindexer codegen typings
to get the latest codegen state - Change all parameter names and types
- Change advanced methods
You can see more details on each section below.
1. Add alloy
to your Cargo.toml
First you should add alloy
to your Cargo.toml
and delete ethers
. You can now remove any references to the ethers
crate and replace
this will the newer alloy
crate. It should be pegged to the same version used by rindexer
internally to ensure type compatibility.
Replace in Cargo.toml
- ethers = "2.0.14"
+ alloy = { version = "0.15.6", features = ["full"] }
Then any references to ethers types in your own code can be replaced with the alloy types. You can read more in the migration docs.
- use ethers::prelude::U256;
+ use alloy::primitives::U256;
2. Run rindexer codegen typings
to get the latest codegen state
Once you have added the alloy
crate and changed any of your project-specific code uses you can now run the rindexer
codegen with rindexer codegen typings
. This will regenerate the bindings with alloy code and types.
If for some reason there are errors in your codegen file, please try deleting it before re-running. Otherwise raise an issue on github: https://github.com/joshstevens19/rindexer/issues.
This should lead to working error-free code in the codegen directory. At this point you should expect to errors in most of the actual custom indexing files if you have specified them. This is mainly due to the reasons below (parameter name changes & type changes).
3. Change all parameter names and types
You must now go through and deal with the errors in your specific handler functions. These will almost exclusively be
related to casing changes i.e. token_id
-> tokenId
. Or it will be a type's name change, i.e H256
-> B256
.
This should be relatively self explanatory, you can read more details below but it's just a simple manual process.
Solidity contract parametersThe casing of solidity contract parameters is now transparent, meaning the prior snake_case
conversion will no longer
be retained and instead you will be required to access an event parameter by it's source name.
This will typically be camelCase
or occasionally UPPERCASE
, the rust compiler will help with this and the conversion
should be relatively simple, albeit it a manual process.
- EthereumSqlTypeWrapper::AddressBytes(t.event_data.on_behalf_of),
+ EthereumSqlTypeWrapper::AddressBytes(t.event_data.onBehalfOf),
The core EthereumSqlTypeWrapper
have been ported to use the new alloy primitives internally, so if you are manually
passing any ethers
types such as the Address
derived manually (i.e. not as an automatically exposed type from rindexer)
then you will need ensure this is migrated to the new types.
Most simple types can be found in the alloy migration guide: https://alloy.rs/migrating-from-ethers/reference/
The most common types which experiences the rename are the Hash
types, renamed to Byte
types:
H256
->B256
H128
->B128
H256
->B256
H512
->B512
The above includes all Vec, and Byte representation variants e.g. VecB512
, etc.
The following types have been retained but should be consisted deprecated and may be removed:
H160
-> UseAddress
types instead (Including all Vec, and Byte representation variants)
A simple find and replace should handle most of these cases
4. Change advanced methods
Most projects will by default use the underlying type, this is for when manual type manipulation is needed.
The final step may be to replace any methods that are erroring out, that previously were not. The most common of this
will be the existence of as_u[BITS]
.
These methods are no longer exposed directly on all solidity primitive uint
types. For example the as_u32()
method
which existed on a U256
is no longer directly accessible.
Instead now, if you wish to downcast, you can use the TryInto
trait on most uint
types to achieve the same outcome and
handle errors gracefully in the event of an overflow (where before a panic would occur implicitly).
- EthereumSqlTypeWrapper::U32(t.tx_information.log_index.as_u32()),
+ EthereumSqlTypeWrapper::U32(t.tx_information.log_index.try_into().expect("log_index should fit in u32")),
You may also opt to match the underlying type
- EthereumSqlTypeWrapper::U32(t.tx_information.log_index.as_u32()),
+ EthereumSqlTypeWrapper::U256(t.tx_information.log_index),