latest changes for cluster key management

This commit is contained in:
vsmk98 2018-12-11 10:07:19 +05:30
parent e22b4929bf
commit 7903dac340
9 changed files with 1179 additions and 593 deletions

View File

@ -393,7 +393,7 @@ func startQuorumPermissionService(ctx *cli.Context, stack *node.Node) {
if v == nil {
utils.Fatalf("Failed to start Quorum Permission API %s", apiName)
}
qapi := v.(*quorum.PermissionAPI)
qapi := v.(*quorum.QuorumControlsAPI)
rpcClient, err := stack.Attach()
if err != nil {
utils.Fatalf("Failed to attach to self: %v", err)

File diff suppressed because one or more lines are too long

View File

@ -7,20 +7,20 @@ contract Clusterkeys {
struct OrgDetails {
string orgId;
string morgId;
string [] privateKey;
string [] tmKey;
string pendingKey;
Operation pendingOp;
}
OrgDetails [] private orgList;
mapping(bytes32 => uint) private OrgIndex;
// Struct for managing the voter accounst for the org
// Struct for managing the voter accounst for the org
struct MasterOrgDetails {
string orgId;
address [] orgVoterAccount;
string [] privateKey;
address [] voterAccount;
string [] tmKey;
}
MasterOrgDetails [] private morgList;
MasterOrgDetails [] private masterOrgList;
mapping(bytes32 => uint) private MasterOrgIndex;
// mapping to monitor the voting status for each acount and
@ -28,31 +28,41 @@ contract Clusterkeys {
mapping (uint => mapping (address => bool)) private voteStatus;
mapping (uint => uint) private voteCount;
uint private numberOfOrgs = 0;
uint private orgVoterNum = 0;
uint private orgNum = 0;
uint private morgNum = 0;
// events related to Master Org add
event MasterOrgAdded(string _orgId);
event MasterOrgExists(string _orgId);
event MasterOrgNotFound(string _orgId);
// events related to Sub Org add
event SubOrgAdded(string _orgId);
event SubOrgExists(string _orgId);
event SubOrgNotFound(string _orgId);
// events related to Org level key management
event OrgKeyAdded(string _orgId, string _privateKey);
event OrgKeyDeleted(string _orgId, string _privateKey);
event KeyNotFound(string _privateKey);
event KeyExists(string _orgId, string _privateKey);
event OrgKeyAdded(string _orgId, string _tmKey);
event OrgKeyDeleted(string _orgId, string _tmKey);
event KeyNotFound(string _tmKey);
event KeyExists(string _orgId, string _tmKey);
event OrgNotFound(string _orgId);
// events related to org level approval process
event PendingApproval(string _orgId);
event ItemForApproval(string _orgId, Operation _pendingOp, string _privateKey);
event ItemForApproval(string _orgId, Operation _pendingOp, string _tmKey);
event NothingToApprove(string _orgId);
// events related to managing voting accounts for the org
event NoVotingAccount(string _orgId);
event VoterAdded(string _orgId, address _address);
event VoterNotFound(string _orgId, address _address);
event VoterAccountDeleted(string _orgId, address _address);
event VoterDeleted(string _orgId, address _address);
event VoterExists(string _orgId, address _address);
// events related to helper functions to print all org keys and voter keys
/* event PrintAll(string _orgId, string _privateKey); */
/* event PrintVoter(string _orgId, address _voterAccount); */
event PrintAll(string _orgId, string _tmKey);
event PrintVoter(string _orgId, address _voterAccount);
// returns the org index for the org list
function getOrgIndex(string _orgId) internal view returns (uint)
@ -61,7 +71,7 @@ contract Clusterkeys {
}
// returns the voter index for the org from voter list
function getMasterIndex(string _orgId) internal view returns (uint)
function getMasterOrgIndex(string _orgId) internal view returns (uint)
{
return MasterOrgIndex[keccak256(abi.encodePacked(_orgId))] - 1;
}
@ -70,9 +80,9 @@ contract Clusterkeys {
modifier canVote(string _orgId){
bool flag = false;
uint orgIndex = getOrgIndex(_orgId);
uint morgIndex = getMasterIndex(orgList[orgIndex].morgId);
for (uint i = 0; i < morgList[morgIndex].orgVoterAccount.length; i++){
if ( morgList[morgIndex].orgVoterAccount[i] == msg.sender){
uint vorgIndex = getMasterOrgIndex(orgList[orgIndex].morgId);
for (uint i = 0; i < masterOrgList[vorgIndex].voterAccount.length; i++){
if ( masterOrgList[vorgIndex].voterAccount[i] == msg.sender){
flag = true;
break;
}
@ -82,12 +92,11 @@ contract Clusterkeys {
}
// checks if the org has any voter accounts set up or not
function checkIfVoterExists(string _orgId, address _address) internal view returns (bool, uint){
function checkIfVoterExists(string _morgId, address _address) internal view returns (bool, uint){
bool keyExists = false;
uint orgIndex = getOrgIndex(_orgId);
uint voterIndex = getMasterIndex(orgList[orgIndex].morgId);
for (uint i = 0; i < morgList[voterIndex].orgVoterAccount.length; i++){
if(keccak256(abi.encodePacked(morgList[voterIndex].orgVoterAccount[i])) == keccak256(abi.encodePacked(_address))){
uint voterIndex = getMasterOrgIndex(_morgId);
for (uint i = 0; i < masterOrgList[voterIndex].voterAccount.length; i++){
if(keccak256(abi.encodePacked(masterOrgList[voterIndex].voterAccount[i])) == keccak256(abi.encodePacked(_address))){
keyExists = true;
break;
}
@ -98,14 +107,9 @@ contract Clusterkeys {
// checks if the voter account is already in the voter accounts list for the org
function checkVotingAccountExists(string _orgId) internal returns (bool)
{
uint orgIndex = getOrgIndex(_orgId);
if (MasterOrgIndex[keccak256(abi.encodePacked(orgList[orgIndex].morgId))] == 0){
emit NoVotingAccount(_orgId);
return false;
}
uint morgIndex = getMasterIndex(orgList[orgIndex].morgId);
if (morgList[morgIndex].orgVoterAccount.length == 0) {
uint vorgIndex = getMasterOrgIndex(orgList[orgIndex].morgId);
if (masterOrgList[vorgIndex].voterAccount.length == 0) {
emit NoVotingAccount(_orgId);
return false;
}
@ -126,140 +130,158 @@ contract Clusterkeys {
}
// checks if there the key is already in the list of private keys for the org
function checkIfKeyExists(string _orgId, string _privateKey) internal view returns (bool, uint){
function checkIfKeyExists(string _orgId, string _tmKey) internal view returns (bool, uint){
bool keyExists = false;
uint orgIndex = getOrgIndex(_orgId);
for (uint i = 0; i < orgList[orgIndex].privateKey.length; i++){
if(keccak256(abi.encodePacked(orgList[orgIndex].privateKey[i])) == keccak256(abi.encodePacked(_privateKey))){
for (uint i = 0; i < orgList[orgIndex].tmKey.length; i++){
if(keccak256(abi.encodePacked(orgList[orgIndex].tmKey[i])) == keccak256(abi.encodePacked(_tmKey))){
keyExists = true;
break;
}
}
return (keyExists, i);
}
// function to check if morg exists
function checkMasterOrgExists (string _morgId) external view returns (bool) {
if (MasterOrgIndex[keccak256(abi.encodePacked(_morgId))] == 0) {
return false;
}
else {
return true;
}
}
// function for adding a new master org
function addMasterOrg(string _morgId) external
{
morgNum++;
MasterOrgIndex[keccak256(abi.encodePacked(_morgId))] = morgNum;
masterOrgList.push( MasterOrgDetails(_morgId, new address[](0), new string[](0)));
emit MasterOrgAdded(_morgId);
}
// function for adding a voter account to a master org
function addVoter(string _orgId, address _address) external
function addVoter(string _morgId, address _address) external
{
if (MasterOrgIndex[keccak256(abi.encodePacked(_orgId))] == 0) {
orgVoterNum++;
MasterOrgIndex[keccak256(abi.encodePacked(_orgId))] = orgVoterNum;
morgList.push( MasterOrgDetails(_orgId, new address[](0), new string[](0)));
morgList[orgVoterNum - 1].orgVoterAccount.push(_address);
emit VoterAdded(_orgId, _address);
if (MasterOrgIndex[keccak256(abi.encodePacked(_morgId))] == 0) {
emit MasterOrgNotFound(_morgId);
}
else {
bool voterExists = false;
uint i = 0;
(voterExists, i) = checkIfVoterExists(_orgId, _address);
(voterExists, i) = checkIfVoterExists(_morgId, _address);
if (voterExists) {
emit VoterExists(_orgId, _address);
emit VoterExists(_morgId, _address);
}
else {
uint voterIndex = getMasterIndex(_orgId);
morgList[voterIndex].orgVoterAccount.push(_address);
emit VoterAdded(_orgId, _address);
uint morgIndex = getMasterOrgIndex(_morgId);
masterOrgList[morgIndex].voterAccount.push(_address);
emit VoterAdded(_morgId, _address);
}
}
}
// function for deleting a voter account to a master org
function deleteVoter(string _orgId, address _address) external
function deleteVoter(string _morgId, address _address) external
{
if (MasterOrgIndex[keccak256(abi.encodePacked(_orgId))] == 0) {
emit OrgNotFound(_orgId);
if (MasterOrgIndex[keccak256(abi.encodePacked(_morgId))] == 0) {
emit MasterOrgNotFound(_morgId);
}
uint morgIndex = getMasterOrgIndex(_morgId);
(bool voterExists, uint i) = checkIfVoterExists(_morgId, _address);
if (voterExists == true) {
for (uint j = i; j < masterOrgList[morgIndex].voterAccount.length -1; j++){
masterOrgList[morgIndex].voterAccount[j] = masterOrgList[morgIndex].voterAccount[j+1];
}
delete masterOrgList[morgIndex].voterAccount[masterOrgList[morgIndex].voterAccount.length -1];
masterOrgList[morgIndex].voterAccount.length --;
emit VoterDeleted(_morgId, _address);
}
else {
uint voterIndex = getMasterIndex(_orgId);
(bool voterExists, uint i) = checkIfVoterExists(_orgId, _address);
emit VoterNotFound(_morgId, _address);
}
}
if (voterExists == true) {
for (uint j = i; j < morgList[voterIndex].orgVoterAccount.length -1; j++){
morgList[voterIndex].orgVoterAccount[j] = morgList[voterIndex].orgVoterAccount[j+1];
}
delete morgList[voterIndex].orgVoterAccount[morgList[voterIndex].orgVoterAccount.length -1];
morgList[voterIndex].orgVoterAccount.length --;
emit VoterAccountDeleted(_orgId, _address);
// function for adding a new master org
function addSubOrg(string _orgId, string _morgId) external
{
// check if master org exists
if (MasterOrgIndex[keccak256(abi.encodePacked(_morgId))] == 0){
emit MasterOrgNotFound(_morgId);
}
else {
if (OrgIndex[keccak256(abi.encodePacked(_orgId))] == 0) {
orgNum++;
OrgIndex[keccak256(abi.encodePacked(_orgId))] = orgNum;
orgList.push( OrgDetails(_orgId, _morgId, new string[](0), new string(0), Operation.None ));
emit SubOrgAdded(_morgId);
}
else {
emit VoterNotFound(_orgId, _address);
emit SubOrgExists(_morgId);
}
}
}
// function to create master org
function addMasterOrg(string _orgId) external
{
require (MasterOrgIndex[keccak256(abi.encodePacked(_orgId))] == 0);
// function for checking if org exists and if there are any pending ops
function checkOrgPendingOp (string _orgId) internal returns (bool) {
if (OrgIndex[keccak256(abi.encodePacked(_orgId))] == 0) {
emit OrgNotFound(_orgId);
return false;
}
if (checkVotingAccountExists(_orgId)){
if (checkingPendingOp(_orgId)){
emit PendingApproval(_orgId);
return false;
}
}
else {
emit NoVotingAccount(_orgId);
return false;
}
return true;
}
// function for adding a private key for the org. Thsi will be added once
// approval process is complete
function addOrgKey(string _orgId, string _morgId, string _privateKey) external
function addOrgKey(string _orgId, string _tmKey) external
{
if (checkVotingAccountExists(_orgId)){
if (OrgIndex[keccak256(abi.encodePacked(_orgId))] == 0) {
numberOfOrgs++;
OrgIndex[keccak256(abi.encodePacked(_orgId))] = numberOfOrgs;
orgList.push( OrgDetails(_orgId, _morgId, new string[](0), _privateKey, Operation.Add));
voterInit(_orgId);
emit ItemForApproval(_orgId, Operation.Add, _privateKey);
bool ret = checkOrgPendingOp(_orgId);
if (ret){
bool keyExists = false;
uint i = 0;
(keyExists, i) = checkIfKeyExists(_orgId, _tmKey);
if (keyExists) {
emit KeyExists(_orgId, _tmKey);
}
else {
if (checkingPendingOp(_orgId)){
emit PendingApproval(_orgId);
}
else {
bool keyExists = false;
uint i = 0;
(keyExists, i) = checkIfKeyExists(_orgId, _privateKey);
if (keyExists) {
emit KeyExists(_orgId, _privateKey);
}
else {
uint orgIndex;
orgIndex = getOrgIndex(_orgId);
orgList[orgIndex].pendingKey = _privateKey;
orgList[orgIndex].pendingOp = Operation.Add;
voterInit(_orgId);
emit ItemForApproval(_orgId,Operation.Add, _privateKey);
}
}
uint orgIndex;
orgIndex = getOrgIndex(_orgId);
orgList[orgIndex].pendingKey = _tmKey;
orgList[orgIndex].pendingOp = Operation.Add;
voterInit(_orgId);
emit ItemForApproval(_orgId,Operation.Add, _tmKey);
}
}
}
// function for deleting a private key for the org. Thsi will be deleted once
// approval process is complete
function deleteOrgKey(string _orgId, string _privateKey) external
function deleteOrgKey(string _orgId, string _tmKey) external
{
if (checkVotingAccountExists(_orgId)){
if (OrgIndex[keccak256(abi.encodePacked(_orgId))] == 0) {
emit OrgNotFound(_orgId);
bool ret = checkOrgPendingOp(_orgId);
if(ret) {
uint orgIndex = getOrgIndex(_orgId);
uint i = 0;
bool keyExists = false;
(keyExists, i) = checkIfKeyExists (_orgId, _tmKey);
if (keyExists == true) {
orgList[orgIndex].pendingKey = _tmKey;
orgList[orgIndex].pendingOp = Operation.Delete;
voterInit(_orgId);
emit ItemForApproval(_orgId, Operation.Delete, _tmKey);
}
else {
if (checkingPendingOp(_orgId)){
emit PendingApproval(_orgId);
}
else {
uint orgIndex = getOrgIndex(_orgId);
uint i = 0;
bool keyExists = false;
(keyExists, i) = checkIfKeyExists (_orgId, _privateKey);
if (keyExists == true) {
orgList[orgIndex].pendingKey = _privateKey;
orgList[orgIndex].pendingOp = Operation.Delete;
voterInit(_orgId);
emit ItemForApproval(_orgId, Operation.Delete, _privateKey);
}
else {
emit KeyNotFound(_privateKey);
}
}
emit KeyNotFound(_tmKey);
}
}
}
@ -281,14 +303,14 @@ contract Clusterkeys {
// new item is initiated for approval
function voterInit(string _orgId) internal {
uint orgIndex = getOrgIndex(_orgId);
uint morgIndex = getMasterIndex(orgList[orgIndex].morgId);
for (uint i = 0; i < morgList[morgIndex].orgVoterAccount.length; i++){
voteStatus[orgIndex][morgList[morgIndex].orgVoterAccount[i]] = false;
uint vorgIndex = getMasterOrgIndex(orgList[orgIndex].morgId);
for (uint i = 0; i < masterOrgList[vorgIndex].voterAccount.length; i++){
voteStatus[orgIndex][masterOrgList[vorgIndex].voterAccount[i]] = false;
}
voteCount[orgIndex] = 0;
}
// processes the vote from the voter account.
// processes the vote from the voter account.
function processVote (string _orgId) internal {
uint orgIndex = getOrgIndex(_orgId);
if (voteStatus[orgIndex][msg.sender] == false ){
@ -301,7 +323,7 @@ contract Clusterkeys {
// returns true
function checkEnoughVotes (string _orgId) internal view returns (bool) {
uint orgIndex = getOrgIndex(_orgId);
if (voteCount[orgIndex] > morgList[orgIndex].orgVoterAccount.length / 2 ){
if (voteCount[orgIndex] > masterOrgList[orgIndex].voterAccount.length / 2 ){
return true;
}
return false;
@ -314,8 +336,8 @@ contract Clusterkeys {
continue;
}
if (keccak256(abi.encodePacked(orgList[i].morgId)) == keccak256(abi.encodePacked(_morgId))){
for (uint j = 0; j < orgList[i].privateKey.length; j++){
if (keccak256(abi.encodePacked(orgList[i].privateKey[j])) == keccak256(abi.encodePacked(_key))){
for (uint j = 0; j < orgList[i].tmKey.length; j++){
if (keccak256(abi.encodePacked(orgList[i].tmKey[j])) == keccak256(abi.encodePacked(_key))){
keyInUse = true;
break;
}
@ -329,18 +351,18 @@ contract Clusterkeys {
}
// updates the master keys list with the key being added or deleted
function masterKeyUpdate(string _orgId, string _morgId, string _key, Operation _op) internal {
uint morgIndex = getMasterIndex(_morgId);
uint morgIndex = getMasterOrgIndex(_morgId);
if (_op == Operation.Add) {
// check if the key is existing. if yes ignore else add to master list
bool keyExists = false;
for (uint i = 0; i < morgList[morgIndex].privateKey.length; i++){
if(keccak256(abi.encodePacked(orgList[morgIndex].privateKey[i])) == keccak256(abi.encodePacked(_key))){
for (uint i = 0; i < masterOrgList[morgIndex].tmKey.length; i++){
if(keccak256(abi.encodePacked(masterOrgList[morgIndex].tmKey[i])) == keccak256(abi.encodePacked(_key))){
keyExists = true;
break;
}
}
if (keyExists == false ){
morgList[morgIndex].privateKey.push(_key);
masterOrgList[morgIndex].tmKey.push(_key);
}
}
else {
@ -348,16 +370,16 @@ contract Clusterkeys {
// key in the private keys
if (!(checkKeyInUse(_orgId, _morgId, _key))){
uint index;
for (index = 0; i < morgList[morgIndex].privateKey.length; index++) {
if(keccak256(abi.encodePacked(morgList[morgIndex].privateKey[index])) == keccak256(abi.encodePacked(_key))) {
for (index = 0; i < masterOrgList[morgIndex].tmKey.length; index++) {
if(keccak256(abi.encodePacked(masterOrgList[morgIndex].tmKey[index])) == keccak256(abi.encodePacked(_key))) {
break;
}
}
for (uint j = index; j < morgList[morgIndex].privateKey.length -1; j++){
morgList[morgIndex].privateKey[j] = morgList[morgIndex].privateKey[j+1];
for (uint j = index; j < masterOrgList[morgIndex].tmKey.length -1; j++){
masterOrgList[morgIndex].tmKey[j] = masterOrgList[morgIndex].tmKey[j+1];
}
delete morgList[morgIndex].privateKey[morgList[morgIndex].privateKey.length -1];
morgList[morgIndex].privateKey.length --;
delete masterOrgList[morgIndex].tmKey[masterOrgList[morgIndex].tmKey.length -1];
masterOrgList[morgIndex].tmKey.length --;
}
}
}
@ -367,7 +389,7 @@ contract Clusterkeys {
if(checkEnoughVotes(orgList[_orgIndex].orgId)){
string storage locKey = orgList[_orgIndex].pendingKey;
if (orgList[_orgIndex].pendingOp == Operation.Add){
orgList[_orgIndex].privateKey.push(orgList[_orgIndex].pendingKey);
orgList[_orgIndex].tmKey.push(orgList[_orgIndex].pendingKey);
masterKeyUpdate(orgList[_orgIndex].orgId, orgList[_orgIndex].morgId, orgList[_orgIndex].pendingKey, Operation.Add);
emit OrgKeyAdded(orgList[_orgIndex].orgId, locKey);
}
@ -375,11 +397,11 @@ contract Clusterkeys {
bool keyExists = false;
uint i = 0;
(keyExists, i) = checkIfKeyExists (orgList[_orgIndex].orgId, locKey);
for (uint j = i; j < orgList[_orgIndex].privateKey.length -1; j++){
orgList[_orgIndex].privateKey[j] = orgList[_orgIndex].privateKey[j+1];
for (uint j = i; j < orgList[_orgIndex].tmKey.length -1; j++){
orgList[_orgIndex].tmKey[j] = orgList[_orgIndex].tmKey[j+1];
}
delete orgList[_orgIndex].privateKey[orgList[_orgIndex].privateKey.length -1];
orgList[_orgIndex].privateKey.length --;
delete orgList[_orgIndex].tmKey[orgList[_orgIndex].tmKey.length -1];
orgList[_orgIndex].tmKey.length --;
masterKeyUpdate(orgList[_orgIndex].orgId, orgList[_orgIndex].morgId, orgList[_orgIndex].pendingKey, Operation.Delete);
emit OrgKeyDeleted(orgList[_orgIndex].orgId, locKey);
}
@ -387,23 +409,4 @@ contract Clusterkeys {
orgList[_orgIndex].pendingKey = "";
}
}
/* // helper function to print all privates keys for an org */
/* function printAllOrg () public { */
/* for (uint i = 0; i < orgList.length; i++){ */
/* for (uint j = 0; j < orgList[i].privateKey.length ; j++){ */
/* emit PrintAll(orgList[i].orgId, orgList[i].privateKey[j]); */
/* } */
/* } */
/* } */
/* // helper function to print all voters accounts for an org */
/* function printAllVoter () public { */
/* for (uint i = 0; i < morgList.length; i++){ */
/* for (uint j = 0; j < morgList[i].orgVoterAccount.length ; j++){ */
/* emit PrintVoter(morgList[i].orgId, morgList[i].orgVoterAccount[j]); */
/* } */
/* } */
/* } */
}

View File

@ -1 +1 @@
[{"constant":false,"inputs":[],"name":"printAllOrg","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"}],"name":"approvePendingOp","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_morgId","type":"string"},{"name":"_privateKey","type":"string"}],"name":"addOrgKey","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_privateKey","type":"string"}],"name":"deleteOrgKey","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_address","type":"address"}],"name":"addVoter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_address","type":"address"}],"name":"deleteVoter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"printAllVoter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_privateKey","type":"string"}],"name":"OrgKeyAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_privateKey","type":"string"}],"name":"OrgKeyDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_privateKey","type":"string"}],"name":"KeyNotFound","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_privateKey","type":"string"}],"name":"KeyExists","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"}],"name":"OrgNotFound","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"}],"name":"PendingApproval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_pendingOp","type":"uint8"},{"indexed":false,"name":"_privateKey","type":"string"}],"name":"ItemForApproval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"}],"name":"NothingToApprove","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"}],"name":"NoVotingAccount","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_address","type":"address"}],"name":"VoterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_address","type":"address"}],"name":"VoterNotFound","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_address","type":"address"}],"name":"VoterAccountDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_address","type":"address"}],"name":"VoterExists","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_privateKey","type":"string"}],"name":"PrintAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_voterAccount","type":"address"}],"name":"PrintVoter","type":"event"}]
[{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_morgId","type":"string"}],"name":"addSubOrg","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"}],"name":"approvePendingOp","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_tmKey","type":"string"}],"name":"deleteOrgKey","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_morgId","type":"string"},{"name":"_address","type":"address"}],"name":"addVoter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_morgId","type":"string"},{"name":"_address","type":"address"}],"name":"deleteVoter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_morgId","type":"string"}],"name":"addMasterOrg","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_orgId","type":"string"},{"name":"_tmKey","type":"string"}],"name":"addOrgKey","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_morgId","type":"string"}],"name":"checkMasterOrgExists","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"}],"name":"MasterOrgAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"}],"name":"MasterOrgExists","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"}],"name":"MasterOrgNotFound","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"}],"name":"SubOrgAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"}],"name":"SubOrgExists","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"}],"name":"SubOrgNotFound","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_tmKey","type":"string"}],"name":"OrgKeyAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_tmKey","type":"string"}],"name":"OrgKeyDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_tmKey","type":"string"}],"name":"KeyNotFound","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_tmKey","type":"string"}],"name":"KeyExists","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"}],"name":"OrgNotFound","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"}],"name":"PendingApproval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_pendingOp","type":"uint8"},{"indexed":false,"name":"_tmKey","type":"string"}],"name":"ItemForApproval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"}],"name":"NothingToApprove","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"}],"name":"NoVotingAccount","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_address","type":"address"}],"name":"VoterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_address","type":"address"}],"name":"VoterNotFound","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_address","type":"address"}],"name":"VoterDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_address","type":"address"}],"name":"VoterExists","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_tmKey","type":"string"}],"name":"PrintAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_orgId","type":"string"},{"indexed":false,"name":"_voterAccount","type":"address"}],"name":"PrintVoter","type":"event"}]

File diff suppressed because one or more lines are too long

View File

@ -63,7 +63,7 @@ func (k *OrgKeyCtrl) populatePrivateKeys() error {
for recExists {
recExists = pastAddEvents.Next()
if recExists {
types.AddOrgKey(pastAddEvents.Event.OrgId, pastAddEvents.Event.PrivateKey)
types.AddOrgKey(pastAddEvents.Event.OrgId, pastAddEvents.Event.TmKey)
}
}
@ -74,7 +74,7 @@ func (k *OrgKeyCtrl) populatePrivateKeys() error {
for recExists {
recExists = pastDeleteEvents.Next()
if recExists {
types.DeleteOrgKey(pastDeleteEvents.Event.OrgId, pastDeleteEvents.Event.PrivateKey)
types.DeleteOrgKey(pastDeleteEvents.Event.OrgId, pastDeleteEvents.Event.TmKey)
}
}
return nil
@ -106,7 +106,7 @@ func (k *OrgKeyCtrl) monitorKeyAdd() {
for {
select {
case newEvent = <-ch:
types.AddOrgKey(newEvent.OrgId, newEvent.PrivateKey)
types.AddOrgKey(newEvent.OrgId, newEvent.TmKey)
}
}
}
@ -131,7 +131,7 @@ func (k *OrgKeyCtrl) monitorKeyDelete() {
for {
select {
case newEvent = <-ch:
types.DeleteOrgKey(newEvent.OrgId, newEvent.PrivateKey)
types.DeleteOrgKey(newEvent.OrgId, newEvent.TmKey)
}
}
}

View File

@ -47,12 +47,17 @@ const (
type OrgKeyAction int
const (
AddOrgKey OrgKeyAction = iota
RemoveOrgKey
AddMasterOrg OrgKeyAction = iota
AddSubOrg
AddOrgVoter
DeleteOrgVoter
AddOrgKey
DeleteOrgKey
ApprovePendingOp
)
// PermissionAPI provides an API to access Quorum's node permission and org key management related services
type PermissionAPI struct {
// QuorumControlsAPI provides an API to access Quorum's node permission and org key management related services
type QuorumControlsAPI struct {
txPool *core.TxPool
ethClnt *ethclient.Client
acntMgr *accounts.Manager
@ -68,7 +73,8 @@ type txArgs struct {
voter common.Address
nodeId string
orgId string
keyId string
morgId string
tmKey string
txa ethapi.SendTxArgs
acctId common.Address
accessType string
@ -100,6 +106,7 @@ var (
ErrPermissionDisabled = ExecStatus{false, "Permissions control not enabled"}
ErrAccountAccess = ExecStatus{false, "Account does not have sufficient access for operation"}
ErrVoterAccountAccess = ExecStatus{false, "Voter account does not have sufficient access"}
ErrMasterOrgExists = ExecStatus{false, "Master org already exists"}
ExecSuccess = ExecStatus{true, "Action completed successfully"}
)
@ -123,9 +130,9 @@ var (
}
)
// NewPermissionAPI creates a new PermissionAPI to access quorum services
func NewPermissionAPI(tp *core.TxPool, am *accounts.Manager) *PermissionAPI {
return &PermissionAPI{tp, nil, am, nil, nil, nil, nil, false}
// NewQuorumControlsAPI creates a new QuorumControlsAPI to access quorum services
func NewQuorumControlsAPI(tp *core.TxPool, am *accounts.Manager) *QuorumControlsAPI {
return &QuorumControlsAPI{tp, nil, am, nil, nil, nil, nil, false}
}
// helper function decodes the node status to string
@ -136,8 +143,8 @@ func decodeNodeStatus(nodeStatus uint8) string {
return "Unknown"
}
//Init initializes PermissionAPI with eth client, permission contract and org key management control
func (p *PermissionAPI) Init(ethClnt *ethclient.Client, key *ecdsa.PrivateKey) error {
//Init initializes QuorumControlsAPI with eth client, permission contract and org key management control
func (p *QuorumControlsAPI) Init(ethClnt *ethclient.Client, key *ecdsa.PrivateKey) error {
p.ethClnt = ethClnt
permContr, err := pbind.NewPermissions(params.QuorumPermissionsContract, p.ethClnt)
if err != nil {
@ -155,7 +162,7 @@ func (p *PermissionAPI) Init(ethClnt *ethclient.Client, key *ecdsa.PrivateKey) e
}
// Returns the list of Nodes and status of each
func (s *PermissionAPI) PermissionNodeList() []nodeStatus {
func (s *QuorumControlsAPI) PermissionNodeList() []nodeStatus {
if !s.enabled {
nodeStatArr := make([]nodeStatus, 1)
nodeStatArr[0].EnodeId = "Permisssions control not enabled for network"
@ -188,7 +195,7 @@ func (s *PermissionAPI) PermissionNodeList() []nodeStatus {
return nodeStatArr
}
func (s *PermissionAPI) PermissionAccountList() []accountInfo {
func (s *QuorumControlsAPI) PermissionAccountList() []accountInfo {
if !s.enabled {
acctInfoArr := make([]accountInfo, 1)
acctInfoArr[0].Address = "Account access control not enable for the network"
@ -218,7 +225,7 @@ func (s *PermissionAPI) PermissionAccountList() []accountInfo {
return acctInfoArr
}
func (s *PermissionAPI) VoterList() []string {
func (s *QuorumControlsAPI) VoterList() []string {
if !s.enabled {
voterArr := make([]string, 1)
voterArr[0] = "Permissions control not enabled for the network"
@ -247,7 +254,7 @@ func (s *PermissionAPI) VoterList() []string {
return voterArr
}
func (s *PermissionAPI) newPermSessionWithNodeKeySigner() *pbind.PermissionsSession {
func (s *QuorumControlsAPI) newPermSessionWithNodeKeySigner() *pbind.PermissionsSession {
auth := bind.NewKeyedTransactor(s.key)
ps := &pbind.PermissionsSession{
Contract: s.permContr,
@ -272,71 +279,90 @@ func decodeAccountPermission(access uint8) string {
}
// AddVoter adds an account to the list of accounts that can approve nodes proposed or deactivated
func (s *PermissionAPI) AddVoter(vaddr common.Address, txa ethapi.SendTxArgs) ExecStatus {
func (s *QuorumControlsAPI) AddVoter(vaddr common.Address, txa ethapi.SendTxArgs) ExecStatus {
return s.executePermAction(AddVoter, txArgs{voter: vaddr, txa: txa})
}
// RemoveVoter removes an account from the list of accounts that can approve nodes proposed or deactivated
func (s *PermissionAPI) RemoveVoter(vaddr common.Address, txa ethapi.SendTxArgs) ExecStatus {
func (s *QuorumControlsAPI) RemoveVoter(vaddr common.Address, txa ethapi.SendTxArgs) ExecStatus {
return s.executePermAction(RemoveVoter, txArgs{voter: vaddr, txa: txa})
}
// ProposeNode proposes a node to join the network
func (s *PermissionAPI) ProposeNode(nodeId string, txa ethapi.SendTxArgs) ExecStatus {
func (s *QuorumControlsAPI) ProposeNode(nodeId string, txa ethapi.SendTxArgs) ExecStatus {
return s.executePermAction(ProposeNode, txArgs{nodeId: nodeId, txa: txa})
}
// ApproveNode approves a proposed node to join the network
func (s *PermissionAPI) ApproveNode(nodeId string, txa ethapi.SendTxArgs) ExecStatus {
func (s *QuorumControlsAPI) ApproveNode(nodeId string, txa ethapi.SendTxArgs) ExecStatus {
return s.executePermAction(ApproveNode, txArgs{nodeId: nodeId, txa: txa})
}
// DeactivateNode requests a node to get deactivated
func (s *PermissionAPI) ProposeNodeDeactivation(nodeId string, txa ethapi.SendTxArgs) ExecStatus {
func (s *QuorumControlsAPI) ProposeNodeDeactivation(nodeId string, txa ethapi.SendTxArgs) ExecStatus {
return s.executePermAction(ProposeNodeDeactivation, txArgs{nodeId: nodeId, txa: txa})
}
// ApproveDeactivateNode approves a node to get deactivated
func (s *PermissionAPI) ApproveNodeDeactivation(nodeId string, txa ethapi.SendTxArgs) ExecStatus {
func (s *QuorumControlsAPI) ApproveNodeDeactivation(nodeId string, txa ethapi.SendTxArgs) ExecStatus {
return s.executePermAction(ApproveNodeDeactivation, txArgs{nodeId: nodeId, txa: txa})
}
// DeactivateNode requests a node to get deactivated
func (s *PermissionAPI) ProposeNodeActivation(nodeId string, txa ethapi.SendTxArgs) ExecStatus {
func (s *QuorumControlsAPI) ProposeNodeActivation(nodeId string, txa ethapi.SendTxArgs) ExecStatus {
return s.executePermAction(ProposeNodeActivation, txArgs{nodeId: nodeId, txa: txa})
}
// ApproveDeactivateNode approves a node to get deactivated
func (s *PermissionAPI) ApproveNodeActivation(nodeId string, txa ethapi.SendTxArgs) ExecStatus {
func (s *QuorumControlsAPI) ApproveNodeActivation(nodeId string, txa ethapi.SendTxArgs) ExecStatus {
return s.executePermAction(ApproveNodeActivation, txArgs{nodeId: nodeId, txa: txa})
}
// DeactivateNode requests a node to get deactivated
func (s *PermissionAPI) ProposeNodeBlacklisting(nodeId string, txa ethapi.SendTxArgs) ExecStatus {
func (s *QuorumControlsAPI) ProposeNodeBlacklisting(nodeId string, txa ethapi.SendTxArgs) ExecStatus {
return s.executePermAction(ProposeNodeBlacklisting, txArgs{nodeId: nodeId, txa: txa})
}
// ApproveDeactivateNode approves a node to get deactivated
func (s *PermissionAPI) ApproveNodeBlacklisting(nodeId string, txa ethapi.SendTxArgs) ExecStatus {
func (s *QuorumControlsAPI) ApproveNodeBlacklisting(nodeId string, txa ethapi.SendTxArgs) ExecStatus {
return s.executePermAction(ApproveNodeBlacklisting, txArgs{nodeId: nodeId, txa: txa})
}
// AddMasterOrg adds an new master organization to the contract
func (s *QuorumControlsAPI) AddMasterOrg(morgId string, txa ethapi.SendTxArgs) ExecStatus {
return s.executeOrgKeyAction(AddMasterOrg, txArgs{txa: txa, morgId: morgId})
}
// RemoveOrgKey removes an org key combination from the org key map
func (s *PermissionAPI) RemoveOrgKey(orgId string, pvtKey string, txa ethapi.SendTxArgs) ExecStatus {
return s.executeOrgKeyAction(RemoveOrgKey, txArgs{txa: txa, orgId: orgId, keyId: pvtKey})
func (s *QuorumControlsAPI) AddSubOrg(orgId string, morgId string, txa ethapi.SendTxArgs) ExecStatus {
return s.executeOrgKeyAction(AddSubOrg, txArgs{txa: txa, orgId: orgId, morgId: morgId})
}
// AddOrgKey adds an org key combination to the org key map
func (s *PermissionAPI) AddOrgKey(orgId string, pvtKey string, txa ethapi.SendTxArgs) ExecStatus {
return s.executeOrgKeyAction(AddOrgKey, txArgs{txa: txa, orgId: orgId, keyId: pvtKey})
func (s *QuorumControlsAPI) AddOrgVoter(morgId string, acctId common.Address, txa ethapi.SendTxArgs) ExecStatus {
return s.executeOrgKeyAction(AddOrgVoter, txArgs{txa: txa, morgId: morgId, acctId: acctId})
}
func (s *PermissionAPI) SetAccountAccess(acct common.Address, access string, txa ethapi.SendTxArgs) ExecStatus {
// RemoveOrgKey removes an org key combination from the org key map
func (s *QuorumControlsAPI) DeleteOrgVoter(morgId string, acctId common.Address, txa ethapi.SendTxArgs) ExecStatus {
return s.executeOrgKeyAction(DeleteOrgVoter, txArgs{txa: txa, morgId: morgId, acctId: acctId})
}
func (s *QuorumControlsAPI) AddOrgKey(orgId string, tmKey string, txa ethapi.SendTxArgs) ExecStatus {
return s.executeOrgKeyAction(AddOrgKey, txArgs{txa: txa, orgId: orgId, tmKey: tmKey})
}
// RemoveOrgKey removes an org key combination from the org key map
func (s *QuorumControlsAPI) DeleteOrgKey(orgId string, tmKey string, txa ethapi.SendTxArgs) ExecStatus {
return s.executeOrgKeyAction(DeleteOrgKey, txArgs{txa: txa, orgId: orgId, tmKey: tmKey})
}
func (s *QuorumControlsAPI) SetAccountAccess(acct common.Address, access string, txa ethapi.SendTxArgs) ExecStatus {
return s.executePermAction(SetAccountAccess, txArgs{acctId: acct, accessType: access, txa: txa})
}
// executePermAction helps to execute an action in permission contract
func (s *PermissionAPI) executePermAction(action PermAction, args txArgs) ExecStatus {
func (s *QuorumControlsAPI) executePermAction(action PermAction, args txArgs) ExecStatus {
if !s.enabled {
return ErrPermissionDisabled
@ -503,7 +529,7 @@ func (s *PermissionAPI) executePermAction(action PermAction, args txArgs) ExecSt
}
// executeOrgKeyAction helps to execute an action in cluster contract
func (s *PermissionAPI) executeOrgKeyAction(action OrgKeyAction, args txArgs) ExecStatus {
func (s *QuorumControlsAPI) executeOrgKeyAction(action OrgKeyAction, args txArgs) ExecStatus {
if !s.enabled {
return ErrPermissionDisabled
}
@ -515,21 +541,37 @@ func (s *PermissionAPI) executeOrgKeyAction(action OrgKeyAction, args txArgs) Ex
var tx *types.Transaction
switch action {
case AddMasterOrg:
// check if the master org exists. if yes throw error
ret, err := ps.CheckMasterOrgExists(args.morgId)
log.Info("SMK-executeOrgKeyAction @547 index is ", "ret", ret, "morgId", args.morgId, "err", err)
if (ret) {
return ErrMasterOrgExists
}
tx, err = ps.AddMasterOrg(args.morgId)
case AddSubOrg:
tx, err = ps.AddSubOrg(args.orgId, args.morgId)
case AddOrgVoter:
tx, err = ps.AddVoter(args.morgId, args.acctId)
case DeleteOrgVoter:
tx, err = ps.DeleteVoter(args.morgId, args.acctId)
case AddOrgKey:
tx, err = ps.AddOrgKey(args.orgId, args.keyId)
case RemoveOrgKey:
tx, err = ps.DeleteOrgKey(args.orgId, args.keyId)
tx, err = ps.AddOrgKey(args.orgId, args.tmKey)
case DeleteOrgKey:
tx, err = ps.DeleteOrgKey(args.orgId, args.tmKey)
case ApprovePendingOp:
tx, err = ps.ApprovePendingOp(args.orgId)
}
if err != nil {
log.Error("Failed to execute orgKey action", "action", action, "err", err)
return ExecStatus{false, err.Error()}
}
log.Debug("executed orgKey action", "action", action, "tx", tx)
return ExecStatus{true, ""}
return ExecSuccess
}
// validateAccount validates the account and returns the wallet associated with that for signing the transaction
func (s *PermissionAPI) validateAccount(from common.Address) (accounts.Wallet, error) {
func (s *QuorumControlsAPI) validateAccount(from common.Address) (accounts.Wallet, error) {
acct := accounts.Account{Address: from}
w, err := s.acntMgr.Find(acct)
if err != nil {
@ -558,7 +600,7 @@ func checkIsVoter(ps *pbind.PermissionsSession, acctId common.Address) bool {
}
// newPermSession creates a new permission contract session
func (s *PermissionAPI) newPermSession(w accounts.Wallet, txa ethapi.SendTxArgs) *pbind.PermissionsSession {
func (s *QuorumControlsAPI) newPermSession(w accounts.Wallet, txa ethapi.SendTxArgs) *pbind.PermissionsSession {
frmAcct, transactOpts, gasLimit, gasPrice, nonce := s.getTxParams(txa, w)
ps := &pbind.PermissionsSession{
Contract: s.permContr,
@ -577,7 +619,7 @@ func (s *PermissionAPI) newPermSession(w accounts.Wallet, txa ethapi.SendTxArgs)
}
// newClusterSession creates a new cluster contract session
func (s *PermissionAPI) newClusterSession(w accounts.Wallet, txa ethapi.SendTxArgs) *pbind.ClusterSession {
func (s *QuorumControlsAPI) newClusterSession(w accounts.Wallet, txa ethapi.SendTxArgs) *pbind.ClusterSession {
frmAcct, transactOpts, gasLimit, gasPrice, nonce := s.getTxParams(txa, w)
cs := &pbind.ClusterSession{
Contract: s.clustContr,
@ -596,7 +638,7 @@ func (s *PermissionAPI) newClusterSession(w accounts.Wallet, txa ethapi.SendTxAr
}
// getTxParams extracts the transaction related parameters
func (s *PermissionAPI) getTxParams(txa ethapi.SendTxArgs, w accounts.Wallet) (accounts.Account, *bind.TransactOpts, uint64, *big.Int, *big.Int) {
func (s *QuorumControlsAPI) getTxParams(txa ethapi.SendTxArgs, w accounts.Wallet) (accounts.Account, *bind.TransactOpts, uint64, *big.Int, *big.Int) {
frmAcct := accounts.Account{Address: txa.From}
transactOpts := bind.NewWalletTransactor(w, frmAcct)
gasLimit := defaultGasLimit

View File

@ -329,19 +329,19 @@ func (s *Ethereum) APIs() []rpc.API {
{
Namespace: "quorumNodeMgmt",
Version: "1.0",
Service: quorum.NewPermissionAPI(s.txPool, s.accountManager),
Service: quorum.NewQuorumControlsAPI(s.txPool, s.accountManager),
Public: true,
},
{
Namespace: "quorumAcctMgmt",
Version: "1.0",
Service: quorum.NewPermissionAPI(s.txPool, s.accountManager),
Service: quorum.NewQuorumControlsAPI(s.txPool, s.accountManager),
Public: true,
},
{
Namespace: "quorumKeyMgmt",
Version: "1.0",
Service: quorum.NewPermissionAPI(s.txPool, s.accountManager),
Service: quorum.NewQuorumControlsAPI(s.txPool, s.accountManager),
Public: true,
},
}...)

View File

@ -793,17 +793,47 @@ web3._extend({
methods:
[
new web3._extend.Method({
name: 'addOrgKey',
call: 'quorumKeyMgmt_addOrgKey',
name: 'addMasterOrg',
call: 'quorumKeyMgmt_addMasterOrg',
params: 2,
inputFormatter: [null,web3._extend.formatters.inputTransactionFormatter]
}),
new web3._extend.Method({
name: 'addSubOrg',
call: 'quorumKeyMgmt_addSubOrg',
params: 3,
inputFormatter: [null,null,web3._extend.formatters.inputTransactionFormatter]
}),
new web3._extend.Method({
name: 'removeOrgKey',
call: 'quorumKeyMgmt_removeOrgKey',
new web3._extend.Method({
name: 'addVoter',
call: 'quorumKeyMgmt_addOrgVoter',
params: 3,
inputFormatter: [null,null,web3._extend.formatters.inputTransactionFormatter]
}),
new web3._extend.Method({
name: 'deleteVoter',
call: 'quorumKeyMgmt_deleteOrgVoter',
params: 3,
inputFormatter: [null,null,web3._extend.formatters.inputTransactionFormatter]
}),
new web3._extend.Method({
name: 'addOrgKey',
call: 'quorumKeyMgmt_addOrgKey',
params: 2,
inputFormatter: [null,web3._extend.formatters.inputTransactionFormatter]
}),
new web3._extend.Method({
name: 'deleteOrgKey',
call: 'quorumKeyMgmt_deleteOrgKey',
params: 2,
inputFormatter: [null,web3._extend.formatters.inputTransactionFormatter]
}),
new web3._extend.Method({
name: 'approvePendingOp',
call: 'quorumKeyMgmt_approvePendingOp',
params: 2,
inputFormatter: [null,web3._extend.formatters.inputTransactionFormatter]
}),
],
properties:
[