added function for event monitoring

This commit is contained in:
vsmk98 2018-07-14 01:22:43 +00:00
parent 1f4abe1ed4
commit aaf0de899d
3 changed files with 133 additions and 74 deletions

View File

@ -255,7 +255,7 @@ func startNode(ctx *cli.Context, stack *node.Node) {
//START - QUORUM Permissioning //START - QUORUM Permissioning
if permissioned := ctx.GlobalBool(utils.EnableNodePermissionFlag.Name); permissioned { if permissioned := ctx.GlobalBool(utils.EnableNodePermissionFlag.Name); permissioned {
permissions.PopulateNodes(ctx, stack) permissions.QuorumPermissioning(ctx, stack)
} }
//END - QUORUM Permissioning //END - QUORUM Permissioning

7
params/quorum.go Normal file
View File

@ -0,0 +1,7 @@
package params
import "github.com/ethereum/go-ethereum/common"
var (
QuorumPermissionsContract = common.Address{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32}
)

View File

@ -9,7 +9,7 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
@ -17,86 +17,138 @@ import (
"github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p"
"gopkg.in/urfave/cli.v1" "gopkg.in/urfave/cli.v1"
) )
//This function first adds the node list from permissioned-nodes.json to
//the permissiones contract deployed as a precompile via genesis.json
func QuorumPermissioning(ctx *cli.Context, stack *node.Node ){
//Create a new ethclient to for interfacing with the contract
e, stateReader := createEthClient(stack)
//call populate nodes to populate the nodes into contract
populateNodesToContract (ctx, stack, e, stateReader)
//monitor for new nodes addition via smart contract
go monitorNewNodeAdd(stateReader)
}
//populates the nodes list from permissioned-nodes.json into the permissions //populates the nodes list from permissioned-nodes.json into the permissions
//smart contract //smart contract
func PopulateNodes(ctx *cli.Context, stack *node.Node ){ func populateNodesToContract(ctx *cli.Context, stack *node.Node, e *eth.Ethereum, stateReader *ethclient.Client){
log.Trace("Quorum permissioning v2 started") //Read the key file from key store. SHOULD WE MAKE IT CONFIG value
key := getKeyFromKeyStore(ctx)
var e *eth.Ethereum permissionsContract, err := NewPermissions(params.QuorumPermissionsContract, stateReader)
if err := stack.Service(&e); err != nil {
utils.Fatalf("Ethereum service not running: %v", err)
}
rpcClient, err := stack.Attach() if err != nil {
if err != nil { utils.Fatalf("Failed to instantiate a Permissions contract: %v", err)
utils.Fatalf("Failed to attach to self: %v", err) }
} auth, err := bind.NewTransactor(strings.NewReader(key), "")
stateReader := ethclient.NewClient(rpcClient) if err != nil {
log.Trace("rpc connection to permissions contract established") utils.Fatalf("Failed to create authorized transactor: %v", err)
}
datadir := ctx.GlobalString(utils.DataDirFlag.Name) permissionsSession := &PermissionsSession{
Contract: permissionsContract,
CallOpts: bind.CallOpts{
Pending: true,
},
TransactOpts: bind.TransactOpts{
From: auth.From,
Signer: auth.Signer,
GasLimit: 3558096384,
GasPrice: big.NewInt(0),
},
}
files, err := ioutil.ReadDir(filepath.Join(datadir, "keystore")) datadir := ctx.GlobalString(utils.DataDirFlag.Name)
if err != nil {
utils.Fatalf("Failed to read keystore directory: %v", err)
}
log.Trace("reading account keys...")
// (zekun) HACK: here we always use the first key as transactor nodes := p2p.ParsePermissionedNodes(datadir)
var keyPath string for _, node := range nodes {
for _, f := range files { enodeID := fmt.Sprintf("%x", node.ID[:])
keyPath = filepath.Join(datadir, "keystore", f.Name()) log.Trace("Adding node to permissions contract", "enodeID", enodeID)
break
}
keyBlob, err := ioutil.ReadFile(keyPath)
if err != nil {
utils.Fatalf("Failed to read key file: %v", err)
}
log.Debug("Finished reading key file", "keyPath", keyPath, "keyBlob", keyBlob)
// n := bytes.IndexByte(keyBlob, 0)
n := len(keyBlob)
log.Debug("Decoding keyBlob", "length", n)
key := string(keyBlob[:n])
log.Debug("Decoded key", "key", key)
contractAddr := common.HexToAddress("0x0000000000000000000000000000000000000020") // hard coded in genesis nonce := e.TxPool().Nonce(permissionsSession.TransactOpts.From)
permissionsContract, err := NewPermissions(contractAddr, stateReader) permissionsSession.TransactOpts.Nonce = new(big.Int).SetUint64(nonce)
if err != nil {
utils.Fatalf("Failed to instantiate a Permissions contract: %v", err) tx, err := permissionsSession.ProposeNode(enodeID, true, true)
} if err != nil {
log.Debug("Permissions contract instantiated") log.Warn("Failed to propose node", "err", err)
auth, err := bind.NewTransactor(strings.NewReader(key), "") }
if err != nil { log.Debug("Transaction pending", "tx hash", tx.Hash())
utils.Fatalf("Failed to create authorized transactor: %v", err) }
} }
log.Debug("Transactor created")
permissionsSession := &PermissionsSession{ //This functions listens on the channel for new node approval via smart contract and
Contract: permissionsContract, // adds the same into permissioned-nodes.json
CallOpts: bind.CallOpts{ func monitorNewNodeAdd(stateReader *ethclient.Client){
Pending: true,
}, permissions, err := NewPermissionsFilterer(params.QuorumPermissionsContract, stateReader)
TransactOpts: bind.TransactOpts{ if err != nil {
From: auth.From, utils.Fatalf("Failed to instantiate a Permissions Filterer: %v", err)
Signer: auth.Signer, }
GasLimit: 3558096384,
GasPrice: big.NewInt(0), ch := make(chan *PermissionsNewNodeProposed)
},
} opts := &bind.WatchOpts{}
var blockNumber uint64 = 1
opts.Start = &blockNumber
log.Info("Inside the new func added")
for {
log.Info("Inside the new loop - addNewNode")
_, err = permissions.WatchNewNodeProposed(opts, ch)
if err != nil {
log.Info("Failed NewNodeProposed: %v", err)
}
// newEvent = <-ch
var newEvent *PermissionsNewNodeProposed = <-ch
log.Info("Found Node add event", "enodeId", newEvent.EnodeId)
}
}
//Create an RPC client for the contract interface
func createEthClient(stack *node.Node ) (*eth.Ethereum, *ethclient.Client){
var e *eth.Ethereum
if err := stack.Service(&e); err != nil {
utils.Fatalf("Ethereum service not running: %v", err)
}
rpcClient, err := stack.Attach()
if err != nil {
utils.Fatalf("Failed to attach to self: %v", err)
}
return e, ethclient.NewClient(rpcClient)
}
//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)
}
// (zekun) 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])
nodes := p2p.ParsePermissionedNodes(datadir)
for _, node := range nodes {
enodeID := fmt.Sprintf("%x", node.ID[:])
log.Trace("Adding node to permissions contract", "enodeID", enodeID)
nonce := e.TxPool().Nonce(permissionsSession.TransactOpts.From)
permissionsSession.TransactOpts.Nonce = new(big.Int).SetUint64(nonce)
log.Trace("Current Nonce", "nonce", nonce)
tx, err := permissionsSession.ProposeNode(enodeID, true, true)
if err != nil {
log.Warn("Failed to propose node", "err", err)
}
log.Debug("Transaction pending", "tx hash", tx.Hash())
}
} }