From d4020c8a8ec65fd24fd59542c85df8f9c19a634a Mon Sep 17 00:00:00 2001 From: Daisuke Kanda Date: Wed, 3 Jul 2024 05:09:52 +0000 Subject: [PATCH 1/2] decode query error Signed-off-by: Daisuke Kanda --- pkg/relay/ethereum/chain.go | 21 ++++++++++++++------- pkg/relay/ethereum/events.go | 14 ++++++++++---- pkg/relay/ethereum/msg.go | 21 ++++++++++++++------- pkg/relay/ethereum/tx.go | 31 +++++++++++++++---------------- 4 files changed, 53 insertions(+), 34 deletions(-) diff --git a/pkg/relay/ethereum/chain.go b/pkg/relay/ethereum/chain.go index a276da9..3b67087 100644 --- a/pkg/relay/ethereum/chain.go +++ b/pkg/relay/ethereum/chain.go @@ -195,7 +195,8 @@ func (c *Chain) QueryClientConsensusState(ctx core.QueryContext, dstClientConsHe defer logger.TimeTrack(time.Now(), "QueryClientConsensusState") s, found, err := c.ibcHandler.GetConsensusState(c.callOptsFromQueryContext(ctx), c.pathEnd.ClientID, pbToHostHeight(dstClientConsHeight)) if err != nil { - logger.Error("failed to get consensus state", err) + revertReason, data := c.parseRpcError(err) + logger.Error("failed to get consensus state", err, logAttrRevertReason, revertReason, logAttrRawErrorData, data) return nil, err } else if !found { logger.Error("client consensus not found", errors.New("client consensus not found")) @@ -221,7 +222,8 @@ func (c *Chain) QueryClientState(ctx core.QueryContext) (*clienttypes.QueryClien defer logger.TimeTrack(time.Now(), "QueryClientState") s, found, err := c.ibcHandler.GetClientState(c.callOptsFromQueryContext(ctx), c.pathEnd.ClientID) if err != nil { - logger.Error("failed to get client state", err) + revertReason, data := c.parseRpcError(err) + logger.Error("failed to get client state", err, logAttrRevertReason, revertReason, logAttrRawErrorData, data) return nil, err } else if !found { logger.Error("client not found", errors.New("client not found")) @@ -262,7 +264,8 @@ func (c *Chain) QueryConnection(ctx core.QueryContext) (*conntypes.QueryConnecti defer logger.TimeTrack(time.Now(), "QueryConnection") conn, found, err := c.ibcHandler.GetConnection(c.callOptsFromQueryContext(ctx), c.pathEnd.ConnectionID) if err != nil { - logger.Error("failed to get connection", err) + revertReason, data := c.parseRpcError(err) + logger.Error("failed to get connection", err, logAttrRevertReason, revertReason, logAttrRawErrorData, data) return nil, err } else if !found { return emptyConnRes, nil @@ -291,7 +294,8 @@ func (c *Chain) QueryChannel(ctx core.QueryContext) (chanRes *chantypes.QueryCha defer logger.TimeTrack(time.Now(), "QueryChannel") chann, found, err := c.ibcHandler.GetChannel(c.callOptsFromQueryContext(ctx), c.pathEnd.PortID, c.pathEnd.ChannelID) if err != nil { - logger.Error("failed to get channel", err) + revertReason, data := c.parseRpcError(err) + logger.Error("failed to get channel", err, logAttrRevertReason, revertReason, logAttrRawErrorData, data) return nil, err } else if !found { return emptyChannelRes, nil @@ -313,7 +317,8 @@ func (c *Chain) QueryUnreceivedPackets(ctx core.QueryContext, seqs []uint64) ([] switch c.Path().GetOrder() { case chantypes.UNORDERED: if rc, err := c.ibcHandler.GetPacketReceipt(c.callOptsFromQueryContext(ctx), c.pathEnd.PortID, c.pathEnd.ChannelID, seq); err != nil { - logger.Error("failed to get packet receipt", err) + revertReason, data := c.parseRpcError(err) + logger.Error("failed to get packet receipt", err, logAttrRevertReason, revertReason, logAttrRawErrorData, data) return nil, err } else if rc == PACKET_RECEIPT_SUCCESSFUL { received = true @@ -327,7 +332,8 @@ func (c *Chain) QueryUnreceivedPackets(ctx core.QueryContext, seqs []uint64) ([] // queried only once nextSequenceRecv, err = c.ibcHandler.GetNextSequenceRecv(c.callOptsFromQueryContext(ctx), c.pathEnd.PortID, c.pathEnd.ChannelID) if err != nil { - logger.Error("failed to get nextSequenceRecv", err) + revertReason, data := c.parseRpcError(err) + logger.Error("failed to get nextSequenceRecv", err, logAttrRevertReason, revertReason, logAttrRawErrorData, data) return nil, err } } @@ -397,7 +403,8 @@ func (c *Chain) QueryUnreceivedAcknowledgements(ctx core.QueryContext, seqs []ui key := crypto.Keccak256Hash(host.PacketCommitmentKey(c.pathEnd.PortID, c.pathEnd.ChannelID, seq)) commitment, err := c.ibcHandler.GetCommitment(c.callOptsFromQueryContext(ctx), key) if err != nil { - logger.Error("failed to get hashed packet commitment", err) + revertReason, data := c.parseRpcError(err) + logger.Error("failed to get hashed packet commitment", err, logAttrRevertReason, revertReason, logAttrRawErrorData, data) return nil, err } else if commitment != [32]byte{} { ret = append(ret, seq) diff --git a/pkg/relay/ethereum/events.go b/pkg/relay/ethereum/events.go index a048230..92bb357 100644 --- a/pkg/relay/ethereum/events.go +++ b/pkg/relay/ethereum/events.go @@ -56,7 +56,10 @@ func (chain *Chain) findSentPackets(ctx core.QueryContext, fromHeight uint64) (c chain.Path().PortID, chain.Path().ChannelID, ); err != nil { - logger.Error("failed to get channel", err) + revertReason, data := chain.parseRpcError(err) + logger.Error("failed to get channel", err, "port_id", chain.Path().PortID, "channel_id", chain.Path().ChannelID, + logAttrRevertReason, revertReason, + logAttrRawErrorData, data) return nil, err } else if !found { err := fmt.Errorf("channel not found") @@ -79,7 +82,8 @@ func (chain *Chain) findSentPackets(ctx core.QueryContext, fromHeight uint64) (c sendPacket, err := chain.ibcHandler.ParseSendPacket(log) if err != nil { - return nil, fmt.Errorf("failed to parse SendPacket event: err=%v, log=%v", err, log) + revertReason, data := chain.parseRpcError(err) + return nil, fmt.Errorf("failed to parse SendPacket event: err=%v, log=%v, reason=%s, data=%s", err, log, revertReason, data) } if sendPacket.SourceChannel != chain.Path().ChannelID || sendPacket.SourcePort != chain.Path().PortID { continue @@ -161,7 +165,8 @@ func (chain *Chain) findRecvPacketEvents(ctx core.QueryContext, fromHeight uint6 for _, log := range logs { event, err := chain.ibcHandler.ParseRecvPacket(log) if err != nil { - return nil, fmt.Errorf("failed to parse RecvPacket event: err=%v, log=%v", err, log) + revertReason, data := chain.parseRpcError(err) + return nil, fmt.Errorf("failed to parse RecvPacket event: err=%v, log=%v, reason%s, data=%s", err, log, revertReason, data) } if event.Packet.DestinationChannel != chain.Path().ChannelID || event.Packet.DestinationPort != chain.Path().PortID { continue @@ -181,7 +186,8 @@ func (chain *Chain) findWriteAckEvents(ctx core.QueryContext, fromHeight uint64) for _, log := range logs { event, err := chain.ibcHandler.ParseWriteAcknowledgement(log) if err != nil { - return nil, fmt.Errorf("failed to parse WriteAcknowledgement event: err=%v, log=%v", err, log) + revertReason, data := chain.parseRpcError(err) + return nil, fmt.Errorf("failed to parse WriteAcknowledgement event: err=%v, log=%v, reason=%s, data=%s", err, log, revertReason, data) } if event.DestinationChannel != chain.Path().ChannelID || event.DestinationPortId != chain.Path().PortID { continue diff --git a/pkg/relay/ethereum/msg.go b/pkg/relay/ethereum/msg.go index 54b98d8..7270cd4 100644 --- a/pkg/relay/ethereum/msg.go +++ b/pkg/relay/ethereum/msg.go @@ -70,25 +70,29 @@ func (c *Chain) parseMsgEventLogs(logs []*types.Log) ([]core.MsgEventLog, error) case abiGeneratedClientIdentifier.ID: ev, err := c.ibcHandler.ParseGeneratedClientIdentifier(*log) if err != nil { - return nil, fmt.Errorf("failed to parse GeneratedClientIdentifier event: logIndex=%d, log=%v", i, log) + revertReason, data := c.parseRpcError(err) + return nil, fmt.Errorf("failed to parse GeneratedClientIdentifier event: logIndex=%d, log=%v, reason=%s, data=%s", i, log, revertReason, data) } event = &core.EventGenerateClientIdentifier{ID: ev.ClientId} case abiGeneratedConnectionIdentifier.ID: ev, err := c.ibcHandler.ParseGeneratedConnectionIdentifier(*log) if err != nil { - return nil, fmt.Errorf("failed to parse GeneratedConnectionIdentifier event: logIndex=%d, log=%v", i, log) + revertReason, data := c.parseRpcError(err) + return nil, fmt.Errorf("failed to parse GeneratedConnectionIdentifier event: logIndex=%d, log=%v, reason=%s, data=%s", i, log, revertReason, data) } event = &core.EventGenerateConnectionIdentifier{ID: ev.ConnectionId} case abiGeneratedChannelIdentifier.ID: ev, err := c.ibcHandler.ParseGeneratedChannelIdentifier(*log) if err != nil { - return nil, fmt.Errorf("failed to parse GeneratedChannelIdentifier event: logIndex=%d, log=%v", i, log) + revertReason, data := c.parseRpcError(err) + return nil, fmt.Errorf("failed to parse GeneratedChannelIdentifier event: logIndex=%d, log=%v, reason=%s, data=%s", i, log, revertReason, data) } event = &core.EventGenerateChannelIdentifier{ID: ev.ChannelId} case abiSendPacket.ID: ev, err := c.ibcHandler.ParseSendPacket(*log) if err != nil { - return nil, fmt.Errorf("failed to parse SendPacket event: logIndex=%d, log=%v", i, log) + revertReason, data := c.parseRpcError(err) + return nil, fmt.Errorf("failed to parse SendPacket event: logIndex=%d, log=%v, reason=%s, data=%s", i, log, revertReason, data) } event = &core.EventSendPacket{ Sequence: ev.Sequence, @@ -101,7 +105,8 @@ func (c *Chain) parseMsgEventLogs(logs []*types.Log) ([]core.MsgEventLog, error) case abiRecvPacket.ID: ev, err := c.ibcHandler.ParseRecvPacket(*log) if err != nil { - return nil, fmt.Errorf("failed to parse RecvPacket event: logIndex=%d, log=%v", i, log) + revertReason, data := c.parseRpcError(err) + return nil, fmt.Errorf("failed to parse RecvPacket event: logIndex=%d, log=%v, reason=%s, data=%s", i, log, revertReason, data) } event = &core.EventRecvPacket{ Sequence: ev.Packet.Sequence, @@ -114,7 +119,8 @@ func (c *Chain) parseMsgEventLogs(logs []*types.Log) ([]core.MsgEventLog, error) case abiWriteAcknowledgement.ID: ev, err := c.ibcHandler.ParseWriteAcknowledgement(*log) if err != nil { - return nil, fmt.Errorf("failed to parse WriteAcknowledgement event: logIndex=%d, log=%v", i, log) + revertReason, data := c.parseRpcError(err) + return nil, fmt.Errorf("failed to parse WriteAcknowledgement event: logIndex=%d, log=%v, reason=%s, data=%s", i, log, revertReason, data) } event = &core.EventWriteAcknowledgement{ Sequence: ev.Sequence, @@ -125,7 +131,8 @@ func (c *Chain) parseMsgEventLogs(logs []*types.Log) ([]core.MsgEventLog, error) case abiAcknowledgePacket.ID: ev, err := c.ibcHandler.ParseAcknowledgePacket(*log) if err != nil { - return nil, fmt.Errorf("failed to parse AcknowledgePacket event: logIndex=%d, log=%v", i, log) + revertReason, data := c.parseRpcError(err) + return nil, fmt.Errorf("failed to parse AcknowledgePacket event: logIndex=%d, log=%v, reason=%s, data=%s", i, log, revertReason, data) } event = &core.EventAcknowledgePacket{ Sequence: ev.Packet.Sequence, diff --git a/pkg/relay/ethereum/tx.go b/pkg/relay/ethereum/tx.go index f19e25d..feb3d09 100644 --- a/pkg/relay/ethereum/tx.go +++ b/pkg/relay/ethereum/tx.go @@ -70,18 +70,8 @@ func (c *Chain) SendMsgs(msgs []sdk.Msg) ([]core.MsgID, error) { estimatedGas, err := c.client.EstimateGasFromTx(ctx, tx) if err != nil { - if revertReason, rawErrorData, err := c.getRevertReasonFromEstimateGas(err); err != nil { - // Raw error data may be available even if revert reason isn't available. - logger.Logger = logger.With(logAttrRawErrorData, hex.EncodeToString(rawErrorData)) - logger.Error("failed to get revert reason", err) - } else { - logger.Logger = logger.With( - logAttrRawErrorData, hex.EncodeToString(rawErrorData), - logAttrRevertReason, revertReason, - ) - } - - logger.Error("failed to estimate gas", err) + revertReason, data := c.parseRpcError(err) + logger.Error("failed to estimate gas", err, logAttrRevertReason, revertReason, logAttrRawErrorData, data) return nil, err } @@ -445,13 +435,13 @@ func (c *Chain) getRevertReasonFromReceipt(ctx context.Context, receipt *client. return revertReason, errorData, nil } -func (c *Chain) getRevertReasonFromEstimateGas(err error) (string, []byte, error) { +func (c *Chain) getRevertReasonFromRpcError(err error) (string, []byte, error) { if de, ok := err.(rpc.DataError); !ok { - return "", nil, fmt.Errorf("eth_estimateGas failed with unexpected error type: errorType=%T", err) + return "", nil, fmt.Errorf("failed with unexpected error type: errorType=%T", err) } else if de.ErrorData() == nil { - return "", nil, fmt.Errorf("eth_estimateGas failed without error data") + return "", nil, fmt.Errorf("failed without error data") } else if errorData, ok := de.ErrorData().(string); !ok { - return "", nil, fmt.Errorf("eth_estimateGas failed with unexpected error data type: errorDataType=%T", de.ErrorData()) + return "", nil, fmt.Errorf("failed with unexpected error data type: errorDataType=%T", de.ErrorData()) } else { errorData := common.FromHex(errorData) revertReason, err := c.errorRepository.ParseError(errorData) @@ -461,3 +451,12 @@ func (c *Chain) getRevertReasonFromEstimateGas(err error) (string, []byte, error return revertReason, errorData, nil } } + +func (c *Chain) parseRpcError(err error) (string, string) { + revertReason, rawErrorData, err := c.getRevertReasonFromRpcError(err) + if err != nil { + revertReason = fmt.Sprintf("failed to get revert reason: %s", err.Error()) + } + // Note that Raw error data may be available even if revert reason isn't available. + return revertReason, hex.EncodeToString(rawErrorData) +} From 1a72a0100aaa2727ee789b3a5bc374061e1ad1ca Mon Sep 17 00:00:00 2001 From: Daisuke Kanda Date: Mon, 8 Jul 2024 19:47:43 +0000 Subject: [PATCH 2/2] revert not to parse as json rpc against error of ibchandler.parseXXX Signed-off-by: Daisuke Kanda --- pkg/relay/ethereum/events.go | 9 +++------ pkg/relay/ethereum/msg.go | 21 +++++++-------------- 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/pkg/relay/ethereum/events.go b/pkg/relay/ethereum/events.go index 92bb357..f6883a9 100644 --- a/pkg/relay/ethereum/events.go +++ b/pkg/relay/ethereum/events.go @@ -82,8 +82,7 @@ func (chain *Chain) findSentPackets(ctx core.QueryContext, fromHeight uint64) (c sendPacket, err := chain.ibcHandler.ParseSendPacket(log) if err != nil { - revertReason, data := chain.parseRpcError(err) - return nil, fmt.Errorf("failed to parse SendPacket event: err=%v, log=%v, reason=%s, data=%s", err, log, revertReason, data) + return nil, fmt.Errorf("failed to parse SendPacket event: err=%v, log=%v", err, log) } if sendPacket.SourceChannel != chain.Path().ChannelID || sendPacket.SourcePort != chain.Path().PortID { continue @@ -165,8 +164,7 @@ func (chain *Chain) findRecvPacketEvents(ctx core.QueryContext, fromHeight uint6 for _, log := range logs { event, err := chain.ibcHandler.ParseRecvPacket(log) if err != nil { - revertReason, data := chain.parseRpcError(err) - return nil, fmt.Errorf("failed to parse RecvPacket event: err=%v, log=%v, reason%s, data=%s", err, log, revertReason, data) + return nil, fmt.Errorf("failed to parse RecvPacket event: err=%v, log=%v", err, log) } if event.Packet.DestinationChannel != chain.Path().ChannelID || event.Packet.DestinationPort != chain.Path().PortID { continue @@ -186,8 +184,7 @@ func (chain *Chain) findWriteAckEvents(ctx core.QueryContext, fromHeight uint64) for _, log := range logs { event, err := chain.ibcHandler.ParseWriteAcknowledgement(log) if err != nil { - revertReason, data := chain.parseRpcError(err) - return nil, fmt.Errorf("failed to parse WriteAcknowledgement event: err=%v, log=%v, reason=%s, data=%s", err, log, revertReason, data) + return nil, fmt.Errorf("failed to parse WriteAcknowledgement event: err=%v, log=%v", err, log) } if event.DestinationChannel != chain.Path().ChannelID || event.DestinationPortId != chain.Path().PortID { continue diff --git a/pkg/relay/ethereum/msg.go b/pkg/relay/ethereum/msg.go index 7270cd4..54b98d8 100644 --- a/pkg/relay/ethereum/msg.go +++ b/pkg/relay/ethereum/msg.go @@ -70,29 +70,25 @@ func (c *Chain) parseMsgEventLogs(logs []*types.Log) ([]core.MsgEventLog, error) case abiGeneratedClientIdentifier.ID: ev, err := c.ibcHandler.ParseGeneratedClientIdentifier(*log) if err != nil { - revertReason, data := c.parseRpcError(err) - return nil, fmt.Errorf("failed to parse GeneratedClientIdentifier event: logIndex=%d, log=%v, reason=%s, data=%s", i, log, revertReason, data) + return nil, fmt.Errorf("failed to parse GeneratedClientIdentifier event: logIndex=%d, log=%v", i, log) } event = &core.EventGenerateClientIdentifier{ID: ev.ClientId} case abiGeneratedConnectionIdentifier.ID: ev, err := c.ibcHandler.ParseGeneratedConnectionIdentifier(*log) if err != nil { - revertReason, data := c.parseRpcError(err) - return nil, fmt.Errorf("failed to parse GeneratedConnectionIdentifier event: logIndex=%d, log=%v, reason=%s, data=%s", i, log, revertReason, data) + return nil, fmt.Errorf("failed to parse GeneratedConnectionIdentifier event: logIndex=%d, log=%v", i, log) } event = &core.EventGenerateConnectionIdentifier{ID: ev.ConnectionId} case abiGeneratedChannelIdentifier.ID: ev, err := c.ibcHandler.ParseGeneratedChannelIdentifier(*log) if err != nil { - revertReason, data := c.parseRpcError(err) - return nil, fmt.Errorf("failed to parse GeneratedChannelIdentifier event: logIndex=%d, log=%v, reason=%s, data=%s", i, log, revertReason, data) + return nil, fmt.Errorf("failed to parse GeneratedChannelIdentifier event: logIndex=%d, log=%v", i, log) } event = &core.EventGenerateChannelIdentifier{ID: ev.ChannelId} case abiSendPacket.ID: ev, err := c.ibcHandler.ParseSendPacket(*log) if err != nil { - revertReason, data := c.parseRpcError(err) - return nil, fmt.Errorf("failed to parse SendPacket event: logIndex=%d, log=%v, reason=%s, data=%s", i, log, revertReason, data) + return nil, fmt.Errorf("failed to parse SendPacket event: logIndex=%d, log=%v", i, log) } event = &core.EventSendPacket{ Sequence: ev.Sequence, @@ -105,8 +101,7 @@ func (c *Chain) parseMsgEventLogs(logs []*types.Log) ([]core.MsgEventLog, error) case abiRecvPacket.ID: ev, err := c.ibcHandler.ParseRecvPacket(*log) if err != nil { - revertReason, data := c.parseRpcError(err) - return nil, fmt.Errorf("failed to parse RecvPacket event: logIndex=%d, log=%v, reason=%s, data=%s", i, log, revertReason, data) + return nil, fmt.Errorf("failed to parse RecvPacket event: logIndex=%d, log=%v", i, log) } event = &core.EventRecvPacket{ Sequence: ev.Packet.Sequence, @@ -119,8 +114,7 @@ func (c *Chain) parseMsgEventLogs(logs []*types.Log) ([]core.MsgEventLog, error) case abiWriteAcknowledgement.ID: ev, err := c.ibcHandler.ParseWriteAcknowledgement(*log) if err != nil { - revertReason, data := c.parseRpcError(err) - return nil, fmt.Errorf("failed to parse WriteAcknowledgement event: logIndex=%d, log=%v, reason=%s, data=%s", i, log, revertReason, data) + return nil, fmt.Errorf("failed to parse WriteAcknowledgement event: logIndex=%d, log=%v", i, log) } event = &core.EventWriteAcknowledgement{ Sequence: ev.Sequence, @@ -131,8 +125,7 @@ func (c *Chain) parseMsgEventLogs(logs []*types.Log) ([]core.MsgEventLog, error) case abiAcknowledgePacket.ID: ev, err := c.ibcHandler.ParseAcknowledgePacket(*log) if err != nil { - revertReason, data := c.parseRpcError(err) - return nil, fmt.Errorf("failed to parse AcknowledgePacket event: logIndex=%d, log=%v, reason=%s, data=%s", i, log, revertReason, data) + return nil, fmt.Errorf("failed to parse AcknowledgePacket event: logIndex=%d, log=%v", i, log) } event = &core.EventAcknowledgePacket{ Sequence: ev.Packet.Sequence,