Skip to content

Commit d3aab1a

Browse files
committed
feat(gateway-contracts): implement coprocessor contexts
chore(gateway-contracts): start updating tests chore(gateway-contracts): add and improve tests from regular contracts chore(gateway-contracts): finish tests
1 parent 76af33e commit d3aab1a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+33633
-6240
lines changed

gateway-contracts/.env.example

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,21 +51,27 @@ KMS_TX_SENDER_ADDRESS_3="0xc45994e4098271c3140117ebD5c74C70dd56D9cd" # accounts[
5151
KMS_SIGNER_ADDRESS_3="0xDb216ECeC4cEd51CdfD9609b6Ce7653aB04f6cAd" # accounts[10] (address)
5252
KMS_NODE_IP_ADDRESS_3="127.0.0.4" # (string)
5353

54+
# Coprocessor feature set
55+
COPROCESSORS_FEATURE_SET="1" # (uint256)
56+
5457
# Coprocessors
5558
# The number of coprocessors must be lower or equal to the number of coprocessors' metadata defined below
5659
NUM_COPROCESSORS="3" # (number)
5760

5861
# Coprocessor 1
62+
COPROCESSOR_NAME_0="Coprocessor 1" # (string)
5963
COPROCESSOR_TX_SENDER_ADDRESS_0="0x6518D50aDc9036Df37119eA465a8159E34417E2E" # accounts[11] (address)
6064
COPROCESSOR_SIGNER_ADDRESS_0="0xa5eE8292dA52d8234248709F3E217ffEBA5E8312" # accounts[12] (address)
6165
COPROCESSOR_S3_BUCKET_URL_0="s3://bucket-1" # (string)
6266

6367
# Coprocessor 2
68+
COPROCESSOR_NAME_1="Coprocessor 2" # (string)
6469
COPROCESSOR_TX_SENDER_ADDRESS_1="0xCFbF539CB91c92ace0343c5B0487149Ad0b82078" # accounts[13] (address)
6570
COPROCESSOR_SIGNER_ADDRESS_1="0xA951F315d5FD35Cac111dFB5250DF231FB8eF905" # accounts[14] (address)
6671
COPROCESSOR_S3_BUCKET_URL_1="s3://bucket-2" # (string)
6772

6873
# Coprocessor 3
74+
COPROCESSOR_NAME_2="Coprocessor 3" # (string)
6975
COPROCESSOR_TX_SENDER_ADDRESS_2="0x3C0033584da3A0f61AA5C7bde50eAF3642875a21" # accounts[15] (address)
7076
COPROCESSOR_SIGNER_ADDRESS_2="0x420AF5A5BBfAd922aE5a501d9a8Bf70a55F52E03" # accounts[16] (address)
7177
COPROCESSOR_S3_BUCKET_URL_2="s3://bucket-3" # (string)

gateway-contracts/contracts/CiphertextCommits.sol

