The trait xxx is not implemented for xxx

Very interesting problem.

Could someone give me a hint?

What different between these 2 code?

git clone https://github.com/darwinia-network/darwinia-common.git
git checkout bear-precompiles-to-one
cd darwinia-common
cd frame/dvm
cargo t

then failed
git clone https://github.com/darwinia-network/darwinia-common.git
git checkout bear-precompiles-to-one
cd darwinia-common
cargo c

everything works good

here's a generic impl darwinia-common/lib.rs at bear-precompiles-to-one · darwinia-network/darwinia-common · GitHub

for the first code, I already impl dvm_ethereum::Config for Test darwinia-common/mock.rs at bear-precompiles-to-one · darwinia-network/darwinia-common · GitHub
for the second code, I already impl dvm_ethereum::Config for Runtime darwinia-common/dvm.rs at bear-precompiles-to-one · darwinia-network/darwinia-common · GitHub

why the compiler complain about the the trait xxx is not implemented for xxx (with first code)

1 Like

Damn, this has been a tough one to diagnose!! :sweat_smile: (btw, one of the github dependencies has renamed the master branch to main, so the Cargo.toml at the root of that workspace ought to be updated with added branch = "main" mentions).

There is definitely something a bit fishy going on in your situation, since you happen to have kind of a cyclic dependency:

What does this mean? Since a true cyclic dependency cannot happen, the actual setup becomes:

In other words: there are actually two distinct dvm-ethereum crates!!

Thus, there are two distinct Config traits as well!

  • The one from dvm-ethereum as a library;

  • The one from dvm-ethereum with --cfg test (and the rest of the unit test harness).

So, when inside a cfg(test) unit-test module, you define a mock Test type, and implement Config for it, you are implementing the latter Config trait. But Precompile is only implemented for Transfers that wrap implementors of the the former Config trait, since that's the Config trait that "reached" / was accessible to darwinia-evm-precompile-transfer.

Hence the error.

Minimal repro: Playground

Solution

One possible solution is to have ::b in the example of the Playground, that is, ::darwinia-evm-precompile-transfer in yours, re-export the ::a crate, that is, the dvm-ethereum it uses, so that you can have access to its items, such as the "true" Config trait.

A cleaner solution would be to be using an integration test, so that dvm-ethereum, in and of itself, is only used as a classic library (no --cfg test recompilation), and then things ought to Just Work™.

13 Likes

Thanks for you patient! Excellent explanation!!

1 Like