-
Notifications
You must be signed in to change notification settings - Fork 125
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
[RnD][WIP] Emulate native bank send messages as Ethereum TXs #347
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey team, some minor comments after reviewing the proposed changes.
// EthereumTx can't contain more than 1 message | ||
if len(tx.GetMsgs()) > 1 { | ||
continue | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why add this check? it could potentially contain multiple banktypes.MsgSend
right?
if !isEth && !isBankSend { | ||
return nil, errors.New("invalid ethereum tx") | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probably makes sense to adjust the error message here too, could be confusing otherwise
if !isEth && !isBankSend { | |
return nil, errors.New("invalid ethereum tx") | |
} | |
if !isEth && !isBankSend { | |
return nil, errors.New("neither a valid ethereum tx or bank transfer") | |
} |
ethMsg, isEth := msg.(*evmtypes.MsgEthereumTx) | ||
_, isBankSend := msg.(*banktypes.MsgSend) | ||
if !isEth && !isBankSend { | ||
continue | ||
} | ||
|
||
if isBankSend { | ||
ethMsg, err = utilstx.BankSendTxAsEthereumTx(tx) | ||
if err != nil { | ||
b.logger.Debug("failed to convert bank send transaction into eth tx", "height", blk.Block.Height, "error", err.Error()) | ||
continue | ||
} | ||
} | ||
|
||
predecessors = append(predecessors, ethMsg) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
more of a nit, but a slight performance boost - if it's an MsgEthereumTx
you don't need the type checking for the MsgSend
. Whether to first check for the Eth transaction or the bank transfer could be decided depending on which of the two is more commonly present on your chain.
ethMsg, isEth := msg.(*evmtypes.MsgEthereumTx) | |
_, isBankSend := msg.(*banktypes.MsgSend) | |
if !isEth && !isBankSend { | |
continue | |
} | |
if isBankSend { | |
ethMsg, err = utilstx.BankSendTxAsEthereumTx(tx) | |
if err != nil { | |
b.logger.Debug("failed to convert bank send transaction into eth tx", "height", blk.Block.Height, "error", err.Error()) | |
continue | |
} | |
} | |
predecessors = append(predecessors, ethMsg) | |
if ethMsg, isEth := msg.(*evmtypes.MsgEthereumTx); isEth { | |
predecessors = append(predecessors, ethMsg) | |
continue | |
} | |
if _, isBankSend := msg.(*banktypes.MsgSend); isBankSend { | |
ethMsg, err = utilstx.BankSendTxAsEthereumTx(tx) | |
if err != nil { | |
b.logger.Debug("failed to convert bank send transaction into eth tx", "height", blk.Block.Height, "error", err.Error()) | |
continue | |
} | |
predecessors = append(predecessors, ethMsg) | |
} |
if len(tx.GetMsgs()) > 1 { | ||
return nil, errors.New("tx has more than one message") | ||
} | ||
|
||
msg := tx.GetMsgs()[0] | ||
sendMsg, ok := msg.(*banktypes.MsgSend) | ||
if !ok { | ||
return nil, errors.New("tx message is not a bank.MsgSend") | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this assumes that only one banktypes.MsgSend
can be present in a transaction - to be sure of this it would probably make sense to add a blocker for such a transaction in the ante handlers. Did you already add that?
if len(sigs) != 1 { | ||
return nil, errors.New("transaction with one signer has more than one signature") | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
error message could be clearer here:
if len(sigs) != 1 { | |
return nil, errors.New("transaction with one signer has more than one signature") | |
} | |
if len(sigs) != 1 { | |
return nil, fmt.Errorf("expected transaction with 1 signer; got %d", len(sigs)) | |
} |
attrs := []sdk.Attribute{ | ||
sdk.NewAttribute(sdk.AttributeKeyAmount, ethTx.Value().String()), | ||
// add event for ethereum transaction hash format | ||
sdk.NewAttribute(evmtypes.AttributeKeyEthereumTxHash, ethMsg.Hash), | ||
// add event for index of valid ethereum tx | ||
sdk.NewAttribute(evmtypes.AttributeKeyTxIndex, strconv.FormatUint(0, 10)), | ||
// add event for eth tx gas used, we can't get it from cosmos tx result when it contains multiple eth tx msgs. | ||
sdk.NewAttribute(evmtypes.AttributeKeyTxGasUsed, strconv.FormatUint(ethMsg.GetGas(), 10)), | ||
} | ||
|
||
if len(ctx.TxBytes()) > 0 { | ||
// add event for tendermint transaction hash format | ||
hash := tmbytes.HexBytes(tmtypes.Tx(ctx.TxBytes()).Hash()) | ||
attrs = append(attrs, sdk.NewAttribute(evmtypes.AttributeKeyTxHash, hash.String())) | ||
} | ||
|
||
if to := ethTx.To(); to != nil { | ||
attrs = append(attrs, sdk.NewAttribute(evmtypes.AttributeKeyRecipient, to.Hex())) | ||
} | ||
|
||
ctx.EventManager().EmitEvents(sdk.Events{ | ||
sdk.NewEvent( | ||
evmtypes.EventTypeEthereumTx, | ||
attrs..., | ||
), | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest adding a corresponding integration test to check if the emitted events from a bank transfer using a Cosmos message and the resulting events from an Ethereum transfer are the same
|
||
ethMsg, isEth := tx.GetMsgs()[res.MsgIndex].(*evmtypes.MsgEthereumTx) | ||
_, isBankSend := tx.GetMsgs()[res.MsgIndex].(*banktypes.MsgSend) | ||
if !isEth && !isBankSend { | ||
return nil, errors.New("invalid ethereum tx") | ||
} | ||
|
||
if isBankSend { | ||
ethMsg, err = utilstx.BankSendTxAsEthereumTx(tx) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to avoid the code duplication it could be better to introduce a helper method
func GetEthMsgOrConvertBankSendToEthMsg(tx sdk.Tx, msg sdk.Msg) (*evmtypes.MsgEthereumTx, error) {
if ethMsg, isEth = msg.(*evmtypes.MsgEthereumTx, error); isEth {
return ethMsg, nil
}
if _, isBankSend = msg.(*banktypes.MsgSend); isBankSend {
return utilstx.BankSendTxAsEthereumTx
}
return nil, fmt.Errorf("neither ethereum tx nor bank transfer; got: %T", msg)
}
ethMsg, isEth := tx.GetMsgs()[res.MsgIndex].(*evmtypes.MsgEthereumTx) | |
_, isBankSend := tx.GetMsgs()[res.MsgIndex].(*banktypes.MsgSend) | |
if !isEth && !isBankSend { | |
return nil, errors.New("invalid ethereum tx") | |
} | |
if isBankSend { | |
ethMsg, err = utilstx.BankSendTxAsEthereumTx(tx) | |
if err != nil { | |
return nil, err | |
} | |
} | |
ethMsg, err := GetEthMsgOrConvertBankSendToEthMsg(tx, tx.GetMsgs()[res.MsgIndex]) | |
if err != nil { | |
return nil, err | |
} |
This pull request has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days-before-close if no further activity occurs. |
Closes: #XXX
Description
For contributor use:
docs/
) or specification (x/<module>/spec/
)godoc
comments.Unreleased
section inCHANGELOG.md
Files changed
in the Github PR explorerFor admin use:
WIP
,R4R
,docs
, etc)