Skip to content

Commit

Permalink
Merge pull request #1165 from skalenetwork/bugfix/fix-agent-authoriza…
Browse files Browse the repository at this point in the history
…tions

Add agent authorized check
  • Loading branch information
payvint authored Jun 24, 2022
2 parents 2596539 + ff15f79 commit f6315a4
Show file tree
Hide file tree
Showing 19 changed files with 531 additions and 124 deletions.
1 change: 1 addition & 0 deletions proxy/contracts/mainnet/MessageProxyForMainnet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ contract MessageProxyForMainnet is SkaleManagerClient, MessageProxy, IMessagePro
{
uint256 gasTotal = gasleft();
bytes32 fromSchainHash = keccak256(abi.encodePacked(fromSchainName));
require(isAgentAuthorized(fromSchainHash, msg.sender), "Agent is not authorized");
require(_checkSchainBalance(fromSchainHash), "Schain wallet has not enough funds");
require(connectedChains[fromSchainHash].inited, "Chain is not initialized");
require(messages.length <= MESSAGES_LENGTH, "Too many messages");
Expand Down
5 changes: 5 additions & 0 deletions proxy/contracts/mainnet/SkaleManagerClient.sol
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,9 @@ contract SkaleManagerClient is Initializable, AccessControlEnumerableUpgradeable
address skaleChainsInternal = contractManagerOfSkaleManager.getContract("SchainsInternal");
return ISchainsInternal(skaleChainsInternal).isOwnerAddress(sender, schainHash);
}

function isAgentAuthorized(bytes32 schainHash, address sender) public view override returns (bool) {
address skaleChainsInternal = contractManagerOfSkaleManager.getContract("SchainsInternal");
return ISchainsInternal(skaleChainsInternal).isNodeAddressesInGroup(schainHash, sender);
}
}
22 changes: 21 additions & 1 deletion proxy/contracts/test/TestNodes.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pragma solidity 0.8.6;
interface INodesTester {
function createNode(address, Nodes.NodeCreationParams calldata params) external;
function getNodeAddress(uint nodeIndex) external view returns (address);
function isNodeExist(address from, uint nodeIndex) external view returns (bool);
}


Expand Down Expand Up @@ -56,14 +57,21 @@ contract Nodes is INodesTester {
string domainName;
}

struct CreatedNodes {
mapping (uint => bool) isNodeExist;
uint numberOfNodes;
}

Node[] public nodes;

mapping (address => CreatedNodes) public nodeIndexes;

modifier checkNodeExists(uint nodeIndex) {
_checkNodeIndex(nodeIndex);
_;
}

