Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 69 additions & 2 deletions ingest/ledger_transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ type LedgerTransaction struct {
Hash xdr.Hash
}

type TransactionEvents struct {
TransactionEvents []xdr.TransactionEvent
OperationEvents [][]xdr.ContractEvent
DiagnosticEvents []xdr.DiagnosticEvent
}

func (t *LedgerTransaction) txInternalError() bool {
return t.Result.Result.Result.Code == xdr.TransactionResultCodeTxInternalError
}
Expand Down Expand Up @@ -236,15 +242,76 @@ func (t *LedgerTransaction) operationChanges(ops operationsMeta, index uint32) [
return changes
}

func (t *LedgerTransaction) GetContractEventsForOperation(opIndex uint32) ([]xdr.ContractEvent, error) {
return t.UnsafeMeta.GetContractEventsForOperation(opIndex)
}

// GetContractEvents returns a []xdr.ContractEvent for pnly smart contract transaction.
// If it is not a smart contract transaction, it throws an error
// For getting events from classic operations/transaction, use GetContractEventsForOperation
// For getting soroban smart contract events,we rely on the fact that there will only be one operation present in the transaction
func (t *LedgerTransaction) GetContractEvents() ([]xdr.ContractEvent, error) {
return t.UnsafeMeta.GetContractEvents()
if !t.IsSorobanTx() {
return nil, errors.New("not a soroban transaction")
}
return t.GetContractEventsForOperation(0)
}

// GetDiagnosticEvents returns all contract events emitted by a given operation.
// GetDiagnosticEvents returns strictly diagnostic events emitted by a given transaction.
// Please note that, depending on the configuration with which txMeta may be generated,
// it is possible that, for smart contract transactions, the list of generated diagnostic events MAY include contract events as well
// Users of this function (horizon, rpc, etc) should be careful not to double count diagnostic events and contract events in that case
func (t *LedgerTransaction) GetDiagnosticEvents() ([]xdr.DiagnosticEvent, error) {
return t.UnsafeMeta.GetDiagnosticEvents()
}

// GetTransactionEvents gives the breakdown of xdr.ContractEvent, xdr.TransactionEvent, xdr.Disgnostic event as they appea in the TxMeta
// In TransactionMetaV3, for soroban transactions, contract events and diagnostic events appear in the SorobanMeta struct in TransactionMetaV3, i.e. at the transaction level
// In TransactionMetaV4 and onwards, there is a more granular breakdown, because of CAP-67 unified events
// - Classic operations will also have contract events.
// - Contract events will now be present in the "operation []OperationMetaV2" in the TransactionMetaV4 structure, instead of at the transaction level as in TxMetaV3.
// This is true for soroban transactions as well, which will only have one operation and thus contract events will appear at index 0 in the []OperationMetaV2 structure
// - Additionally, if its a soroban transaction, the diagnostic events will also be included in the "DiagnosticEvents []DiagnosticEvent" structure
// - Non soroban transactions will have an empty list for DiagnosticEvents
//
// It is preferred to use this function in horizon and rpc
func (t *LedgerTransaction) GetTransactionEvents() (TransactionEvents, error) {
txEvents := TransactionEvents{}
switch t.UnsafeMeta.V {
case 1, 2:
return txEvents, nil
case 3:
// There wont be any events for classic operations in TxMetaV3
if !t.IsSorobanTx() {
return txEvents, nil
}
contractEvents, err := t.GetContractEvents()
if err != nil {
return txEvents, err
}
diagnosticEvents, err := t.GetDiagnosticEvents()
if err != nil {
return txEvents, err
}
// There will only ever be 1 smart contract operation per tx.
txEvents.OperationEvents = make([][]xdr.ContractEvent, 1)
txEvents.OperationEvents[0] = contractEvents
txEvents.DiagnosticEvents = diagnosticEvents
case 4:
txMeta := t.UnsafeMeta.MustV4()
txEvents.TransactionEvents = txMeta.Events
txEvents.DiagnosticEvents = txMeta.DiagnosticEvents
txEvents.OperationEvents = make([][]xdr.ContractEvent, len(txMeta.Operations))
for i, op := range txMeta.Operations {
txEvents.OperationEvents[i] = op.Events
}
default:
return txEvents, fmt.Errorf("unsupported TransactionMeta version: %v", t.UnsafeMeta.V)
}
return txEvents, nil

}

func (t *LedgerTransaction) ID() int64 {
return toid.New(int32(t.Ledger.LedgerSequence()), int32(t.Index), 0).ToInt64()
}
Expand Down
Loading
Loading