Skip to content

Commit

Permalink
chore: merge horizon branch
Browse files Browse the repository at this point in the history
  • Loading branch information
Maikol committed May 20, 2024
2 parents c052943 + 7aa3798 commit 65157fb
Show file tree
Hide file tree
Showing 89 changed files with 5,350 additions and 1,586 deletions.
30 changes: 30 additions & 0 deletions .github/workflows/ci-subgraph-service.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: CI - packages/subgraph-service

env:
CI: true

on:
push:
branches: "*"
paths:
- packages/subgraph-service/**
pull_request:
branches: "*"
paths:
- packages/subgraph-service/**
workflow_dispatch:

jobs:
test-ci:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
- name: Set up environment
uses: ./.github/actions/setup
- name: Run tests
run: |
pushd packages/subgraph-service
yarn test
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "packages/subgraph-service/lib/forge-std"]
path = packages/subgraph-service/lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "packages/horizon/lib/forge-std"]
path = packages/horizon/lib/forge-std
url = https://github.com/foundry-rs/forge-std
5 changes: 5 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ pushd packages/contracts
npx --no-install lint-staged
popd

# subgraph service
pushd packages/subgraph-service
npx --no-install lint-staged
popd

# data-edge
pushd packages/data-edge
npx --no-install lint-staged
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ This repository is a Yarn workspaces monorepo containing the following packages:
| [eslint-graph-config](./packages/eslint-graph-config) | [![npm version]()]() | Shared linting and formatting rules for TypeScript projects. |
| [horizon](./packages/horizon) | [![npm version]()]() | Contracts for Graph Horizon, the next iteration of The Graph protocol. |
| [sdk](./packages/sdk) | [![npm version](https://badge.fury.io/js/@graphprotocol%2Fsdk.svg)](https://badge.fury.io/js/@graphprotocol%2Fsdk) | TypeScript based SDK to interact with the protocol contracts |
| [solhint-graph-config](./packages/eslint-graph-config) | [![npm version]()]() | Shared linting and formatting rules for Solidity projects. |
| [solhint-graph-config](./packages/solhint-graph-config) | [![npm version]()]() | Shared linting and formatting rules for Solidity projects. |
| [solhint-plugin-graph](./packages/solhint-plugin-graph) | [![npm version]()]() | Plugin for Solhint with specific Graph linting rules. |
| [subgraph-service](./packages/subgraph-service) | [![npm version]()]() | Contracts for the Subgraph data service in Graph Horizon. |
| [token-distribution](./packages/token-distribution) | - | Contracts managing token locks for network participants |


Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
"packages/horizon",
"packages/sdk",
"packages/solhint-graph-config",
"packages/solhint-plugin-graph",
"packages/subgraph-service",
"packages/token-distribution"
],
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/contracts/contracts/governance/Controller.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity >=0.6.12 <0.9.0;
pragma solidity >=0.7.6 <0.9.0;

import { IController } from "./IController.sol";
import { IManaged } from "./IManaged.sol";
Expand Down
2 changes: 1 addition & 1 deletion packages/contracts/contracts/governance/Governed.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity >=0.6.12 <0.9.0;
pragma solidity >=0.7.6 <0.9.0;

/**
* @title Graph Governance contract
Expand Down
2 changes: 1 addition & 1 deletion packages/contracts/contracts/governance/Pausable.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity >=0.6.12 <0.9.0;
pragma solidity >=0.7.6 <0.9.0;

abstract contract Pausable {
/**
Expand Down
166 changes: 166 additions & 0 deletions packages/contracts/contracts/staking/IHorizonStaking.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity >=0.7.6 <0.9.0;
pragma abicoder v2;

interface Test {
function test() external returns (uint256);
}

interface IHorizonStaking {
struct Provision {
// Service provider that created the provision
address serviceProvider;
// tokens in the provision
uint256 tokens;
// delegated tokens in the provision
uint256 delegatedTokens;
// tokens that are being thawed (and will stop being slashable soon)
uint256 tokensThawing;
// timestamp of provision creation
uint64 createdAt;
// authority to slash the provision
address verifier;
// max amount that can be taken by the verifier when slashing, expressed in parts-per-million of the amount slashed
uint32 maxVerifierCut;
// time, in seconds, tokens must thaw before being withdrawn
uint64 thawingPeriod;
}

// the new "Indexer" struct
struct ServiceProviderInternal {
// Tokens on the Service Provider stake (staked by the provider)
uint256 tokensStaked;
// Tokens used in allocations
uint256 __DEPRECATED_tokensAllocated;
// Tokens locked for withdrawal subject to thawing period
uint256 __DEPRECATED_tokensLocked;
// Block when locked tokens can be withdrawn
uint256 __DEPRECATED_tokensLockedUntil;
// tokens used in a provision
uint256 tokensProvisioned;
// tokens that initiated a thawing in any one of the provider's provisions
uint256 tokensRequestedThaw;
// tokens that have been removed from any one of the provider's provisions after thawing
uint256 tokensFulfilledThaw;
// provisions that take priority for undelegation force thawing
bytes32[] forceThawProvisions;
}

struct ServiceProvider {
// Tokens on the provider stake (staked by the provider)
uint256 tokensStaked;
// tokens used in a provision
uint256 tokensProvisioned;
// tokens that initiated a thawing in any one of the provider's provisions
uint256 tokensRequestedThaw;
// tokens that have been removed from any one of the provider's provisions after thawing
uint256 tokensFulfilledThaw;
// provisions that take priority for undelegation force thawing
bytes32[] forceThawProvisions;
}

struct DelegationPool {
uint32 __DEPRECATED_cooldownBlocks; // solhint-disable-line var-name-mixedcase
uint32 __DEPRECATED_indexingRewardCut; // in PPM
uint32 __DEPRECATED_queryFeeCut; // in PPM
uint256 __DEPRECATED_updatedAtBlock; // Block when the pool was last updated
uint256 tokens; // Total tokens as pool reserves
uint256 shares; // Total shares minted in the pool
mapping(address => Delegation) delegators; // Mapping of delegator => Delegation
}

struct Delegation {
// shares owned by the delegator in the pool
uint256 shares;
// tokens delegated to the pool
uint256 tokens;
// Timestamp when locked tokens can be undelegated (after the timelock)
uint256 tokensLockedUntil;
}

struct ThawRequest {
// tokens that are being thawed by this request
uint256 tokens;
// the provision id to which this request corresponds to
bytes32 provisionId;
// the address that initiated the thaw request, allowed to remove the funds once thawed
address owner;
// the timestamp when the thawed funds can be removed from the provision
uint64 thawingUntil;
// the value of `ServiceProvider.tokensRequestedThaw` the moment the thaw request is created
uint256 tokensRequestedThawSnapshot;
}

// whitelist/deny a verifier
function allowVerifier(address verifier, bool allow) external;

// deposit stake
function stake(uint256 tokens) external;

// create a provision
function provision(uint256 tokens, address verifier, uint32 maxVerifierCut, uint64 thawingPeriod) external;

// accept a provision
function acceptProvision(address serviceProvider) external;

// initiate a thawing to remove tokens from a provision
function thaw(bytes32 provisionId, uint256 tokens) external returns (bytes32 thawRequestId);

// moves thawed stake from a provision back into the provider's available stake
function deprovision(bytes32 thawRequestId) external;

// moves thawed stake from one provision into another provision
function reprovision(bytes32 thawRequestId, bytes32 provisionId) external;

// moves thawed stake back to the owner's account - stake is removed from the protocol
function withdraw(bytes32 thawRequestId) external;

// delegate tokens to a provider
function delegate(address serviceProvider, uint256 tokens) external;

// undelegate tokens
function undelegate(
address serviceProvider,
uint256 tokens,
bytes32[] calldata provisions
) external returns (bytes32 thawRequestId);

// slash a service provider
function slash(address serviceProvider, uint256 tokens, uint256 reward, address rewardsDestination) external;

// set the Service Provider's preferred provisions to be force thawed
function setForceThawProvisions(bytes32[] calldata provisions) external;

// total staked tokens to the provider
// `ServiceProvider.tokensStaked + DelegationPool.serviceProvider.tokens`
function getStake(address serviceProvider) external view returns (uint256 tokens);

// staked tokens that are currently not provisioned, aka idle stake
// `getStake(serviceProvider) - ServiceProvider.tokensProvisioned`
function getIdleStake(address serviceProvider) external view returns (uint256 tokens);

// staked tokens the provider can provision before hitting the delegation cap
// `ServiceProvider.tokensStaked * Staking.delegationRatio - Provision.tokensProvisioned`
function getCapacity(address serviceProvider) external view returns (uint256 tokens);

// provisioned tokens that are not being used
// `Provision.tokens - Provision.tokensThawing`
function getTokensAvailable(address serviceProvider, address verifier) external view returns (uint256 tokens);

function getServiceProvider(address serviceProvider) external view returns (ServiceProvider memory);

function getProvision(address serviceProvider, address verifier) external view returns (Provision memory);

/**
* @notice Check if an operator is authorized for the caller on a specific verifier / data service.
* @param _operator The address to check for auth
* @param _serviceProvider The service provider on behalf of whom they're claiming to act
* @param _verifier The verifier / data service on which they're claiming to act
*/
function isAuthorized(address _operator, address _serviceProvider, address _verifier) external view returns (bool);

