Code changes for populating the initial node list from static-nodes.json

This commit is contained in:
vsmk98 2018-10-24 10:21:21 +00:00
parent 4dc1f3376b
commit 5187dd9430
7 changed files with 157 additions and 19 deletions

View File

@ -7,15 +7,15 @@ import (
"github.com/ethereum/go-ethereum/node"
)
// Create an RPC client for the contract interface
func CreateEthClient(stack *node.Node ) (*ethclient.Client, error){
func CreateEthClient(stack *node.Node ) (*ethclient.Client, *eth.Ethereum, error){
var e *eth.Ethereum
if err := stack.Service(&e); err != nil {
return nil, err
return nil, nil, err
}
rpcClient, err := stack.Attach()
if err != nil {
return nil, err
return nil, nil, err
}
return ethclient.NewClient(rpcClient), nil
return ethclient.NewClient(rpcClient), e, nil
}

View File

@ -15,7 +15,7 @@ import (
// the permissiones contract deployed as a precompile via genesis.json
func ManageOrgKeys(ctx *cli.Context, stack *node.Node ) error {
// Create a new ethclient to for interfacing with the contract
stateReader, err := controls.CreateEthClient(stack)
stateReader, _, err := controls.CreateEthClient(stack)
if err != nil {
log.Error ("Unable to create ethereum client for cluster check : ", "err" , err)
return err

View File

@ -30,6 +30,9 @@ contract Permissions {
// valid vote count
mapping (uint => uint) private voteCount;
// checks if firts time network boot up has happened or not
bool networkBoot = false;
// node permission events for new node propose
event NodeProposed(string _enodeId);
event NodeApproved(string _enodeId, string _ipAddrPort, string _discPort, string _raftPort);
@ -130,22 +133,34 @@ contract Permissions {
}
// state change functions
// update the networ boot status as true
function updateNetworkBootStatus() external {
require (networkBoot == false, "Invalid call: Network boot up completed");
networkBoot = true;
}
// propose a new node to the network
function proposeNode(string _enodeId, string _ipAddrPort, string _discPort, string _raftPort) external enodeNotInList(_enodeId)
{
if (checkVotingAccountExist()){
// increment node number, add node to the list
if (!(networkBoot)){
numberOfNodes++;
nodeIdToIndex[keccak256(abi.encodePacked(_enodeId))] = numberOfNodes;
nodeList.push(NodeDetails(_enodeId, _ipAddrPort,_discPort, _raftPort, NodeStatus.PendingApproval));
// add voting status, numberOfNodes is the index of current proposed node
for (uint i = 0; i < accountList.length; i++){
voteStatus[numberOfNodes][accountList[i]] = false;
nodeList.push(NodeDetails(_enodeId, _ipAddrPort,_discPort, _raftPort, NodeStatus.Approved));
}
else {
if (checkVotingAccountExist()){
// increment node number, add node to the list
numberOfNodes++;
nodeIdToIndex[keccak256(abi.encodePacked(_enodeId))] = numberOfNodes;
nodeList.push(NodeDetails(_enodeId, _ipAddrPort,_discPort, _raftPort, NodeStatus.PendingApproval));
// add voting status, numberOfNodes is the index of current proposed node
for (uint i = 0; i < accountList.length; i++){
voteStatus[numberOfNodes][accountList[i]] = false;
}
voteCount[numberOfNodes] = 0;
// emit event
emit NodeProposed(_enodeId);
}
voteCount[numberOfNodes] = 0;
// emit event
emit NodeProposed(_enodeId);
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,18 +1,23 @@
package permissions
import (
"fmt"
"encoding/json"
"io/ioutil"
"path/filepath"
"math/big"
"os"
"sync"
"strings"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/p2p/discover"
"github.com/ethereum/go-ethereum/controls"
"github.com/ethereum/go-ethereum/cmd/utils"
@ -36,7 +41,7 @@ const (
// the permissiones contract deployed as a precompile via genesis.json
func QuorumPermissioning(ctx *cli.Context, stack *node.Node ) error {
// Create a new ethclient to for interfacing with the contract
stateReader, err := controls.CreateEthClient(stack)
stateReader, e, err := controls.CreateEthClient(stack)
if err != nil {
log.Error ("Unable to create ethereum client for permissions check : ", "err" , err)
return err
@ -52,7 +57,7 @@ func QuorumPermissioning(ctx *cli.Context, stack *node.Node ) error {
consensusEngine = RAFT
}
// Monitors node addition and decativation from network
manageNodePermissions(stack, stateReader, consensusEngine);
manageNodePermissions(ctx, stack, e, stateReader, consensusEngine);
// Monitors account level persmissions update from smart contarct
manageAccountPermissions(stack, stateReader);
@ -62,7 +67,11 @@ func QuorumPermissioning(ctx *cli.Context, stack *node.Node ) error {
// Manages node addition and decavtivation from network
func manageNodePermissions(stack *node.Node, stateReader *ethclient.Client, consensusEngine string) {
func manageNodePermissions(ctx *cli.Context, stack *node.Node, e *eth.Ethereum, stateReader *ethclient.Client, consensusEngine string) {
// populate the initial list of nodes into the smart contract
// from permissioned-nodes.json
populateNodesToContract(ctx, stack, e, stateReader)
//monitor for new nodes addition via smart contract
go monitorNewNodeAdd(stack, stateReader, consensusEngine)
@ -347,3 +356,95 @@ func formatEnodeId( enodeId , ipAddrPort, discPort, raftPort, consensusEngine st
}
return newEnodeId
}
//populates the nodes list from permissioned-nodes.json into the permissions
//smart contract
func populateNodesToContract(ctx *cli.Context, stack *node.Node, e *eth.Ethereum, stateReader *ethclient.Client){
log.Info("SMK - inside populateNodesToContract @363")
//Read the key file from key store. SHOULD WE MAKE IT CONFIG value
key := getKeyFromKeyStore(ctx)
permissionsContract, err := NewPermissions(params.QuorumPermissionsContract, stateReader)
if err != nil {
utils.Fatalf("Failed to instantiate a Permissions contract: %v", err)
}
auth, err := bind.NewTransactor(strings.NewReader(key), "")
if err != nil {
utils.Fatalf("Failed to create authorized transactor: %v", err)
}
permissionsSession := &PermissionsSession{
Contract: permissionsContract,
CallOpts: bind.CallOpts{
Pending: true,
},
TransactOpts: bind.TransactOpts{
From: auth.From,
Signer: auth.Signer,
GasLimit: 3558096384,
GasPrice: big.NewInt(0),
},
}
datadir := ctx.GlobalString(utils.DataDirFlag.Name)
nodes := p2p.ParsePermissionedNodes(datadir)
for _, node := range nodes {
enodeID := fmt.Sprintf("%x", node.ID[:])
ipAddr := fmt.Sprintf("%v", node.IP)
port := fmt.Sprintf("%v", node.TCP)
discPort := fmt.Sprintf("%v", node.UDP)
raftPort := fmt.Sprintf("%v", node.RaftPort)
ipAddrPort := ipAddr + ":" + port
log.Info("SMK-values are : ", "enodeId", enodeID, "ipAddrPort", ipAddrPort, "discPort", discPort, "raftPort", raftPort)
log.Trace("Adding node to permissions contract", "enodeID", enodeID)
nonce := e.TxPool().Nonce(permissionsSession.TransactOpts.From)
permissionsSession.TransactOpts.Nonce = new(big.Int).SetUint64(nonce)
tx, err := permissionsSession.ProposeNode(enodeID, ipAddrPort, discPort, raftPort)
if err != nil {
log.Warn("Failed to propose node", "err", err)
}
log.Debug("Transaction pending", "tx hash", tx.Hash())
}
// update the network boot status to true
nonce := e.TxPool().Nonce(permissionsSession.TransactOpts.From)
permissionsSession.TransactOpts.Nonce = new(big.Int).SetUint64(nonce)
tx, err := permissionsSession.UpdateNetworkBootStatus()
if err != nil {
log.Warn("Failed to udpate network boot status ", "err", err)
}
log.Debug("Transaction pending", "tx hash", tx.Hash())
}
//This functions reads the first file in key store directory, reads the key
//value and returns the same
func getKeyFromKeyStore(ctx *cli.Context) string {
datadir := ctx.GlobalString(utils.DataDirFlag.Name)
files, err := ioutil.ReadDir(filepath.Join(datadir, "keystore"))
if err != nil {
utils.Fatalf("Failed to read keystore directory: %v", err)
}
// HACK: here we always use the first key as transactor
var keyPath string
for _, f := range files {
keyPath = filepath.Join(datadir, "keystore", f.Name())
break
}
keyBlob, err := ioutil.ReadFile(keyPath)
if err != nil {
utils.Fatalf("Failed to read key file: %v", err)
}
// n := bytes.IndexByte(keyBlob, 0)
n := len(keyBlob)
return string(keyBlob[:n])
}

File diff suppressed because one or more lines are too long