Skip to content

Commit

Permalink
Add NodeDriver docs
Browse files Browse the repository at this point in the history
  • Loading branch information
thaarok committed Nov 1, 2024
1 parent 20fc210 commit 48c9947
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 8 deletions.
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

0 comments on commit 48c9947

Please sign in to comment.