Skip to content

Commit

Permalink
make GetOperationEvents return diagnostic events
Browse files Browse the repository at this point in the history
  • Loading branch information
tamirms committed Mar 24, 2023
1 parent 9b2187e commit a9f98be
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 20 deletions.
19 changes: 11 additions & 8 deletions ingest/ledger_transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ func operationChanges(ops []xdr.OperationMeta, index uint32) []Change {
}

// GetOperationEvents returns all contract events emitted by a given operation.
func (t *LedgerTransaction) GetOperationEvents(operationIndex uint32) ([]xdr.ContractEvent, error) {
func (t *LedgerTransaction) GetOperationEvents(operationIndex uint32) ([]xdr.DiagnosticEvent, error) {
// Ignore operations meta if txInternalError https://github.com/stellar/go/issues/2111
if t.txInternalError() {
return nil, nil
Expand All @@ -167,18 +167,21 @@ func (t *LedgerTransaction) GetOperationEvents(operationIndex uint32) ([]xdr.Con
case 3:
diagnosticEventsByOperation := t.UnsafeMeta.MustV3().DiagnosticEvents
if int(operationIndex) < len(diagnosticEventsByOperation) {
diagnosticEvents := diagnosticEventsByOperation[operationIndex].Events
events := make([]xdr.ContractEvent, len(diagnosticEvents))
for i, d := range diagnosticEvents {
events[i] = d.Event
}
return events, nil
return diagnosticEventsByOperation[operationIndex].Events, nil
}
eventsByOperation := t.UnsafeMeta.MustV3().Events
if int(operationIndex) >= len(eventsByOperation) {
return nil, nil
}
return eventsByOperation[operationIndex].Events, nil
events := eventsByOperation[operationIndex].Events
diagnosticEvents := make([]xdr.DiagnosticEvent, len(events))
for i, event := range events {
diagnosticEvents[i] = xdr.DiagnosticEvent{
InSuccessfulContractCall: true,
Event: event,
}
}
return diagnosticEvents, nil
default:
return nil, fmt.Errorf("unsupported TransactionMeta version: %v", t.UnsafeMeta.V)
}
Expand Down
18 changes: 12 additions & 6 deletions ingest/ledger_transaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ func TestGetOperationEvents(t *testing.T) {
events, err := tx.GetOperationEvents(0)
assert.NoError(t, err)
assert.Len(t, events, 1)
assert.Equal(t, *events[0].Body.V0.Data.U32, values[0])
assert.True(t, events[0].InSuccessfulContractCall)
assert.Equal(t, *events[0].Event.Body.V0.Data.U32, values[0])

events, err = tx.GetOperationEvents(1)
assert.NoError(t, err)
Expand All @@ -79,8 +80,10 @@ func TestGetOperationEvents(t *testing.T) {
events, err = tx.GetOperationEvents(2)
assert.NoError(t, err)
assert.Len(t, events, 2)
assert.Equal(t, *events[0].Body.V0.Data.U32, values[1])
assert.Equal(t, *events[1].Body.V0.Data.U32, values[2])
assert.True(t, events[0].InSuccessfulContractCall)
assert.Equal(t, *events[0].Event.Body.V0.Data.U32, values[1])
assert.True(t, events[1].InSuccessfulContractCall)
assert.Equal(t, *events[1].Event.Body.V0.Data.U32, values[2])

events, err = tx.GetOperationEvents(3)
assert.NoError(t, err)
Expand Down Expand Up @@ -162,7 +165,8 @@ func TestGetDiagnosticEvents(t *testing.T) {
events, err := tx.GetOperationEvents(0)
assert.NoError(t, err)
assert.Len(t, events, 1)
assert.Equal(t, *events[0].Body.V0.Data.U32, values[0])
assert.False(t, events[0].InSuccessfulContractCall)
assert.Equal(t, *events[0].Event.Body.V0.Data.U32, values[0])

events, err = tx.GetOperationEvents(1)
assert.NoError(t, err)
Expand All @@ -171,8 +175,10 @@ func TestGetDiagnosticEvents(t *testing.T) {
events, err = tx.GetOperationEvents(2)
assert.NoError(t, err)
assert.Len(t, events, 2)
assert.Equal(t, *events[0].Body.V0.Data.U32, values[1])
assert.Equal(t, *events[1].Body.V0.Data.U32, values[2])
assert.True(t, events[0].InSuccessfulContractCall)
assert.Equal(t, *events[0].Event.Body.V0.Data.U32, values[1])
assert.True(t, events[1].InSuccessfulContractCall)
assert.Equal(t, *events[1].Event.Body.V0.Data.U32, values[2])

events, err = tx.GetOperationEvents(3)
assert.NoError(t, err)
Expand Down
15 changes: 13 additions & 2 deletions services/horizon/internal/ingest/processors/effects_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,14 +236,14 @@ func (operation *transactionOperationWrapper) effects() ([]effect, error) {
case xdr.OperationTypeInvokeHostFunction:
// If there's an invokeHostFunction operation, there's definitely V3
// meta in the transaction, which means this error is real.
events, innerErr := operation.transaction.GetOperationEvents(operation.index)
diagnosticEvents, innerErr := operation.transaction.GetOperationEvents(operation.index)
if innerErr != nil {
return nil, innerErr
}

// For now, the only effects are related to the events themselves.
// Possible add'l work: https://github.com/stellar/go/issues/4585
err = wrapper.addInvokeHostFunctionEffects(events)
err = wrapper.addInvokeHostFunctionEffects(filterEvents(diagnosticEvents))

default:
return nil, fmt.Errorf("unknown operation type: %s", op.Body.Type)
Expand Down Expand Up @@ -274,6 +274,17 @@ func (operation *transactionOperationWrapper) effects() ([]effect, error) {
return wrapper.effects, nil
}

func filterEvents(diagnosticEvents []xdr.DiagnosticEvent) []xdr.ContractEvent {
var filtered []xdr.ContractEvent
for _, diagnosticEvent := range diagnosticEvents {
if !diagnosticEvent.InSuccessfulContractCall || diagnosticEvent.Event.Type != xdr.ContractEventTypeContract {
continue
}
filtered = append(filtered, diagnosticEvent.Event)
}
return filtered
}

type effectsWrapper struct {
effects []effect
operation *transactionOperationWrapper
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,13 +268,13 @@ func (operation *transactionOperationWrapper) IsPayment() bool {
case xdr.OperationTypeAccountMerge:
return true
case xdr.OperationTypeInvokeHostFunction:
events, err := operation.transaction.GetOperationEvents(0)
diagnosticEvents, err := operation.transaction.GetOperationEvents(operation.index)
if err != nil {
return false
}
// scan all the contract events for at least one SAC event, qualified to be a payment
// in horizon
for _, contractEvent := range events {
for _, contractEvent := range filterEvents(diagnosticEvents) {
if sacEvent, err := contractevents.NewStellarAssetContractEvent(&contractEvent, operation.network); err == nil {
switch sacEvent.GetType() {
case contractevents.EventTypeTransfer:
Expand Down Expand Up @@ -719,14 +719,14 @@ func (operation *transactionOperationWrapper) Details() (map[string]interface{},
func (operation *transactionOperationWrapper) parseAssetBalanceChangesFromContractEvents() ([]map[string]interface{}, error) {
balanceChanges := []map[string]interface{}{}

events, err := operation.transaction.GetOperationEvents(0)
diagnosticEvents, err := operation.transaction.GetOperationEvents(operation.index)
if err != nil {
// this operation in this context must be an InvokeHostFunctionOp, therefore V3Meta should be present
// as it's in same soroban model, so if any err, it's real,
return nil, err
}

for _, contractEvent := range events {
for _, contractEvent := range filterEvents(diagnosticEvents) {
// Parse the xdr contract event to contractevents.StellarAssetContractEvent model

// has some convenience like to/from attributes are expressed in strkey format for accounts(G...) and contracts(C...)
Expand Down

0 comments on commit a9f98be

Please sign in to comment.