Skip to content

Commit

Permalink
Add all types of change reasons to the Change struct. Simplify Ledger…
Browse files Browse the repository at this point in the history
…Transaction.GetChanges()
  • Loading branch information
karthikiyer56 committed Nov 21, 2024
1 parent 070c552 commit 26780fa
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 36 deletions.
33 changes: 24 additions & 9 deletions ingest/change.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,33 @@ import (
// If an entry is removed: Pre is not nil and Post is nil.
// If this change is caused by a operation in a transaction, include the operation information. Wont work when changes are compacted
type Change struct {
Type xdr.LedgerEntryType
Pre *xdr.LedgerEntry
Post *xdr.LedgerEntry
isOperationChange bool
operationInfo *OperationInfo
Type xdr.LedgerEntryType
Pre *xdr.LedgerEntry
Post *xdr.LedgerEntry
reason LedgerEntryChangeReason
TransactionData *TransactionEnvelopeAndResult
operationInfo *OperationInfo
}

type LedgerEntryChangeReason uint16

const (
Unknown LedgerEntryChangeReason = iota
Operation
Transaction
FeeChange
ProtocolUpgrade
Eviction
)

type TransactionEnvelopeAndResult struct {
Envelope *xdr.TransactionEnvelope
Result *xdr.TransactionResultPair
}

type OperationInfo struct {
operationIdx uint32
operation *xdr.Operation
operationResult *xdr.OperationResultTr
txEnvelope *xdr.TransactionEnvelope
operationIdx uint32
operation *xdr.Operation
}

// String returns a best effort string representation of the change.
Expand Down
10 changes: 7 additions & 3 deletions ingest/ledger_change_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,10 @@ func (r *LedgerChangeReader) Read() (Change, error) {
entry := entries[i]
// when a ledger entry is evicted it is removed from the ledger
changes[i] = Change{
Type: entry.Data.Type,
Pre: &entry,
Post: nil,
Type: entry.Data.Type,
Pre: &entry,
Post: nil,
reason: Eviction,
}
}
sortChanges(changes)
Expand All @@ -200,6 +201,9 @@ func (r *LedgerChangeReader) Read() (Change, error) {
changes := GetChangesFromLedgerEntryChanges(
r.LedgerTransactionReader.lcm.UpgradesProcessing()[r.upgradeIndex].Changes,
)
for _, change := range changes {
change.reason = ProtocolUpgrade // Is there any other information that we can add here?
}
r.pending = append(r.pending, changes...)
r.upgradeIndex++
return r.Read()
Expand Down
61 changes: 37 additions & 24 deletions ingest/ledger_transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,30 @@ func (t *LedgerTransaction) txInternalError() bool {
// GetFeeChanges returns a developer friendly representation of LedgerEntryChanges
// connected to fees.
func (t *LedgerTransaction) GetFeeChanges() []Change {
return GetChangesFromLedgerEntryChanges(t.FeeChanges)
changes := GetChangesFromLedgerEntryChanges(t.FeeChanges)
txData := &TransactionEnvelopeAndResult{Envelope: &t.Envelope, Result: &t.Result}
for _, change := range changes {
change.reason = FeeChange
change.TransactionData = txData
}
return changes
}

// GetChanges returns a developer friendly representation of LedgerEntryChanges.
// It contains transaction changes and operation changes in that order. If the
// transaction failed with TxInternalError, operations and txChangesAfter are
// omitted. It doesn't support legacy TransactionMeta.V=0.

func (t *LedgerTransaction) getTransactionChanges(ledgerEntryChanges xdr.LedgerEntryChanges) []Change {
changes := GetChangesFromLedgerEntryChanges(ledgerEntryChanges)
txData := &TransactionEnvelopeAndResult{Envelope: &t.Envelope, Result: &t.Result}
for _, change := range changes {
change.reason = Transaction
change.TransactionData = txData
}
return changes
}

func (t *LedgerTransaction) GetChanges() ([]Change, error) {
var changes []Change

Expand All @@ -43,7 +60,7 @@ func (t *LedgerTransaction) GetChanges() ([]Change, error) {
case 1:
v1Meta := t.UnsafeMeta.MustV1()
// The var `txChanges` reflect the ledgerEntryChanges that are changed because of the transaction as a whole
txChanges := GetChangesFromLedgerEntryChanges(v1Meta.TxChanges)
txChanges := t.getTransactionChanges(v1Meta.TxChanges)
changes = append(changes, txChanges...)

// Ignore operations meta if txInternalError https://github.com/stellar/go/issues/2111
Expand All @@ -58,7 +75,7 @@ func (t *LedgerTransaction) GetChanges() ([]Change, error) {
// operationMeta is a list of lists.
// Each element in operationMeta is a list of ledgerEntryChanges
// caused by the operation at that index of the element
for opIdx, _ := range operationMeta {
for opIdx := range operationMeta {
opChanges := t.operationChanges(v1Meta.Operations, uint32(opIdx))
changes = append(changes, opChanges...)
}
Expand All @@ -83,7 +100,7 @@ func (t *LedgerTransaction) GetChanges() ([]Change, error) {
panic("Invalid meta version, expected 2 or 3")
}

txChangesBefore := GetChangesFromLedgerEntryChanges(txBeforeChanges)
txChangesBefore := t.getTransactionChanges(txBeforeChanges)
changes = append(changes, txChangesBefore...)

// Ignore operations meta and txChangesAfter if txInternalError
Expand All @@ -95,12 +112,12 @@ func (t *LedgerTransaction) GetChanges() ([]Change, error) {
// operationMeta is a list of lists.
// Each element in operationMeta is a list of ledgerEntryChanges
// caused by the operation at that index of the element
for opIdx, _ := range operationMeta {
for opIdx := range operationMeta {
opChanges := t.operationChanges(operationMeta, uint32(opIdx))
changes = append(changes, opChanges...)
}

txChangesAfter := GetChangesFromLedgerEntryChanges(txAfterChanges)
txChangesAfter := t.getTransactionChanges(txAfterChanges)
changes = append(changes, txChangesAfter...)
default:
return changes, errors.New("Unsupported TransactionMeta version")
Expand Down Expand Up @@ -151,29 +168,25 @@ func (t *LedgerTransaction) operationChanges(ops []xdr.OperationMeta, index uint
}

operationMeta := ops[index]
changes := GetChangesFromLedgerEntryChanges(
operationMeta.Changes,
)
changes := GetChangesFromLedgerEntryChanges(operationMeta.Changes)
op, found := t.GetOperation(index)
operationInfo := &OperationInfo{
operationIdx: index,
operation: &op,
}
txData := &TransactionEnvelopeAndResult{Envelope: &t.Envelope, Result: &t.Result}

res := make([]Change, 0, len(changes))
for _, change := range changes {
op, found := t.GetOperation(index)
if !found {
continue
}
results, ok := t.Result.OperationResults()
if !ok || len(results) == 0 { // This shouldnt happen.
continue
}
operationResult := results[index].MustTr()
operationInfo := OperationInfo{
operationIdx: index,
operation: &op,
operationResult: &operationResult,
txEnvelope: &t.Envelope,
}
change.operationInfo = &operationInfo
change.isOperationChange = true
change.operationInfo = operationInfo
change.reason = Operation
change.TransactionData = txData
res = append(res, change)
}
return changes
return res
}

// GetDiagnosticEvents returns all contract events emitted by a given operation.
Expand Down

0 comments on commit 26780fa

Please sign in to comment.