Skip to content

Commit

Permalink
rename to superBlock and L1Block in settlement sols
Browse files Browse the repository at this point in the history
  • Loading branch information
apenzk committed Feb 11, 2025
1 parent 86e0e06 commit b074f84
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 79 deletions.
126 changes: 63 additions & 63 deletions protocol-units/settlement/mcr/contracts/src/settlement/MCR.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ contract MCR is Initializable, BaseSettlement, MCRStorage, IMCR {

function initialize(
IMovementStaking _stakingContract,
uint256 _lastAcceptedBlockHeight,
uint256 _leadingBlockTolerance,
uint256 _lastAcceptedSuperBlockHeight,
uint256 _leadingSuperBlockTolerance,
uint256 _epochDuration,
address[] memory _custodians
) public initializer {
__BaseSettlement_init_unchained();
stakingContract = _stakingContract;
leadingBlockTolerance = _leadingBlockTolerance;
lastAcceptedBlockHeight = _lastAcceptedBlockHeight;
leadingSuperBlockTolerance = _leadingSuperBlockTolerance;
lastAcceptedSuperBlockHeight = _lastAcceptedSuperBlockHeight;
stakingContract.registerDomain(_epochDuration, _custodians);
grantCommitmentAdmin(msg.sender);
grantTrustedAttester(msg.sender);
Expand Down Expand Up @@ -56,22 +56,22 @@ contract MCR is Initializable, BaseSettlement, MCRStorage, IMCR {
function createSuperBlockCommitment(
uint256 height,
bytes32 commitment,
bytes32 blockId
bytes32 blockID
) public pure returns (SuperBlockCommitment memory) {
return SuperBlockCommitment(height, commitment, blockId);
return SuperBlockCommitment(height, commitment, blockID);
}

// gets the max tolerable block height
function getMaxTolerableBlockHeight() public view returns (uint256) {
return lastAcceptedBlockHeight + leadingBlockTolerance;
// gets the max tolerable superBlock height
function getMaxTolerableSuperBlockHeight() public view returns (uint256) {
return lastAcceptedSuperBlockHeight + leadingSuperBlockTolerance;
}

// gets the would be epoch for the current block time
function getEpochByBlockTime() public view returns (uint256) {
// gets the would be epoch for the current L1Block time
function getEpochByL1BlockTime() public view returns (uint256) {
return stakingContract.getEpochByBlockTime(address(this));
}

// gets the current epoch up to which blocks have been accepted
// gets the current epoch up to which superBlocks have been accepted
function getCurrentEpoch() public view returns (uint256) {
return stakingContract.getCurrentEpoch(address(this));
}
Expand Down Expand Up @@ -176,79 +176,79 @@ contract MCR is Initializable, BaseSettlement, MCRStorage, IMCR {
return computeAllTotalStakeForEpoch(getCurrentEpoch());
}

function getValidatorCommitmentAtBlockHeight(
function getValidatorCommitmentAtSuperBlockHeight(
uint256 height,
address attester
) public view returns (SuperBlockCommitment memory) {
return commitments[height][attester];
}

// Sets the accepted commitment at a give block height
// Sets the accepted commitment at a given superBlock height
function setAcceptedCommitmentAtBlockHeight(SuperBlockCommitment memory superBlockCommitment) public {
require(
hasRole(COMMITMENT_ADMIN, msg.sender),
"SET_LAST_ACCEPTED_COMMITMENT_AT_HEIGHT_IS_COMMITMENT_ADMIN_ONLY"
);
versionedAcceptedBlocks[acceptedBlocksVersion][superBlockCommitment.height] = superBlockCommitment;
versionedAcceptedSuperBlocks[acceptedSuperBlocksVersion][superBlockCommitment.height] = superBlockCommitment;
}

// Sets the last accepted block height.
function setLastAcceptedBlockHeight(uint256 height) public {
// Sets the last accepted superBlock height.
function setlastAcceptedSuperBlockHeight(uint256 height) public {
require(
hasRole(COMMITMENT_ADMIN, msg.sender),
"SET_LAST_ACCEPTED_BLOCK_HEIGHT_IS_COMMITMENT_ADMIN_ONLY"
"SET_LAST_ACCEPTED_SUPERBLOCK_HEIGHT_IS_COMMITMENT_ADMIN_ONLY"
);
lastAcceptedBlockHeight = height;
lastAcceptedSuperBlockHeight = height;
}

// Forces the latest attestation by setting the block height
// Forces the latest attestation by setting the superBlock height
// Note: this only safe when we are running with a single validator as it does not zero out follow-on commitments.
function forceLatestCommitment(SuperBlockCommitment memory superBlockCommitment) public {
/*require(
hasRole(DEFAULT_ADMIN_ROLE, msg.sender),
"FORCE_LATEST_COMMITMENT_IS_COMMITMENT_ADMIN_ONLY"
);*/

// increment the acceptedBlocksVersion (effectively removing all other accepted blocks)
acceptedBlocksVersion += 1;
versionedAcceptedBlocks[acceptedBlocksVersion][superBlockCommitment.height] = superBlockCommitment;
lastAcceptedBlockHeight = superBlockCommitment.height;
// increment the acceptedSuperBlocksVersion (effectively removing all other accepted superBlocks)
acceptedSuperBlocksVersion += 1;
versionedAcceptedSuperBlocks[acceptedSuperBlocksVersion][superBlockCommitment.height] = superBlockCommitment;
lastAcceptedSuperBlockHeight = superBlockCommitment.height;
}

function getAcceptedCommitmentAtBlockHeight(uint256 height) public view returns (SuperBlockCommitment memory) {
return versionedAcceptedBlocks[acceptedBlocksVersion][height];
function getAcceptedCommitmentAtSuperBlockHeight(uint256 height) public view returns (SuperBlockCommitment memory) {
return versionedAcceptedSuperBlocks[acceptedSuperBlocksVersion][height];
}

function getAttesters() public view returns (address[] memory) {
return stakingContract.getAttestersByDomain(address(this));
}

/**
* @dev submits a block commitment for an attester.
* @dev submits a superBlock commitment for an attester.
*/
function submitSuperBlockCommitmentForAttester(
address attester,
SuperBlockCommitment memory superBlockCommitment
) internal {
// Attester has already committed to a block at this height
// Attester has already committed to a superBlock at this height
if (commitments[superBlockCommitment.height][attester].height != 0)
revert AttesterAlreadyCommitted();

// note: do no uncomment the below, we want to allow this in case we have lagging attesters
// Attester has committed to an already accepted block
// if ( lastAcceptedBlockHeight > superBlockCommitment.height) revert AlreadyAcceptedBlock();
// Attester has committed to a block too far ahead of the last accepted block
// Attester has committed to an already accepted superBlock
// if ( lastAcceptedSuperBlockHeight > superBlockCommitment.height) revert AlreadyAcceptedSuperBlock();
// Attester has committed to a superBlock too far ahead of the last accepted superBlock
if (
lastAcceptedBlockHeight + leadingBlockTolerance <
lastAcceptedSuperBlockHeight + leadingSuperBlockTolerance <
superBlockCommitment.height
) revert AttesterAlreadyCommitted();

// assign the block height to the current epoch if it hasn't been assigned yet
// assign the superBlock height to the current epoch if it hasn't been assigned yet
if (superBlockHeightEpochAssignments[superBlockCommitment.height] == 0) {
// note: this is an intended race condition, but it is benign because of the tolerance
superBlockHeightEpochAssignments[
superBlockCommitment.height
] = getEpochByBlockTime();
] = getEpochByL1BlockTime();
}

// register the attester's commitment
Expand All @@ -261,45 +261,45 @@ contract MCR is Initializable, BaseSettlement, MCRStorage, IMCR {
] += allCurrentEpochStake;

emit SuperBlockCommitmentSubmitted(
superBlockCommitment.blockId,
superBlockCommitment.blockID,
superBlockCommitment.commitment,
allCurrentEpochStake
);

// keep ticking through to find accepted blocks
// keep ticking through to find accepted superBlocks
// note: this is what allows for batching to be successful
// we can commit to blocks out to the tolerance point
// we can commit to superBlocks out to the tolerance point
// then we can accept them in order
// ! however, this does potentially become very costly for whomever submits this last block
// ! however, this does potentially become very costly for whomever submits this last superBlock
// ! rewards need to be managed accordingly
while (tickOnBlockHeight(lastAcceptedBlockHeight + 1)) {}
while (tickOnSuperBlockHeight(lastAcceptedSuperBlockHeight + 1)) {}
}

/**
*/
function tickOnBlockHeight(uint256 blockHeight) internal returns (bool) {
// get the epoch assigned to the block height
uint256 blockEpoch = superBlockHeightEpochAssignments[blockHeight];
function tickOnSuperBlockHeight(uint256 superBlockHeight) internal returns (bool) {
// get the epoch assigned to the superBlock height
uint256 superBlockEpoch = superBlockHeightEpochAssignments[superBlockHeight];

// if the current epoch is far behind, that's okay that just means there weren't blocks submitted
// so long as we ensure that we go through the blocks in order and that the block to epoch assignment is non-decreasing, we're good
// if the current epoch is far behind, that's okay that just means there weren't superBlocks submitted
// so long as we ensure that we go through the superBlocks in order and that the superBlock to epoch assignment is non-decreasing, we're good
// so, we'll just keep rolling over the epoch until we catch up
while (getCurrentEpoch() < blockEpoch) {
while (getCurrentEpoch() < superBlockEpoch) {
rollOverEpoch();
}

// note: we could keep track of seen commitments in a set
// but since the operations we're doing are very cheap, the set actually adds overhead
uint256 supermajority = (2 * computeAllTotalStakeForEpoch(blockEpoch)) /
uint256 supermajority = (2 * computeAllTotalStakeForEpoch(superBlockEpoch)) /
3;
address[] memory attesters = getAttesters();

// iterate over the attester set
for (uint256 i = 0; i < attesters.length; i++) {
address attester = attesters[i];

// get a commitment for the attester at the block height
SuperBlockCommitment memory superBlockCommitment = commitments[blockHeight][
// get a commitment for the attester at the superBlock height
SuperBlockCommitment memory superBlockCommitment = commitments[superBlockHeight][
attester
];

Expand All @@ -309,7 +309,7 @@ contract MCR is Initializable, BaseSettlement, MCRStorage, IMCR {
][superBlockCommitment.commitment];

if (totalStakeOnCommitment > supermajority) {
// accept the block commitment (this may trigger a roll over of the epoch)
// accept the superBlock commitment (this may trigger a roll over of the epoch)
_acceptSuperBlockCommitment(superBlockCommitment);

// we found a commitment that was accepted
Expand Down Expand Up @@ -338,52 +338,52 @@ contract MCR is Initializable, BaseSettlement, MCRStorage, IMCR {
function submitSuperBlockCommitment(SuperBlockCommitment memory superBlockCommitment) public {
require(
openAttestationEnabled || hasRole(TRUSTED_ATTESTER, msg.sender),
"UNAUTHORIZED_BLOCK_COMMITMENT"
"UNAUTHORIZED_SUPERBLOCK_COMMITMENT"
);
submitSuperBlockCommitmentForAttester(msg.sender, superBlockCommitment);
}

function submitBatchSuperBlockCommitment(SuperBlockCommitment[] memory superBlockCommitments) public {
require(
openAttestationEnabled || hasRole(TRUSTED_ATTESTER, msg.sender),
"UNAUTHORIZED_BLOCK_COMMITMENT"
"UNAUTHORIZED_SUPERBLOCK_COMMITMENT"
);
for (uint256 i = 0; i < superBlockCommitments.length; i++) {
submitSuperBlockCommitmentForAttester(msg.sender, superBlockCommitments[i]);
}
}

/**
* @dev Accepts a block commitment.
* @dev Under the current implementation this shares in recursion with the tickOnBlockHeight, so it should be reentrant.
* @dev Accepts a superBlock commitment.
* @dev Under the current implementation this shares in recursion with the tickOnSuperBlockHeight, so it should be reentrant.
*/
function _acceptSuperBlockCommitment(
SuperBlockCommitment memory superBlockCommitment
) internal {
uint256 currentEpoch = getCurrentEpoch();
// get the epoch for the block commitment
// Block commitment is not in the current epoch, it cannot be accepted. This indicates a bug in the protocol.
// get the epoch for the superBlock commitment
// SuperBlock commitment is not in the current epoch, it cannot be accepted. This indicates a bug in the protocol.
if (superBlockHeightEpochAssignments[superBlockCommitment.height] != currentEpoch)
revert UnacceptableSuperBlockCommitment();

// set accepted block commitment
versionedAcceptedBlocks[acceptedBlocksVersion][superBlockCommitment.height] = superBlockCommitment;
// set accepted superBlock commitment
versionedAcceptedSuperBlocks[acceptedSuperBlocksVersion][superBlockCommitment.height] = superBlockCommitment;

// set last accepted block height
lastAcceptedBlockHeight = superBlockCommitment.height;
// set last accepted superBlock height
lastAcceptedSuperBlockHeight = superBlockCommitment.height;

// slash minority attesters w.r.t. to the accepted block commitment
// slash minority attesters w.r.t. to the accepted superBlock commitment
slashMinority(superBlockCommitment);

// emit the block accepted event
// emit the superBlock accepted event
emit BlockAccepted(
superBlockCommitment.blockId,
superBlockCommitment.blockID,
superBlockCommitment.commitment,
superBlockCommitment.height
);

// if the timestamp epoch is greater than the current epoch, roll over the epoch
if (getEpochByBlockTime() > currentEpoch) {
if (getEpochByL1BlockTime() > currentEpoch) {
rollOverEpoch();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,27 @@ contract MCRStorage {

IMovementStaking public stakingContract;

// the number of blocks that can be submitted ahead of the lastAcceptedBlockHeight
// the number of superBlocks that can be submitted ahead of the lastAcceptedSuperBlockHeight
// this allows for things like batching to take place without some attesters locking down the attester set by pushing too far ahead
// ? this could be replaced by a 2/3 stake vote on the block height to epoch assignment
// ? this could be replaced by a 2/3 stake vote on the superBlock height to epoch assignment
// ? however, this protocol becomes more complex as you to take steps to ensure that...
// ? 1. Block heights have a non-decreasing mapping to epochs
// ? 1. superBlock heights have a non-decreasing mapping to epochs
// ? 2. Votes get accumulated reasonable near the end of the epoch (i.e., your vote is cast for the epoch you vote fore and the next)
// ? if howevever, you simply allow a race with the tolerance below, both of these are satisfied without the added complexity
uint256 public leadingBlockTolerance;
uint256 public leadingSuperBlockTolerance;

// track the last accepted block height, so that we can require blocks are submitted in order and handle staking effectively
uint256 public lastAcceptedBlockHeight;
// track the last accepted superBlock height, so that we can require superBlocks are submitted in order and handle staking effectively
uint256 public lastAcceptedSuperBlockHeight;

struct SuperBlockCommitment {
// currently, to simplify the api, we'll say 0 is uncommitted all other numbers are legitimate heights

uint256 height;
bytes32 commitment;
bytes32 blockId;
bytes32 blockID;
}

// map each block height to an epoch
// map each superBlock height to an epoch
mapping(uint256 superBlockHeight => uint256 epoch) public superBlockHeightEpochAssignments;

// track each commitment from each attester for each superBlock height
Expand All @@ -43,9 +43,9 @@ contract MCRStorage {
// whether we allow open attestation
bool public openAttestationEnabled;

// versioned scheme for accepted blocks
mapping(uint256 => mapping(uint256 blockHeight => SuperBlockCommitment)) public versionedAcceptedBlocks;
uint256 public acceptedBlocksVersion;
// versioned scheme for accepted superBlocks
mapping(uint256 => mapping(uint256 superBlockHeight => SuperBlockCommitment)) public versionedAcceptedSuperBlocks;
uint256 public acceptedSuperBlocksVersion;

uint256[47] internal __gap;

Expand Down
Loading

0 comments on commit b074f84

Please sign in to comment.