function createNode(address, NodeCreationParams calldata params)
function createNode(address from, NodeCreationParams calldata params)
external override
{
nodes.push(Node({
Expand All @@ -78,6 +86,8 @@ contract Nodes is INodesTester {
status: NodeStatus.Active,
validatorId: 1337
}));
nodeIndexes[from].isNodeExist[nodes.length - 1] = true;
nodeIndexes[from].numberOfNodes++;
}

function getNodeAddress(uint nodeIndex)
Expand All @@ -90,6 +100,16 @@ contract Nodes is INodesTester {
return _publicKeyToAddress(nodes[nodeIndex].publicKey);
}

function isNodeExist(address from, uint nodeIndex)
public
view
override
checkNodeExists(nodeIndex)
returns (bool)
{
return nodeIndexes[from].isNodeExist[nodeIndex];
}

function _checkNodeIndex(uint nodeIndex) private view {
require(nodeIndex < nodes.length, "Node with such index does not exist");
}
Expand Down
25 changes: 18 additions & 7 deletions proxy/contracts/test/TestSchainsInternal.sol
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ interface ISchainsInternalTester {
function isSchainExist(bytes32 schainHash) external view returns (bool);
function getSchains() external view returns (bytes32[] memory);
function getSchainName(bytes32 schainHash) external view returns (string memory);
function getNodesInGroup(bytes32 schainHash) external view returns (uint[] memory);
}


Expand Down Expand Up @@ -66,6 +67,8 @@ contract SchainsInternal is ISchainsInternalTester {

bytes32[] public schainsAtSystem;

mapping (bytes32 => mapping (address => bool)) private _nodeAddressInSchain;

function addContractManager(address newContractManager) external override {
contractManager = ContractManager(newContractManager);
}
Expand All @@ -89,17 +92,16 @@ contract SchainsInternal is ISchainsInternalTester {
}

function addNodesToSchainsGroups(bytes32 schainHash, uint[] memory nodes) external override {
Nodes nodesContract = Nodes(contractManager.getContract("Nodes"));
schainsGroups[schainHash] = nodes;
for (uint i = 0; i < nodes.length; i++) {
address nodeAddress = nodesContract.getNodeAddress(nodes[i]);
_nodeAddressInSchain[schainHash][nodeAddress] = true;
}
}

function isNodeAddressesInGroup(bytes32 schainHash, address sender) external view override returns (bool) {
Nodes nodes = Nodes(contractManager.getContract("Nodes"));
for (uint i = 0; i < schainsGroups[schainHash].length; i++) {
if (nodes.getNodeAddress(schainsGroups[schainHash][i]) == sender) {
return true;
}
}
return true;
return _nodeAddressInSchain[schainHash][sender];
}

function isOwnerAddress(address from, bytes32 schainHash) external view override returns (bool) {
Expand All @@ -122,4 +124,13 @@ contract SchainsInternal is ISchainsInternalTester {
{
return schains[schainHash].name;
}

function getNodesInGroup(bytes32 schainHash)
external
view
override
returns (uint[] memory)
{
return schainsGroups[schainHash];
}
}
57 changes: 31 additions & 26 deletions proxy/gas/calculateGas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,11 @@ import { deployTokenManagerERC1155 } from "../test/utils/deploy/schain/tokenMana
import { deployMessageProxyForSchain } from "../test/utils/deploy/schain/messageProxyForSchain";
import { deployMessages } from "../test/utils/deploy/messages";

import { randomString, stringValue } from "../test/utils/helper";
import { randomString, stringValue, getPublicKey } from "../test/utils/helper";

import { ethers, web3 } from "hardhat";
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/dist/src/signer-with-address";
import { BigNumber, BytesLike } from "ethers";
import { BigNumber, BytesLike, Wallet } from "ethers";

import { assert, expect } from "chai";
import { deployCommunityLocker } from "../test/utils/deploy/schain/communityLocker";
Expand All @@ -101,6 +101,8 @@ describe("Gas calculation", () => {
let deployer: SignerWithAddress;
let user: SignerWithAddress;
let schainOwner: SignerWithAddress;
let richGuy: SignerWithAddress;
let nodeAddress: Wallet;

let imaLinker: Linker;
let depositBoxEth: DepositBoxEth;
Expand Down Expand Up @@ -141,9 +143,17 @@ describe("Gas calculation", () => {
const mainnetName = "Mainnet";

before(async () => {
[deployer, schainOwner, user] = await ethers.getSigners();
[deployer, schainOwner, user, richGuy] = await ethers.getSigners();
nodeAddress = Wallet.createRandom().connect(ethers.provider);
const balanceRichGuy = await richGuy.getBalance();
await richGuy.sendTransaction({to: nodeAddress.address, value: balanceRichGuy.sub(ethers.utils.parseEther("1"))});
})

after(async () => {
const balanceNode = await nodeAddress.getBalance();
await nodeAddress.sendTransaction({to: richGuy.address, value: balanceNode.sub(ethers.utils.parseEther("1"))});
});

beforeEach(async () => {
// skale-manager mock preparation
contractManager = await deployContractManager(contractManagerAddress);
Expand All @@ -165,37 +175,32 @@ describe("Gas calculation", () => {
await schainsInternal.connect(deployer).addContractManager(contractManager.address);
await wallets.connect(deployer).addContractManager(contractManager.address);

const nodePublicKey: [BytesLike, BytesLike] = [
"0x1122334455667788990011223344556677889900112233445566778899001122",
"0x1122334455667788990011223344556677889900112233445566778899001122"
];

// setup 16 nodes
const nodeCreationParams = {
port: 1337,
nonce: 1337,
ip: "0x12345678",
publicIp: "0x12345678",
publicKey: nodePublicKey,
publicKey: getPublicKey(nodeAddress),
name: "GasCalculationNode",
domainName: "gascalculationnode.com"
};
await nodes.connect(deployer).createNode(deployer.address, nodeCreationParams);
await nodes.connect(deployer).createNode(deployer.address, nodeCreationParams);
await nodes.connect(deployer).createNode(deployer.address, nodeCreationParams);
await nodes.connect(deployer).createNode(deployer.address, nodeCreationParams);
await nodes.connect(deployer).createNode(deployer.address, nodeCreationParams);
await nodes.connect(deployer).createNode(deployer.address, nodeCreationParams);
await nodes.connect(deployer).createNode(deployer.address, nodeCreationParams);
await nodes.connect(deployer).createNode(deployer.address, nodeCreationParams);
await nodes.connect(deployer).createNode(deployer.address, nodeCreationParams);
await nodes.connect(deployer).createNode(deployer.address, nodeCreationParams);
await nodes.connect(deployer).createNode(deployer.address, nodeCreationParams);
await nodes.connect(deployer).createNode(deployer.address, nodeCreationParams);
await nodes.connect(deployer).createNode(deployer.address, nodeCreationParams);
await nodes.connect(deployer).createNode(deployer.address, nodeCreationParams);
await nodes.connect(deployer).createNode(deployer.address, nodeCreationParams);
await nodes.connect(deployer).createNode(deployer.address, nodeCreationParams);
await nodes.connect(deployer).createNode(nodeAddress.address, nodeCreationParams);
await nodes.connect(deployer).createNode(nodeAddress.address, nodeCreationParams);
await nodes.connect(deployer).createNode(nodeAddress.address, nodeCreationParams);
await nodes.connect(deployer).createNode(nodeAddress.address, nodeCreationParams);
await nodes.connect(deployer).createNode(nodeAddress.address, nodeCreationParams);
await nodes.connect(deployer).createNode(nodeAddress.address, nodeCreationParams);
await nodes.connect(deployer).createNode(nodeAddress.address, nodeCreationParams);
await nodes.connect(deployer).createNode(nodeAddress.address, nodeCreationParams);
await nodes.connect(deployer).createNode(nodeAddress.address, nodeCreationParams);
await nodes.connect(deployer).createNode(nodeAddress.address, nodeCreationParams);
await nodes.connect(deployer).createNode(nodeAddress.address, nodeCreationParams);
await nodes.connect(deployer).createNode(nodeAddress.address, nodeCreationParams);
await nodes.connect(deployer).createNode(nodeAddress.address, nodeCreationParams);
await nodes.connect(deployer).createNode(nodeAddress.address, nodeCreationParams);
await nodes.connect(deployer).createNode(nodeAddress.address, nodeCreationParams);
await nodes.connect(deployer).createNode(nodeAddress.address, nodeCreationParams);

// initialize schain and data
await schainsInternal.connect(deployer).initializeSchain(schainName, schainOwner.address, 12345678, 12345678);
Expand Down Expand Up @@ -565,7 +570,7 @@ describe("Gas calculation", () => {
};

async function postIncomingMessages(startingCounter: number, arrayOfMessages: any, action: string) {
const res = await (await messageProxyForMainnet.connect(deployer).postIncomingMessages(
const res = await (await messageProxyForMainnet.connect(nodeAddress).postIncomingMessages(
schainName,
startingCounter,
arrayOfMessages,
Expand Down
33 changes: 33 additions & 0 deletions proxy/migrations/deploySkaleManagerComponents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import { deployLibraries, getLinkedContractFactory } from "./tools/factory";
import { getAbi } from './tools/abi';
import { Manifest, hashBytecode } from "@openzeppelin/upgrades-core";
import { KeyStorageMock } from '../typechain/KeyStorageMock';
import { Wallet } from 'ethers';
import { getPublicKey, stringValue } from '../test/utils/helper';

export function getContractKeyInAbiFile(contract: string) {
return contract.replace(/([a-z0-9])(?=[A-Z])/g, '$1_').toLowerCase();
Expand Down Expand Up @@ -114,6 +116,8 @@ async function main() {

await schains.addContractManager( contractManager.address );
console.log("Add ContractManager address", contractManager.address, "as ContractManager to Contract Schains", schains.address, "\n");
await schainsInternal.addContractManager( contractManager.address );
console.log("Add ContractManager address", contractManager.address, "as ContractManager to Contract SchainsInternal", schainsInternal.address, "\n");
await wallets.addContractManager( contractManager.address );
console.log("Add ContractManager address", contractManager.address, "as ContractManager to Contract Wallets", wallets.address, "\n");
await contractManager.setContractsAddress( "Schains", schains.address );
Expand All @@ -128,8 +132,37 @@ async function main() {
console.log("Set KeyStorage", keyStorage.address, "to ContractManager", contractManager.address, "\n");
await contractManager.setContractsAddress( "Nodes", nodes.address );
console.log("Set Nodes", nodes.address, "to ContractManager", contractManager.address, "\n");
const nodeAddress1 = new Wallet(stringValue(process.env.PRIVATE_KEY_FOR_ETHEREUM)).connect(ethers.provider);
const nodeAddress2 = new Wallet(stringValue(process.env.PRIVATE_KEY_FOR_SCHAIN)).connect(ethers.provider);
await owner.sendTransaction({to: nodeAddress1.address, value: ethers.utils.parseEther("1")});
await owner.sendTransaction({to: nodeAddress2.address, value: ethers.utils.parseEther("1")});

const nodeCreationParams1 = {
port: 1337,
nonce: 1337,
ip: "0x12345678",
publicIp: "0x12345678",
publicKey: getPublicKey(nodeAddress1),
name: "TestNode1",
domainName: "testnode1.com"
};
const nodeCreationParams2 = {
port: 1337,
nonce: 1337,
ip: "0x12345678",
publicIp: "0x12345678",
publicKey: getPublicKey(nodeAddress1),
name: "TestNode2",
domainName: "testnode2.com"
};
await nodes.connect(owner).createNode(nodeAddress1.address, nodeCreationParams1);
console.log("Create Node 0 with address", nodeAddress1.address, "\n");
await nodes.connect(owner).createNode(nodeAddress2.address, nodeCreationParams2);
console.log("Create Node 1 with address", nodeAddress2.address, "\n");
await schainsInternal.initializeSchain( schainName, owner.address, 1, 1 );
console.log("Initialize Schain", schainName, "with address", owner.address, "\n");
await schainsInternal.connect(owner).addNodesToSchainsGroups(stringValue(ethers.utils.id(schainName)), [0, 1]);
console.log("Add Nodes 0 and 1 to schain", schainName, "\n");
const BLSPublicKey = {
x: {
a: "8276253263131369565695687329790911140957927205765534740198480597854608202714",
Expand Down
3 changes: 2 additions & 1 deletion proxy/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"@openzeppelin/contracts-upgradeable": "^4.3.2",
"@openzeppelin/hardhat-upgrades": "^1.9.0",
"@skalenetwork/etherbase-interfaces": "^0.0.1-develop.20",
"@skalenetwork/ima-interfaces": "1.0.0-develop.16",
"@skalenetwork/ima-interfaces": "1.0.0-develop.17",
"@skalenetwork/skale-manager-interfaces": "1.0.0-develop.1",
"axios": "^0.21.4",
"dotenv": "^10.0.0",
Expand All @@ -45,6 +45,7 @@
"@types/chai": "^4.2.12",
"@types/chai-almost": "^1.0.1",
"@types/chai-as-promised": "^7.1.3",
"@types/elliptic": "^6.4.14",
"@types/minimist": "^1.2.0",
"@types/mocha": "^8.2.2",
"@types/sinon-chai": "^3.2.5",
Expand Down
Loading

0 comments on commit f6315a4

Please sign in to comment.