Skip to content

Commit

Permalink
CAP-0067 Update (#1617)
Browse files Browse the repository at this point in the history
* Clear up path payment section

* Hash events into ledger
  • Loading branch information
sisuresh authored Jan 15, 2025
1 parent bb1c8d7 commit 5fa1220
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 20 deletions.
2 changes: 1 addition & 1 deletion core/cap-0063.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ In order to maintain the read-only TTL update semantics, the CAP also defines th
### XDR Changes

This patch of XDR changes is based on the XDR files in commit `a41b2db15ea34a9f9da5326b996bb8a7ceb5740f` of stellar-xdr.
```
```diff mddiffcheck.ignore=true
diff --git a/Stellar-contract-config-setting.x b/Stellar-contract-config-setting.x
index 9f09c7b..a8d3325 100644
--- a/Stellar-contract-config-setting.x
Expand Down
2 changes: 1 addition & 1 deletion core/cap-0064.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ This CAP introduces a new version of Soroban address credentials that allows use

This patch of XDR changes is based on the XDR files in commit `a41b2db15ea34a9f9da5326b996bb8a7ceb5740f` of stellar-xdr.

```
```diff mddiffcheck.ignore=true
Stellar-ledger-entries.x | 3 ++-
Stellar-transaction.x | 27 ++++++++++++++++++++++++++-
2 files changed, 28 insertions(+), 2 deletions(-)
Expand Down
2 changes: 1 addition & 1 deletion core/cap-0066.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ mostly finalized in [CAP-0057](cap-0057.md), it is now appropriate to introduce

### XDR changes

```
```diff mddiffcheck.ignore=true
--- a/Stellar-contract-config-setting.x
+++ b/Stellar-contract-config-setting.x
@@ -26,38 +26,48 @@ struct ConfigSettingContractComputeV0
Expand Down
85 changes: 68 additions & 17 deletions core/cap-0067.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Protocol version: 23

## Simple Summary

Emit `transfer`, `mint`, `burn`, `clawback`, `set_authorized`, and `fee` events in Classic in the same format as what we see in Soroban so that the movement of assets can be tracked using a single stream of data. In addition to emitting events in Classic, update the events emitted in the Stellar Asset Contract to be semantically correct and compatible with SEP-41.
Emit `transfer`, `mint`, `burn`, `clawback`, and `fee` events in Classic in the same format as what we see in Soroban so that the movement of assets can be tracked using a single stream of data. In addition to emitting events in Classic, update the events emitted in the Stellar Asset Contract to be semantically correct and compatible with SEP-41.

## Motivation

Expand All @@ -35,14 +35,12 @@ This CAP specifies three changes -
2. Remove the admin from the topics of the `mint` and `clawback` events emitted in the SAC.
3. Update issuer semantics in the SAC so that a `transfer` involving the issuer will emit the semantically correct event (`mint` or `burn`).

The added events will not be a protocol change because they won't be hashed into the ledger, but the Stellar Asset Contract changes will be.

## Specification

### XDR Changes

This patch of XDR changes is based on the XDR files in commit `734bcccdbb6d1f7e794793ad3b8be51f3ba76f92` of stellar-xdr.
```
```diff mddiffcheck.ignore=true
diff --git a/Stellar-contract.x b/Stellar-contract.x
index 5113005..ee10e20 100644
--- a/Stellar-contract.x
Expand All @@ -69,6 +67,49 @@ index 5113005..ee10e20 100644
};

%struct SCVal;
diff --git a/Stellar-ledger.x b/Stellar-ledger.x
index 6ab63fb..80a2635 100644
--- a/Stellar-ledger.x
+++ b/Stellar-ledger.x
@@ -447,6 +447,7 @@ struct TransactionMetaV3
};

// This is in Stellar-ledger.x to due to a circular dependency
+// Only used before protocol 23
struct InvokeHostFunctionSuccessPreImage
{
SCVal returnValue;
diff --git a/Stellar-transaction.x b/Stellar-transaction.x
index 6b10e4d..163430e 100644
--- a/Stellar-transaction.x
+++ b/Stellar-transaction.x
@@ -1883,7 +1883,7 @@ enum InvokeHostFunctionResultCode
union InvokeHostFunctionResult switch (InvokeHostFunctionResultCode code)
{
case INVOKE_HOST_FUNCTION_SUCCESS:
- Hash success; // sha256(InvokeHostFunctionSuccessPreImage)
+ Hash success; // sha256(SCVal)
case INVOKE_HOST_FUNCTION_MALFORMED:
case INVOKE_HOST_FUNCTION_TRAPPED:
case INVOKE_HOST_FUNCTION_RESOURCE_LIMIT_EXCEEDED:
@@ -2083,6 +2083,8 @@ struct InnerTransactionResult
{
case 0:
void;
+ case 1:
+ Hash eventsHash;
}
ext;
};
@@ -2130,6 +2132,8 @@ struct TransactionResult
{
case 0:
void;
+ case 1:
+ Hash eventsHash;
}
ext;
};
```

## Semantics
Expand All @@ -90,8 +131,9 @@ contract: asset, topics: ["clawback", from:Address, sep0011_asset:String], data:
At the moment, if the issuer is the sender in a Stellar Asset Contract `transfer`, the asset will be minted. If the issuer is the recipient, the asset will be burned. The event emitted in both scenarios, however, is the `transfer` event. This CAP changes that behavior to instead emit the `mint`/`burn` event.

### New Events
This section will go over the semantics of how the additional `transfer` events are emitted for each operation, as well as the `fee` event emitted for the fee paid by the source account. These events will be emitted through `TransactionMeta`, and will not be hashed into the ledger. Note that
the `contract` field for these events corresponds to the Stellar Asset Contract address for the respective asset. Note that the Stellar Asset Contract instance is not required to be deployed for the asset. The events will be published using the reserved contract address regardless of deployment status.
This section will go over the semantics of how the additional `transfer` events are emitted for each operation, as well as the `fee` event emitted for the fee paid by the source account. These events will be emitted through the `events<>` field in `SorobanTransactionMeta`, and the SHA-256 hash of the events will be saved in the new `eventsHash` extension of `TransactionResult`. For consistency, the preimage of the hash stored in `InvokeHostFunctionResult` on success will just be the `returnValue` `SCVal`, and the events hash will be stored in `eventsHash` like any other transaction.

Note that the `contract` field for these events corresponds to the Stellar Asset Contract address for the respective asset. Note that the Stellar Asset Contract instance is not required to be deployed for the asset. The events will be published using the reserved contract address regardless of deployment status.

#### Fees paid by source account

Expand Down Expand Up @@ -120,23 +162,31 @@ contract: asset, topics: ["burn", from:Address, sep0011_asset:String], data: amo
```

