diff --git a/core/tx.go b/core/tx.go index c628a6f3..567cd0c8 100644 --- a/core/tx.go +++ b/core/tx.go @@ -39,6 +39,8 @@ import ( "github.com/cosmos/cosmos-sdk/types" cosmosTx "github.com/cosmos/cosmos-sdk/types/tx" "gorm.io/gorm" + + indexerEvents "github.com/DefiantLabs/cosmos-tax-cli/cosmos/events" ) // Unmarshal JSON to a particular type. There can be more than one handler for each type. @@ -272,6 +274,10 @@ func ProcessRPCBlockByHeightTXs(db *gorm.DB, cl *client.ChainClient, blockResult // We can entirely ignore failed TXs in downstream parsers, because according to the Cosmos specification, a single failed message in a TX fails the whole TX if txResult.Code == 0 { logs, err = types.ParseABCILogs(txResult.Log) + + if err != nil { + logs, err = indexerEvents.ParseTxEventsToMessageIndexEvents(len(txFull.Body.Messages), txResult.Events) + } } else { err = nil } @@ -344,6 +350,16 @@ func ProcessRPCTXs(db *gorm.DB, cl *client.ChainClient, txEventResp *cosmosTx.Ge currTx := txEventResp.Txs[txIdx] currTxResp := txEventResp.TxResponses[txIdx] + if len(currTxResp.Logs) == 0 && len(currTxResp.Events) != 0 { + parsedLogs, err := indexerEvents.ParseTxEventsToMessageIndexEvents(len(currTx.Body.Messages), currTxResp.Events) + if err != nil { + config.Log.Errorf("Error parsing events to message index events to normalize: %v", err) + return nil, blockTime, err + } + + currTxResp.Logs = parsedLogs + } + // Get the Messages and Message Logs for msgIdx := range currTx.Body.Messages { currMsg := currTx.Body.Messages[msgIdx].GetCachedValue() diff --git a/cosmos/events/normalization.go b/cosmos/events/normalization.go new file mode 100644 index 00000000..d2ee2f67 --- /dev/null +++ b/cosmos/events/normalization.go @@ -0,0 +1,89 @@ +package events + +import ( + "fmt" + "strconv" + + "github.com/DefiantLabs/cosmos-tax-cli/config" + txtypes "github.com/DefiantLabs/cosmos-tax-cli/cosmos/modules/tx" + cometAbciTypes "github.com/cometbft/cometbft/abci/types" + "github.com/cosmos/cosmos-sdk/types" +) + +func NormalizedAttributesToAttributes(attrs []txtypes.Attribute) []types.Attribute { + list := []types.Attribute{} + for _, attr := range attrs { + lma := types.Attribute{Key: attr.Key, Value: attr.Value} + list = append(list, lma) + } + + return list +} + +func AttributesToNormalizedAttributes(attrs []types.Attribute) []txtypes.Attribute { + list := []txtypes.Attribute{} + for _, attr := range attrs { + lma := txtypes.Attribute{Key: attr.Key, Value: attr.Value} + list = append(list, lma) + } + + return list +} + +func EventAttributesToNormalizedAttributes(attrs []cometAbciTypes.EventAttribute) []txtypes.Attribute { + list := []txtypes.Attribute{} + for _, attr := range attrs { + lma := txtypes.Attribute{Key: attr.Key, Value: attr.Value} + list = append(list, lma) + } + + return list +} + +func StringEventstoNormalizedEvents(msgEvents types.StringEvents) (list []txtypes.LogMessageEvent) { + for _, evt := range msgEvents { + lme := txtypes.LogMessageEvent{Type: evt.Type, Attributes: AttributesToNormalizedAttributes(evt.Attributes)} + list = append(list, lme) + } + + return list +} + +func toNormalizedEvents(msgEvents []cometAbciTypes.Event) (list []txtypes.LogMessageEvent) { + for _, evt := range msgEvents { + lme := txtypes.LogMessageEvent{Type: evt.Type, Attributes: EventAttributesToNormalizedAttributes(evt.Attributes)} + list = append(list, lme) + } + + return list +} + +func ParseTxEventsToMessageIndexEvents(numMessages int, events []cometAbciTypes.Event) (types.ABCIMessageLogs, error) { + parsedLogs := make(types.ABCIMessageLogs, numMessages) + for index := range parsedLogs { + parsedLogs[index] = types.ABCIMessageLog{ + MsgIndex: uint32(index), + } + } + + // TODO: Fix this to be more efficient, no need to translate multiple times to hack this together + logMessageEvents := toNormalizedEvents(events) + for _, event := range logMessageEvents { + loopEvent := event + val, err := txtypes.GetValueForAttribute("msg_index", &loopEvent) + + if err == nil && val != "" { + msgIndex, err := strconv.Atoi(val) + if err != nil { + config.Log.Error(fmt.Sprintf("Error parsing msg_index from event: %v", err)) + return nil, err + } + + if msgIndex >= 0 && msgIndex < len(parsedLogs) { + parsedLogs[msgIndex].Events = append(parsedLogs[msgIndex].Events, types.StringEvent{Type: event.Type, Attributes: NormalizedAttributesToAttributes(event.Attributes)}) + } + } + } + + return parsedLogs, nil +}