function getDelegationCut(address serviceProvider, uint8 paymentType) external view returns (uint256 delegationCut);
function addToDelegationPool(address serviceProvider, uint256 tokens) external;
function stakeToProvision(address _serviceProvider, address _verifier, uint256 _tokens) external;
}
2 changes: 1 addition & 1 deletion packages/contracts/contracts/utils/TokenUtils.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity ^0.7.6;
pragma solidity >=0.7.6 <=0.8.24;

import "../token/IGraphToken.sol";

Expand Down
39 changes: 39 additions & 0 deletions packages/horizon/contracts/data-service/DataService.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.24;

import { IDataService } from "../interfaces/IDataService.sol";

import { DataServiceV1Storage } from "./DataServiceStorage.sol";
import { GraphDirectory } from "./GraphDirectory.sol";
import { ProvisionManager } from "./utilities/ProvisionManager.sol";

/**
* @title Implementation of the {IDataService} interface.
* @dev This implementation provides base functionality for a data service:
* - GraphDirectory, allows the data service to interact with Graph Horizon contracts
* - ProvisionManager, provides functionality to manage provisions
*
* The derived contract should add functionality that implements the interfaces described in {IDataService}.
*/
abstract contract DataService is GraphDirectory, ProvisionManager, DataServiceV1Storage, IDataService {
/**
* @dev Addresses in GraphDirectory are immutables, they can only be set in this constructor.
* @param controller The address of the Graph Horizon controller contract.
*/
constructor(address controller) GraphDirectory(controller) {}

/**
* @notice Verifies and accepts the provision of a service provider in the {Graph Horizon staking
* contract}.
* @dev This internal function is a wrapper around {ProvisionManager-checkAndAcceptProvision}
* that ensures the event {ProvisionAccepted} is emitted when called from different contexts.
*
* Emits a {ProvisionAccepted} event.
*
* @param _serviceProvider The address of the service provider.
*/
function _acceptProvision(address _serviceProvider) internal {
_checkAndAcceptProvision(_serviceProvider);
emit ProvisionAccepted(_serviceProvider);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.24;

abstract contract DataServiceV1Storage {
/// @dev Gap to allow adding variables in future upgrades
uint256[50] private __gap;
}
55 changes: 55 additions & 0 deletions packages/horizon/contracts/data-service/GraphDirectory.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity 0.8.24;

import { IController } from "@graphprotocol/contracts/contracts/governance/IController.sol";
import { IHorizonStaking } from "../interfaces/IHorizonStaking.sol";
import { IGraphToken } from "@graphprotocol/contracts/contracts/token/IGraphToken.sol";
// import { IGraphTokenGateway } from "@graphprotocol/contracts/contracts/gateway/IGraphTokenGateway.sol";
import { IEpochManager } from "@graphprotocol/contracts/contracts/epochs/IEpochManager.sol";
import { IRewardsManager } from "@graphprotocol/contracts/contracts/rewards/IRewardsManager.sol";
import { IGraphEscrow } from "../interfaces/IGraphEscrow.sol";
import { IGraphPayments } from "../interfaces/IGraphPayments.sol";

abstract contract GraphDirectory {
IController public immutable GRAPH_CONTROLLER;
IHorizonStaking public immutable GRAPH_STAKING;
IEpochManager public immutable GRAPH_EPOCH_MANAGER;
IGraphToken public immutable GRAPH_TOKEN;
// IGraphTokenGateway public immutable graphTokenGateway;
IGraphEscrow public immutable GRAPH_ESCROW;
IGraphPayments public immutable GRAPH_PAYMENTS;
IRewardsManager public immutable GRAPH_REWARDS_MANAGER;

event GraphDirectoryInitialized(
IController graphController,
IHorizonStaking graphStaking,
IEpochManager graphEpochManager,
IGraphToken graphToken,
// address graphTokenGateway,
IGraphEscrow graphEscrow,
IGraphPayments graphPayments,
IRewardsManager graphRewardsManager
);

constructor(address controller) {
GRAPH_CONTROLLER = IController(controller);
GRAPH_STAKING = IHorizonStaking(GRAPH_CONTROLLER.getContractProxy(keccak256("Staking")));
GRAPH_EPOCH_MANAGER = IEpochManager(GRAPH_CONTROLLER.getContractProxy(keccak256("EpochManager")));
GRAPH_TOKEN = IGraphToken(GRAPH_CONTROLLER.getContractProxy(keccak256("GraphToken")));
// graphTokenGateway = graphController.getContractProxy(keccak256("GraphTokenGateway"));
GRAPH_ESCROW = IGraphEscrow(GRAPH_CONTROLLER.getContractProxy(keccak256("GraphEscrow")));
GRAPH_PAYMENTS = IGraphPayments(GRAPH_CONTROLLER.getContractProxy(keccak256("GraphPayments")));
GRAPH_REWARDS_MANAGER = IRewardsManager(GRAPH_CONTROLLER.getContractProxy(keccak256("RewardsManager")));
emit GraphDirectoryInitialized(
GRAPH_CONTROLLER,
GRAPH_STAKING,
GRAPH_EPOCH_MANAGER,
GRAPH_TOKEN,
// graphTokenGateway,
GRAPH_ESCROW,
GRAPH_PAYMENTS,
GRAPH_REWARDS_MANAGER
);
}
}

0 comments on commit 65157fb

Please sign in to comment.