diff --git a/contracts/GroupsData.sol b/contracts/GroupsData.sol index 0fa3037d2..aa157ef70 100644 --- a/contracts/GroupsData.sol +++ b/contracts/GroupsData.sol @@ -18,6 +18,7 @@ */ pragma solidity ^0.5.3; +pragma experimental ABIEncoderV2; import "./Permissions.sol"; import "./interfaces/IGroupsData.sol"; @@ -53,6 +54,8 @@ contract GroupsData is IGroupsData, Permissions { // contain all groups mapping (bytes32 => Group) public groups; + // past groups common BLS public keys + mapping (bytes32 => uint[4][]) public previousPublicKeys; // mapping for checking Has Node already joined to the group mapping (bytes32 => GroupCheck) exceptions; @@ -101,6 +104,10 @@ contract GroupsData is IGroupsData, Permissions { uint publicKeyx2, uint publicKeyy2) external allow("SkaleDKG") { + if (!isPublicKeyZero(groupIndex)) { + uint[4] memory previousKey = groups[groupIndex].groupsPublicKey; + previousPublicKeys[groupIndex].push(previousKey); + } groups[groupIndex].groupsPublicKey[0] = publicKeyx1; groups[groupIndex].groupsPublicKey[1] = publicKeyy1; groups[groupIndex].groupsPublicKey[2] = publicKeyx2; @@ -165,6 +172,8 @@ contract GroupsData is IGroupsData, Permissions { groups[groupIndex].active = false; delete groups[groupIndex].groupData; delete groups[groupIndex].recommendedNumberOfNodes; + uint[4] memory previousKey = groups[groupIndex].groupsPublicKey; + previousPublicKeys[groupIndex].push(previousKey); delete groups[groupIndex].groupsPublicKey; delete groups[groupIndex]; // delete channel @@ -217,6 +226,19 @@ contract GroupsData is IGroupsData, Permissions { ); } + function getPreviousGroupsPublicKey(bytes32 groupIndex) external view returns (uint, uint, uint, uint) { + uint length = previousPublicKeys[groupIndex].length; + if (length == 0) { + return (0, 0, 0, 0); + } + return ( + previousPublicKeys[groupIndex][length - 1][0], + previousPublicKeys[groupIndex][length - 1][1], + previousPublicKeys[groupIndex][length - 1][2], + previousPublicKeys[groupIndex][length - 1][3] + ); + } + function isGroupFailedDKG(bytes32 groupIndex) external view returns (bool) { return !groups[groupIndex].succesfulDKG; } @@ -266,4 +288,12 @@ contract GroupsData is IGroupsData, Permissions { Permissions.initialize(newContractsAddress); executorName = newExecutorName; } + + function isPublicKeyZero(bytes32 groupIndex) internal view returns (bool) { + return groups[groupIndex].groupsPublicKey[0] == 0 && + groups[groupIndex].groupsPublicKey[1] == 0 && + groups[groupIndex].groupsPublicKey[2] == 0 && + groups[groupIndex].groupsPublicKey[3] == 0; + } + } diff --git a/contracts/SchainsData.sol b/contracts/SchainsData.sol index 38e35b559..1d5aebd5a 100644 --- a/contracts/SchainsData.sol +++ b/contracts/SchainsData.sol @@ -37,6 +37,7 @@ contract SchainsData is GroupsData { uint8 partOfNode; uint lifetime; uint32 startDate; + uint startBlock; uint deposit; uint64 index; } @@ -96,6 +97,7 @@ contract SchainsData is GroupsData { schains[schainId].name = name; schains[schainId].owner = from; schains[schainId].startDate = uint32(block.timestamp); + schains[schainId].startBlock = block.number; schains[schainId].lifetime = lifetime; schains[schainId].deposit = deposit; schains[schainId].index = numberOfSchains; diff --git a/contracts/SkaleDKG.sol b/contracts/SkaleDKG.sol index 84a04e219..a8254ce4e 100644 --- a/contracts/SkaleDKG.sol +++ b/contracts/SkaleDKG.sol @@ -57,10 +57,10 @@ contract SkaleDKG is Permissions { Fp2 publicKeyy; uint numberOfCompleted; bool[] completed; - uint startedBlockNumber; + uint startedBlockTimestamp; uint nodeToComplaint; uint fromNodeToComplaint; - uint startComplaintBlockNumber; + uint startComplaintBlockTimestamp; } struct Fp2 { @@ -187,17 +187,17 @@ contract SkaleDKG is Permissions { // need to wait a response from toNodeIndex channels[groupIndex].nodeToComplaint = toNodeIndex; channels[groupIndex].fromNodeToComplaint = fromNodeIndex; - channels[groupIndex].startComplaintBlockNumber = block.number; + channels[groupIndex].startComplaintBlockTimestamp = block.timestamp; emit ComplaintSent(groupIndex, fromNodeIndex, toNodeIndex); } else if (isBroadcasted(groupIndex, toNodeIndex) && channels[groupIndex].nodeToComplaint != toNodeIndex) { revert("One complaint has already sent"); } else if (isBroadcasted(groupIndex, toNodeIndex) && channels[groupIndex].nodeToComplaint == toNodeIndex) { - require(channels[groupIndex].startComplaintBlockNumber.add(120) <= block.number, "One more complaint rejected"); + require(channels[groupIndex].startComplaintBlockTimestamp.add(1800) <= block.timestamp, "One more complaint rejected"); // need to penalty Node - toNodeIndex finalizeSlashing(groupIndex, channels[groupIndex].nodeToComplaint); } else if (!isBroadcasted(groupIndex, toNodeIndex)) { // if node have not broadcasted params - require(channels[groupIndex].startedBlockNumber.add(120) <= block.number, "Complaint rejected"); + require(channels[groupIndex].startedBlockTimestamp.add(1800) <= block.timestamp, "Complaint rejected"); // need to penalty Node - toNodeIndex finalizeSlashing(groupIndex, channels[groupIndex].nodeToComplaint); } @@ -215,12 +215,6 @@ contract SkaleDKG is Permissions { { require(channels[groupIndex].nodeToComplaint == fromNodeIndex, "Not this Node"); require(isNodeByMessageSender(fromNodeIndex, msg.sender), "Node does not exist for message sender"); - - // uint secret = decryptMessage(groupIndex, secretNumber); - - // DKG verification(secret key contribution, verification vector) - // uint indexOfNode = findNode(groupIndex, fromNodeIndex); - // bytes memory verVec = data[groupIndex][indexOfNode].verificationVector; bool verificationResult = verify( groupIndex, fromNodeIndex, @@ -275,13 +269,13 @@ contract SkaleDKG is Permissions { bool complaintSending = channels[groupIndex].nodeToComplaint == uint(-1) || ( channels[groupIndex].broadcasted[indexTo] && - channels[groupIndex].startComplaintBlockNumber.add(120) <= block.number && + channels[groupIndex].startComplaintBlockTimestamp.add(1800) <= block.timestamp && channels[groupIndex].nodeToComplaint == toNodeIndex ) || ( !channels[groupIndex].broadcasted[indexTo] && channels[groupIndex].nodeToComplaint == toNodeIndex && - channels[groupIndex].startedBlockNumber.add(120) <= block.number + channels[groupIndex].startedBlockTimestamp.add(1800) <= block.timestamp ); return channels[groupIndex].active && indexFrom < IGroupsData(channels[groupIndex].dataAddress).getNumberOfNodesInGroup(groupIndex) && diff --git a/contracts/SkaleToken.sol b/contracts/SkaleToken.sol index b71c3b249..373d8fe16 100644 --- a/contracts/SkaleToken.sol +++ b/contracts/SkaleToken.sol @@ -46,7 +46,7 @@ contract SkaleToken is LockableERC777, Permissions, IDelegatableToken { Permissions.initialize(contractsAddress); // TODO remove after testing - uint money = 1e7 * 10 ** DECIMALS; + uint money = 5e9 * 10 ** DECIMALS; _mint( address(0), address(msg.sender), diff --git a/migrations/1_deploy_skale_manager_system.js b/migrations/1_deploy_skale_manager_system.js index 10606882e..aced40add 100644 --- a/migrations/1_deploy_skale_manager_system.js +++ b/migrations/1_deploy_skale_manager_system.js @@ -134,13 +134,19 @@ async function deploy(deployer, networkName, accounts) { console.log("Contract", contract, "with address", address, "is registered in Contract Manager"); }); } - - console.log("Done"); await deployer.deploy(SkaleToken, contractManager.address, [], {gas: gasLimit * gas_multiplier}); await contractManager.methods.setContractsAddress("SkaleToken", SkaleToken.address).send({from: deployAccount}).then(function(res) { console.log("Contract Skale Token with address", SkaleToken.address, "registred in Contract Manager"); }); + + // TODO: Remove after testing + const skaleTokenInst = await SkaleToken.deployed(); + await skaleTokenInst.send( + deployed.get("SkaleBalances").address, + "1000000000000000000000000000", + "0x000000000000000000000000" + deployed.get("SkaleManager").address.slice(2) + ); console.log('Deploy done, writing results...'); diff --git a/test/SchainsData.ts b/test/SchainsData.ts index 5721d33ad..d94559ea9 100644 --- a/test/SchainsData.ts +++ b/test/SchainsData.ts @@ -18,18 +18,22 @@ class Schain { public partOfNode: number; public lifetime: BigNumber; public startDate: BigNumber; + public startBlock: BigNumber; public deposit: BigNumber; public index: BigNumber; - constructor(arrayData: [string, string, BigNumber, BigNumber, BigNumber, BigNumber, BigNumber, BigNumber]) { + constructor( + arrayData: [string, string, BigNumber, BigNumber, BigNumber, BigNumber, BigNumber, BigNumber, BigNumber], + ) { this.name = arrayData[0]; this.owner = arrayData[1]; this.indexInOwnerList = new BigNumber(arrayData[2]); this.partOfNode = new BigNumber(arrayData[3]).toNumber(); this.lifetime = new BigNumber(arrayData[4]); this.startDate = new BigNumber(arrayData[5]); - this.deposit = new BigNumber(arrayData[6]); - this.index = new BigNumber(arrayData[7]); + this.startBlock = new BigNumber(arrayData[6]); + this.deposit = new BigNumber(arrayData[7]); + this.index = new BigNumber(arrayData[8]); } } diff --git a/test/SchainsFunctionality.ts b/test/SchainsFunctionality.ts index 7a5ff41c8..13e35f2a9 100644 --- a/test/SchainsFunctionality.ts +++ b/test/SchainsFunctionality.ts @@ -444,11 +444,16 @@ contract("SchainsFunctionality", ([owner, holder, validator]) => { obtainedPart, obtainedLifetime, obtainedStartDate, + obtainedBlock, obtainedDeposit, obtainedIndex] = schainsArray; obtainedSchainName.should.be.equal("d2"); obtainedSchainOwner.should.be.equal(holder); + console.log(obtainedPart.toString()); + console.log(obtainedLifetime.toString()); + console.log(obtainedDeposit.toString()); + console.log(deposit.toString()); expect(obtainedPart.eq(web3.utils.toBN(1))).be.true; expect(obtainedLifetime.eq(web3.utils.toBN(5))).be.true; expect(obtainedDeposit.eq(web3.utils.toBN(deposit))).be.true; diff --git a/test/SkaleToken.ts b/test/SkaleToken.ts index edc803a9f..ecfbdb8b8 100644 --- a/test/SkaleToken.ts +++ b/test/SkaleToken.ts @@ -15,7 +15,7 @@ contract("SkaleToken", ([owner, holder, receiver, nilAddress, accountWith99]) => let contractManager: ContractManagerInstance; const TOKEN_CAP: number = 7000000000; - const TOTAL_SUPPLY = 10000000; + const TOTAL_SUPPLY = 5000000000; console.log("Holder", holder); console.log("Owner", owner); @@ -99,7 +99,7 @@ contract("SkaleToken", ([owner, holder, receiver, nilAddress, accountWith99]) => it("an owner address should have more than 0 tokens", async () => { const balance = new BigNumber(await skaleToken.balanceOf(owner)); - assert(balance.isEqualTo(toWei(10000000))); + expect(balance.isEqualTo(toWei(5000000000))); }); it("should emit a Transfer Event", async () => {