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
112 changes: 54 additions & 58 deletions contracts/contracts/coordination/Coordinator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ contract Coordinator is Initializable, AccessControlDefaultAdminRulesUpgradeable

// DKG Protocol
event StartRitual(uint32 indexed ritualId, address indexed authority, address[] participants);
event ImportRitual(uint32 indexed ritualId);
event StartAggregationRound(uint32 indexed ritualId);
event EndRitual(uint32 indexed ritualId, bool successful);
event TranscriptPosted(uint32 indexed ritualId, address indexed node, bytes32 transcriptDigest);
Expand Down Expand Up @@ -98,21 +99,15 @@ contract Coordinator is Initializable, AccessControlDefaultAdminRulesUpgradeable
ITACoChildApplication public immutable application;
uint96 private immutable minAuthorization; // TODO use child app for checking eligibility

Ritual[] internal ritualsStub; // former rituals, "internal" for testing only
uint32 public timeout;
uint16 public maxDkgSize;
bool private stub1; // former isInitiationPublic

uint256 private stub2; // former totalPendingFees
mapping(uint256 => uint256) private stub3; // former pendingFees
address private stub4; // former feeModel

IReimbursementPool internal reimbursementPool;
mapping(address => ParticipantKey[]) internal participantKeysHistory;
mapping(bytes32 => uint32) internal ritualPublicKeyRegistry;
mapping(IFeeModel => bool) public feeModelsRegistry;

mapping(uint256 index => Ritual ritual) internal _rituals;
mapping(uint256 index => Ritual ritual) public rituals;
uint256 public numberOfRituals;
// Note: Adjust the __preSentinelGap size if more contract variables are added

Expand All @@ -136,64 +131,15 @@ contract Coordinator is Initializable, AccessControlDefaultAdminRulesUpgradeable
__AccessControlDefaultAdminRules_init(0, _admin);
}

/// @dev use `upgradeAndCall` for upgrading together with re-initialization
function initializeNumberOfRituals() external reinitializer(2) {
if (numberOfRituals == 0) {
numberOfRituals = ritualsStub.length;
}
}

/// @dev use `upgradeAndCall` for upgrading together with re-initialization
function reinitializeDefaultAdmin(address newDefaultAdmin) external reinitializer(3) {
_beginDefaultAdminTransfer(newDefaultAdmin);
}

function rituals(
uint256 ritualId // uint256 for backward compatibility
)
external
view
returns (
address initiator,
uint32 initTimestamp,
uint32 endTimestamp,
uint16 totalTranscripts,
uint16 totalAggregations,
//
address authority,
uint16 dkgSize,
uint16 threshold,
bool aggregationMismatch,
//
IEncryptionAuthorizer accessController,
BLS12381.G1Point memory publicKey,
bytes memory aggregatedTranscript,
IFeeModel feeModel
)
{
Ritual storage ritual = storageRitual(uint32(ritualId));
initiator = ritual.initiator;
initTimestamp = ritual.initTimestamp;
endTimestamp = ritual.endTimestamp;
totalTranscripts = ritual.totalTranscripts;
totalAggregations = ritual.totalAggregations;
authority = ritual.authority;
dkgSize = ritual.dkgSize;
threshold = ritual.threshold;
aggregationMismatch = ritual.aggregationMismatch;
accessController = ritual.accessController;
publicKey = ritual.publicKey;
aggregatedTranscript = ritual.aggregatedTranscript;
feeModel = ritual.feeModel;
}

// for backward compatibility
function storageRitual(uint32 ritualId) internal view returns (Ritual storage) {
if (ritualId < ritualsStub.length) {
return ritualsStub[ritualId];
}
require(ritualId < numberOfRituals, "Ritual id out of bounds");
return _rituals[ritualId];
return rituals[ritualId];
}

function getInitiator(uint32 ritualId) external view returns (address) {
Expand Down Expand Up @@ -359,7 +305,7 @@ contract Coordinator is Initializable, AccessControlDefaultAdminRulesUpgradeable
require(duration >= 24 hours, "Invalid ritual duration"); // TODO: Define minimum duration #106

uint32 id = uint32(numberOfRituals);
Ritual storage ritual = _rituals[id];
Ritual storage ritual = rituals[id];
numberOfRituals += 1;
ritual.initiator = msg.sender;
ritual.authority = authority;
Expand Down Expand Up @@ -395,6 +341,56 @@ contract Coordinator is Initializable, AccessControlDefaultAdminRulesUpgradeable
return id;
}

