Skip to content

Commit de6b7a1

Browse files
f: several upgrades, including versioned agreements
1 parent c059f74 commit de6b7a1

File tree

16 files changed

+1030
-740
lines changed

16 files changed

+1030
-740
lines changed

IndexingPaymentsTodo.md

+23-10
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
1-
### Still pending
1+
# Still pending
22

3-
* Rename `agreementId` to `voucherId`?
4-
* Update `DisputeManager` and Arbitration Charter to support disputing Indexing Fees.
5-
* Support indexing agreement upgadeability, so that there is a mechanism to adjust the rates without having to cancel and start over.
6-
* Built-in upgrade path to indexing agreements v2. So that indexers can be paid per byte instead of per entity.
7-
* Support for agreements that end up in `RecurringCollectorCollectionTooLate` or ways to avoid getting to that state.
8-
* Should we deal with zero entities declared as a special case?
9-
* Since an allocation is required for collecting, do we want to expect that the allocation is not stale? Do we want to add code to collect rewards as part of the collection of fees? Make sure allocation is more than one epoch old if we attempt this.
10-
* Reject Zero POIs?
11-
* What happens if the escrow doesn't have enough funds? Since you can't collect that means you lose out forever?
3+
* Double-check it supports paying per byte instead of per entity and eventually a subgraph-gas metric. DONE: ~~Built-in upgrade path to indexing agreements v2~~
4+
* Update Arbitration Charter to support disputing Indexing Fees. DONE: ~~Support `DisputeManager`~~
5+
* Economics
6+
* If service wants to collect more than collector allows. Collector limits but doesn't tell the service?
7+
* Support for agreements that end up in `RecurringCollectorCollectionTooLate` or ways to avoid getting to that state.
8+
* Should we deal with zero entities declared as a special case?
9+
* Since an allocation is required for collecting, do we want to expect that the allocation is not stale? Do we want to add code to collect rewards as part of the collection of fees? Make sure allocation is more than one epoch old if we attempt this.
10+
* Reject Zero POIs?
11+
* What happens if the escrow doesn't have enough funds? Since you can't collect that means you lose out forever?
12+
* Don't pay for entities on initial collection?
13+
* Should we set a different param for initial collection time max? Some subgraphs take a lot to catch up.
14+
* How do we solve for the case where an indexer has reached their max expected payout for the initial sync but haven't reached the current epoch (thus their POI is incorrect)?
15+
* Double check cancelation policy. Who can cancel when? Right now is either party at any time.
1216
* Expose a function that indexers can use to calculate the tokens to be collected and other collection params?
17+
* Support a way for gateway to shop an agreement around? Deadline + dedup key? So only one agreement with the dedupe key can be accepted?
18+
* Maybe check that the epoch the indexer is sending is the one the transaction will be run in?
19+
* Check upgrade conditions. Support indexing agreement upgadeability, so that there is a mechanism to adjust the rates without having to cancel and start over.
20+
* If an indexer closes an allocation, what should happen to the accepeted agreement?
21+
* test_SubgraphService_CollectIndexingFee_Integration fails with PaymentsEscrowInconsistentCollection
22+
* Reduce the number of errors declared and returned
23+
* DONE: ~~Make `agreementId` unique globally so that we don't need the full tuple (`payer`+`indexer`+`agreementId`) as key?~~
24+
* DONE: ~~Maybe IRecurringCollector.cancel(address payer, address serviceProvider, bytes16 agreementId) should only take in agreementId?~~
25+
* DONE: ~~Unify to one error in Decoder.sol~~

packages/horizon/contracts/interfaces/IRecurringCollector.sol

