Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem: evm contract can't call native module message #45

Merged
merged 12 commits into from
Sep 9, 2021

Conversation

yihuang
Copy link
Collaborator

@yihuang yihuang commented Sep 3, 2021

Closes #29

Solution:

  • implement bank and gravity evm hooks

👮🏻👮🏻👮🏻 !!!! REFERENCE THE PROBLEM YOUR ARE SOLVING IN THE PR TITLE AND DESCRIBE YOUR SOLUTION HERE !!!! DO NOT FORGET !!!! 👮🏻👮🏻👮🏻

PR Checklist:

  • Have you read the CONTRIBUTING.md?
  • Does your PR follow the C4 patch requirements?
  • Have you rebased your work on top of the latest master?
  • Have you checked your code compiles? (make)
  • Have you included tests for any non-trivial functionality?
  • Have you checked your code passes the unit tests? (make test)
  • Have you checked your code formatting is correct? (go fmt)
  • Have you checked your basic code style is fine? (golangci-lint run)
  • If you added any dependencies, have you checked they do not contain any known vulnerabilities? (go list -json -m all | nancy sleuth)
  • If your changes affect the client infrastructure, have you run the integration test?
  • If your changes affect public APIs, does your PR follow the C4 evolution of public contracts?
  • If your code changes public APIs, have you incremented the crate version numbers and documented your changes in the CHANGELOG.md?
  • If you are contributing for the first time, please read the agreement in CONTRIBUTING.md now and add a comment to this pull request stating that your PR is in accordance with the Developer's Certificate of Origin.

Thank you for your code, it's appreciated! :)

@codecov
Copy link

codecov bot commented Sep 3, 2021

Codecov Report

Merging #45 (6c5bd94) into main (3ea70c5) will increase coverage by 4.13%.
The diff coverage is 83.19%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main      #45      +/-   ##
==========================================
+ Coverage   21.51%   25.64%   +4.13%     
==========================================
  Files          27       29       +2     
  Lines        1729     1848     +119     
==========================================
+ Hits          372      474     +102     
- Misses       1324     1337      +13     
- Partials       33       37       +4     
Impacted Files Coverage Δ
app/app.go 3.90% <0.00%> (-0.05%) ⬇️
x/cronos/keeper/evmhooks.go 80.00% <80.00%> (ø)
x/cronos/keeper/evm_log_handlers.go 88.29% <88.29%> (ø)
x/cronos/keeper/keeper.go 100.00% <0.00%> (+5.66%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 0d6b1d6...6c5bd94. Read the comment docs.

}

func (h BankSendHook) PostTxProcessing(ctx sdk.Context, txHash common.Hash, logs []*ethtypes.Log) error {
for _, log := range logs {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could be cleanup a bit to loop only one time

I think instead of creating 2 hooks (for bank and gravity), you can define another interface which implement EventProcessing

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, do you mean to register the log processors into sth like: event_id -> processer? sounds good.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will the log/event order make a difference? And in some cases a processor may need to handle multiple events?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just pushed a new implementation.

Will the log/event order make a difference? And in some cases a processor may need to handle multiple events?

Currently we only have one handler for one event, if we need to support more, can change the EventID method to return an array.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where is decimal conversion
10^8 -> 10^18 ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#35
that is handled in this PR

Solution:
- implement bank and gravity evm hooks

update gomod2nix

changelog

test contract native call

comment
Copy link
Contributor

@leejw51crypto leejw51crypto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

constructor() public ERC20("Bitcoin MAX", "MAX") {
_mint(msg.sender, 100000000000000000000000000);
}

function test_native_transfer(uint amount) public {
emit __CronosNativeTransfer(msg.sender, amount);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't u have to burn the amount?

imo __CronosNativeTransfer is not clear for the operation. A transfer imply an origin and a destination.

Here it seems that you are either converting or minting?

It seems more that you are con

Copy link
Collaborator Author

@yihuang yihuang Sep 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is solely for testing the native call, the semantic of the call is to transfer mapped native token from contract address to recipient.
But because we can't setup token mapping in e2e testing right now, so the test itself is not complete yet (there's a TODO in that).

This is not the e2e testing for the complete bridge yet.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so maybe __CronosCosmosConvert or __CronosCosmosMint?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so maybe __CronosCosmosConvert or __CronosCosmosMint?

“Native” stands for native token, “Transfer” is also self explanatory I believe?

Copy link
Collaborator

@thomas-nguy thomas-nguy Sep 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is also self explanatory I believe?

I dont think so..
"Native" has barely any meaning without context. And using "Transfer" without specifying a sender and destination sounds weird.

If we can't find a proper short term to describe the operation, I would prefer to be very explicit and call the event
"__CronosSendFromContractToAccount(receiver, amount)" instead...

Mind that most smart contract developer won't have deep knowledge about the internal implementation, or cosmos implementation

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I think about it again, can we say "From" is implied because the action is "Send" and we are executing a contract? It is the "Subject" (what token) and "To" that's unclear.

So

___CronosSendXToAccount // Account or Native Account? need to address in the terminology issue
___CronosSendXToEthereum // Send X (From the contract account) To Ethereum
___CronosSendXToIBCChannel
// Similar to Gravity Bridge `SendToCosmos` but be more explicit about the token type

p.s. Having "From" is no harm, my motive is if we think event name is too long then we can think about to trim it or not. I am okay to include it and be more explicit. (Is there any restricting on event name length?)

Copy link
Collaborator Author

@yihuang yihuang Sep 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I think about it again, can we say "From" is implied because the action is "Send" and we are executing a contract? It is the "Subject" (what token) and "To" that's unclear.

So

___CronosSendXToAccount // Account or Native Account? need to address in the terminology issue
___CronosSendXToEthereum // Send X (From the contract account) To Ethereum
___CronosSendXToIBCChannel
// Similar to Gravity Bridge `SendToCosmos` but be more explicit about the token type

p.s. Having "From" is no harm, my motive is if we think event name is too long then we can think about to trim it or not. I am okay to include it and be more explicit. (Is there any restricting on event name length?)

Looks good to me.
And let's use NativeTokens for X for now? or Coins?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe 'X' can be omitted now?

__CronosSendToAccount
__CronosSendToEthereum
__CronosSendToIBCChannel

Even if we add NativeToken or Coins, it is not clear which coin is it. We need a proper term to designate the "Coin associated with the contract"

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe 'X' can be omitted now?

__CronosSendToAccount
__CronosSendToEthereum
__CronosSendToIBCChannel

Even if we add NativeToken or Coins, it is not clear which coin is it. We need a proper term to designate the "Coin associated with the contract"

Looks good too, I suppose we'll have detailed documentation about them as part of the CRC20 standard.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#62
opened issue and documented decision so far in it.


denom, found := h.cronosKeeper.GetDenomByContract(ctx, contract)
if !found {
return errors.New("contract is not connected to native token")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am thinking if we could wrap add those errors in the ethereum log, it could be nice

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add the contract address in the error?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am thinking if we could wrap add those errors in the ethereum log, it could be nice

I believe that’s the case, the error returned by hook is saved in the return value of the EVM call.
But I need to double check on the rpc response.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/tharsis/ethermint/blob/main/x/evm/keeper/state_transition.go#L198

Hmm, the detailed error won't appear in the response, the RPC user only sees a fixed error string.
But it do get logged in a logfile as an error.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay I created a new issue for that #61

Copy link
Collaborator

@thomas-nguy thomas-nguy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM except for the event name convention.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Problem: evm contract can't call native module message
4 participants