function importRitual(
uint32 ritualId,
address initiator,
uint32 initTimestamp,
uint32 endTimestamp,
uint16 totalTranscripts,
uint16 totalAggregations,
//
address authority,
uint16 dkgSize,
// uint16 threshold,
// bool aggregationMismatch,
//
// IEncryptionAuthorizer accessController,
BLS12381.G1Point memory publicKey,
bytes memory aggregatedTranscript,
//IFeeModel feeModel,
Participant[] calldata participant
) external onlyRole(DEFAULT_ADMIN_ROLE) {
require(ritualId == numberOfRituals, "Ritual id out of bounds");

Ritual storage ritual = rituals[numberOfRituals];
numberOfRituals += 1;
ritual.initiator = initiator;
ritual.initTimestamp = initTimestamp;
ritual.endTimestamp = endTimestamp;
ritual.totalTranscripts = totalTranscripts;
ritual.totalAggregations = totalAggregations;
ritual.authority = authority;
ritual.dkgSize = dkgSize;
// ritual.threshold = threshold;
// ritual.aggregationMismatch = aggregationMismatch;
// ritual.accessController = accessController;
ritual.publicKey = publicKey;
ritual.aggregatedTranscript = aggregatedTranscript;
// ritual.feeModel = feeModel;

for (uint256 i = 0; i < participant.length; i++) {
Participant storage newParticipant = ritual.participant.push();
Participant calldata current = participant[i];
newParticipant.provider = current.provider;
newParticipant.aggregated = current.aggregated;
newParticipant.transcript = current.transcript;
newParticipant.decryptionRequestStaticKey = current.decryptionRequestStaticKey;
}
bytes32 registryKey = keccak256(abi.encodePacked(BLS12381.g1PointToBytes(publicKey)));
ritualPublicKeyRegistry[registryKey] = ritualId + 1;
emit ImportRitual(ritualId);
}

function cohortFingerprint(address[] calldata nodes) public pure returns (bytes32) {
return keccak256(abi.encode(nodes));
}
Expand Down
34 changes: 0 additions & 34 deletions contracts/test/CoordinatorTestSet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,37 +34,3 @@ contract ChildApplicationForCoordinatorMock is ITACoChildApplication {
// solhint-disable-next-line no-empty-blocks
function penalize(address _stakingProvider) external {}
}

contract ExtendedCoordinator is Coordinator {
constructor(ITACoChildApplication _application) Coordinator(_application) {}

function initiateOldRitual(
IFeeModel feeModel,
address[] calldata providers,
address authority,
uint32 duration,
IEncryptionAuthorizer accessController
) external returns (uint32) {
uint16 length = uint16(providers.length);

uint32 id = uint32(ritualsStub.length);
Ritual storage ritual = ritualsStub.push();
ritual.initiator = msg.sender;
ritual.authority = authority;
ritual.dkgSize = length;
ritual.threshold = getThresholdForRitualSize(length);
ritual.initTimestamp = uint32(block.timestamp);
ritual.endTimestamp = ritual.initTimestamp + duration;
ritual.accessController = accessController;
ritual.feeModel = feeModel;

address previous = address(0);
for (uint256 i = 0; i < length; i++) {
Participant storage newParticipant = ritual.participant.push();
address current = providers[i];
newParticipant.provider = current;
previous = current;
}
return id;
}
}
103 changes: 103 additions & 0 deletions scripts/export_ritual.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#!/usr/bin/python3

import click
from ape import networks
from ape.cli import ConnectedProviderCommand, account_option

from deployment import registry
from deployment.constants import ACCESS_CONTROLLERS, SUPPORTED_TACO_DOMAINS
from deployment.params import Transactor
from deployment.types import ChecksumAddress
from deployment.utils import check_plugins


@click.command(cls=ConnectedProviderCommand, name="export-rituals")
@account_option()
# @network_option(required=True)
@click.option(
"--domain-from",
"-df",
help="From TACo domain",
type=click.Choice(SUPPORTED_TACO_DOMAINS),
required=True,
)
@click.option(
"--domain-to",
"-dt",
help="To TACo domain",
type=click.Choice(SUPPORTED_TACO_DOMAINS),
required=True,
)
@click.option(
"--access-controller",
"-c",
help="The registry name of an access controller contract.",
type=click.Choice(ACCESS_CONTROLLERS),
required=True,
)
@click.option(
"--fee-model",
"-f",
help="The address of the fee model/subscription contract.",
type=ChecksumAddress(),
required=True,
)
@click.option("--ritual-id", "-r", help="Ritual ID to check", type=int, required=True)
def cli(
domain_from,
domain_to,
account,
# network,
access_controller,
fee_model,
ritual_id,
):
"""Export a ritual between TACo domains."""

# Setup
check_plugins()
# click.echo(f"Connected to {network.name} network.")

# Get the contracts from the registry
ritual = None
participants = None
with networks.polygon.mainnet.use_provider("infura"):
coordinator_contract_from = registry.get_contract(
domain=domain_from, contract_name="Coordinator"
)
ritual = coordinator_contract_from.rituals(ritual_id)
participants = coordinator_contract_from.getParticipants(ritual_id)

with networks.polygon.sepolia.use_provider("infura"):
coordinator_contract_to = registry.get_contract(
domain=domain_to, contract_name="Coordinator"
)
# access_controller_contract = registry.get_contract(
# domain=domain_to, contract_name=access_controller
# )
# fee_model_contract = Contract(fee_model)

# Initiate the ritual
transactor = Transactor(account=account)
transactor.transact(
coordinator_contract_to.importRitual,
ritual_id,
ritual.initiator,
ritual.initTimestamp,
ritual.endTimestamp,
ritual.totalTranscripts,
ritual.totalAggregations,
ritual.authority,
ritual.dkgSize,
# ritual.threshold,
# ritual.aggregationMismatch,
# access_controller_contract.address,
ritual.publicKey,
ritual.aggregatedTranscript,
# fee_model_contract.address,
participants,
)


if __name__ == "__main__":
cli()
Loading
Loading