@@ -17,6 +17,7 @@ import { DataServiceFees } from "@graphprotocol/horizon/contracts/data-service/e
17
17
import { Directory } from "./utilities/Directory.sol " ;
18
18
import { AllocationManager } from "./utilities/AllocationManager.sol " ;
19
19
import { SubgraphServiceV1Storage } from "./SubgraphServiceStorage.sol " ;
20
+ import { Decoder } from "./Decoder.sol " ;
20
21
21
22
import { TokenUtils } from "@graphprotocol/contracts/contracts/utils/TokenUtils.sol " ;
22
23
import { PPMMath } from "@graphprotocol/horizon/contracts/libraries/PPMMath.sol " ;
@@ -40,6 +41,7 @@ contract SubgraphService is
40
41
Directory ,
41
42
AllocationManager ,
42
43
SubgraphServiceV1Storage ,
44
+ Decoder ,
43
45
IRewardsIssuer ,
44
46
ISubgraphService
45
47
{
@@ -288,11 +290,9 @@ contract SubgraphService is
288
290
);
289
291
paymentCollected = _collectIndexingRewards (allocationId, poi, _delegationRatio);
290
292
} else if (paymentType == IGraphPayments.PaymentTypes.IndexingFee) {
291
- (IndexingAgreementKey memory key , uint256 entities , bytes32 poi ) = abi.decode (
292
- data,
293
- (IndexingAgreementKey, uint256 , bytes32 )
294
- );
295
- paymentCollected = _collectIndexingFees (key, entities, poi);
293
+ (IndexingAgreementKey memory key , bytes memory iaCollectionData ) = _decodeCollectIndexingFeeData (data);
294
+
295
+ paymentCollected = _collectIndexingFees (key, iaCollectionData);
296
296
} else {
297
297
revert SubgraphServiceInvalidPaymentType (paymentType);
298
298
}
@@ -555,6 +555,10 @@ contract SubgraphService is
555
555
mapping (address indexer = > mapping (address payer = > mapping (bytes16 agreementId = > IndexingAgreementData data )))
556
556
public indexingAgreements;
557
557
558
+ /// @notice Tracks indexing agreements parameters (V1)
559
+ mapping (address indexer = > mapping (address payer = > mapping (bytes16 agreementId = > IndexingAgreementTermsV1 data )))
560
+ public indexingAgreementTermsV1;
561
+
558
562
/// @notice Lookup agreement key by allocation ID
559
563
mapping (address allocationId = > IndexingAgreementKey key ) public allocationToActiveAgreementKey;
560
564
@@ -572,7 +576,7 @@ contract SubgraphService is
572
576
* - Agreement must not have been accepted before
573
577
* - Allocation must not have an agreement already
574
578
*
575
- * @dev signedRCV.rcv.metadata is an encoding of {ISubgraphService.RCVMetadata }
579
+ * @dev signedRCV.rcv.metadata is an encoding of {ISubgraphService.RCVIndexingAgreementMetadata }
576
580
*
577
581
* Emits {IndexingAgreementAccepted} event
578
582
*
@@ -594,22 +598,17 @@ contract SubgraphService is
594
598
SubgraphServiceIndexingAgreementDataServiceMismatch (signedRCV.rcv.dataService)
595
599
);
596
600
597
- RCVMetadata memory metadata;
598
- try this .decodeRCVMetadata (signedRCV.rcv.metadata) returns (RCVMetadata memory decoded ) {
599
- metadata = decoded;
600
- _acceptIndexingAgreement (allocationId, signedRCV, decoded);
601
- } catch {
602
- revert SubgraphServiceInvalidRCVMetadata (signedRCV.rcv.metadata);
603
- }
601
+ RCVIndexingAgreementMetadata memory metadata = _decodeRCVMetadata (signedRCV.rcv.metadata);
602
+ _acceptIndexingAgreement (allocationId, signedRCV, metadata);
604
603
605
604
emit IndexingAgreementAccepted (
606
605
signedRCV.rcv.serviceProvider,
607
606
signedRCV.rcv.payer,
608
607
signedRCV.rcv.agreementId,
609
608
allocationId,
610
609
metadata.subgraphDeploymentId,
611
- metadata.tokensPerSecond ,
612
- metadata.tokensPerEntityPerSecond
610
+ metadata.version ,
611
+ metadata.terms
613
612
);
614
613
}
615
614
@@ -681,16 +680,6 @@ contract SubgraphService is
681
680
return indexingAgreements[key.indexer][key.payer][key.agreementId];
682
681
}
683
682
684
- /**
685
- * @notice Decodes the indexing agreement metadata.
686
- *
687
- * @param metadata The metadata to decode. See {ISubgraphService.RCVMetadata}
688
- * @return The decoded metadata
689
- */
690
- function decodeRCVMetadata (bytes calldata metadata ) public pure returns (RCVMetadata memory ) {
691
- return abi.decode (metadata, (RCVMetadata));
692
- }
693
-
694
683
/**
695
684
* @notice Collect Indexing fees
696
685
* Stake equal to the amount being collected times the `stakeToFeesRatio` is locked into a stake claim.
@@ -709,53 +698,54 @@ contract SubgraphService is
709
698
*
710
699
* Emits a {StakeClaimsReleased} event, and a {StakeClaimReleased} event for each claim released.
711
700
* Emits a {StakeClaimLocked} event.
712
- * Emits a {IndexingFeesCollected } event.
701
+ * Emits a {IndexingFeesCollectedV1 } event.
713
702
*
714
703
* @param _key The indexing agreement key
715
- * @param _entities The number of entities indexed
716
- * @param _poi The proof of indexing
704
+ * @param _data The indexing agreement collection data
717
705
* @return The amount of fees collected
718
706
*/
719
- function _collectIndexingFees (
720
- IndexingAgreementKey memory _key ,
721
- uint256 _entities ,
722
- bytes32 _poi
723
- ) private returns (uint256 ) {
707
+ function _collectIndexingFees (IndexingAgreementKey memory _key , bytes memory _data ) private returns (uint256 ) {
724
708
IndexingAgreementData memory agreement = _requireActiveIndexingAgreement (_key);
725
709
Allocation.State memory allocation = _requireValidAllocation (agreement.allocationId, _key.indexer);
726
710
711
+ require (
712
+ agreement.version == IndexingAgreementVersion.V1,
713
+ SubgraphServiceInvalidIndexingAgreementVersion (agreement.version)
714
+ );
715
+ (uint256 entities , bytes32 poi ) = _decodeCollectIndexingFeeDataV1 (_data);
716
+
727
717
uint256 tokensCollected = _indexingAgreementCollect (
728
718
_key,
729
719
bytes32 (uint256 (uint160 (agreement.allocationId))),
730
- _indexingAgreementTokensToCollect (_key, _entities )
720
+ _indexingAgreementTokensToCollect (_key, entities )
731
721
);
732
722
733
723
_releaseAndLockStake (_key.indexer, tokensCollected);
734
724
735
- emit IndexingFeesCollected (
725
+ emit IndexingFeesCollectedV1 (
736
726
_key.indexer,
737
727
_key.payer,
738
728
_key.agreementId,
739
729
agreement.allocationId,
740
730
allocation.subgraphDeploymentId,
741
731
_graphEpochManager ().currentEpoch (),
742
732
tokensCollected,
743
- _entities ,
744
- _poi
733
+ entities ,
734
+ poi
745
735
);
746
736
return tokensCollected;
747
737
}
748
738
749
739
function _acceptIndexingAgreement (
750
740
address _allocationId ,
751
741
IRecurringCollector.SignedRCV calldata _signedRCV ,
752
- RCVMetadata memory _metadata
742
+ RCVIndexingAgreementMetadata memory _agreementMetadata
753
743
) private {
754
744
Allocation.State memory allocation = _requireValidAllocation (_allocationId, _signedRCV.rcv.serviceProvider);
755
745
require (
756
- allocation.subgraphDeploymentId == _metadata .subgraphDeploymentId,
746
+ allocation.subgraphDeploymentId == _agreementMetadata .subgraphDeploymentId,
757
747
SubgraphServiceIndexingAgreementDeploymentIdMismatch (
758
- _metadata .subgraphDeploymentId,
748
+ _agreementMetadata .subgraphDeploymentId,
759
749
_allocationId,
760
750
allocation.subgraphDeploymentId
761
751
)
@@ -776,25 +766,37 @@ contract SubgraphService is
776
766
allocationToActiveAgreementKey[_allocationId] = key;
777
767
778
768
agreement.allocationId = _allocationId;
779
- agreement.tokensPerSecond = _metadata.tokensPerSecond;
780
- agreement.tokensPerEntityPerSecond = _metadata.tokensPerEntityPerSecond;
781
769
agreement.acceptedAt = block .timestamp ;
782
770
771
+ require (
772
+ _agreementMetadata.version == IndexingAgreementVersion.V1,
773
+ SubgraphServiceInvalidIndexingAgreementVersion (_agreementMetadata.version)
774
+ );
775
+ _acceptIndexingAgreementTermsV1 (key, _agreementMetadata.terms);
776
+
783
777
_recurringCollector ().accept (_signedRCV);
784
778
}
785
779
780
+ function _acceptIndexingAgreementTermsV1 (IndexingAgreementKey memory _key , bytes memory _data ) private {
781
+ IndexingAgreementTermsV1 memory agreementTermsV1 = _decodeAcceptIndexingAgreementTermsV1 (_data);
782
+ IndexingAgreementTermsV1 storage termsV1 = _getForUpdateIndexingAgreementTermsV1 (_key);
783
+ termsV1.tokensPerSecond = agreementTermsV1.tokensPerSecond;
784
+ termsV1.tokensPerEntityPerSecond = agreementTermsV1.tokensPerEntityPerSecond;
785
+ }
786
+
786
787
function _indexingAgreementTokensToCollect (
787
788
IndexingAgreementKey memory _key ,
788
789
uint256 _entities
789
790
) private returns (uint256 ) {
790
791
IndexingAgreementData storage agreement = _getForUpdateIndexingAgreement (_key);
792
+ IndexingAgreementTermsV1 memory termsV1 = _getIndexingAgreementTermsV1 (_key);
791
793
792
794
uint256 collectionSeconds = block .timestamp ;
793
795
collectionSeconds -= agreement.lastCollectionAt > 0 ? agreement.lastCollectionAt : agreement.acceptedAt;
794
796
agreement.lastCollectionAt = block .timestamp ;
795
797
796
798
// FIX-ME: this is bad because it encourages people to collect at max seconds allowed to maximize collection.
797
- return collectionSeconds * (agreement .tokensPerSecond + agreement .tokensPerEntityPerSecond * _entities);
799
+ return collectionSeconds * (termsV1 .tokensPerSecond + termsV1 .tokensPerEntityPerSecond * _entities);
798
800
}
799
801
800
802
function _indexingAgreementCollect (
@@ -851,6 +853,18 @@ contract SubgraphService is
851
853
return indexingAgreements[_key.indexer][_key.payer][_key.agreementId];
852
854
}
853
855
856
+ function _getForUpdateIndexingAgreementTermsV1 (
857
+ IndexingAgreementKey memory _key
858
+ ) private view returns (IndexingAgreementTermsV1 storage ) {
859
+ return indexingAgreementTermsV1[_key.indexer][_key.payer][_key.agreementId];
860
+ }
861
+
862
+ function _getIndexingAgreementTermsV1 (
863
+ IndexingAgreementKey memory _key
864
+ ) private view returns (IndexingAgreementTermsV1 memory ) {
865
+ return indexingAgreementTermsV1[_key.indexer][_key.payer][_key.agreementId];
866
+ }
867
+
854
868
function _requireValidAllocation (
855
869
address _allocationId ,
856
870
address _indexer
0 commit comments