Lines changed: 56 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
// SPDX-License-Identifier: BSD-3-Clause-Clear
22
pragma solidity ^0.8.24;
33
import { gatewayConfigAddress } from "../addresses/GatewayConfigAddress.sol";
4+
import { coprocessorContextsAddress } from "../addresses/CoprocessorContextsAddress.sol";
45
import { kmsManagementAddress } from "../addresses/KmsManagementAddress.sol";
56
import { Ownable2StepUpgradeable } from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol";
67
import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
78
import "./interfaces/ICiphertextCommits.sol";
89
import "./interfaces/IGatewayConfig.sol";
10+
import { ICoprocessorContexts } from "./interfaces/ICoprocessorContexts.sol";
911
import "./interfaces/IKmsManagement.sol";
1012
import "./shared/UUPSUpgradeableEmptyProxy.sol";
1113
import "./shared/GatewayConfigChecks.sol";
1214
import "./shared/Pausable.sol";
1315
import "./libraries/HandleOps.sol";
14-
16+
import { CoprocessorContexts } from "./CoprocessorContexts.sol";
17+
import { ContextChecks } from "./shared/ContextChecks.sol";
1518
/**
1619
* @title CiphertextCommits smart contract
1720
* @dev See {ICiphertextCommits}.
@@ -21,11 +24,15 @@ contract CiphertextCommits is
2124
Ownable2StepUpgradeable,
2225
UUPSUpgradeableEmptyProxy,
2326
GatewayConfigChecks,
24-
Pausable
27+
Pausable,
28+
ContextChecks
2529
{
26-
/// @notice The address of the GatewayConfig contract, used for fetching information about coprocessors.
30+
/// @notice The address of the GatewayConfig contract, used for fetching information about host chains.
2731
IGatewayConfig private constant GATEWAY_CONFIG = IGatewayConfig(gatewayConfigAddress);
2832

33+
/// @notice The address of the CoprocessorContexts contract, used for fetching information about coprocessors.
34+
ICoprocessorContexts private constant COPROCESSOR_CONTEXTS = ICoprocessorContexts(coprocessorContextsAddress);
35+
2936
/// @notice The address of the KmsManagement contract, used for fetching information about the current key.
3037
IKmsManagement private constant KMS_MANAGEMENT = IKmsManagement(kmsManagementAddress);
3138

@@ -59,6 +66,8 @@ contract CiphertextCommits is
5966
_alreadyAddedCoprocessorTxSenders;
6067
/// @notice The mapping of the coprocessor transaction senders that have added the ciphertext.
6168
mapping(bytes32 ctHandle => address[] coprocessorTxSenderAddresses) _coprocessorTxSenderAddresses;
69+
/// @notice The coprocessor context ID associated to the add ciphertext
70+
mapping(bytes32 addCiphertextHash => uint256 contextId) inputVerificationContextId;
6271
}
6372

6473
/// @dev Storage location has been computed using the following command:
@@ -77,27 +86,55 @@ contract CiphertextCommits is
7786
* @dev This function needs to be public in order to be called by the UUPS proxy.
7887
*/
7988
/// @custom:oz-upgrades-validate-as-initializer
80-
function initializeFromEmptyProxy() public virtual onlyFromEmptyProxy reinitializer(2) {
89+
function initializeFromEmptyProxy() public virtual onlyFromEmptyProxy reinitializer(3) {
8190
__Ownable_init(owner());
8291
__Pausable_init();
8392
}
8493

94+
/// @notice Reinitializes the contract.
95+
function reinitializeV2() external reinitializer(3) {}
96+
8597
/// @notice See {ICiphertextCommits-addCiphertextMaterial}.
86-
/// @dev This function calls the GatewayConfig contract to check that the sender address is a Coprocessor.
8798
function addCiphertextMaterial(
8899
bytes32 ctHandle,
89100
uint256 keyId,
90101
bytes32 ciphertextDigest,
91102
bytes32 snsCiphertextDigest
92-
) external virtual onlyCoprocessorTxSender whenNotPaused {
103+
) external virtual whenNotPaused refreshCoprocessorContextStatuses {
93104
/// @dev Extract the chainId from the ciphertext handle
94105
uint256 chainId = HandleOps.extractChainId(ctHandle);
95106

96107
/// @dev Check that the associated host chain is registered
97108
GATEWAY_CONFIG.checkHostChainIsRegistered(chainId);
98109

110+
// Compute the hash of the ciphertext material to differentiate different ciphertext
111+
// material additions
112+
bytes32 addCiphertextHash = keccak256(
113+
abi.encode(ctHandle, chainId, keyId, ciphertextDigest, snsCiphertextDigest)
114+
);
115+
99116
CiphertextCommitsStorage storage $ = _getCiphertextCommitsStorage();
100117

118+
// Get the context ID from the input verification context ID mapping
119+
uint256 contextId = $.inputVerificationContextId[addCiphertextHash];
120+
121+
// If the context ID is not set, get the active coprocessor context's ID and associate it to
122+
// this ciphertext material addition
123+
if (contextId == 0) {
124+
contextId = COPROCESSOR_CONTEXTS.getActiveCoprocessorContextId();
125+
$.inputVerificationContextId[addCiphertextHash] = contextId;
126+
127+
// Else, that means a coprocessor already started to add the ciphertext material
128+
// and we need to check that the context is active or suspended
129+
// If it is not, that means the context is no longer valid for this operation and we revert
130+
} else if (!COPROCESSOR_CONTEXTS.isCoprocessorContextActiveOrSuspended(contextId)) {
131+
ContextStatus contextStatus = COPROCESSOR_CONTEXTS.getCoprocessorContextStatus(contextId);
132+
revert InvalidCoprocessorContextAddCiphertext(ctHandle, contextId, contextStatus);
133+
}
134+
135+
// Only accept coprocessor transaction senders from the same context
136+
COPROCESSOR_CONTEXTS.checkIsCoprocessorTxSenderFromContext(contextId, msg.sender);
137+
101138
/**
102139
* @dev Check if the coprocessor transaction sender has already added the ciphertext handle.
103140
* Note that a coprocessor transaction sender cannot add the same ciphertext material on
@@ -118,20 +155,17 @@ contract CiphertextCommits is
118155
* Coprocessors can only have a consensus on a ciphertext material with the same information.
119156
* This hash is used to track the addition consensus on the received ciphertext material.
120157
*/
121-
bytes32 addCiphertextHash = keccak256(
122-
abi.encode(ctHandle, chainId, keyId, ciphertextDigest, snsCiphertextDigest)
123-
);
124158
$._addCiphertextHashCounters[addCiphertextHash]++;
125159

126160
$._alreadyAddedCoprocessorTxSenders[ctHandle][msg.sender] = true;
127161
$._coprocessorTxSenderAddresses[ctHandle].push(msg.sender);
128162

129-
/// @dev Only send the event if consensus has not been reached in a previous call
130-
/// @dev and the consensus is reached in the current call.
131-
/// @dev This means a "late" addition will not be reverted, just ignored
163+
// Only send the event if consensus has not been reached in a previous call and the consensus
164+
// is reached in the current call. This means a "late" addition will not be reverted, just ignored
165+
// Besides, consensus only considers the coprocessors of the same context
132166
if (
133167
!$._isCiphertextMaterialAdded[ctHandle] &&
134-
_isConsensusReached($._addCiphertextHashCounters[addCiphertextHash])
168+
_isConsensusReached(contextId, $._addCiphertextHashCounters[addCiphertextHash])
135169
) {
136170
$._ciphertextDigests[ctHandle] = ciphertextDigest;
137171
$._snsCiphertextDigests[ctHandle] = snsCiphertextDigest;
@@ -141,6 +175,7 @@ contract CiphertextCommits is
141175

142176
emit AddCiphertextMaterial(
143177
ctHandle,
178+
contextId,
144179
ciphertextDigest,
145180
snsCiphertextDigest,
146181
$._coprocessorTxSenderAddresses[ctHandle]
@@ -220,11 +255,14 @@ contract CiphertextCommits is
220255
// solhint-disable-next-line no-empty-blocks
221256
function _authorizeUpgrade(address _newImplementation) internal virtual override onlyOwner {}
222257

223-
/// @notice Checks if the consensus is reached among the Coprocessors.
224-
/// @param coprocessorCounter The number of coprocessors that agreed
225-
/// @return Whether the consensus is reached
226-
function _isConsensusReached(uint256 coprocessorCounter) internal view virtual returns (bool) {
227-
uint256 consensusThreshold = GATEWAY_CONFIG.getCoprocessorMajorityThreshold();
258+
/**
259+
* @notice Checks if the consensus is reached among the coprocessors from the same context.
260+
* @param contextId The coprocessor context ID
261+
* @param coprocessorCounter The number of coprocessors that agreed
262+
* @return Whether the consensus is reached
263+
*/
264+
function _isConsensusReached(uint256 contextId, uint256 coprocessorCounter) internal view virtual returns (bool) {
265+
uint256 consensusThreshold = COPROCESSOR_CONTEXTS.getCoprocessorMajorityThresholdFromContext(contextId);
228266
return coprocessorCounter >= consensusThreshold;
229267
}
230268

0 commit comments

Comments
 (0)