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

Contract redesign #931

Closed
wants to merge 6 commits into from
Closed
Changes from 1 commit
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
Prev Previous commit
Next Next commit
migrate to lib
cryptoAtwill committed May 16, 2024
commit 19277775747be8948bf5a8da009314c2866e41e6
20 changes: 12 additions & 8 deletions contracts/src/lib/power/LibPower.sol
Original file line number Diff line number Diff line change
@@ -239,9 +239,19 @@ library LibPowerQuery {
}
}

library ProofOfPowerStorage {
function diamondStorage() internal pure returns (ProofOfPower storage ds) {
bytes32 position = keccak256("ipc.lib.power.storage");
assembly {
ds.slot := position
}
}

}

/// @notice Handles the proof of power with child subnet.
/// @dev This is a contract instead of a library so that hooks can be added for downstream use cases.
abstract contract PowerChangeInitiator {
library LibPowerChange {
using LibPowerChangeLog for PowerChangeLog;
using LibMaxPQ for MaxPQ;
using LibMinPQ for MinPQ;
@@ -253,13 +263,9 @@ abstract contract PowerChangeInitiator {
event ActiveValidatorReplaced(address oldValidator, address newValidator);
event ActiveValidatorLeft(address validator);
event WaitingValidatorLeft(address validator);

uint64 internal constant INITIAL_CONFIGURATION_NUMBER = 1;

event ConfigurationNumberConfirmed(uint64 number);

/// @notice Hook for handling when the power of the validaor has changes
function handlePowerChange(address validator, uint256 oldPower, uint256 newPower) internal virtual;
uint64 internal constant INITIAL_CONFIGURATION_NUMBER = 1;

/// @notice Set the metadata of a validator
function setValidatorMetadata(ProofOfPower storage self, address validator, bytes calldata metadata) internal {
@@ -325,8 +331,6 @@ abstract contract PowerChangeInitiator {
} else {
reduceReshuffle({self: self, validator: validator, newPower: newPower});
}

handlePowerChange(validator, oldPower, newPower);
}

function validatePublicKeys(
34 changes: 15 additions & 19 deletions contracts/src/subnet/FederatedSubnetFacet.sol
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
pragma solidity ^0.8.23;

import {InvalidXnetMessage, InvalidXnetMessageReason, DuplicatedGenesisValidator, WrongSubnet, InvalidFederationPayload, NotEnoughGenesisValidators} from "../errors/IPCErrors.sol";
import {PowerChangeInitiator, ProofOfPower, LibPowerQuery} from "../lib/power/LibPower.sol";
import {LibPowerChange, ProofOfPowerStorage, ProofOfPower, LibPowerQuery} from "../lib/power/LibPower.sol";
import {ReentrancyGuard} from "../lib/LibReentrancyGuard.sol";
import {Pausable} from "../lib/LibPausable.sol";
import {LibDiamond} from "../lib/LibDiamond.sol";
@@ -13,7 +13,6 @@ import {IGenesisComponent} from "../interfaces/IGenesis.sol";
library LibFederatedPower {
// The federated power storage
struct FederatedPowerStorage {
ProofOfPower power;
uint64 minValidators;
/// @notice If the federated power mode is bootstrapped
bool bootstrapped;
@@ -27,8 +26,9 @@ library LibFederatedPower {
}
}

contract FederatedSubnetFacet is IGenesisComponent, PowerChangeInitiator, ReentrancyGuard, Pausable {
contract FederatedSubnetFacet is IGenesisComponent, ReentrancyGuard, Pausable {
using LibPowerQuery for ProofOfPower;
using LibPowerChange for ProofOfPower;

event FederatedPowerBootstrapped();

@@ -62,7 +62,7 @@ contract FederatedSubnetFacet is IGenesisComponent, PowerChangeInitiator, Reentr
revert InvalidFederationPayload();
}

validatePublicKeys(validators, publicKeys);
LibPowerChange.validatePublicKeys(validators, publicKeys);

// only subnet owner is allowed to set powers
LibDiamond.enforceIsContractOwner();
@@ -77,13 +77,11 @@ contract FederatedSubnetFacet is IGenesisComponent, PowerChangeInitiator, Reentr

// ===== Getters =====
function confimedPower(address addr) external view returns(uint256) {
LibFederatedPower.FederatedPowerStorage storage fps = LibFederatedPower.diamondStorage();
return fps.power.getConfirmedPower(addr);
return ProofOfPowerStorage.diamondStorage().getConfirmedPower(addr);
}

function unconfirmedPower(address addr) external view returns(uint256) {
LibFederatedPower.FederatedPowerStorage storage fps = LibFederatedPower.diamondStorage();
return fps.power.getUnconfirmedPower(addr);
return ProofOfPowerStorage.diamondStorage().getUnconfirmedPower(addr);
}

// ======= Internal functions ======
@@ -93,7 +91,9 @@ contract FederatedSubnetFacet is IGenesisComponent, PowerChangeInitiator, Reentr
uint256[] calldata powers
) internal {
uint256 length = validators.length;

LibFederatedPower.FederatedPowerStorage storage fps = LibFederatedPower.diamondStorage();
ProofOfPower storage proofS = ProofOfPowerStorage.diamondStorage();

if (length <= fps.minValidators) {
revert NotEnoughGenesisValidators();
@@ -102,12 +102,12 @@ contract FederatedSubnetFacet is IGenesisComponent, PowerChangeInitiator, Reentr
for (uint256 i; i < length; ) {
// performing deduplication
// validator should have no power when first added
if (fps.power.getConfirmedPower(validators[i]) > 0) {
if (proofS.getConfirmedPower(validators[i]) > 0) {
revert DuplicatedGenesisValidator();
}

confirmMetadata(fps.power, validators[i], publicKeys[i]);
confirmNewPower(fps.power, validators[i], powers[i]);
proofS.confirmMetadata(validators[i], publicKeys[i]);
proofS.confirmNewPower(validators[i], powers[i]);

// s.genesisValidators.push(Validator({addr: validators[i], weight: powers[i], metadata: publicKeys[i]}));

@@ -128,19 +128,15 @@ contract FederatedSubnetFacet is IGenesisComponent, PowerChangeInitiator, Reentr
uint256[] calldata powers
) internal {
uint256 length = validators.length;
LibFederatedPower.FederatedPowerStorage storage fps = LibFederatedPower.diamondStorage();
ProofOfPower storage proofS = ProofOfPowerStorage.diamondStorage();

for (uint256 i; i < length; ) {
setValidatorMetadata(fps.power, validators[i], publicKeys[i]);
setNewPower(fps.power, validators[i], powers[i]);
proofS.setValidatorMetadata(validators[i], publicKeys[i]);
proofS.setNewPower(validators[i], powers[i]);

unchecked {
++i;
}
}
}

function handlePowerChange(address validator, uint256 oldPower, uint256 newPower) internal override {
// no opt required
}
}