ava-labs / teleporter

EVM cross-chain messaging protocol built on top of Avalanche Warp Messaging
Other
46 stars 22 forks source link

Design unified ethclient interface #208

Open cam-schultz opened 8 months ago

cam-schultz commented 8 months ago

Context and scope Our E2E tests use ethclient as defined in coreth and subnet-evm. While similar, the interfaces are not identical as they use types from the respective repositories. This causes certain methods to behave differently. For example, getting a block via BlockByNumber and calculating the hash results in different values for the same endpoint, since the hash calculation is performed on the type from the same repository as the client. Therefore, calculating the hash of a C-Chain block via a subnet-evm client (even when dialing ext/bc/C) will produce the wrong hash.

Discussion and alternatives We should design an interface that accounts for the differences between the two clients. Alternatively, we could add distinct fields to SubnetTestInfo with separate coreth and subnet-evm clients, and add utility functions to make that distinction under the hood. In any case, we want to avoid workarounds such as this.

Open questions Can we do this while still using subnet-evm's abigen?

geoff-vball commented 8 months ago

Talked to Aaron Buchwald and he said the only difference at the API level should be with the block structure/hashing. We should be able to write a wrapper around the clients which adds some additional logic to block-related API calls to get the correct result for the calling chain.

If there's one client that has strictly more block information than the other, we can probably always use that client, and then form the other block type and calculate the appropriate hash. If they're altogether different, we'll probably have to create a struct that is the lowest-common-denominator of the two, call the correct client, and then return our new block struct.

BlockByHash and BlockByNumber will definitely need new implementations because they return block structs.

CallContractAtHash, and TransactionInBlock may need new implementations because they accept a block hash as a parameter, but it's possible both clients would handle this properly.