Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Token Transfer Processor - Derive classic events from operation and operation results #5609

Open
wants to merge 80 commits into
base: master
Choose a base branch
from

Conversation

karthikiyer56
Copy link
Contributor

@karthikiyer56 karthikiyer56 commented Feb 19, 2025

This PR deals with deriving TokenTransferEvents from operation and operation results as described in #5580
This PR is strictly dealing with classic and classic operations, i.e the PR implements the ask from #5592

@karthikiyer56 karthikiyer56 force-pushed the karthik/ttp-classic-operations branch from 36946d4 to 571679c Compare February 20, 2025 23:41
return changes
}

func mapsEqual(map1, map2 map[balanceKey]int64) bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I want to retain this, since I will use this to print a delta, assuming we find that verifcation fails for some ledgers


eventType := event.GetEventType()
switch eventType {
case "Fee":
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should have constant variables for the event type strings so they can be referenced here and other places which reference event types

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the reminder here.
I had meant to change it to switch on types instead.
I will make the change

"github.com/stellar/go/ingest"
addressProto "github.com/stellar/go/ingest/address"
assetProto "github.com/stellar/go/ingest/asset"
"github.com/stellar/go/support/errors"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should avoid using this package as the go standard library now has support for wrapping / unwrapping errors.

instead of errors.New() from github.com/stellar/go/support/errors we should prefer https://pkg.go.dev/errors#New and instead of errors.Wrap() from github.com/stellar/go/support/errors we should be wrapping errors using fmt.Errorf in the way described here, https://pkg.go.dev/errors#pkg-overview

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, the "github.com/pkg/errors" itself has errors.New and errors.WrapF . I am just using that and removing "github.com/stellar/go/support/errors"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

github.com/pkg/errors is not part of the standard library. github.com/pkg/errors Is currently in maintenance mode. the errors package in the standard library is preferred over github.com/pkg/errors

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL
WIll make the change

Copy link
Contributor Author

@karthikiyer56 karthikiyer56 Mar 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dpone
reworked all errors in this package to use the golang errors package or fmt.Errorf

Comment on lines +251 to +260
isSuccess := mapsEqual(eventsMap, changesMap)
if !isSuccess {
fmt.Println("----ChangeMap-----")
printMap(changesMap)
fmt.Println("------")
fmt.Println("----EventsMap-----")
printMap(eventsMap)
fmt.Println("------")
}
return isSuccess
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider using this library to get a diff which can then be printed by the caller of this function

Comment on lines 874 to 888
// Calculate the difference
var diff int64
if existsInChanges && existsInEvents {
// Both maps have entries for this account/asset
diff = changesBalance - eventsBalance
} else if existsInChanges {
// Only in changes map, not in events map
diff = changesBalance
} else if existsInEvents {
// Only in events map, not in changes map
diff = -eventsBalance
} else {
// Not in either map, no difference
return events
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't need the existsInChanges and existsInEvents variables because if a key doesn't exist in the map the zero value of the type is returned:

https://gobyexample.com/maps

It is generally considered good style to "make the zero value useful"

So your calculation can be simplified to:

Suggested change
// Calculate the difference
var diff int64
if existsInChanges && existsInEvents {
// Both maps have entries for this account/asset
diff = changesBalance - eventsBalance
} else if existsInChanges {
// Only in changes map, not in events map
diff = changesBalance
} else if existsInEvents {
// Only in events map, not in changes map
diff = -eventsBalance
} else {
// Not in either map, no difference
return events
}
diff := changesBalance - eventsBalance

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I had a few debug breakpoints there, to see why my code wasnt working.
i wil clean it up.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines 821 to 822
changesBalance, existsInChanges := changesMap[key]
eventsBalance, existsInEvents := eventsMap[key]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
changesBalance, existsInChanges := changesMap[key]
eventsBalance, existsInEvents := eventsMap[key]
changesBalance := changesMap[key]
eventsBalance := eventsMap[key]

see comment below where I explain why the exists check is not necessary

Copy link
Contributor Author

@karthikiyer56 karthikiyer56 Mar 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.
reworked this to remove checks

Comment on lines 913 to 914
// DO not run this reconciliation check for ledgers > 8 or if operation is Inflation
if tx.Ledger.ProtocolVersion() > 8 {
Copy link
Contributor

@tamirms tamirms Mar 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In https://github.com/stellar/stellar-protocol/blob/master/core/cap-0067.md#retroactively-emitting-events it states:

Another relevant detail for replaying events is that prior to protocol 8, there was a bug that could result in the minting/burning of XLM.

Suggested change
// DO not run this reconciliation check for ledgers > 8 or if operation is Inflation
if tx.Ledger.ProtocolVersion() > 8 {
// DO not run this reconciliation check for ledgers with protocol version >= 8 or if operation is Inflation
if tx.Ledger.ProtocolVersion() >= 8 {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the if statement should also check that op.Body.Type is not xdr.OperationTypeInflation to be consistent with your comment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice catch.
will make the change

Copy link
Contributor Author

@karthikiyer56 karthikiyer56 Mar 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.
removed the check altogether from this function.
The check is not at callsite, and at the callsite (EventsFromOperation()), reconciliation will be skipped for tx.Ledger.ProtocolVersion() >= 8

Comment on lines +63 to +79
func protoAddressFromLpHash(lpId xdr.PoolId) string {
return xdr.Hash(lpId).HexString()
}

func protoAddressFromClaimableBalanceId(cb xdr.ClaimableBalanceId) string {
return cb.MustV0().HexString()
}

// TODO convert to strkey for LpId
func lpIdToStrkey(lpId xdr.PoolId) string {
return xdr.Hash(lpId).HexString()
}

// TODO convert to strkey for CbId
func cbIdToStrkey(cbId xdr.ClaimableBalanceId) string {
return cbId.MustV0().HexString()
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems like these functions are duplicates of each other so we should probably be deleting lpIdToStrkey() and cbIdToStrkey() and replacing their uses with protoAddressFromLpHash() and protoAddressFromClaimableBalanceId()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤦 yup, will make the change

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Generate TokenTransferEvents from operation and operation results for classic operations
4 participants