The trait xxx is not implemented for xxx

Very interesting problem.

Could someone give me a hint?

What different between these 2 code?

https://github.com/darwinia-network/darwinia-common/blob/bear-precompiles-to-one/frame/dvm/src/mock.rs#L160-L164

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

https://github.com/darwinia-network/darwinia-common/blob/bear-precompiles-to-one/bin/node/runtime/pangolin/src/pallets/evm_.rs#L33-L35

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 https://github.com/darwinia-network/darwinia-common/blob/bear-precompiles-to-one/frame/evm/precompile/contracts/transfer/src/lib.rs#L46-L47

for the first code, I already impl dvm_ethereum::Config for Test https://github.com/darwinia-network/darwinia-common/blob/bear-precompiles-to-one/frame/dvm/src/mock.rs#L194
for the second code, I already impl dvm_ethereum::Config for Runtime https://github.com/darwinia-network/darwinia-common/blob/bear-precompiles-to-one/bin/node/runtime/pangolin/src/pallets/dvm.rs#L22

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™.

15 Likes

Thanks for you patient! Excellent explanation!!

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.