Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/horizon/ignition/modules/core/HorizonStaking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ export default buildModule('HorizonStaking', (m) => {
const subgraphServiceAddress = m.getParameter('subgraphServiceAddress')
const maxThawingPeriod = m.getParameter('maxThawingPeriod')

// Deploy HorizonStaking implementation
// Deploy HorizonStaking implementation - requires periphery and proxies to be registered in the controller
const HorizonStakingImplementation = deployImplementation(m, {
name: 'HorizonStaking',
artifact: HorizonStakingArtifact,
constructorArgs: [Controller, subgraphServiceAddress],
})
}, { after: [GraphPeripheryModule, HorizonProxiesModule] })

// Upgrade proxy to implementation contract
const HorizonStaking = upgradeGraphProxy(m, GraphProxyAdmin, HorizonStakingProxy, HorizonStakingImplementation, {
Expand Down
2 changes: 2 additions & 0 deletions packages/interfaces/src/types/horizon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@
IL2GNSToolshed,
ILegacyRewardsManager,
IPaymentsEscrowToolshed,
IRecurringCollector,
IRewardsManagerToolshed,
IStaking,
ISubgraphNFT,
} from '../../types'

export {

Check failure on line 19 in packages/interfaces/src/types/horizon.ts

View workflow job for this annotation

GitHub Actions / Lint Files

Run autofix to sort these exports!
IControllerToolshed as Controller,
IEpochManagerToolshed as EpochManager,
IGraphPayments as GraphPayments,
Expand All @@ -29,5 +30,6 @@
IStaking as LegacyStaking,
IPaymentsEscrowToolshed as PaymentsEscrow,
IRewardsManagerToolshed as RewardsManager,
IRecurringCollector,
ISubgraphNFT as SubgraphNFT,
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
"disputeManagerProxyAdminAddress": "",
"subgraphServiceProxyAddress": "",
"subgraphServiceProxyAdminAddress": "",
"graphTallyCollectorAddress": ""
"graphTallyCollectorAddress": "",
"recurringCollectorAddress": ""
},
"DisputeManager": {
"disputePeriod": 2419200,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
"disputeManagerProxyAdminAddress": "",
"subgraphServiceProxyAddress": "",
"subgraphServiceProxyAdminAddress": "",
"graphTallyCollectorAddress": ""
"graphTallyCollectorAddress": "",
"recurringCollectorAddress": ""
},
"DisputeManager": {
"disputePeriod": 7200, // 2 hours = 7200 seconds
Expand Down
49 changes: 45 additions & 4 deletions packages/subgraph-service/ignition/modules/SubgraphService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export default buildModule('SubgraphService', (m) => {
const subgraphServiceProxyAdminAddress = m.getParameter('subgraphServiceProxyAdminAddress')
const disputeManagerProxyAddress = m.getParameter('disputeManagerProxyAddress')
const graphTallyCollectorAddress = m.getParameter('graphTallyCollectorAddress')
const recurringCollectorAddress = m.getParameter('recurringCollectorAddress')
const curationProxyAddress = m.getParameter('curationProxyAddress')
const minimumProvisionTokens = m.getParameter('minimumProvisionTokens')
const maximumDelegationRatio = m.getParameter('maximumDelegationRatio')
Expand All @@ -28,12 +29,52 @@ export default buildModule('SubgraphService', (m) => {
subgraphServiceProxyAddress,
)

// Deploy implementation
const SubgraphServiceImplementation = deployImplementation(m, {
name: 'SubgraphService',
constructorArgs: [controllerAddress, disputeManagerProxyAddress, graphTallyCollectorAddress, curationProxyAddress],
// Deploy libraries required by SubgraphService's audit-branch constructor.
// The contract has been refactored to pull allocation, stake-claim, and
// indexing-agreement logic into stand-alone libraries; these must be
// deployed and link-passed to the implementation so the bytecode's
// placeholder slots resolve at deploy time.
//
// Ordering matters: IndexingAgreement calls into IndexingAgreementDecoder,
// which in turn calls into IndexingAgreementDecoderRaw, so the deeper
// libraries have to be deployed and linked first.
const StakeClaims = m.library('StakeClaims')
const AllocationHandler = m.library('AllocationHandler')
const IndexingAgreementDecoderRaw = m.library('IndexingAgreementDecoderRaw')
const IndexingAgreementDecoder = m.library('IndexingAgreementDecoder', {
libraries: {
IndexingAgreementDecoderRaw,
},
})
const IndexingAgreement = m.library('IndexingAgreement', {
libraries: {
IndexingAgreementDecoder,
},
})

// Deploy implementation
const SubgraphServiceImplementation = deployImplementation(
m,
{
name: 'SubgraphService',
constructorArgs: [
controllerAddress,
disputeManagerProxyAddress,
graphTallyCollectorAddress,
curationProxyAddress,
recurringCollectorAddress,
],
},
{
libraries: {
StakeClaims,
AllocationHandler,
IndexingAgreement,
IndexingAgreementDecoder,
},
},
)

// Upgrade implementation
const SubgraphService = upgradeTransparentUpgradeableProxy(
m,
Expand Down
1 change: 1 addition & 0 deletions packages/subgraph-service/tasks/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ task('deploy:protocol', 'Deploy a new version of the Graph Protocol Horizon cont
subgraphServiceProxyAddress: proxiesDeployment.Transparent_Proxy_SubgraphService.target as string,
subgraphServiceProxyAdminAddress: proxiesDeployment.Transparent_ProxyAdmin_SubgraphService.target as string,
graphTallyCollectorAddress: horizonDeployment.GraphTallyCollector.target as string,
recurringCollectorAddress: horizonDeployment.Transparent_Proxy_RecurringCollector.target as string,
gnsProxyAddress: horizonDeployment.Graph_Proxy_L2GNS.target as string,
gnsImplementationAddress: horizonDeployment.Implementation_L2GNS.target as string,
subgraphNFTAddress: horizonDeployment.SubgraphNFT.target as string,
Expand Down
1 change: 1 addition & 0 deletions packages/toolshed/src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ export * from './custom-errors'
export * from './disputes'
export * from './graph-tally'
export * from './poi'
export * from './recurring-collector'
export * from './subgraph-service'
export * from './types'
85 changes: 85 additions & 0 deletions packages/toolshed/src/core/recurring-collector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { BytesLike, ethers } from 'ethers'

// -- ABI tuple types for decoding --

const RCA_TUPLE =
'tuple(uint64 deadline, uint64 endsAt, address payer, address dataService, address serviceProvider, uint256 maxInitialTokens, uint256 maxOngoingTokensPerSecond, uint32 minSecondsPerCollection, uint32 maxSecondsPerCollection, uint16 conditions, uint256 nonce, bytes metadata)'

const SIGNED_RCA_TUPLE = `tuple(${RCA_TUPLE} rca, bytes signature)`

const ACCEPT_METADATA_TUPLE = 'tuple(bytes32 subgraphDeploymentId, uint8 version, bytes terms)'

const TERMS_V1_TUPLE = 'tuple(uint256 tokensPerSecond, uint256 tokensPerEntityPerSecond)'

// -- Return types --

export interface RecurringCollectionAgreement {
deadline: bigint
endsAt: bigint
payer: string
dataService: string
serviceProvider: string
maxInitialTokens: bigint
maxOngoingTokensPerSecond: bigint
minSecondsPerCollection: bigint
maxSecondsPerCollection: bigint
conditions: bigint
nonce: bigint
metadata: string
}

export interface SignedRCA {
rca: RecurringCollectionAgreement
signature: string
}

export interface AcceptIndexingAgreementMetadata {
subgraphDeploymentId: string
version: bigint
terms: string
}

export interface IndexingAgreementTermsV1 {
tokensPerSecond: bigint
tokensPerEntityPerSecond: bigint
}

// -- Decoders --

export function decodeSignedRCA(data: BytesLike): SignedRCA {
const [decoded] = ethers.AbiCoder.defaultAbiCoder().decode([SIGNED_RCA_TUPLE], data)
return {
rca: {
deadline: decoded.rca.deadline,
endsAt: decoded.rca.endsAt,
payer: decoded.rca.payer,
dataService: decoded.rca.dataService,
serviceProvider: decoded.rca.serviceProvider,
maxInitialTokens: decoded.rca.maxInitialTokens,
maxOngoingTokensPerSecond: decoded.rca.maxOngoingTokensPerSecond,
minSecondsPerCollection: decoded.rca.minSecondsPerCollection,
maxSecondsPerCollection: decoded.rca.maxSecondsPerCollection,
conditions: decoded.rca.conditions,
nonce: decoded.rca.nonce,
metadata: decoded.rca.metadata,
},
signature: decoded.signature,
}
}

export function decodeAcceptIndexingAgreementMetadata(data: BytesLike): AcceptIndexingAgreementMetadata {
const [decoded] = ethers.AbiCoder.defaultAbiCoder().decode([ACCEPT_METADATA_TUPLE], data)
return {
subgraphDeploymentId: decoded.subgraphDeploymentId,
version: decoded.version,
terms: decoded.terms,
}
}

export function decodeIndexingAgreementTermsV1(data: BytesLike): IndexingAgreementTermsV1 {
const [decoded] = ethers.AbiCoder.defaultAbiCoder().decode([TERMS_V1_TUPLE], data)
return {
tokensPerSecond: decoded.tokensPerSecond,
tokensPerEntityPerSecond: decoded.tokensPerEntityPerSecond,
}
}
15 changes: 15 additions & 0 deletions packages/toolshed/src/core/subgraph-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,21 @@ export function encodeCollectQueryFeesData(rav: RAV, signature: string, tokensTo
)
}

export function encodeCollectIndexingFeesData(
agreementId: string,
entities: bigint,
poi: BytesLike,
poiBlockNumber: bigint,
metadata: BytesLike,
maxSlippage: bigint,
) {
const innerData = ethers.AbiCoder.defaultAbiCoder().encode(
['uint256', 'bytes32', 'uint256', 'bytes', 'uint256'],
[entities, poi, poiBlockNumber, metadata, maxSlippage],
)
return ethers.AbiCoder.defaultAbiCoder().encode(['bytes16', 'bytes'], [agreementId, innerData])
}

export function encodeStopServiceData(allocationId: string) {
return ethers.AbiCoder.defaultAbiCoder().encode(['address'], [allocationId])
}
3 changes: 3 additions & 0 deletions packages/toolshed/src/deployments/horizon/contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type {
GraphProxyAdmin,
GraphTallyCollector,
HorizonStaking,
IRecurringCollector,
L2Curation,
L2GNS,
L2GraphToken,
Expand Down Expand Up @@ -36,6 +37,7 @@ export const GraphHorizonContractNameList = [
'GraphPayments',
'PaymentsEscrow',
'GraphTallyCollector',
'RecurringCollector',
] as const

export interface GraphHorizonContracts extends ContractList<GraphHorizonContractName> {
Expand All @@ -56,6 +58,7 @@ export interface GraphHorizonContracts extends ContractList<GraphHorizonContract
GraphPayments: GraphPayments
PaymentsEscrow: PaymentsEscrow
GraphTallyCollector: GraphTallyCollector
RecurringCollector: IRecurringCollector

// Aliases
GraphToken: L2GraphToken
Expand Down
Loading
Loading