Skip to content

Commit

Permalink
Merge pull request #45 from gnosisguild:couple-e3ps-with-compute-prov…
Browse files Browse the repository at this point in the history
…iders

Move Compute Provider validation and coordination to the E3Program contract
  • Loading branch information
auryn-macmillan authored Sep 16, 2024
2 parents f4ec8a6 + 9e13cac commit 448f0fc
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 253 deletions.
83 changes: 18 additions & 65 deletions packages/evm/contracts/Enclave.sol
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.8.27;

import {
IEnclave,
E3,
IE3Program,
IComputeProvider
} from "./interfaces/IEnclave.sol";
import { IEnclave, E3, IE3Program } from "./interfaces/IEnclave.sol";
import { ICiphernodeRegistry } from "./interfaces/ICiphernodeRegistry.sol";
import { IInputValidator } from "./interfaces/IInputValidator.sol";
import { IDecryptionVerifier } from "./interfaces/IDecryptionVerifier.sol";
Expand All @@ -33,19 +28,9 @@ contract Enclave is IEnclave, OwnableUpgradeable {
uint256 public nexte3Id; // ID of the next E3.
uint256 public requests; // total number of requests made to Enclave.

// TODO: should computation and compute providers be explicitly allowed?
// My intuition is that an allowlist is required since they impose slashing conditions.
// But perhaps this is one place where node pools might be utilized, allowing nodes to
// opt in to being selected for specific computations, along with the corresponding slashing conditions.
// This would reduce the governance overhead for Enclave.

// Mapping of allowed E3 Programs.
mapping(IE3Program e3Program => bool allowed) public e3Programs;

// Mapping of allowed compute providers.
mapping(IComputeProvider computeProvider => bool allowed)
public computeProviders;

// Mapping of E3s.
mapping(uint256 e3Id => E3 e3) public e3s;

Expand All @@ -72,8 +57,10 @@ contract Enclave is IEnclave, OwnableUpgradeable {
error ModuleNotEnabled(address module);
error InputDeadlinePassed(uint256 e3Id, uint256 expiration);
error InputDeadlineNotPassed(uint256 e3Id, uint256 expiration);
error InvalidComputation();
error InvalidComputeProviderSetup();
error InvalidComputationRequest(
IInputValidator inputValidator,
IDecryptionVerifier decryptionVerifier
);
error InvalidCiphernodeRegistry(ICiphernodeRegistry ciphernodeRegistry);
error InvalidInput();
error InvalidDuration(uint256 duration);
Expand Down Expand Up @@ -127,7 +114,6 @@ contract Enclave is IEnclave, OwnableUpgradeable {
uint256 duration,
IE3Program e3Program,
bytes memory e3ProgramParams,
IComputeProvider computeProvider,
bytes memory computeProviderParams
) external payable returns (uint256 e3Id, E3 memory e3) {
// TODO: allow for other payment methods or only native tokens?
Expand All @@ -148,33 +134,25 @@ contract Enclave is IEnclave, OwnableUpgradeable {
InvalidDuration(duration)
);
require(e3Programs[e3Program], E3ProgramNotAllowed(e3Program));
require(
computeProviders[computeProvider],
ModuleNotEnabled(address(computeProvider))
);

// TODO: should IDs be incremental or produced deterministically?
e3Id = nexte3Id;
nexte3Id++;
uint256 seed = uint256(keccak256(abi.encode(block.prevrandao, e3Id)));

IInputValidator inputValidator = e3Program.validate(
e3Id,
seed,
e3ProgramParams
);
require(address(inputValidator) != address(0), InvalidComputation());

// TODO: validate that the requested computation can be performed by the given compute provider.
// Perhaps the compute provider should be returned by the E3 Program?
IDecryptionVerifier decryptionVerifier = computeProvider.validate(
e3Id,
seed,
computeProviderParams
);
(
IInputValidator inputValidator,
IDecryptionVerifier decryptionVerifier
) = e3Program.validate(
e3Id,
seed,
e3ProgramParams,
computeProviderParams
);
require(
address(decryptionVerifier) != address(0),
InvalidComputeProviderSetup()
address(inputValidator) != address(0) &&
address(decryptionVerifier) != address(0),
InvalidComputationRequest(inputValidator, decryptionVerifier)
);

e3 = E3({
Expand All @@ -186,7 +164,6 @@ contract Enclave is IEnclave, OwnableUpgradeable {
e3Program: e3Program,
e3ProgramParams: e3ProgramParams,
inputValidator: inputValidator,
computeProvider: computeProvider,
decryptionVerifier: decryptionVerifier,
committeePublicKey: hex"",
ciphertextOutput: hex"",
Expand All @@ -199,7 +176,7 @@ contract Enclave is IEnclave, OwnableUpgradeable {
CommitteeSelectionFailed()
);

emit E3Requested(e3Id, e3s[e3Id], filter, e3Program, computeProvider);
emit E3Requested(e3Id, e3s[e3Id], filter, e3Program);
}

function activate(uint256 e3Id) external returns (bool success) {
Expand Down Expand Up @@ -336,18 +313,6 @@ contract Enclave is IEnclave, OwnableUpgradeable {
emit E3ProgramEnabled(e3Program);
}

function enableComputeProvider(
IComputeProvider computeProvider
) public onlyOwner returns (bool success) {
require(
!computeProviders[computeProvider],
ModuleAlreadyEnabled(address(computeProvider))
);
computeProviders[computeProvider] = true;
success = true;
emit ComputeProviderEnabled(computeProvider);
}

function disableE3Program(
IE3Program e3Program
) public onlyOwner returns (bool success) {
Expand All @@ -357,18 +322,6 @@ contract Enclave is IEnclave, OwnableUpgradeable {
emit E3ProgramDisabled(e3Program);
}

function disableComputeProvider(
IComputeProvider computeProvider
) public onlyOwner returns (bool success) {
require(
computeProviders[computeProvider],
ModuleNotEnabled(address(computeProvider))
);
delete computeProviders[computeProvider];
success = true;
emit ComputeProviderDisabled(computeProvider);
}

////////////////////////////////////////////////////////////
// //
// Get Functions //
Expand Down
1 change: 0 additions & 1 deletion packages/evm/contracts/interfaces/IE3.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ struct E3 {
IE3Program e3Program;
bytes e3ProgramParams;
IInputValidator inputValidator;
IComputeProvider computeProvider;
IDecryptionVerifier decryptionVerifier;
bytes committeePublicKey;
bytes ciphertextOutput;
Expand Down
15 changes: 12 additions & 3 deletions packages/evm/contracts/interfaces/IE3Program.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,27 @@
pragma solidity >=0.8.27;

import { IInputValidator } from "./IInputValidator.sol";
import { IDecryptionVerifier } from "./IDecryptionVerifier.sol";

interface IE3Program {
/// @notice This function should be called by the Enclave contract to validate the computation parameters.
/// @param e3Id ID of the E3.
/// @param seed Seed for the computation.
/// @param params ABI encoded computation parameters.
/// @param e3ProgramParams ABI encoded computation parameters.
/// @param computeProviderParams ABI encoded compute provider parameters.
/// @return inputValidator The input validator to be used for the computation.
/// @return decryptionVerifier The decryption verifier to be used for the computation.
function validate(
uint256 e3Id,
uint256 seed,
bytes calldata params
) external returns (IInputValidator inputValidator);
bytes calldata e3ProgramParams,
bytes calldata computeProviderParams
)
external
returns (
IInputValidator inputValidator,
IDecryptionVerifier decryptionVerifier
);

/// @notice This function should be called by the Enclave contract to verify the decrypted output of an E3.
/// @param e3Id ID of the E3.
Expand Down
16 changes: 2 additions & 14 deletions packages/evm/contracts/interfaces/IEnclave.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.8.27;

import { E3, IE3Program, IComputeProvider } from "./IE3.sol";
import { E3, IE3Program } from "./IE3.sol";

interface IEnclave {
////////////////////////////////////////////////////////////
Expand All @@ -15,13 +15,11 @@ interface IEnclave {
/// @param e3 Details of the E3.
/// @param filter Address of the pool of nodes from which the Cipher Node committee was selected.
/// @param e3Program Address of the Computation module selected.
/// @param computeProvider Address of the compute provider selected.
event E3Requested(
uint256 e3Id,
E3 e3,
address filter,
IE3Program indexed e3Program,
IComputeProvider indexed computeProvider
IE3Program indexed e3Program
);

/// @notice This event MUST be emitted when an Encrypted Execution Environment (E3) is successfully activated.
Expand Down Expand Up @@ -76,14 +74,6 @@ interface IEnclave {
/// @param e3Program The address of the E3 Program.
event E3ProgramDisabled(IE3Program e3Program);

/// @notice This event MUST be emitted any time an compute provider is enabled.
/// @param computeProvider The address of the compute provider.
event ComputeProviderEnabled(IComputeProvider computeProvider);

/// @notice This event MUST be emitted any time an compute provider is disabled.
/// @param computeProvider The address of the compute provider.
event ComputeProviderDisabled(IComputeProvider computeProvider);

////////////////////////////////////////////////////////////
// //
// Core Entrypoints //
Expand All @@ -97,7 +87,6 @@ interface IEnclave {
/// @param duration The duration of the computation in seconds.
/// @param e3Program Address of the E3 Program.
/// @param e3ProgramParams ABI encoded computation parameters.
/// @param computeProvider Address of the compute provider.
/// @param computeProviderParams ABI encoded compute provider parameters.
/// @return e3Id ID of the E3.
/// @return e3 The E3 struct.
Expand All @@ -108,7 +97,6 @@ interface IEnclave {
uint256 duration,
IE3Program e3Program,
bytes memory e3ProgramParams,
IComputeProvider computeProvider,
bytes memory computeProviderParams
) external payable returns (uint256 e3Id, E3 memory e3);

Expand Down
28 changes: 22 additions & 6 deletions packages/evm/contracts/test/MockE3Program.sol
Original file line number Diff line number Diff line change
@@ -1,20 +1,36 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.8.27;

import { IE3Program, IInputValidator } from "../interfaces/IE3Program.sol";
import {
IE3Program,
IInputValidator,
IDecryptionVerifier
} from "../interfaces/IE3Program.sol";

contract MockE3Program is IE3Program {
error invalidParams(bytes params);
error invalidParams(bytes e3ProgramParams, bytes computeProviderParams);

function validate(
uint256,
uint256,
bytes memory params
) external pure returns (IInputValidator inputValidator) {
require(params.length == 32, "invalid params");
bytes memory e3ProgramParams,
bytes memory computeProviderParams
)
external
pure
returns (
IInputValidator inputValidator,
IDecryptionVerifier decryptionVerifier
)
{
require(
e3ProgramParams.length == 32 && computeProviderParams.length == 32,
invalidParams(e3ProgramParams, computeProviderParams)
);
// solhint-disable no-inline-assembly
assembly {
inputValidator := mload(add(params, 32))
inputValidator := mload(add(e3ProgramParams, 32))
decryptionVerifier := mload(add(computeProviderParams, 32))
}
}

Expand Down
Loading

0 comments on commit 448f0fc

Please sign in to comment.