mirror of https://github.com/poanetwork/quorum.git
add api stubs for permission node
This commit is contained in:
parent
63a38ae054
commit
299c17598a
|
@ -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 {
|
||||
|
|
|
@ -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"
|
|
@ -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,
|
||||
|
|
27
node/node.go
27
node/node.go
|
@ -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()...)
|
||||
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 {
|
||||
|
|
Loading…
Reference in New Issue