From e53f7d465a5cadc048038cd20e98831dd55ca3aa Mon Sep 17 00:00:00 2001 From: apenzk Date: Sun, 2 Mar 2025 11:19:03 +0100 Subject: [PATCH] postconfirmer not acceptor --- .../mcr/contracts/src/settlement/MCR.sol | 142 +++++++-------- .../contracts/src/settlement/MCRStorage.sol | 22 +-- .../mcr/contracts/test/settlement/MCR.sol | 172 +++++++++--------- 3 files changed, 168 insertions(+), 168 deletions(-) diff --git a/protocol-units/settlement/mcr/contracts/src/settlement/MCR.sol b/protocol-units/settlement/mcr/contracts/src/settlement/MCR.sol index 5aa2a142c..fe8fe2415 100644 --- a/protocol-units/settlement/mcr/contracts/src/settlement/MCR.sol +++ b/protocol-units/settlement/mcr/contracts/src/settlement/MCR.sol @@ -18,39 +18,39 @@ contract MCR is Initializable, BaseSettlement, MCRStorage, IMCR { // Trusted attesters admin bytes32 public constant TRUSTED_ATTESTER = keccak256("TRUSTED_ATTESTER"); - /// @notice Error thrown when acceptor term is greater than 256 blocks - error AcceptorDurationTooLong(); + /// @notice Error thrown when postconfirmer term is greater than 256 blocks + error PostconfirmerDurationTooLong(); - /// @notice Error thrown when acceptor term is too large for epoch duration - error AcceptorDurationTooLongForEpoch(); + /// @notice Error thrown when postconfirmer term is too large for epoch duration + error PostconfirmerDurationTooLongForEpoch(); /// @notice Error thrown when minimum commitment age is greater than epoch duration error MinCommitmentAgeTooLong(); - /// @notice Error thrown when maximum acceptor non-reactivity time is greater than epoch duration - error MaxAcceptorNonReactivityTimeTooLong(); + /// @notice Error thrown when maximum postconfirmer non-reactivity time is greater than epoch duration + error MaxPostconfirmerNonReactivityTimeTooLong(); - /// @notice Sets the acceptor term duration, must be less than epoch duration - /// @param _acceptorDuration New acceptor term duration in time units - function setAcceptorDuration(uint256 _acceptorDuration) public onlyRole(COMMITMENT_ADMIN) { - // Ensure acceptor term is sufficiently small compared to epoch duration + /// @notice Sets the postconfirmer term duration, must be less than epoch duration + /// @param _postconfirmerDuration New postconfirmer term duration in time units + function setPostconfirmerDuration(uint256 _postconfirmerDuration) public onlyRole(COMMITMENT_ADMIN) { + // Ensure postconfirmer term is sufficiently small compared to epoch duration uint256 epochDuration = stakingContract.getEpochDuration(address(this)); // TODO If we would use block heights instead of timestamps we could handle everything much smoother. - if (2 * _acceptorDuration >= epochDuration ) { - revert AcceptorDurationTooLongForEpoch(); + if (2 * _postconfirmerDuration >= epochDuration ) { + revert PostconfirmerDurationTooLongForEpoch(); } - acceptorDuration = _acceptorDuration; + postconfirmerDuration = _postconfirmerDuration; } - function getAcceptorDuration() public view returns (uint256) { - return acceptorDuration; + function getPostconfirmerDuration() public view returns (uint256) { + return postconfirmerDuration; } /// @notice Sets the minimum time that must pass before a commitment can be postconfirmed /// @param _minCommitmentAgeForPostconfirmation New minimum commitment age // TODO we also require a check when setting the epoch length that it is larger than the min commitment age - // TODO we need to set these values such that it works for acceptor Term and maxAcceptorNonReactivityTime, etc... there are many constraints here. + // TODO we need to set these values such that it works for postconfirmer Term and maxPostconfirmerNonReactivityTime, etc... there are many constraints here. function setMinCommitmentAgeForPostconfirmation(uint256 _minCommitmentAgeForPostconfirmation) public onlyRole(COMMITMENT_ADMIN) { // Ensure min age is less than epoch duration to allow postconfirmation within same epoch if (_minCommitmentAgeForPostconfirmation >= stakingContract.getEpochDuration(address(this))) { @@ -63,20 +63,20 @@ contract MCR is Initializable, BaseSettlement, MCRStorage, IMCR { return minCommitmentAgeForPostconfirmation; } - /// @notice Sets the maximum time the acceptor can be non-reactive to an honest superBlock commitment - /// @param _maxAcceptorNonReactivityTime New maximum time the acceptor can be non-reactive to an honest superBlock commitment - function setAcceptorPrivilegeWindow(uint256 _maxAcceptorNonReactivityTime) public onlyRole(COMMITMENT_ADMIN) { + /// @notice Sets the maximum time the postconfirmer can be non-reactive to an honest superBlock commitment + /// @param _maxPostconfirmerNonReactivityTime New maximum time the postconfirmer can be non-reactive to an honest superBlock commitment + function setPostconfirmerPrivilegeWindow(uint256 _maxPostconfirmerNonReactivityTime) public onlyRole(COMMITMENT_ADMIN) { // Ensure max non-reactivity time is less than epoch duration - if (_maxAcceptorNonReactivityTime >= stakingContract.getEpochDuration(address(this))) { - revert MaxAcceptorNonReactivityTimeTooLong(); + if (_maxPostconfirmerNonReactivityTime >= stakingContract.getEpochDuration(address(this))) { + revert MaxPostconfirmerNonReactivityTimeTooLong(); } - maxAcceptorNonReactivityTime = _maxAcceptorNonReactivityTime; + maxPostconfirmerNonReactivityTime = _maxPostconfirmerNonReactivityTime; } - /// @notice Gets the maximum time the acceptor can be non-reactive to an honest superBlock commitment - /// @return The maximum time the acceptor can be non-reactive to an honest superBlock commitment - function getMaxAcceptorNonReactivityTime() public view returns (uint256) { - return maxAcceptorNonReactivityTime; + /// @notice Gets the maximum time the postconfirmer can be non-reactive to an honest superBlock commitment + /// @return The maximum time the postconfirmer can be non-reactive to an honest superBlock commitment + function getMaxPostconfirmerNonReactivityTime() public view returns (uint256) { + return maxPostconfirmerNonReactivityTime; } @@ -86,7 +86,7 @@ contract MCR is Initializable, BaseSettlement, MCRStorage, IMCR { uint256 _leadingSuperBlockTolerance, uint256 _epochDuration, // in time units address[] memory _custodians, - uint256 _acceptorDuration, // in time units + uint256 _postconfirmerDuration, // in time units address _moveTokenAddress // the primary custodian for rewards in the staking contract ) public initializer { __BaseSettlement_init_unchained(); @@ -96,7 +96,7 @@ contract MCR is Initializable, BaseSettlement, MCRStorage, IMCR { stakingContract.registerDomain(_epochDuration, _custodians); grantCommitmentAdmin(msg.sender); grantTrustedAttester(msg.sender); - acceptorDuration = _acceptorDuration; + postconfirmerDuration = _postconfirmerDuration; moveTokenAddress = _moveTokenAddress; // Set default values to 1/10th of epoch duration @@ -105,7 +105,7 @@ contract MCR is Initializable, BaseSettlement, MCRStorage, IMCR { // NOTE If they are small at most only the last fraction within an epoch will behave differently. // TODO Examine the effects of the above. minCommitmentAgeForPostconfirmation = _epochDuration / 10; - maxAcceptorNonReactivityTime = _epochDuration / 10; + maxPostconfirmerNonReactivityTime = _epochDuration / 10; rewardPerAttestationPoint = 1; rewardPerPostconfirmationPoint = 1; } @@ -350,36 +350,36 @@ contract MCR is Initializable, BaseSettlement, MCRStorage, IMCR { postconfirmAndRolloverWithAttester(msg.sender); } - /// @notice The current acceptor can postconfirm a superBlock height, given there is a supermajority of stake on a commitment - /// @notice If the current acceptor is live, we should not accept postconfirmations from voluntary attesters + /// @notice The current postconfirmer can postconfirm a superBlock height, given there is a supermajority of stake on a commitment + /// @notice If the current postconfirmer is live, we should not accept postconfirmations from voluntary attesters // TODO: this will be improved, such that voluntary attesters can postconfirm but will not be rewarded before the liveness period has ended - /// @notice If the current acceptor is not live, we should accept postconfirmations from any attester + /// @notice If the current postconfirmer is not live, we should accept postconfirmations from any attester // TODO: this will be improved, such that the first voluntary attester to do sowill be rewarded function postconfirmAndRolloverWithAttester(address /* attester */) internal { - // keep ticking through postconfirmations and rollovers as long as the acceptor is permitted to do + // keep ticking through postconfirmations and rollovers as long as the postconfirmer is permitted to do // ! rewards need to be // ! - at least the cost for gas cost of postconfirmation - // ! - reward the acceptor well to incentivize postconfirmation at every height + // ! - reward the postconfirmer well to incentivize postconfirmation at every height while (attemptPostconfirmOrRollover(lastPostconfirmedSuperBlockHeight + 1)) { } } - /// @notice Checks, for a given superBlock commitment, if the current L1 block time is within the acceptor's privilege window - /// @dev The acceptor's privilege window is the time period when only the acceptor will get rewarded for postconfirmation - function isWithinAcceptorPrivilegeWindow(SuperBlockCommitment memory superBlockCommitment) public view returns (bool) { + /// @notice Checks, for a given superBlock commitment, if the current L1 block time is within the postconfirmer's privilege window + /// @dev The postconfirmer's privilege window is the time period when only the postconfirmer will get rewarded for postconfirmation + function isWithinPostconfirmerPrivilegeWindow(SuperBlockCommitment memory superBlockCommitment) public view returns (bool) { if (getCommitmentFirstSeenAt(superBlockCommitment) == 0) { - console.log("[isWithinAcceptorPrivilegeWindow] timestamp is not set for this commitment"); + console.log("[isWithinPostconfirmerPrivilegeWindow] timestamp is not set for this commitment"); return false; } - // based on the first timestamp for the commitment we can determine if the acceptor has been live sufficiently recently + // based on the first timestamp for the commitment we can determine if the postconfirmer has been live sufficiently recently // use getCommitmentFirstSeenAt, and the mappings - console.log("[isWithinAcceptorPrivilegeWindow] getCommitmentFirstSeenAt", getCommitmentFirstSeenAt(superBlockCommitment)); - console.log("[isWithinAcceptorPrivilegeWindow] getMinCommitmentAgeForPostconfirmation", getMinCommitmentAgeForPostconfirmation()); - console.log("[isWithinAcceptorPrivilegeWindow] getMaxAcceptorNonReactivityTime", getMaxAcceptorNonReactivityTime()); + console.log("[isWithinPostconfirmerPrivilegeWindow] getCommitmentFirstSeenAt", getCommitmentFirstSeenAt(superBlockCommitment)); + console.log("[isWithinPostconfirmerPrivilegeWindow] getMinCommitmentAgeForPostconfirmation", getMinCommitmentAgeForPostconfirmation()); + console.log("[isWithinPostconfirmerPrivilegeWindow] getMaxPostconfirmerNonReactivityTime", getMaxPostconfirmerNonReactivityTime()); if (getCommitmentFirstSeenAt(superBlockCommitment) + getMinCommitmentAgeForPostconfirmation() - + getMaxAcceptorNonReactivityTime() + + getMaxPostconfirmerNonReactivityTime() < block.timestamp) { return false; } @@ -392,26 +392,26 @@ contract MCR is Initializable, BaseSettlement, MCRStorage, IMCR { return currentTime - (currentTime % stakingContract.getEpochDuration(address(this))); } - /// @notice Gets the time at which the current acceptor's term started - function getAcceptorStartTime() public view returns (uint256) { + /// @notice Gets the time at which the current postconfirmer's term started + function getPostconfirmerStartTime() public view returns (uint256) { uint256 currentTime = block.timestamp; // We reset the times to match the start of epochs. This ensures every epoch has the same setup. uint256 currentTimeCorrected = currentTime % stakingContract.getEpochDuration(address(this)); - return currentTimeCorrected - (currentTimeCorrected % acceptorDuration); + return currentTimeCorrected - (currentTimeCorrected % postconfirmerDuration); } - /// @notice Determines the acceptor in the accepting epoch using L1 block hash as a source of randomness - // At the border between epochs this is not ideal as getAcceptor works on blocks and epochs works with time. - // Thus we must consider the edge cases where the acceptor is only active for a short time. - function getAcceptor() public view returns (address) { + /// @notice Determines the postconfirmer in the accepting epoch using L1 block hash as a source of randomness + // At the border between epochs this is not ideal as getPostconfirmer works on blocks and epochs works with time. + // Thus we must consider the edge cases where the postconfirmer is only active for a short time. + function getPostconfirmer() public view returns (address) { // TODO unless we swap with everything, including epochs, we must use block.timestamp. - // However, to get easy access to L1 randomness we need to know the block at which the acceptor started, which is expensive (unless we count in blocks instead of time) + // However, to get easy access to L1 randomness we need to know the block at which the postconfirmer started, which is expensive (unless we count in blocks instead of time) // TODO as long as we do not swap to block.number, the randomness below is precictable. - uint256 randSeed1 = getAcceptorStartTime(); + uint256 randSeed1 = getPostconfirmerStartTime(); uint256 randSeed2 = getEpochStartTime(); address[] memory attesters = stakingContract.getStakedAttestersForAcceptingEpoch(address(this)); - uint256 acceptorIndex = uint256(keccak256(abi.encodePacked(randSeed1, randSeed2))) % attesters.length; // randomize the order of the attesters - return attesters[acceptorIndex]; + uint256 postconfirmerIndex = uint256(keccak256(abi.encodePacked(randSeed1, randSeed2))) % attesters.length; // randomize the order of the attesters + return attesters[postconfirmerIndex]; } /// @dev it is possible if the accepting epoch is behind the presentEpoch that heights dont obtain enough votes in the assigned epoch. @@ -442,12 +442,12 @@ contract MCR is Initializable, BaseSettlement, MCRStorage, IMCR { // if the accepting epoch is far behind the superBlockEpoch (which is determined by commitments measured in L1 block time), then the protocol was not live for a while // We keep rolling over the epoch (i.e. update stakes) until we catch up with the present epoch while (getAcceptingEpoch() < superBlockEpoch) { - // TODO only permit rollover after some liveness criteria for the acceptor, as this is related to the reward model (rollovers should be rewarded) + // TODO only permit rollover after some liveness criteria for the postconfirmer, as this is related to the reward model (rollovers should be rewarded) rollOverEpoch(); console.log("[attemptPostconfirmOrRollover] rolled over epoch to %s", getAcceptingEpoch()); } - // TODO only permit postconfirmation after some liveness criteria for the acceptor, as this is related to the reward model (postconfirmation should be rewarded) + // TODO only permit postconfirmation after some liveness criteria for the postconfirmer, as this is related to the reward model (postconfirmation should be rewarded) uint256 supermajority = (2 * getTotalStake(superBlockEpoch)) / 3 + 1; address[] memory attesters = getStakedAttestersForAcceptingEpoch(); @@ -479,8 +479,8 @@ contract MCR is Initializable, BaseSettlement, MCRStorage, IMCR { // TODO: for rewards we have to run through all the attesters, as we need to acknowledge that they get rewards. - // TODO: if the attester is the current acceptor, we need to record that the acceptor has shown liveness. - // TODO: this liveness needs to be discoverable by isWithinAcceptorPrivilegeWindow() + // TODO: if the attester is the current postconfirmer, we need to record that the postconfirmer has shown liveness. + // TODO: this liveness needs to be discoverable by isWithinPostconfirmerPrivilegeWindow() return true; } @@ -556,18 +556,18 @@ contract MCR is Initializable, BaseSettlement, MCRStorage, IMCR { } // Award points to postconfirmer - if (!isWithinAcceptorPrivilegeWindow(superBlockCommitment)) { - // if we are outside the privilege window, for the acceptor reward anyone who postconfirms + if (!isWithinPostconfirmerPrivilegeWindow(superBlockCommitment)) { + // if we are outside the privilege window, for the postconfirmer reward anyone who postconfirms console.log("[postconfirmSuperBlockCommitment] privilege window is over"); postconfirmerRewardPoints[currentAcceptingEpoch][attester] += 1; } else { - // if we are within the privilege window, only award points to the acceptor - // TODO optimization: even if the height has been volunteer postconfirmed we need to allow that that acceptor gets rewards, - // TODO otherwise weak acceptors may could get played (rich volunteer acceptors pay the fees and poor acceptors never get any reward) + // if we are within the privilege window, only award points to the postconfirmer + // TODO optimization: even if the height has been volunteer postconfirmed we need to allow that that postconfirmer gets rewards, + // TODO otherwise weak postconfirmers may could get played (rich volunteer postconfirmers pay the fees and poor postconfirmers never get any reward) // TODO but check if this is really required game theoretically. - console.log("[postconfirmSuperBlockCommitment] currentAcceptor is %s", getAcceptor()); + console.log("[postconfirmSuperBlockCommitment] currentPostconfirmer is %s", getPostconfirmer()); console.log("[postconfirmSuperBlockCommitment] attester is %s", attester); - if (getAcceptor() == attester) { + if (getPostconfirmer() == attester) { postconfirmerRewardPoints[currentAcceptingEpoch][attester] += 1; } } @@ -628,21 +628,21 @@ contract MCR is Initializable, BaseSettlement, MCRStorage, IMCR { console.log("[rollOverEpoch] msg.sender is %s", msg.sender); stakingContract.rewardFromDomain(attesters[i], reward, moveTokenAddress); // TODO : check if we really have to keep postconfirmerRewardPoints per epoch, or whether we could simply delete the points here for a given postconfirmer. - // TODO also the postconfirmer list is super short. typically for a given height only the acceptor and at most the acceptor and a volunteer acceptor. + // TODO also the postconfirmer list is super short. typically for a given height only the postconfirmer and at most the postconfirmer and a volunteer postconfirmer. // TODO So this can be heavily optimized. } } stakingContract.rollOverEpoch(); - setAcceptor(); + setPostconfirmer(); } - // determine the new acceptor. to do so use the blockhash of the L1 block that executes the rollover function - function setAcceptor() internal { + // determine the new postconfirmer. to do so use the blockhash of the L1 block that executes the rollover function + function setPostconfirmer() internal { // TODO: make this weighted by stake address[] memory attesters = stakingContract.getStakedAttestersForAcceptingEpoch(address(this)); - uint256 acceptorIndex = uint256(blockhash(block.number-1)) % attesters.length; - currentAcceptor = attesters[acceptorIndex]; + uint256 postconfirmerIndex = uint256(blockhash(block.number-1)) % attesters.length; + currentPostconfirmer = attesters[postconfirmerIndex]; } /// @notice Gets the commitment submitted by an attester for a given height diff --git a/protocol-units/settlement/mcr/contracts/src/settlement/MCRStorage.sol b/protocol-units/settlement/mcr/contracts/src/settlement/MCRStorage.sol index 43c73bc5d..ed11993f0 100644 --- a/protocol-units/settlement/mcr/contracts/src/settlement/MCRStorage.sol +++ b/protocol-units/settlement/mcr/contracts/src/settlement/MCRStorage.sol @@ -25,19 +25,19 @@ contract MCRStorage { // track the last postconfirmed superBlock height, so that we can require superBlocks are submitted in order and handle staking effectively uint256 public lastPostconfirmedSuperBlockHeight; - /// Acceptor term time in seconds. The acceptor remains the same for acceptorDuration period. - // The Acceptor term can be minimal, but it should not be too small as the acceptor should have some time + /// Postconfirmer term time in seconds. The postconfirmer remains the same for postconfirmerDuration period. + // The Postconfirmer term can be minimal, but it should not be too small as the postconfirmer should have some time // to prepare and post L1-transactions that will start the validation of attestations. - uint256 public acceptorDuration; + uint256 public postconfirmerDuration; /// @notice Minimum time that must pass before a commitment can be postconfirmed uint256 public minCommitmentAgeForPostconfirmation; - /// @notice Max time the acceptor can be non-reactive to an honest superBlock commitment - uint256 public maxAcceptorNonReactivityTime; + /// @notice Max time the postconfirmer can be non-reactive to an honest superBlock commitment + uint256 public maxPostconfirmerNonReactivityTime; - // the acceptor for the accepting epoch - address public currentAcceptor; + // the postconfirmer for the accepting epoch + address public currentPostconfirmer; // TODO i added these param descriptions. are these correct? /// Struct to store block commitment details @@ -66,9 +66,9 @@ contract MCRStorage { // Track which attester postconfirmed a given superBlock height mapping(uint256 superBlockHeight => address attester) public postconfirmedBy; - // Track if acceptor postconfirmed a given superBlock height + // Track if postconfirmer postconfirmed a given superBlock height // TODO this may be redundant due to one of the mappings below - mapping(uint256 superBlockHeight => bool) public postconfirmedByAcceptor; + mapping(uint256 superBlockHeight => bool) public postconfirmedByPostconfirmer; // Track the L1Block height when a superBlock height was postconfirmed mapping(uint256 superBlockHeight => uint256 L1BlockHeight) public postconfirmedAtL1BlockHeight; @@ -77,8 +77,8 @@ contract MCRStorage { // Track the L1Block timestamp when a superBlock height was postconfirmed mapping(uint256 superBlockHeight => uint256 L1BlockTimestamp) public postconfirmedAtL1BlockTimestamp; - // Track the L1Block height when a superBlock height was postconfirmed by the acceptor - mapping(uint256 superBlockHeight => uint256 L1BlockHeight) public postconfirmedAtL1BlockHeightByAcceptor; + // Track the L1Block height when a superBlock height was postconfirmed by the postconfirmer + mapping(uint256 superBlockHeight => uint256 L1BlockHeight) public postconfirmedAtL1BlockHeightByPostconfirmer; // map superBlock height to postconfirmed superBlock hash mapping(uint256 superBlockHeight => SuperBlockCommitment) public postconfirmedSuperBlocks; diff --git a/protocol-units/settlement/mcr/contracts/test/settlement/MCR.sol b/protocol-units/settlement/mcr/contracts/test/settlement/MCR.sol index 5b898c2e7..bde73f3e9 100644 --- a/protocol-units/settlement/mcr/contracts/test/settlement/MCR.sol +++ b/protocol-units/settlement/mcr/contracts/test/settlement/MCR.sol @@ -21,7 +21,7 @@ contract MCRTest is Test, IMCR { string public stakingSignature = "initialize(address)"; string public mcrSignature = "initialize(address,uint256,uint256,uint256,address[],uint256,address)"; uint256 epochDuration = 7200 seconds; - uint256 acceptorDuration = epochDuration/12 seconds/4; + uint256 postconfirmerDuration = epochDuration/4; bytes32 honestCommitmentTemplate = keccak256(abi.encodePacked(uint256(1), uint256(2), uint256(3))); bytes32 honestBlockIdTemplate = keccak256(abi.encodePacked(uint256(1), uint256(2), uint256(3))); bytes32 dishonestCommitmentTemplate = keccak256(abi.encodePacked(uint256(3), uint256(2), uint256(1))); @@ -88,9 +88,9 @@ contract MCRTest is Test, IMCR { 5, // _leadingSuperBlockTolerance, max blocks ahead of last confirmed epochDuration, // _epochDuration, how long an epoch lasts, constant stakes in that time custodians, // _custodians, array with moveProxy address - acceptorDuration, // _acceptorDuration, how long an acceptor serves + postconfirmerDuration, // _postconfirmerDuration, how long an postconfirmer serves // TODO can we replace the following line with the moveToken address? - address(moveProxy) // _moveTokenAddress, the primary custodian for rewards in the staking contract + address(moveProxy) // _moveTokenAddress, the primary custodian for rewards in the staking contract ); TransparentUpgradeableProxy mcrProxy = new TransparentUpgradeableProxy( address(mcrImplementation), @@ -105,9 +105,9 @@ contract MCRTest is Test, IMCR { // set the min commitment age for postconfirmation to 0 to make the tests easier mcr.setMinCommitmentAgeForPostconfirmation(0); assertEq(mcr.getMinCommitmentAgeForPostconfirmation(), 0, "The default min commitment age for tests is set to 0"); - // set the max acceptor non-reactivity time to 0 to make the tests easier - mcr.setAcceptorPrivilegeWindow(0); - assertEq(mcr.getMaxAcceptorNonReactivityTime(), 0, "The default max acceptor non-reactivity time for tests is set to 0"); + // set the max postconfirmer non-reactivity time to 0 to make the tests easier + mcr.setPostconfirmerPrivilegeWindow(0); + assertEq(mcr.getMaxPostconfirmerNonReactivityTime(), 0, "The default max postconfirmer non-reactivity time for tests is set to 0"); } // Helper function to setup genesis with 1 attester and their stake @@ -665,8 +665,8 @@ contract MCRTest is Test, IMCR { assert(aliceCommitment.commitment == commitment.commitment); assert(bobCommitment.commitment == commitment.commitment); - // Verify acceptor state - assert(mcr.isWithinAcceptorPrivilegeWindow(commitment)); + // Verify postconfirmer state + assert(mcr.isWithinPostconfirmerPrivilegeWindow(commitment)); assertEq(mcr.getSuperBlockHeightAssignedEpoch(targetHeight), mcr.getAcceptingEpoch()); // Attempt postconfirmation @@ -701,8 +701,8 @@ contract MCRTest is Test, IMCR { assert(aliceCommitment.commitment == commitment.commitment); assert(bobCommitment.commitment == commitment.commitment); - // Verify acceptor state - assert(mcr.isWithinAcceptorPrivilegeWindow(commitment)); + // Verify postconfirmer state + assert(mcr.isWithinPostconfirmerPrivilegeWindow(commitment)); assertEq(mcr.getSuperBlockHeightAssignedEpoch(targetHeight), mcr.getAcceptingEpoch()); // Attempt postconfirmation - this should fail because there's no supermajority @@ -806,76 +806,76 @@ contract MCRTest is Test, IMCR { // ---------------------------------------------------------------- - // -------- Acceptor tests -------------------------------------- + // -------- Postconfirmer tests -------------------------------------- // ---------------------------------------------------------------- - /// @notice Test that getAcceptorStartTime correctly calculates term start times - function testAcceptorStartTime() public { + /// @notice Test that getPostconfirmerStartTime correctly calculates term start times + function testPostconfirmerStartTime() public { // Test at block 0 assertEq(block.timestamp, 1, "Current time should be 1"); // TODO why is it 1? and not 0? - assertEq(acceptorDuration, mcr.getAcceptorDuration(), "Acceptor term should be correctly set"); - assertEq(mcr.getAcceptorStartTime(), 0, "Acceptor term should start at (1) time 0"); + assertEq(postconfirmerDuration, mcr.getPostconfirmerDuration(), "Postconfirmer term should be correctly set"); + assertEq(mcr.getPostconfirmerStartTime(), 0, "Postconfirmer term should start at (1) time 0"); - // Test at half an acceptor term - vm.warp(acceptorDuration-1); - assertEq(mcr.getAcceptorStartTime(), 0, "Acceptor term should start at (2) time 0"); + // Test at half an postconfirmer term + vm.warp(postconfirmerDuration-1); + assertEq(mcr.getPostconfirmerStartTime(), 0, "Postconfirmer term should start at (2) time 0"); - // Test at an acceptor term boundary - vm.warp(acceptorDuration); + // Test at an postconfirmer term boundary + vm.warp(postconfirmerDuration); console.log("current time", block.timestamp); - console.log("acceptorDuration", acceptorDuration); + console.log("postconfirmerDuration", postconfirmerDuration); console.log("epochTime", epochDuration); - assertEq(mcr.getAcceptorStartTime(), acceptorDuration, "Acceptor term should start at (3) time acceptorDuration"); + assertEq(mcr.getPostconfirmerStartTime(), postconfirmerDuration, "Postconfirmer term should start at (3) time postconfirmerDuration"); - // Test at an acceptor term boundary - vm.warp(acceptorDuration+1); - assertEq(mcr.getAcceptorStartTime(), acceptorDuration, "Acceptor term should start at (4) time acceptorDuration"); + // Test at an postconfirmer term boundary + vm.warp(postconfirmerDuration+1); + assertEq(mcr.getPostconfirmerStartTime(), postconfirmerDuration, "Postconfirmer term should start at (4) time postconfirmerDuration"); - // Test at 1.5 acceptor terms - vm.warp(2 * acceptorDuration ); - assertEq(mcr.getAcceptorStartTime(), 2 * acceptorDuration, "Acceptor term should start at (5) time 2 * acceptorDuration"); + // Test at 1.5 postconfirmer terms + vm.warp(2 * postconfirmerDuration ); + assertEq(mcr.getPostconfirmerStartTime(), 2 * postconfirmerDuration, "Postconfirmer term should start at (5) time 2 * postconfirmerDuration"); } - /// @notice Test setting acceptor duration with validation - function testSetAcceptorDuration() public { + /// @notice Test setting postconfirmer duration with validation + function testSetPostconfirmerDuration() public { // Check the epoch duration is set correctly assertEq(epochDuration, staking.getEpochDuration(address(mcr))); // Test valid duration (less than half epoch duration) uint256 validDuration = epochDuration / 2 - 1; - mcr.setAcceptorDuration(validDuration); - assertEq(mcr.getAcceptorDuration(), validDuration, "Duration should be updated to valid value"); + mcr.setPostconfirmerDuration(validDuration); + assertEq(mcr.getPostconfirmerDuration(), validDuration, "Duration should be updated to valid value"); // Test duration too long compared to epoch (>= epochDuration/2) uint256 invalidDuration = epochDuration / 2; - vm.expectRevert(MCR.AcceptorDurationTooLongForEpoch.selector); - mcr.setAcceptorDuration(invalidDuration); - assertEq(mcr.getAcceptorDuration(), validDuration, "Duration should remain at previous valid value"); + vm.expectRevert(MCR.PostconfirmerDurationTooLongForEpoch.selector); + mcr.setPostconfirmerDuration(invalidDuration); + assertEq(mcr.getPostconfirmerDuration(), validDuration, "Duration should remain at previous valid value"); // Test duration equal to epoch duration (should fail) - vm.expectRevert(MCR.AcceptorDurationTooLongForEpoch.selector); - mcr.setAcceptorDuration(epochDuration); - assertEq(mcr.getAcceptorDuration(), validDuration, "Duration should remain at previous valid value"); + vm.expectRevert(MCR.PostconfirmerDurationTooLongForEpoch.selector); + mcr.setPostconfirmerDuration(epochDuration); + assertEq(mcr.getPostconfirmerDuration(), validDuration, "Duration should remain at previous valid value"); } - /// @notice Test that getAcceptor correctly selects an acceptor based on block hash - function testGetAcceptor() public { + /// @notice Test that getPostconfirmer correctly selects an postconfirmer based on block hash + function testGetPostconfirmer() public { // Setup with three attesters with equal stakes (, address bob, address carol) = setupGenesisWithThreeAttesters(1, 1, 1); - uint256 myAcceptorDuration = 13; - mcr.setAcceptorDuration(myAcceptorDuration); - assertEq(myAcceptorDuration,mcr.getAcceptorDuration(),"Acceptor duration not set correctly"); + uint256 myPostconfirmerDuration = 13; + mcr.setPostconfirmerDuration(myPostconfirmerDuration); + assertEq(myPostconfirmerDuration,mcr.getPostconfirmerDuration(),"Postconfirmer duration not set correctly"); - address initialAcceptor = mcr.getAcceptor(); - assertEq(initialAcceptor, bob, "Acceptor should be bob"); + address initialPostconfirmer = mcr.getPostconfirmer(); + assertEq(initialPostconfirmer, bob, "Postconfirmer should be bob"); - vm.warp(myAcceptorDuration-1); - assertEq(mcr.getAcceptor(), initialAcceptor, "Acceptor should not change within term"); + vm.warp(myPostconfirmerDuration-1); + assertEq(mcr.getPostconfirmer(), initialPostconfirmer, "Postconfirmer should not change within term"); - // Move two acceptor terms (moving one resulted still in bob as acceptor with current randomness) - vm.warp(2*myAcceptorDuration); - address newAcceptor = mcr.getAcceptor(); - assertEq(mcr.getAcceptorStartTime(),2*myAcceptorDuration,"Acceptor start time should be myAcceptorDuration"); - assertEq(newAcceptor, carol, "New acceptor should be Carol"); + // Move two postconfirmer terms (moving one resulted still in bob as postconfirmer with current randomness) + vm.warp(2*myPostconfirmerDuration); + address newPostconfirmer = mcr.getPostconfirmer(); + assertEq(mcr.getPostconfirmerStartTime(),2*myPostconfirmerDuration,"Postconfirmer start time should be myPostconfirmerDuration"); + assertEq(newPostconfirmer, carol, "New postconfirmer should be Carol"); } @@ -942,8 +942,8 @@ contract MCRTest is Test, IMCR { assertEq(moveToken.balanceOf(carol), carolInitialBalance + mcr.getStakeForAcceptingEpoch(address(moveToken), carol), "Carol reward not correct."); } - /// @notice Test that postconfirmation rewards are distributed correctly when the acceptor is live - function testPostconfirmationRewardsLiveAcceptor() public { + /// @notice Test that postconfirmation rewards are distributed correctly when the postconfirmer is live + function testPostconfirmationRewardsLivePostconfirmer() public { uint256 stake = 7; // alice has supermajority stake uint256 aliceStake = 3*stake; @@ -951,9 +951,9 @@ contract MCRTest is Test, IMCR { (address alice, address bob, ) = setupGenesisWithThreeAttesters(aliceStake, bobStake, 0); uint256 aliceInitialBalance = moveToken.balanceOf(alice); uint256 bobInitialBalance = moveToken.balanceOf(bob); - // set the max acceptor non-reactivity time to 1/4 epochDuration - mcr.setAcceptorPrivilegeWindow(epochDuration/4); - console.log("acceptor privilege window", mcr.getMaxAcceptorNonReactivityTime()); + // set the max postconfirmer non-reactivity time to 1/4 epochDuration + mcr.setPostconfirmerPrivilegeWindow(epochDuration/4); + console.log("postconfirmer privilege window", mcr.getMaxPostconfirmerNonReactivityTime()); vm.prank(alice); mcr.submitSuperBlockCommitment(makeHonestCommitment(1)); @@ -961,11 +961,11 @@ contract MCRTest is Test, IMCR { console.log("commitment first seen at", mcr.getCommitmentFirstSeenAt(makeHonestCommitment(1))); assertGt(mcr.getCommitmentFirstSeenAt(makeHonestCommitment(1)), 0, "Commitment first seen at should be set"); - console.log("acceptor", mcr.getAcceptor()); - assertEq(mcr.getAcceptor(), bob, "Bob should be the acceptor but its not"); - assertEq(mcr.isWithinAcceptorPrivilegeWindow(makeHonestCommitment(1)), true, "Acceptor should be live"); + console.log("postconfirmer", mcr.getPostconfirmer()); + assertEq(mcr.getPostconfirmer(), bob, "Bob should be the postconfirmer but its not"); + assertEq(mcr.isWithinPostconfirmerPrivilegeWindow(makeHonestCommitment(1)), true, "Postconfirmer should be live"); - // acceptor postconfirms while acceptor is live + // postconfirmer postconfirms while postconfirmer is live vm.prank(bob); mcr.postconfirmSuperBlocksAndRollover(); assertEq(mcr.getAcceptingEpoch(), 0, "Should be in epoch 0"); @@ -987,9 +987,9 @@ contract MCRTest is Test, IMCR { assertEq(moveToken.balanceOf(bob), bobInitialBalance + bobStake, "Bob should have received the rewards"); } - /// @notice Test that volunteer postconfirmation rewards are not distributed to volunteer acceptor when acceptor is live - // TODO once the acceptor can get postconfirm points within the acceptor privilege window, whether or not the height has previously been postconfirmed, this test should be updated - function testVolunteerPostconfirmationRewardsLiveAcceptor() public { + /// @notice Test that volunteer postconfirmation rewards are not distributed to volunteer postconfirmer when postconfirmer is live + // TODO once the postconfirmer can get postconfirm points within the postconfirmer privilege window, whether or not the height has previously been postconfirmed, this test should be updated + function testVolunteerPostconfirmationRewardsLivePostconfirmer() public { uint256 aliceStake = 9; // alice has supermajority stake (address alice, address bob, ) = setupGenesisWithThreeAttesters(aliceStake, 0, 0); @@ -1000,12 +1000,12 @@ contract MCRTest is Test, IMCR { mcr.submitSuperBlockCommitment(makeHonestCommitment(1)); console.log("length of staked attesters", mcr.getStakedAttestersForAcceptingEpoch().length); - console.log("acceptor", mcr.getAcceptor()); + console.log("postconfirmer", mcr.getPostconfirmer()); - assertEq(mcr.getAcceptor(), alice, "Alice should be the acceptor since it is the only staked attester."); - assertEq(mcr.isWithinAcceptorPrivilegeWindow(makeHonestCommitment(1)), true, "Acceptor should be live"); + assertEq(mcr.getPostconfirmer(), alice, "Alice should be the postconfirmer since it is the only staked attester."); + assertEq(mcr.isWithinPostconfirmerPrivilegeWindow(makeHonestCommitment(1)), true, "Postconfirmer should be live"); - // volunteer acceptor postconfirms while acceptor is live + // volunteer postconfirmer postconfirms while postconfirmer is live vm.prank(bob); mcr.postconfirmSuperBlocksAndRollover(); assertEq(mcr.getLastPostconfirmedSuperBlockHeight(), 1); @@ -1026,9 +1026,9 @@ contract MCRTest is Test, IMCR { assertEq(moveToken.balanceOf(alice), aliceInitialBalance + aliceStake, "Alice should have received the attester rewards"); } - /// @notice Test that postconfirmation rewards are distributed to volunteer acceptor when acceptor is not live + /// @notice Test that postconfirmation rewards are distributed to volunteer postconfirmer when postconfirmer is not live // TODO this test should probably be merged with the above test - function testVolunteerPostconfirmationRewardsNotLiveAcceptor() public { + function testVolunteerPostconfirmationRewardsNotLivePostconfirmer() public { // alice has supermajority stake uint256 stake =13; uint256 aliceStake = 3*stake; @@ -1036,26 +1036,26 @@ contract MCRTest is Test, IMCR { (address alice, address bob, ) = setupGenesisWithThreeAttesters(aliceStake, bobStake, 0); uint256 aliceInitialBalance = moveToken.balanceOf(alice); uint256 bobInitialBalance = moveToken.balanceOf(bob); - uint256 thisAcceptorDuration = mcr.getAcceptorDuration(); + uint256 thisPostconfirmerDuration = mcr.getPostconfirmerDuration(); // set the time windows assertEq(mcr.getMinCommitmentAgeForPostconfirmation(), 0, "Min commitment age should be 0"); - uint256 thisAcceptorPriviledgeWindow = epochDuration/100; - mcr.setAcceptorPrivilegeWindow(thisAcceptorPriviledgeWindow); - assertEq(mcr.getMaxAcceptorNonReactivityTime(), thisAcceptorPriviledgeWindow, "Max acceptor non-reactivity time should be 1/100 epochDuration"); - console.log("getMaxAcceptorNonReactivityTime", mcr.getMaxAcceptorNonReactivityTime()); - console.log("thisAcceptorDuration", thisAcceptorDuration); - assertGt(thisAcceptorDuration, thisAcceptorPriviledgeWindow, "Acceptor term should be greater than thisAcceptorPriviledgeWindow"); + uint256 thisPostconfirmerPriviledgeWindow = epochDuration/100; + mcr.setPostconfirmerPrivilegeWindow(thisPostconfirmerPriviledgeWindow); + assertEq(mcr.getMaxPostconfirmerNonReactivityTime(), thisPostconfirmerPriviledgeWindow, "Max postconfirmer non-reactivity time should be 1/100 epochDuration"); + console.log("getMaxPostconfirmerNonReactivityTime", mcr.getMaxPostconfirmerNonReactivityTime()); + console.log("thisPostconfirmerDuration", thisPostconfirmerDuration); + assertGt(thisPostconfirmerDuration, thisPostconfirmerPriviledgeWindow, "Postconfirmer term should be greater than thisPostconfirmerPriviledgeWindow"); vm.prank(alice); mcr.submitSuperBlockCommitment(makeHonestCommitment(1)); - assertEq(mcr.getAcceptor(), bob, "bob should be the acceptor"); - assertEq(mcr.isWithinAcceptorPrivilegeWindow(makeHonestCommitment(1)), true, "Acceptor should be live"); + assertEq(mcr.getPostconfirmer(), bob, "bob should be the postconfirmer"); + assertEq(mcr.isWithinPostconfirmerPrivilegeWindow(makeHonestCommitment(1)), true, "Postconfirmer should be live"); - // warp out of acceptor privilege window - vm.warp(block.timestamp + thisAcceptorPriviledgeWindow + 1 ); // TODO check why + 1 is needed - assertEq(mcr.isWithinAcceptorPrivilegeWindow(makeHonestCommitment(1)), false, "Acceptor should not be live"); + // warp out of postconfirmer privilege window + vm.warp(block.timestamp + thisPostconfirmerPriviledgeWindow + 1 ); // TODO check why + 1 is needed + assertEq(mcr.isWithinPostconfirmerPrivilegeWindow(makeHonestCommitment(1)), false, "Postconfirmer should not be live"); vm.prank(alice); mcr.postconfirmSuperBlocksAndRollover(); assertEq(mcr.getAcceptingEpoch(), 0, "Should be in epoch 0"); @@ -1074,15 +1074,15 @@ contract MCRTest is Test, IMCR { } // ---------------------------------------------------------------- - // -------- Acceptor reward tests -------------------------------------- + // -------- Postconfirmer reward tests -------------------------------------- // ---------------------------------------------------------------- - // An acceptor that is in place for acceptorDuration time should be replaced by a new acceptor after their term ended. + // An postconfirmer that is in place for postconfirmerDuration time should be replaced by a new postconfirmer after their term ended. // TODO reward logic is not yet implemented - function testAcceptorRewards() public { + function testPostconfirmerRewards() public { (address alice, address bob, ) = setupGenesisWithThreeAttesters(1, 1, 0); - assertEq(mcr.getAcceptor(), bob, "Bob should be the acceptor"); + assertEq(mcr.getPostconfirmer(), bob, "Bob should be the postconfirmer"); // make superBlock commitments MCRStorage.SuperBlockCommitment memory initCommitment = makeHonestCommitment(1);