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

Add NodeDriver docs #86

Merged
merged 1 commit into from
Nov 1, 2024
Merged
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
31 changes: 27 additions & 4 deletions contracts/sfc/NodeDriver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ contract NodeDriver is Initializable {

event UpdatedBackend(address indexed backend);

/// NodeDriverAuth can replace itself
function setBackend(address _backend) external onlyBackend {
emit UpdatedBackend(_backend);
backend = NodeDriverAuth(_backend);
}

/// Callable only by NodeDriverAuth (which mediates calls from SFC and from admins)
modifier onlyBackend() {
if (msg.sender != address(backend)) {
revert NotBackend();
Expand All @@ -36,6 +38,8 @@ contract NodeDriver is Initializable {
event UpdateNetworkVersion(uint256 version);
event AdvanceEpochs(uint256 num);

/// Initialization is called only once, after the contract deployment.
/// Because the contract code is written directly into genesis, constructor cannot be used.
function initialize(address _backend, address _evmWriterAddress) external initializer {
backend = NodeDriverAuth(_backend);
emit UpdatedBackend(_backend);
Expand All @@ -62,26 +66,38 @@ contract NodeDriver is Initializable {
evmWriter.incNonce(acc, diff);
}

/// Update network rules configuring the chain.
/// Emitted event is being observed by Sonic client.
function updateNetworkRules(bytes calldata diff) external onlyBackend {
emit UpdateNetworkRules(diff);
}

/// Update advertised version of the network.
/// Emitted event is being observed by Sonic client.
function updateNetworkVersion(uint256 version) external onlyBackend {
emit UpdateNetworkVersion(version);
}

/// Enforce sealing given number of epochs.
/// Emitted event is being observed by Sonic client.
function advanceEpochs(uint256 num) external onlyBackend {
emit AdvanceEpochs(num);
}

/// Update weight of a validator. Used to propagate a stake change from SFC to the client.
/// Emitted event is being observed by Sonic client.
function updateValidatorWeight(uint256 validatorID, uint256 value) external onlyBackend {
emit UpdateValidatorWeight(validatorID, value);
}

/// Update public key of a validator. Used to propagate a change from SFC to the client.
/// Emitted event is being observed by Sonic client.
function updateValidatorPubkey(uint256 validatorID, bytes calldata pubkey) external onlyBackend {
emit UpdateValidatorPubkey(validatorID, pubkey);
}

/// Callable only from Sonic client itself as an internal tx.
/// Used for propagating network event (validator doublesign, epoch sealing) from node to SFC.
modifier onlyNode() {
if (msg.sender != address(0)) {
revert NotNode();
Expand All @@ -91,6 +107,7 @@ contract NodeDriver is Initializable {

// Methods which are called only by the node

/// Set an initial validator. Called only as part of network initialization/genesis file generating.
function setGenesisValidator(
address auth,
uint256 validatorID,
Expand All @@ -100,18 +117,18 @@ contract NodeDriver is Initializable {
backend.setGenesisValidator(auth, validatorID, pubkey, createdTime);
}

/// Set an initial delegation. Called only as part of network initialization/genesis file generating.
function setGenesisDelegation(address delegator, uint256 toValidatorID, uint256 stake) external onlyNode {
backend.setGenesisDelegation(delegator, toValidatorID, stake);
}

/// Deactivate a validator. Called by network node when a double-sign of the given validator is registered.
/// Is called before sealEpoch() call.
function deactivateValidator(uint256 validatorID, uint256 status) external onlyNode {
backend.deactivateValidator(validatorID, status);
}

function sealEpochValidators(uint256[] calldata nextValidatorIDs) external onlyNode {
backend.sealEpochValidators(nextValidatorIDs);
}

/// Seal epoch. Called BEFORE epoch sealing made by the client itself.
function sealEpoch(
uint256[] calldata offlineTimes,
uint256[] calldata offlineBlocks,
Expand All @@ -121,6 +138,7 @@ contract NodeDriver is Initializable {
backend.sealEpoch(offlineTimes, offlineBlocks, uptimes, originatedTxsFee, 841669690);
}

/// Seal epoch. To be called BEFORE epoch sealing made by the client itself - currently not used.
function sealEpochV1(
uint256[] calldata offlineTimes,
uint256[] calldata offlineBlocks,
Expand All @@ -130,4 +148,9 @@ contract NodeDriver is Initializable {
) external onlyNode {
backend.sealEpoch(offlineTimes, offlineBlocks, uptimes, originatedTxsFee, usedGas);
}

/// Seal epoch. Called AFTER epoch sealing made by the client itself.
function sealEpochValidators(uint256[] calldata nextValidatorIDs) external onlyNode {
backend.sealEpochValidators(nextValidatorIDs);
}
}
35 changes: 31 additions & 4 deletions contracts/sfc/NodeDriverAuth.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,23 @@ contract NodeDriverAuth is Initializable, Ownable {
sfc = ISFC(_sfc);
}

/// Callable only by SFC contract.
modifier onlySFC() {
if (msg.sender != address(sfc)) {
revert NotSFC();
}
_;
}

/// Callable only by NodeDriver (mediates messages from the network client)
modifier onlyDriver() {
if (msg.sender != address(driver)) {
revert NotDriver();
}
_;
}

/// Change NodeDriverAuth used by NodeDriver. Callable by network admin.
function migrateTo(address newDriverAuth) external onlyOwner {
driver.setBackend(newDriverAuth);
}
Expand All @@ -59,10 +62,16 @@ contract NodeDriverAuth is Initializable, Ownable {
}
}

/// Execute a batch update of network configuration.
/// Run given contract with a permission of the NodeDriverAuth owner.
/// Does not allow changing NodeDriver and NodeDriverAuth code.
function execute(address executable) external onlyOwner {
_execute(executable, owner(), _getCodeHash(address(this)), _getCodeHash(address(driver)));
}

/// Execute a batch update of network configuration.
/// Run given contract with a permission of the NodeDriverAuth owner.
/// Allows changing NodeDriver and NodeDriverAuth code.
function mutExecute(
address executable,
address newOwner,
Expand All @@ -72,53 +81,66 @@ contract NodeDriverAuth is Initializable, Ownable {
_execute(executable, newOwner, selfCodeHash, driverCodeHash);
}

/// Mint native token. To be used by SFC for minting validators rewards.
function incBalance(address acc, uint256 diff) external onlySFC {
if (acc != address(sfc)) {
revert RecipientNotSFC();
}
driver.setBalance(acc, address(acc).balance + diff);
}

/// Upgrade code of given contract by coping it from other deployed contract.
/// Avoids setting code to an external address.
function upgradeCode(address acc, address from) external onlyOwner {
if (!isContract(acc) || !isContract(from)) {
revert NotContract();
}
driver.copyCode(acc, from);
}

/// Upgrade code of given contract by coping it from other deployed contract.
/// Does not avoid setting code to an external address. (DANGEROUS!)
function copyCode(address acc, address from) external onlyOwner {
driver.copyCode(acc, from);
}

/// Increment nonce of the given account.
function incNonce(address acc, uint256 diff) external onlyOwner {
driver.incNonce(acc, diff);
}

/// Update network rules by providing a JSON patch.
function updateNetworkRules(bytes calldata diff) external onlyOwner {
driver.updateNetworkRules(diff);
}

/// Update MinGasPrice. Called by SFC during epoch sealing.
function updateMinGasPrice(uint256 minGasPrice) external onlySFC {
// prettier-ignore
driver.updateNetworkRules(bytes(strConcat("{\"Economy\":{\"MinGasPrice\":", uint256ToStr(minGasPrice), "}}")));
}

/// Update advertised network version.
function updateNetworkVersion(uint256 version) external onlyOwner {
driver.updateNetworkVersion(version);
}

/// Enforce sealing given number of epochs.
function advanceEpochs(uint256 num) external onlyOwner {
driver.advanceEpochs(num);
}

/// Update weight of a validator. Used to propagate a stake change from SFC to the client.
function updateValidatorWeight(uint256 validatorID, uint256 value) external onlySFC {
driver.updateValidatorWeight(validatorID, value);
}

/// Update public key of a validator. Used to propagate a change from SFC to the client.
function updateValidatorPubkey(uint256 validatorID, bytes calldata pubkey) external onlySFC {
driver.updateValidatorPubkey(validatorID, pubkey);
}

/// Set an initial validator into SFC. Called only as part of network initialization/genesis file generating.
function setGenesisValidator(
address auth,
uint256 validatorID,
Expand All @@ -128,18 +150,18 @@ contract NodeDriverAuth is Initializable, Ownable {
sfc.setGenesisValidator(auth, validatorID, pubkey, createdTime);
}

/// Set an initial delegation. Called only as part of network initialization/genesis file generating.
function setGenesisDelegation(address delegator, uint256 toValidatorID, uint256 stake) external onlyDriver {
sfc.setGenesisDelegation(delegator, toValidatorID, stake);
}

/// Deactivate a validator. Called by network node when a double-sign of the given validator is registered.
/// Is called before sealEpoch() call.
function deactivateValidator(uint256 validatorID, uint256 status) external onlyDriver {
sfc.deactivateValidator(validatorID, status);
}

function sealEpochValidators(uint256[] calldata nextValidatorIDs) external onlyDriver {
sfc.sealEpochValidators(nextValidatorIDs);
}

/// Seal epoch. Called BEFORE epoch sealing made by the client itself.
function sealEpoch(
uint256[] calldata offlineTimes,
uint256[] calldata offlineBlocks,
Expand All @@ -150,6 +172,11 @@ contract NodeDriverAuth is Initializable, Ownable {
sfc.sealEpoch(offlineTimes, offlineBlocks, uptimes, originatedTxsFee, usedGas);
}

/// Seal epoch. Called AFTER epoch sealing made by the client itself.
function sealEpochValidators(uint256[] calldata nextValidatorIDs) external onlyDriver {
sfc.sealEpochValidators(nextValidatorIDs);
}

function isContract(address account) internal view returns (bool) {
uint256 size;
// solhint-disable-next-line no-inline-assembly
Expand Down
Loading