#### Path Payment Strict Send / Path Payment Strict Receive
For each movement of the asset created by the path payment, emit one of the following -
For each movement of the asset created by the path payment, emit one of the following -

For a movement not involving the issuer:
```
contract: asset, topics: ["transfer", from:Address, to:Address, sep0011_asset:String], data: amount:i128
contract: assetA, topics: ["transfer", from:Address, to:Address, sep0011_asset:String], data: amount:i128
contract: assetB, topics: ["transfer", from:Address, to:Address, sep0011_asset:String], data: amount:i128
```

When sending from an issuer:
If `from` is the issuer on a side of the trade, emit the following instead for that side of the trade:
```
contract: asset, topics: ["mint", from:Address, sep0011_asset:String], data: amount:i128
contract: asset, topics: ["mint", to:Address, sep0011_asset:String], data: amount:i128
```

When sending to an issuer:
If `to` is the issuer on a side of the trade, emit the following instead for that side of the trade:
```
contract: asset, topics: ["burn", from:Address, sep0011_asset:String], data: amount:i128
```

* `from` is the account being debited (seller).
* `to` is the account being credited (buyer).

The trades within a path payment are conceptually between the source account and the owner of the offers. Those are the addresses that'll appear on the event pairs specified above. At the end of all the trades, we need to emit one more `transfer` (or `burn` if the destination is the issuer) event to indicate a transfer from the source account to the destination account. The amount will be equivalent to the sum of the destination asset received on the trades of the final hop.

Note that if the path payment has an empty path and `sendAsset == destAsset`, then the operation is effectively a regular [payment](#payment), so emit an event following the specifications of the payment section.


#### Create Account
Emit the following event:
```
Expand Down Expand Up @@ -227,16 +277,19 @@ contract: assetA, topics: ["transfer", from:Address, to:Address, sep0011_asset:S
contract: assetB, topics: ["transfer", from:Address, to:Address, sep0011_asset:String], data: amount:i128
```

If an asset is a movement from the issuer of the asset, instead emit for that movement:
If `from` is the issuer on a side of the trade, emit the following instead for that side of the trade:
```
contract: asset, topics: ["mint", to:Address, sep0011_asset:String], data: amount:i128
```

If an asset is a movement to the issuer of the asset, instead emit for the movement:
If `to` is the issuer on a side of the trade, emit the following instead for that side of the trade:
```
contract: asset, topics: ["burn", from:Address, sep0011_asset:String], data: amount:i128
```

* `from` is the account being debited (seller).
* `to` is the account being credited (buyer).

#### Clawback / Clawback Claimable Balance
Emit the following event:

Expand Down Expand Up @@ -267,9 +320,7 @@ The admin isn't relevant information when a mint or `clawback` occurs, and it hi

### No change to TransactionMeta XDR

By using the existing `events<>` vector in `SorobanTransactionMeta`. We can avoid making any xdr changes. This does have some tradeoffs, mainly that
1. All events for a given transaction will be emitted in a single vector, making it impossible to distinguish which operation emitted a specific event. The alternative would be to move Soroban meta from the transaction layer into the operation layer of transaction meta, but that would be a breaking change.
2. Soroban events are hashed into the return value of `InvokeHostFunctionResult` which allows you to cryptographically verify the `events<>` vector. Using the same `events<>` vector may cause some confusion because the Classic events won't be hashed into anything.
By using the existing `events<>` vector in `SorobanTransactionMeta`. We can avoid making any xdr changes. This does have some tradeoffs, mainly that all events for a given transaction will be emitted in a single vector, making it impossible to distinguish which operation emitted a specific event. The alternative would be to move Soroban meta from the transaction layer into the operation layer of transaction meta, but that would be a breaking change.

### Emit the semantically correct event instead of no longer allowing the issuer to transfer due to missing a trustline

Expand Down

0 comments on commit 5fa1220

Please sign in to comment.