Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move Compute Provider validation and coordination to the E3Program contract #45

Merged
merged 1 commit into from
Sep 16, 2024
Merged
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
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
Loading