add api stubs for permission node

This commit is contained in:
amalraj.manigmail.com 2018-10-29 12:23:53 +08:00
parent 63a38ae054
commit 299c17598a
4 changed files with 146 additions and 33 deletions

View File

@ -3,34 +3,122 @@ package backend
import (
"github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/log"
)
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"strings"
"math/big"
"github.com/ethereum/go-ethereum/p2p/discover"
"fmt"
"io/ioutil"
"path/filepath"
"github.com/ethereum/go-ethereum/controls/permbind"
)
type PermissionAPI struct {
}
func NewPermissionAPI() *PermissionAPI {
return &PermissionAPI{}
}
func APIs() []rpc.API {
func APIs(ec *ethclient.Client, e *eth.Ethereum, datadir string) []rpc.API {
return []rpc.API{
{
Namespace: "permnode",
Version: "1.0",
Service: NewPermissionAPI(),
Service: NewPermissionAPI(ec, e, datadir),
Public: true,
},
}
}
type PermissionAPI struct {
ethClient *ethclient.Client
eth *eth.Ethereum
permissionsContr *permbind.Permissions
transOpts *bind.TransactOpts
}
func getKeyFromKeyStore(datadir string) string {
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])
}
func NewPermissionAPI(ec *ethclient.Client, e *eth.Ethereum, datadir string) *PermissionAPI {
permissionsContract, err := permbind.NewPermissions(params.QuorumPermissionsContract, ec)
if err != nil {
utils.Fatalf("Failed to instantiate a Permissions contract: %v", err)
}
//TODO check if reading from keystore is correct approach
key := getKeyFromKeyStore(datadir)
auth, err := bind.NewTransactor(strings.NewReader(key), "")
if err != nil {
utils.Fatalf("Failed to create authorized transactor: %v", err)
}
return &PermissionAPI{ec, e, permissionsContract, auth}
}
func (s *PermissionAPI) AddVoter(addr string) string {
log.Info("AJ-called1")
return "added voter " + addr
}
func (s *PermissionAPI) ProposeNode(enodeId string) string {
log.Info("AJ-called2")
return "proposed node " + enodeId
node, err := discover.ParseNode(enodeId)
if err != nil {
return fmt.Sprintf("invalid node id: %v", err)
}
enodeID := node.ID.String()
ipAddr := node.IP.String()
port := fmt.Sprintf("%v", node.TCP)
discPort := fmt.Sprintf("%v", node.UDP)
raftPort := fmt.Sprintf("%v", node.RaftPort)
ipAddrPort := ipAddr + ":" + port
log.Trace("AJ-Adding node to permissions contract", "enodeID", enodeID)
nonce := s.eth.TxPool().Nonce(s.transOpts.From)
s.transOpts.Nonce = new(big.Int).SetUint64(nonce)
permissionsSession := &permbind.PermissionsSession{
Contract: s.permissionsContr,
CallOpts: bind.CallOpts{
Pending: true,
},
TransactOpts: bind.TransactOpts{
From: s.transOpts.From,
Signer: s.transOpts.Signer,
GasLimit: 4700000,
GasPrice: big.NewInt(0),
},
}
tx, err := permissionsSession.ProposeNode(enodeID, ipAddrPort, discPort, raftPort)
if err != nil {
log.Warn("AJ-Failed to propose node", "err", err)
}
statusMsg := fmt.Sprintf("Transaction pending tx hash %s", tx.Hash())
log.Debug(statusMsg)
return statusMsg
}
func (s *PermissionAPI) BlacklistNode(enodeId string) string {

View File

@ -1,7 +1,7 @@
// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package permissions
package permbind
import (
"math/big"

View File

@ -23,6 +23,7 @@ import (
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/raft"
"gopkg.in/urfave/cli.v1"
"github.com/ethereum/go-ethereum/controls/permbind"
)
const (
PERMISSIONED_CONFIG = "permissioned-nodes.json"
@ -50,7 +51,7 @@ func QuorumPermissioning(ctx *cli.Context, stack *node.Node ) error {
}
// check if permissioning contract is there at address. If not return from here
if _ , err = NewPermissionsFilterer(params.QuorumPermissionsContract, stateReader); err != nil {
if _ , err = permbind.NewPermissionsFilterer(params.QuorumPermissionsContract, stateReader); err != nil {
log.Error ("Permissions not enabled for the network : ", "err" , err)
return nil
}
@ -110,17 +111,17 @@ func manageNodePermissions(ctx *cli.Context, stack *node.Node, e *eth.Ethereum,
// This functions listens on the channel for new node approval via smart contract and
// adds the same into permissioned-nodes.json
func monitorNewNodeAdd(stack *node.Node, stateReader *ethclient.Client, isRaft bool) {
permissions, err := NewPermissionsFilterer(params.QuorumPermissionsContract, stateReader)
permissions, err := permbind.NewPermissionsFilterer(params.QuorumPermissionsContract, stateReader)
if err != nil {
log.Error ("failed to monitor new node add : ", "err" , err)
}
ch := make(chan *PermissionsNodeApproved, 1)
ch := make(chan *permbind.PermissionsNodeApproved, 1)
opts := &bind.WatchOpts{}
var blockNumber uint64 = 1
opts.Start = &blockNumber
var nodeAddEvent *PermissionsNodeApproved
var nodeAddEvent *permbind.PermissionsNodeApproved
_, err = permissions.WatchNodeApproved(opts, ch)
if err != nil {
@ -138,17 +139,17 @@ func monitorNewNodeAdd(stack *node.Node, stateReader *ethclient.Client, isRaft b
// This functions listens on the channel for new node approval via smart contract and
// adds the same into permissioned-nodes.json
func monitorNodeDeactivation(stack *node.Node, stateReader *ethclient.Client, isRaft bool) {
permissions, err := NewPermissionsFilterer(params.QuorumPermissionsContract, stateReader)
permissions, err := permbind.NewPermissionsFilterer(params.QuorumPermissionsContract, stateReader)
if err != nil {
log.Error ("Failed to monitor node delete: ", "err" , err)
}
ch := make(chan *PermissionsNodeDeactivated)
ch := make(chan *permbind.PermissionsNodeDeactivated)
opts := &bind.WatchOpts{}
var blockNumber uint64 = 1
opts.Start = &blockNumber
var newNodeDeleteEvent *PermissionsNodeDeactivated
var newNodeDeleteEvent *permbind.PermissionsNodeDeactivated
_, err = permissions.WatchNodeDeactivated(opts, ch)
if err != nil {
@ -167,16 +168,16 @@ func monitorNodeDeactivation(stack *node.Node, stateReader *ethclient.Client, is
// This function listnes on the channel for any node blacklisting event via smart contract
// and adds the same disallowed-nodes.json
func monitorNodeBlacklisting(stack *node.Node, stateReader *ethclient.Client, isRaft bool) {
permissions, err := NewPermissionsFilterer(params.QuorumPermissionsContract, stateReader)
permissions, err := permbind.NewPermissionsFilterer(params.QuorumPermissionsContract, stateReader)
if err != nil {
log.Error ("failed to monitor new node add : ", "err" , err)
}
ch := make(chan *PermissionsNodeBlacklisted, 1)
ch := make(chan *permbind.PermissionsNodeBlacklisted, 1)
opts := &bind.WatchOpts{}
var blockNumber uint64 = 1
opts.Start = &blockNumber
var nodeBlacklistEvent *PermissionsNodeBlacklisted
var nodeBlacklistEvent *permbind.PermissionsNodeBlacklisted
_, err = permissions.WatchNodeBlacklisted(opts, ch)
if err != nil {
@ -220,7 +221,7 @@ func updatePermissionedNodes(stack *node.Node, enodeId , ipAddrPort, discPort, r
}
//this function populates the new node information into the permissioned-nodes.json file
func updateDisallowedNodes(nodeBlacklistEvent *PermissionsNodeBlacklisted, stack *node.Node, isRaft bool){
func updateDisallowedNodes(nodeBlacklistEvent *permbind.PermissionsNodeBlacklisted, stack *node.Node, isRaft bool){
dataDir := stack.DataDir()
log.Debug("updateDisallowedNodes", "DataDir", dataDir, "file", BLACKLIST_CONFIG)
@ -275,7 +276,7 @@ func manageAccountPermissions(stack *node.Node, stateReader *ethclient.Client) e
// populates the nodes list from permissioned-nodes.json into the permissions
// smart contract
func populatePermissionedNodes (stack *node.Node, stateReader *ethclient.Client, isRaft bool) error{
permissions, err := NewPermissionsFilterer(params.QuorumPermissionsContract, stateReader)
permissions, err := permbind.NewPermissionsFilterer(params.QuorumPermissionsContract, stateReader)
if err != nil {
log.Error ("Failed to monitor node delete: ", "err" , err)
return err
@ -308,7 +309,7 @@ func populatePermissionedNodes (stack *node.Node, stateReader *ethclient.Client,
// populates the nodes list from permissioned-nodes.json into the permissions
// smart contract
func populateAcctPermissions(stack *node.Node, stateReader *ethclient.Client) error{
permissions, err := NewPermissionsFilterer(params.QuorumPermissionsContract, stateReader)
permissions, err := permbind.NewPermissionsFilterer(params.QuorumPermissionsContract, stateReader)
if err != nil {
log.Error ("Failed to monitor node delete: ", "err" , err)
return err
@ -331,16 +332,16 @@ func populateAcctPermissions(stack *node.Node, stateReader *ethclient.Client) er
// Monitors permissions changes at acount level and uodate the global permissions
// map with the same
func monitorAccountPermissions(stack *node.Node, stateReader *ethclient.Client) {
permissions, err := NewPermissionsFilterer(params.QuorumPermissionsContract, stateReader)
permissions, err := permbind.NewPermissionsFilterer(params.QuorumPermissionsContract, stateReader)
if err != nil {
log.Error ("Failed to monitor Account permissions : ", "err" , err)
}
ch := make(chan *PermissionsAccountAccessModified)
ch := make(chan *permbind.PermissionsAccountAccessModified)
opts := &bind.WatchOpts{}
var blockNumber uint64 = 1
opts.Start = &blockNumber
var newEvent *PermissionsAccountAccessModified
var newEvent *permbind.PermissionsAccountAccessModified
_, err = permissions.WatchAccountAccessModified(opts, ch)
if err != nil {
@ -392,11 +393,10 @@ func formatEnodeId( enodeId , ipAddrPort, discPort, raftPort string, isRaft bool
//populates the nodes list from permissioned-nodes.json into the permissions
//smart contract
func populateStaticNodesToContract(ctx *cli.Context, stack *node.Node, e *eth.Ethereum, stateReader *ethclient.Client){
//Read the key file from key store. SHOULD WE MAKE IT CONFIG value
key := getKeyFromKeyStore(ctx)
permissionsContract, err := NewPermissions(params.QuorumPermissionsContract, stateReader)
permissionsContract, err := permbind.NewPermissions(params.QuorumPermissionsContract, stateReader)
if err != nil {
utils.Fatalf("Failed to instantiate a Permissions contract: %v", err)
@ -406,7 +406,7 @@ func populateStaticNodesToContract(ctx *cli.Context, stack *node.Node, e *eth.Et
utils.Fatalf("Failed to create authorized transactor: %v", err)
}
permissionsSession := &PermissionsSession{
permissionsSession := &permbind.PermissionsSession{
Contract: permissionsContract,
CallOpts: bind.CallOpts{
Pending: true,

View File

@ -35,6 +35,12 @@ import (
"github.com/ethereum/go-ethereum/rpc"
"github.com/prometheus/prometheus/util/flock"
"github.com/ethereum/go-ethereum/controls/backend"
/* "github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/cmd/utils"*/
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/eth"
)
// Node is a container on which services can be registered.
@ -249,6 +255,18 @@ func (n *Node) openDataDir() error {
return nil
}
func createEthClient(stack *Node) (*ethclient.Client, *eth.Ethereum, error){
var e *eth.Ethereum
if err := stack.Service(&e); err != nil {
return nil, nil, err
}
rpcClient, err := stack.Attach()
if err != nil {
return nil, nil, err
}
return ethclient.NewClient(rpcClient), e, nil
}
// startRPC is a helper method to start all the various RPC endpoint during node
// startup. It's not meant to be called at any time afterwards as it makes certain
// assumptions about the state of the node.
@ -256,11 +274,18 @@ func (n *Node) startRPC(services map[reflect.Type]Service) error {
// Gather all the possible APIs to surface
apis := n.apis()
for _, service := range services {
//TODO get a ethereum service and pass the config from it to add perm service
apis = append(apis, service.APIs()...)
}
apis = append(apis, backend.APIs()...)
log.Info("AJ-permissions api added")
if n.config.EnableNodePermission {
ec, e, err := createEthClient(n)
if err != nil {
utils.Fatalf("Error creating eth client: %v", err)
}
apis = append(apis, backend.APIs(ec, e, n.InstanceDir())...)
log.Info("AJ-permissions api added")
}
// Start the various API endpoints, terminating all in case of errors
if err := n.startInProc(apis); err != nil {