Skip to content

Commit

Permalink
remove public key after wait time
Browse files Browse the repository at this point in the history
  • Loading branch information
darcys22 committed Dec 1, 2023
1 parent 8a73bf6 commit 9dc4654
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 4 deletions.
8 changes: 5 additions & 3 deletions contracts/ServiceNodeRewards.sol
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ contract ServiceNodeRewards is Ownable {
error BLSPubkeyAlreadyExists(uint64 serviceNodeID);
error RecipientAddressNotProvided(uint64 serviceNodeID);
error EarlierLeaveRequestMade(uint64 serviceNodeID, address recipient);
error LeaveRequestTooEarly(uint64 serviceNodeID, uint256 timestamp);
error LeaveRequestTooEarly(uint64 serviceNodeID, uint256 timestamp, uint256 currenttime);
error ServiceNodeDoesntExist(uint64 serviceNodeID);
error InvalidBLSSignature();
error InvalidBLSProofOfPossession();
Expand Down Expand Up @@ -266,8 +266,10 @@ contract ServiceNodeRewards is Ownable {
/// @notice Removes a BLS public key after a specified wait time, this can be called without the BLS signature because the node has waited extra long .
/// @param serviceNodeID The ID of the service node to be removed.
function removeBLSPublicKeyAfterWaitTime(uint64 serviceNodeID) external {
uint256 timestamp = serviceNodes[serviceNodeID].leaveRequestTimestamp + MAX_SERVICE_NODE_REMOVAL_WAIT_TIME;
if(block.timestamp < timestamp) revert LeaveRequestTooEarly(serviceNodeID, timestamp);
uint256 leaveRequestTimestamp = serviceNodes[serviceNodeID].leaveRequestTimestamp;
if(leaveRequestTimestamp == 0) revert LeaveRequestTooEarly(serviceNodeID, leaveRequestTimestamp, block.timestamp);
uint256 timestamp = leaveRequestTimestamp + MAX_SERVICE_NODE_REMOVAL_WAIT_TIME;
if(block.timestamp < timestamp) revert LeaveRequestTooEarly(serviceNodeID, timestamp, block.timestamp);
_removeBLSPublicKey(serviceNodeID);
}

Expand Down
2 changes: 1 addition & 1 deletion test/cpp/external/ethyl
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class ServiceNodeRewardsContract {

Transaction liquidateBLSPublicKeyWithSignature(const uint64_t service_node_id, const std::string& sig, const std::vector<uint64_t>& non_signer_indices);
Transaction initiateRemoveBLSPublicKey(const uint64_t service_node_id);
Transaction removeBLSPublicKeyAfterWaitTime(const uint64_t service_node_id);

Transaction checkSigAGG(const std::string& sig, const std::string& message);
Transaction checkAggPubkey(const std::string& aggPubkey);
Expand Down
8 changes: 8 additions & 0 deletions test/cpp/src/service_node_rewards_contract.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ Transaction ServiceNodeRewardsContract::initiateRemoveBLSPublicKey(const uint64_
return tx;
}

Transaction ServiceNodeRewardsContract::removeBLSPublicKeyAfterWaitTime(const uint64_t service_node_id) {
Transaction tx(contractAddress, 0, 3000000);
std::string functionSelector = utils::getFunctionSignature("removeBLSPublicKeyAfterWaitTime(uint64)");
std::string node_id_padded = utils::padTo32Bytes(utils::decimalToHex(service_node_id), utils::PaddingDirection::LEFT);
tx.data = functionSelector + node_id_padded;
return tx;
}

//TODO sean review this function
Transaction ServiceNodeRewardsContract::checkSigAGG(const std::string& sig, const std::string& message) {
Transaction tx(contractAddress, 0, 30000000);
Expand Down
57 changes: 57 additions & 0 deletions test/cpp/test/src/rewards_contract.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <iostream>
#include <limits>
#include <chrono>

#include "ethyl/provider.hpp"
#include "ethyl/signer.hpp"
Expand Down Expand Up @@ -141,4 +142,60 @@ TEST_CASE( "Rewards Contract", "[ethereum]" ) {
REQUIRE_THROWS(signer.sendTransaction(tx, badseckey));
REQUIRE(rewards_contract.serviceNodesLength() == 3);
}

SECTION( "Remove public key after wait time should fail if node hasn't initiated removal" ) {
ServiceNodeList snl(3);
for(auto& node : snl.nodes) {
const auto pubkey = node.getPublicKeyHex();
const auto proof_of_possession = node.proofOfPossession(config.CHAIN_ID, contract_address);
tx = rewards_contract.addBLSPublicKey(pubkey, proof_of_possession);
signer.sendTransaction(tx, seckey);
}
const uint64_t service_node_to_remove = snl.randomServiceNodeID();
tx = rewards_contract.removeBLSPublicKeyAfterWaitTime(service_node_to_remove);
REQUIRE_THROWS(signer.sendTransaction(tx, seckey));
REQUIRE(rewards_contract.serviceNodesLength() == 3);
}

SECTION( "Remove public key after wait time should fail if not enough time has passed since node initiated removal" ) {
ServiceNodeList snl(3);
for(auto& node : snl.nodes) {
const auto pubkey = node.getPublicKeyHex();
const auto proof_of_possession = node.proofOfPossession(config.CHAIN_ID, contract_address);
tx = rewards_contract.addBLSPublicKey(pubkey, proof_of_possession);
signer.sendTransaction(tx, seckey);
}
const uint64_t service_node_to_remove = snl.randomServiceNodeID();
tx = rewards_contract.initiateRemoveBLSPublicKey(service_node_to_remove);
hash = signer.sendTransaction(tx, seckey);
REQUIRE(hash != "");
REQUIRE(provider->transactionSuccessful(hash));
tx = rewards_contract.removeBLSPublicKeyAfterWaitTime(service_node_to_remove);
REQUIRE_THROWS(signer.sendTransaction(tx, seckey));
REQUIRE(rewards_contract.serviceNodesLength() == 3);
}

SECTION( "Remove public key after wait time should succeed if enough time has passed since node initiated removal" ) {
ServiceNodeList snl(3);
for(auto& node : snl.nodes) {
const auto pubkey = node.getPublicKeyHex();
const auto proof_of_possession = node.proofOfPossession(config.CHAIN_ID, contract_address);
tx = rewards_contract.addBLSPublicKey(pubkey, proof_of_possession);
signer.sendTransaction(tx, seckey);
}
const uint64_t service_node_to_remove = snl.randomServiceNodeID();
tx = rewards_contract.initiateRemoveBLSPublicKey(service_node_to_remove);
hash = signer.sendTransaction(tx, seckey);
REQUIRE(hash != "");
REQUIRE(provider->transactionSuccessful(hash));
// Fast forward 31 days
provider->evm_increaseTime(std::chrono::hours(31 * 24));
tx = rewards_contract.removeBLSPublicKeyAfterWaitTime(service_node_to_remove);
hash = signer.sendTransaction(tx, seckey);
REQUIRE(hash != "");
REQUIRE(provider->transactionSuccessful(hash));
REQUIRE(rewards_contract.serviceNodesLength() == 2);
snl.deleteNode(service_node_to_remove);
REQUIRE(rewards_contract.aggregatePubkey() == "0x" + snl.aggregatePubkeyHex());
}
}

0 comments on commit 9dc4654

Please sign in to comment.