+64-59
Original file line numberDiff line numberDiff line change
@@ -13,32 +13,32 @@ import { IAuthorizable } from "./IAuthorizable.sol";
1313
* recurrent payments.
1414
*/
1515
interface IRecurringCollector is IAuthorizable, IPaymentsCollector {
16-
/// @notice A representation of a signed Recurrent Collection Voucher (RCV)
17-
struct SignedRCV {
18-
// The RCV
19-
RecurrentCollectionVoucher rcv;
16+
/// @notice A representation of a signed Recurring Collection Agreement (RCA)
17+
struct SignedRCA {
18+
// The RCA
19+
RecurringCollectionAgreement rca;
2020
// Signature - 65 bytes: r (32 Bytes) || s (32 Bytes) || v (1 Byte)
2121
bytes signature;
2222
}
2323

24-
/// @notice The Recurrent Collection Voucher (RCV)
25-
struct RecurrentCollectionVoucher {
26-
// The agreement ID of the RCV
24+
/// @notice The Recurring Collection Agreement (RCA)
25+
struct RecurringCollectionAgreement {
26+
// The agreement ID of the RCA
2727
bytes16 agreementId;
28-
// The deadline for accepting the RCV
28+
// The deadline for accepting the RCA
2929
uint256 acceptDeadline;
30-
// The duration of the RCV in seconds
30+
// The duration of the RCA in seconds
3131
uint256 duration;
32-
// The address of the payer the RCV was issued by
32+
// The address of the payer the RCA was issued by
3333
address payer;
34-
// The address of the data service the RCV was issued to
34+
// The address of the data service the RCA was issued to
3535
address dataService;
36-
// The address of the service provider the RCV was issued to
36+
// The address of the service provider the RCA was issued to
3737
address serviceProvider;
3838
// The maximum amount of tokens that can be collected in the first collection
3939
// on top of the amount allowed for subsequent collections
4040
uint256 maxInitialTokens;
41-
// The maximum amount of tokens that can be collected in a single collection
41+
// The maximum amount of tokens that can be collected per second
4242
// except for the first collection
4343
uint256 maxOngoingTokensPerSecond;
4444
// The minimum amount of seconds that must pass between collections
@@ -51,6 +51,12 @@ interface IRecurringCollector is IAuthorizable, IPaymentsCollector {
5151

5252
/// @notice The data for an agreement
5353
struct AgreementData {
54+
// The address of the data service
55+
address dataService;
56+
// The address of the payer
57+
address payer;
58+
// The address of the service provider
59+
address serviceProvider;
5460
// The timestamp when the agreement was accepted
5561
uint256 acceptedAt;
5662
// The timestamp when the agreement was last collected at
@@ -60,31 +66,20 @@ interface IRecurringCollector is IAuthorizable, IPaymentsCollector {
6066
// The maximum amount of tokens that can be collected in the first collection
6167
// on top of the amount allowed for subsequent collections
6268
uint256 maxInitialTokens;
63-
// The maximum amount of tokens that can be collected in a single collection
69+
// The maximum amount of tokens that can be collected per second
6470
// except for the first collection
6571
uint256 maxOngoingTokensPerSecond;
6672
// The minimum amount of seconds that must pass between collections
6773
uint32 minSecondsPerCollection;
6874
// The maximum amount of seconds that can pass between collections
6975
uint32 maxSecondsPerCollection;
70-
}
71-
72-
/// @notice The key for a stored agreement
73-
struct AgreementKey {
74-
// The address of the data service the agreement was issued to
75-
address dataService;
76-
// The address of the payer the agreement was issued by
77-
address payer;
78-
// The address of the service provider the agreement was issued to
79-
address serviceProvider;
80-
// The ID of the agreement
81-
bytes16 agreementId;
76+
// The agreement ID of the previous agreement
77+
bytes16 updatedFromAgreementId;
8278
}
8379

8480
/// @notice The params for collecting an agreement
8581
struct CollectParams {
86-
// The agreement key that uniquely identifies it
87-
AgreementKey key;
82+
bytes16 agreementId;
8883
// The collection ID
8984
bytes32 collectionId;
9085
// The amount of tokens to collect
@@ -94,12 +89,12 @@ interface IRecurringCollector is IAuthorizable, IPaymentsCollector {
9489
}
9590

9691
/**
97-
* @notice Emitted when an RCV is collected
92+
* @notice Emitted when an RCA is collected
9893
* @param dataService The address of the data service
9994
* @param payer The address of the payer
10095
* @param serviceProvider The address of the service provider
10196
*/
102-
event RCVCollected(
97+
event RCACollected(
10398
address indexed dataService,
10499
address indexed payer,
105100
address indexed serviceProvider,
@@ -108,16 +103,23 @@ interface IRecurringCollector is IAuthorizable, IPaymentsCollector {
108103
uint256 dataServiceCut
109104
);
110105

106+
/**
107+
* Thrown when calling cancel() for an agreement not owned by the calling data service
108+
* @param agreementId The agreement ID
109+
* @param dataService The address of the data service
110+
*/
111+
error RecurringCollectorDataServiceNotAuthorized(bytes16 agreementId, address dataService);
112+
111113
/**
112114
* Thrown when calling accept() for an agreement with an elapsed acceptance deadline
113115
* @param elapsedAt The timestamp when the acceptance deadline elapsed
114116
*/
115117
error RecurringCollectorAgreementAcceptanceElapsed(uint256 elapsedAt);
116118

117119
/**
118-
* Thrown when the RCV signer is invalid
120+
* Thrown when the RCA signer is invalid
119121
*/
120-
error RecurringCollectorInvalidRCVSigner();
122+
error RecurringCollectorInvalidRCASigner();
121123

122124
/**
123125
* Thrown when the payment type is not IndexingFee
@@ -126,7 +128,7 @@ interface IRecurringCollector is IAuthorizable, IPaymentsCollector {
126128
error RecurringCollectorInvalidPaymentType(IGraphPayments.PaymentTypes paymentType);
127129

128130
/**
129-
* Thrown when the caller is not the data service the RCV was issued to
131+
* Thrown when the caller is not the data service the RCA was issued to
130132
* @param caller The address of the caller
131133
* @param dataService The address of the data service
132134
*/
@@ -140,79 +142,82 @@ interface IRecurringCollector is IAuthorizable, IPaymentsCollector {
140142

141143
/**
142144
* Thrown when calling accept() for an already accepted agreement
143-
* @param key The agreement key
145+
* @param agreementId The agreement ID
144146
*/
145-
error RecurringCollectorAgreementAlreadyAccepted(AgreementKey key);
147+
error RecurringCollectorAgreementAlreadyAccepted(bytes16 agreementId);
146148

147149
/**
148150
* Thrown when calling cancel() for a never accepted agreement
149-
* @param key The agreement key
151+
* @param agreementId The agreement ID
150152
*/
151-
error RecurringCollectorAgreementNeverAccepted(AgreementKey key);
153+
error RecurringCollectorAgreementNeverAccepted(bytes16 agreementId);
152154

153155
/**
154156
* Thrown when calling collect() on an invalid agreement
155-
* @param key The agreement key
157+
* @param agreementId The agreement ID
156158
* @param acceptedAt The agreement accepted timestamp
157159
*/
158-
error RecurringCollectorAgreementInvalid(AgreementKey key, uint256 acceptedAt);
160+
error RecurringCollectorAgreementInvalid(bytes16 agreementId, uint256 acceptedAt);
159161

160162
/**
161163
* Thrown when calling collect() on an elapsed agreement
162-
* @param key The agreement key
164+
* @param agreementId The agreement ID
163165
* @param agreementEnd The agreement end timestamp
164166
*/
165-
error RecurringCollectorAgreementElapsed(AgreementKey key, uint256 agreementEnd);
167+
error RecurringCollectorAgreementElapsed(bytes16 agreementId, uint256 agreementEnd);
166168

167169
/**
168170
* Thrown when calling collect() too soon
169-
* @param key The agreement key
171+
* @param agreementId The agreement ID
170172
* @param secondsSinceLast Seconds since last collection
171173
* @param minSeconds Minimum seconds between collections
172174
*/
173-
error RecurringCollectorCollectionTooSoon(AgreementKey key, uint256 secondsSinceLast, uint256 minSeconds);
175+
error RecurringCollectorCollectionTooSoon(bytes16 agreementId, uint256 secondsSinceLast, uint256 minSeconds);
174176

175177
/**
176178
* Thrown when calling collect() too late
177-
* @param key The agreement key
179+
* @param agreementId The agreement ID
178180
* @param secondsSinceLast Seconds since last collection
179181
* @param maxSeconds Maximum seconds between collections
180182
*/
181-
error RecurringCollectorCollectionTooLate(AgreementKey key, uint256 secondsSinceLast, uint256 maxSeconds);
183+
error RecurringCollectorCollectionTooLate(bytes16 agreementId, uint256 secondsSinceLast, uint256 maxSeconds);
182184

183185
/**
184186
* Thrown when calling collect() too late
185-
* @param key The agreement key
187+
* @param agreementId The agreement ID
186188
* @param tokens The amount of tokens to collect
187189
* @param maxTokens The maximum amount of tokens allowed to collect
188190
*/
189-
error RecurringCollectorCollectAmountTooHigh(AgreementKey key, uint256 tokens, uint256 maxTokens);
191+
error RecurringCollectorCollectAmountTooHigh(bytes16 agreementId, uint256 tokens, uint256 maxTokens);
190192

191193
/**
192194
* @dev Accept an indexing agreement.
193-
* @param signedRCV The signed Recurrent Collection Voucher which is to be accepted.
195+
* @param signedRCA The signed Recurring Collection Agreement which is to be accepted.
194196
*/
195-
function accept(SignedRCV memory signedRCV) external;
197+
function accept(SignedRCA memory signedRCA) external;
196198

197199
/**
198200
* @dev Cancel an indexing agreement.
199-
* @param payer The address of the payer for the agreement.
200-
* @param serviceProvider The address of the serviceProvider for the agreement.
201201
* @param agreementId The agreement's ID.
202202
*/
203-
function cancel(address payer, address serviceProvider, bytes16 agreementId) external;
203+
function cancel(bytes16 agreementId) external;
204+
205+
/**
206+
* @dev Upgrade an indexing agreement.
207+
*/
208+
function upgrade() external;
204209

205210
/**
206-
* @dev Computes the hash of a RecurrentCollectionVoucher (RCV).
207-
* @param rcv The RCV for which to compute the hash.
208-
* @return The hash of the RCV.
211+
* @dev Computes the hash of a RecurringCollectionAgreement (RCA).
212+
* @param rca The RCA for which to compute the hash.
213+
* @return The hash of the RCA.
209214
*/
210-
function encodeRCV(RecurrentCollectionVoucher calldata rcv) external view returns (bytes32);
215+
function encodeRCA(RecurringCollectionAgreement calldata rca) external view returns (bytes32);
211216

212217
/**
213-
* @dev Recovers the signer address of a signed RecurrentCollectionVoucher (RCV).
214-
* @param signedRCV The SignedRCV containing the RCV and its signature.
218+
* @dev Recovers the signer address of a signed RecurringCollectionAgreement (RCA).
219+
* @param signedRCA The SignedRCA containing the RCA and its signature.
215220
* @return The address of the signer.
216221
*/
217-
function recoverRCVSigner(SignedRCV calldata signedRCV) external view returns (address);
222+
function recoverRCASigner(SignedRCA calldata signedRCA) external view returns (address);
218223
}

0 commit comments

Comments
 (0)