Skip to content

Commit

Permalink
Support logs for evm hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
thomas-nguy committed Apr 8, 2022
1 parent ba751ea commit c71a354
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 17 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Unrelease

### Improvements
- [cronos#418](https://github.com/crypto-org-chain/cronos/pull/418) Support logs in evm-hooks and return id for SendToEthereum events


*January 21, 2022*

## v0.7.0
Expand Down
35 changes: 32 additions & 3 deletions x/cronos/keeper/evm_hooks.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package keeper

import (
"math/big"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/crypto-org-chain/cronos/x/cronos/types"
"github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types"

"github.com/crypto-org-chain/cronos/x/cronos/types"
)

// LogProcessEvmHook is an evm hook that convert specific contract logs into native module calls
Expand All @@ -25,6 +26,7 @@ func NewLogProcessEvmHook(handlers ...types.EvmLogHandler) *LogProcessEvmHook {

// PostTxProcessing implements EvmHook interface
func (h LogProcessEvmHook) PostTxProcessing(ctx sdk.Context, from common.Address, to *common.Address, receipt *ethtypes.Receipt) error {
addLogToReceiptFunc := newFuncAddLogToReceipt(receipt)
for _, log := range receipt.Logs {
if len(log.Topics) == 0 {
continue
Expand All @@ -33,10 +35,37 @@ func (h LogProcessEvmHook) PostTxProcessing(ctx sdk.Context, from common.Address
if !ok {
continue
}
err := handler.Handle(ctx, log.Address, log.Data)
err := handler.Handle(ctx, log.Address, log.Data, addLogToReceiptFunc)
if err != nil {
return err
}
}
return nil
}

// newFuncAddLogToReceipt return a function to add additional logs to the receipt
func newFuncAddLogToReceipt(receipt *ethtypes.Receipt) func(logSig common.Hash, logData []byte) {
return func(logSig common.Hash, logData []byte) {
if receipt.BlockNumber == nil {
return
}
newLog := &ethtypes.Log{
Address: receipt.ContractAddress,
Topics: []common.Hash{logSig},
Data: logData,
BlockNumber: receipt.BlockNumber.Uint64(),
TxHash: receipt.TxHash,
TxIndex: receipt.TransactionIndex,
BlockHash: receipt.BlockHash,
Index: uint(len(receipt.Logs) + 1),
Removed: false,
}

// Compute block bloom filter and set to the receipt
bloom := receipt.Bloom.Big()
bloom.Or(bloom, big.NewInt(0).SetBytes(ethtypes.LogsBloom([]*ethtypes.Log{newLog})))
receipt.Bloom = ethtypes.BytesToBloom(bloom.Bytes())

receipt.Logs = append(receipt.Logs, newLog)
}
}
36 changes: 27 additions & 9 deletions x/cronos/keeper/evm_log_handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ var (
)

const (
SendToAccountEventName = "__CronosSendToAccount"
SendToEthereumEventName = "__CronosSendToEthereum"
SendToIbcEventName = "__CronosSendToIbc"
SendCroToIbcEventName = "__CronosSendCroToIbc"
SendToAccountEventName = "__CronosSendToAccount"
SendToEthereumEventName = "__CronosSendToEthereum"
SendToEthereumResponseEventName = "__CronosSendToEthereumResponse"
SendToIbcEventName = "__CronosSendToIbc"
SendCroToIbcEventName = "__CronosSendCroToIbc"
)

var (
Expand All @@ -35,6 +36,10 @@ var (
// `event __CronosSendToEthereum(address recipient, uint256 amount, uint256 bridge_fee)`
SendToEthereumEvent abi.Event

// SendToEthereumResponseEvent represent the signature of
// `event __CronosSendToEthereumResponse(uint256 id)`
SendToEthereumResponseEvent abi.Event

// SendToIbcEvent represent the signature of
// `event __CronosSendToIbc(string recipient, uint256 amount)`
SendToIbcEvent abi.Event
Expand Down Expand Up @@ -80,6 +85,16 @@ func init() {
Indexed: false,
}},
)
SendToEthereumResponseEvent = abi.NewEvent(
SendToEthereumResponseEventName,
SendToEthereumResponseEventName,
false,
abi.Arguments{abi.Argument{
Name: "id",
Type: uint256Type,
Indexed: false,
}},
)
SendToIbcEvent = abi.NewEvent(
SendToIbcEventName,
SendToIbcEventName,
Expand Down Expand Up @@ -135,7 +150,7 @@ func (h SendToAccountHandler) EventID() common.Hash {
return SendToAccountEvent.ID
}

func (h SendToAccountHandler) Handle(ctx sdk.Context, contract common.Address, data []byte) error {
func (h SendToAccountHandler) Handle(ctx sdk.Context, contract common.Address, data []byte, _ func(logSig common.Hash, logData []byte)) error {
unpacked, err := SendToAccountEvent.Inputs.Unpack(data)
if err != nil {
// log and ignore
Expand Down Expand Up @@ -177,7 +192,7 @@ func (h SendToEthereumHandler) EventID() common.Hash {
}

// Handle `__CronosSendToEthereum` log only if gravity is activated.
func (h SendToEthereumHandler) Handle(ctx sdk.Context, contract common.Address, data []byte) error {
func (h SendToEthereumHandler) Handle(ctx sdk.Context, contract common.Address, data []byte, addLogToReceipt func(logSig common.Hash, logData []byte)) error {
if h.gravitySrv == nil {
return fmt.Errorf("native action %s is not implemented", SendToEthereumEventName)
}
Expand Down Expand Up @@ -208,10 +223,13 @@ func (h SendToEthereumHandler) Handle(ctx sdk.Context, contract common.Address,
Amount: sdk.NewCoin(denom, amount),
BridgeFee: sdk.NewCoin(denom, bridgeFee),
}
_, err = h.gravitySrv.SendToEthereum(sdk.WrapSDKContext(ctx), &msg)
resp, err := h.gravitySrv.SendToEthereum(sdk.WrapSDKContext(ctx), &msg)
if err != nil {
return err
}

logData, _ := SendToEthereumResponseEvent.Inputs.Pack(resp.Id)
addLogToReceipt(SendToEthereumResponseEvent.ID, logData)
return nil
}

Expand All @@ -232,7 +250,7 @@ func (h SendToIbcHandler) EventID() common.Hash {
return SendToIbcEvent.ID
}

func (h SendToIbcHandler) Handle(ctx sdk.Context, contract common.Address, data []byte) error {
func (h SendToIbcHandler) Handle(ctx sdk.Context, contract common.Address, data []byte, _ func(logSig common.Hash, logData []byte)) error {
unpacked, err := SendToIbcEvent.Inputs.Unpack(data)
if err != nil {
// log and ignore
Expand Down Expand Up @@ -283,7 +301,7 @@ func (h SendCroToIbcHandler) EventID() common.Hash {
return SendCroToIbcEvent.ID
}

func (h SendCroToIbcHandler) Handle(ctx sdk.Context, contract common.Address, data []byte) error {
func (h SendCroToIbcHandler) Handle(ctx sdk.Context, contract common.Address, data []byte, _ func(logSig common.Hash, logData []byte)) error {
unpacked, err := SendCroToIbcEvent.Inputs.Unpack(data)
if err != nil {
// log and ignore
Expand Down
8 changes: 4 additions & 4 deletions x/cronos/keeper/evm_log_handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func (suite *KeeperTestSuite) TestSendToAccountHandler() {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
handler := keeper.NewSendToAccountHandler(suite.app.BankKeeper, suite.app.CronosKeeper)
tc.malleate()
err := handler.Handle(suite.ctx, contract, data)
err := handler.Handle(suite.ctx, contract, data, func(logSig common.Hash, logData []byte) {})
if tc.error != nil {
suite.Require().EqualError(err, tc.error.Error())
} else {
Expand Down Expand Up @@ -188,7 +188,7 @@ func (suite *KeeperTestSuite) TestSendToEthereumHandler() {
handler := keeper.NewSendToEthereumHandler(
gravitykeeper.NewMsgServerImpl(suite.app.GravityKeeper), suite.app.CronosKeeper)
tc.malleate()
err := handler.Handle(suite.ctx, contract, data)
err := handler.Handle(suite.ctx, contract, data, func(logSig common.Hash, logData []byte) {})
if tc.error != nil {
suite.Require().EqualError(err, tc.error.Error())
} else {
Expand Down Expand Up @@ -292,7 +292,7 @@ func (suite *KeeperTestSuite) TestSendToIbcHandler() {
)
handler := keeper.NewSendToIbcHandler(suite.app.BankKeeper, cronosKeeper)
tc.malleate()
err := handler.Handle(suite.ctx, contract, data)
err := handler.Handle(suite.ctx, contract, data, func(logSig common.Hash, logData []byte) {})
if tc.error != nil {
suite.Require().EqualError(err, tc.error.Error())
} else {
Expand Down Expand Up @@ -381,7 +381,7 @@ func (suite *KeeperTestSuite) TestSendCroToIbcHandler() {
)
handler := keeper.NewSendCroToIbcHandler(suite.app.BankKeeper, cronosKeeper)
tc.malleate()
err := handler.Handle(suite.ctx, contract, data)
err := handler.Handle(suite.ctx, contract, data, func(logSig common.Hash, logData []byte) {})
if tc.error != nil {
suite.Require().EqualError(err, tc.error.Error())
} else {
Expand Down
2 changes: 1 addition & 1 deletion x/cronos/types/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ type EvmLogHandler interface {
// Return the id of the log signature it handles
EventID() common.Hash
// Process the log
Handle(ctx sdk.Context, contract common.Address, data []byte) error
Handle(ctx sdk.Context, contract common.Address, data []byte, addLogToReceipt func(logSig common.Hash, logData []byte)) error
}

// EvmKeeper defines the interface for evm keeper
Expand Down

0 comments on commit c71a354

Please sign in to comment.