diff --git a/contracts/SkaleDKG.sol b/contracts/SkaleDKG.sol index 317e78bee..7f34a5d7f 100644 --- a/contracts/SkaleDKG.sol +++ b/contracts/SkaleDKG.sol @@ -260,12 +260,59 @@ contract SkaleDKG is Permissions { return channels[groupIndex].active; } + function isBroadcastPossible(bytes32 groupIndex, uint nodeIndex) external view returns (bool) { + uint index = findNode(groupIndex, nodeIndex); + return channels[groupIndex].active && + index < IGroupsData(channels[groupIndex].dataAddress).getNumberOfNodesInGroup(groupIndex) && + isNodeByMessageSender(nodeIndex, msg.sender) && + !channels[groupIndex].broadcasted[index]; + } + + function isComplaintPossible(bytes32 groupIndex, uint fromNodeIndex, uint toNodeIndex) external view returns (bool) { + uint indexFrom = findNode(groupIndex, fromNodeIndex); + uint indexTo = findNode(groupIndex, toNodeIndex); + bool complaintSending = channels[groupIndex].nodeToComplaint == uint(-1) || + ( + channels[groupIndex].broadcasted[indexTo] && + channels[groupIndex].startComplaintBlockNumber + 120 <= block.number && + channels[groupIndex].nodeToComplaint == toNodeIndex + ) || + ( + !channels[groupIndex].broadcasted[indexTo] && + channels[groupIndex].nodeToComplaint == toNodeIndex && + channels[groupIndex].startedBlockNumber + 120 <= block.number + ); + return channels[groupIndex].active && + indexFrom < IGroupsData(channels[groupIndex].dataAddress).getNumberOfNodesInGroup(groupIndex) && + indexTo < IGroupsData(channels[groupIndex].dataAddress).getNumberOfNodesInGroup(groupIndex) && + isNodeByMessageSender(fromNodeIndex, msg.sender) && + complaintSending; + } + + function isAlrightPossible(bytes32 groupIndex, uint nodeIndex) external view returns (bool) { + uint index = findNode(groupIndex, nodeIndex); + return channels[groupIndex].active && + index < IGroupsData(channels[groupIndex].dataAddress).getNumberOfNodesInGroup(groupIndex) && + isNodeByMessageSender(nodeIndex, msg.sender) && + IGroupsData(channels[groupIndex].dataAddress).getNumberOfNodesInGroup(groupIndex) == channels[groupIndex].numberOfBroadcasted && + !channels[groupIndex].completed[index]; + } + + function isResponsePossible(bytes32 groupIndex, uint nodeIndex) external view returns (bool) { + uint index = findNode(groupIndex, nodeIndex); + return channels[groupIndex].active && + index < IGroupsData(channels[groupIndex].dataAddress).getNumberOfNodesInGroup(groupIndex) && + isNodeByMessageSender(nodeIndex, msg.sender) && + channels[groupIndex].nodeToComplaint == nodeIndex; + } + function finalizeSlashing(bytes32 groupIndex, uint badNode) internal { address schainsFunctionalityInternalAddress = contractManager.contracts( keccak256(abi.encodePacked("SchainsFunctionalityInternal")) ); uint[] memory possibleNodes = ISchainsFunctionalityInternal(schainsFunctionalityInternalAddress).isEnoughNodes(groupIndex); emit BadGuy(badNode); + emit FailedDKG(groupIndex); if (possibleNodes.length > 0) { uint newNode = ISchainsFunctionalityInternal(schainsFunctionalityInternalAddress).replaceNode( badNode, @@ -279,7 +326,6 @@ contract SkaleDKG is Permissions { groupIndex ); IGroupsData(channels[groupIndex].dataAddress).setGroupFailedDKG(groupIndex); - emit FailedDKG(groupIndex); } delete channels[groupIndex]; } diff --git a/package.json b/package.json index 7315515c2..a6df42d72 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "slither": "slither . --exclude naming-convention,solc-version,assembly,timestamp,calls-loop,reentrancy-no-eth,constant-function,pragma --filter-path @openzeppelin/contracts/ --truffle-version truffle@latest" }, "dependencies": { - "@openzeppelin/contracts": "^2.3.0", + "@openzeppelin/contracts": "2.3.0", "@types/chai": "^4.1.7", "@types/chai-as-promised": "^7.1.0", "@types/minimist": "^1.2.0", @@ -45,9 +45,9 @@ "chai": "^4.2.0", "chai-as-promised": "^7.1.1", "ethereumjs-tx": "1.3.7", - "openzeppelin-solidity": "^2.3.0", + "openzeppelin-solidity": "2.3.0", "solc": "^0.5.7", - "truffle": "^5.0.12", + "truffle": "^5.1.5", "truffle-hdwallet-provider": "^1.0.8", "truffle-typings": "^1.0.8", "ts-node": "^8.3.0", @@ -69,4 +69,4 @@ "tslint-no-unused-expression-chai": "^0.1.4", "typescript": "^3.5.2" } -} +} \ No newline at end of file diff --git a/test/SkaleDKG.ts b/test/SkaleDKG.ts index d56fc6630..f4548bc5c 100644 --- a/test/SkaleDKG.ts +++ b/test/SkaleDKG.ts @@ -314,6 +314,26 @@ contract("SkaleDKG", ([validator1, validator2]) => { assert.equal(result.logs[0].args.fromNode.toString(), "0"); }); + it("should broadcast data from 1 node & check", async () => { + const result = await skaleDKG.broadcast( + web3.utils.soliditySha3(schainName), + 0, + verificationVectors[indexes[0]], + encryptedSecretKeyContributions[indexes[0]], + {from: validatorsAccount[0]}, + ); + assert.equal(result.logs[0].event, "BroadcastAndKeyShare"); + assert.equal(result.logs[0].args.groupIndex, web3.utils.soliditySha3(schainName)); + assert.equal(result.logs[0].args.fromNode.toString(), "0"); + + const res = await skaleDKG.isBroadcastPossible( + web3.utils.soliditySha3(schainName), + 0, + {from: validatorsAccount[0]}, + ); + assert(res.should.be.false); + }); + it("should broadcast data from 2 node", async () => { const result = await skaleDKG.broadcast( web3.utils.soliditySha3(schainName), @@ -367,6 +387,24 @@ contract("SkaleDKG", ([validator1, validator2]) => { assert.equal(result.logs[0].args.nodeIndex.toString(), "0"); }); + it("should send alright from 1 node", async () => { + const result = await skaleDKG.allright( + web3.utils.soliditySha3(schainName), + 0, + {from: validatorsAccount[0]}, + ); + assert.equal(result.logs[0].event, "AllDataReceived"); + assert.equal(result.logs[0].args.groupIndex, web3.utils.soliditySha3(schainName)); + assert.equal(result.logs[0].args.nodeIndex.toString(), "0"); + + const res = await skaleDKG.isAlrightPossible( + web3.utils.soliditySha3(schainName), + 0, + {from: validatorsAccount[0]}, + ); + assert(res.should.be.false); + }); + it("should send alright from 2 node", async () => { const result = await skaleDKG.allright( web3.utils.soliditySha3(schainName), @@ -407,7 +445,24 @@ contract("SkaleDKG", ([validator1, validator2]) => { ); }); + it("should check is possible to send complaint", async () => { + const res = await skaleDKG.isComplaintPossible( + web3.utils.soliditySha3(schainName), + 1, + 0, + {from: validatorsAccount[1]}, + ); + assert(res.should.be.false); + }); + it("should send correct response", async () => { + const res = await skaleDKG.isResponsePossible( + web3.utils.soliditySha3(schainName), + 0, + {from: validatorsAccount[0]}, + ); + assert(res.should.be.true); + const result = await skaleDKG.response( web3.utils.soliditySha3(schainName), 0, diff --git a/truffle-config.js b/truffle-config.js index 0bdbb0988..95b1da355 100644 --- a/truffle-config.js +++ b/truffle-config.js @@ -48,7 +48,7 @@ module.exports = { }, compilers: { solc: { - version: "0.5.11", + version: "0.5.15", settings: { optimizer: { enabled: true, diff --git a/yarn.lock b/yarn.lock index f394a60b8..835695385 100644 --- a/yarn.lock +++ b/yarn.lock @@ -126,7 +126,7 @@ web3-eth-abi "1.2.1" web3-utils "1.2.1" -"@openzeppelin/contracts@^2.3.0": +"@openzeppelin/contracts@2.3.0": version "2.3.0" resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-2.3.0.tgz#043961a6e37b87e0eb80647c7528a7c62c41361f" integrity sha512-lf8C3oULQAnsu3OTRP4tP5/ddfil6l65Lg3JQCwAIgc99vZ1jz5qeBoETGGGmczxt+bIyMI06WPP2apC74EZag== @@ -2786,24 +2786,7 @@ ethereumjs-util@^4.0.1, ethereumjs-util@^4.3.0: rlp "^2.0.0" secp256k1 "^3.0.1" -ethereumjs-vm@^2.1.0, ethereumjs-vm@^2.3.4, ethereumjs-vm@^2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-2.6.0.tgz#76243ed8de031b408793ac33907fb3407fe400c6" - integrity sha512-r/XIUik/ynGbxS3y+mvGnbOKnuLo40V5Mj1J25+HEO63aWYREIqvWeRO/hnROlMBE5WoniQmPmhiaN0ctiHaXw== - dependencies: - async "^2.1.2" - async-eventemitter "^0.2.2" - ethereumjs-account "^2.0.3" - ethereumjs-block "~2.2.0" - ethereumjs-common "^1.1.0" - ethereumjs-util "^6.0.0" - fake-merkle-patricia-tree "^1.0.1" - functional-red-black-tree "^1.0.1" - merkle-patricia-tree "^2.3.2" - rustbn.js "~0.2.0" - safe-buffer "^5.1.1" - -"ethereumjs-vm@https://github.com/leapdao/ethereumjs-vm-sc.git#master": +ethereumjs-vm@^2.1.0, ethereumjs-vm@^2.3.4, ethereumjs-vm@^2.6.0, "ethereumjs-vm@https://github.com/leapdao/ethereumjs-vm-sc.git#master": version "2.6.0" resolved "https://github.com/leapdao/ethereumjs-vm-sc.git#1fdd9d832f93bf948bdcf9421a6aa627dde8f574" dependencies: @@ -5432,7 +5415,7 @@ once@1.x, once@^1.3.0, once@^1.3.1, once@^1.4.0: dependencies: wrappy "1" -openzeppelin-solidity@^2.3.0: +openzeppelin-solidity@2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/openzeppelin-solidity/-/openzeppelin-solidity-2.3.0.tgz#1ab7b4cc3782a5472ed61eb740c56a8bfdd74119" integrity sha512-QYeiPLvB1oSbDt6lDQvvpx7k8ODczvE474hb2kLXZBPKMsxKT1WxTCHBYrCU7kS7hfAku4DcJ0jqOyL+jvjwQw== @@ -7272,10 +7255,10 @@ truffle-typings@^1.0.8: "@types/mocha" "^5.2.5" "@types/web3" "^1.0.18" -truffle@^5.0.12: - version "5.0.41" - resolved "https://registry.yarnpkg.com/truffle/-/truffle-5.0.41.tgz#a7ef0b6e97d3a22aaf5da2cc4ef6a13f39596ffb" - integrity sha512-vQm7OHRN8qh4Te3QZ9A74JsDoZfcYoJLuI1FrcLpJoicdTrzCZU4UXGIYFUIZ+UmOTlMS07lUufxDSraSHxpdg== +truffle@^5.1.5: + version "5.1.5" + resolved "https://registry.yarnpkg.com/truffle/-/truffle-5.1.5.tgz#87730b484103bb77e7371a14d69628e1ec20a094" + integrity sha512-9zloOGyY/+kj+lqX6S9eCARrBvCLPlT1y+q41SPP2dfieRLsfXYDmBqgzCh5dSpccABlqkCUvE4nedhqi6Qggg== dependencies: app-module-path "^2.2.0" mocha "5.2.0"