Merge branch '1812-permission-rpc-api' of https://github.com/vsmk98/quorum into 1812-permission-rpc-api

merge with Amal's api segregation changes
This commit is contained in:
vsmk98 2018-11-15 13:25:25 +08:00
commit d49ed0318e
6 changed files with 176 additions and 106 deletions

View File

@ -361,8 +361,16 @@ func startNode(ctx *cli.Context, stack *node.Node) {
}
func startQuorumPermissionService(ctx *cli.Context, stack *node.Node) {
var quorumApis []string
if ctx.GlobalBool(utils.EnableNodePermissionFlag.Name) {
//default quorum api list
quorumApis = []string{"quorumNodeMgmt", "quorumAcctMgmt", "quorumKeyMgmt"}
} else {
quorumApis = []string{"quorumKeyMgmt"}
}
// start the permissions management service
pc, err := permission.NewQuorumPermissionCtrl(stack, ctx.GlobalBool(utils.EnableNodePermissionFlag.Name),ctx.GlobalBool(utils.RaftModeFlag.Name))
pc, err := permission.NewQuorumPermissionCtrl(stack, ctx.GlobalBool(utils.EnableNodePermissionFlag.Name), ctx.GlobalBool(utils.RaftModeFlag.Name))
if err != nil {
utils.Fatalf("Failed to start Quorum Permission contract service: %v", err)
}
@ -379,16 +387,20 @@ func startQuorumPermissionService(ctx *cli.Context, stack *node.Node) {
log.Trace("Key management service started")
}
v := stack.GetRPC("quorum")
if v == nil {
utils.Fatalf("Failed to start Quorum Permission API")
for _, apiName := range quorumApis {
v := stack.GetRPC(apiName)
if v == nil {
utils.Fatalf("Failed to start Quorum Permission API %s", apiName)
}
qapi := v.(*quorum.PermissionAPI)
rpcClient, err := stack.Attach()
if err != nil {
utils.Fatalf("Failed to attach to self: %v", err)
}
stateReader := ethclient.NewClient(rpcClient)
qapi.Init(stateReader, stack.GetNodeKey())
log.Info("Permission API started.", "apiName", apiName)
}
qapi := v.(*quorum.PermissionAPI)
rpcClient, err := stack.Attach()
if err != nil {
utils.Fatalf("Failed to attach to self: %v", err)
}
stateReader := ethclient.NewClient(rpcClient)
qapi.Init(stateReader, stack.GetNodeKey())
log.Info("Permission API initialized")
}

View File

@ -3,8 +3,8 @@ package permission
import (
"crypto/ecdsa"
"encoding/json"
"fmt"
"errors"
"fmt"
"io/ioutil"
"math/big"
"os"
@ -38,14 +38,14 @@ const (
)
type PermissionCtrl struct {
node *node.Node
ethClnt *ethclient.Client
eth *eth.Ethereum
isRaft bool
node *node.Node
ethClnt *ethclient.Client
eth *eth.Ethereum
isRaft bool
permissionedMode bool
key *ecdsa.PrivateKey
dataDir string
pm *pbind.Permissions
key *ecdsa.PrivateKey
dataDir string
pm *pbind.Permissions
}
// Creates the controls structure for permissions
@ -429,7 +429,7 @@ func (p *PermissionCtrl) populateInitPermission() error {
utils.Fatalf("Joining a permissioned network in non-permissioned mode. Bring up get with --permissioned.")
}
if !p.permissionedMode{
if !p.permissionedMode {
return errors.New("Node started in non-permissioned mode")
}
if tx != true {

View File

@ -73,7 +73,7 @@ type txArgs struct {
}
type nodeStatus struct {
Name string
Name string
Status string
}
@ -82,6 +82,17 @@ type ExecStatus struct {
Msg string
}
var nodeApproveStatus = map[uint8]string{
0: "Unknown",
1: "PendingApproval",
2: "Approved",
3: "PendingDeactivation",
4: "Deactivated",
5: "PendingActivation",
6: "PendingBlacklisting",
7: "Blacklisted",
}
// 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}
@ -89,28 +100,10 @@ func NewPermissionAPI(tp *core.TxPool, am *accounts.Manager) *PermissionAPI {
// helper function decodes the node status to string
func decodeNodeStatus(nodeStatus uint8) string {
var status string
switch nodeStatus{
case 0:
status = "Unknown"
case 1:
status = "PendingApproval"
case 2:
status = "Approved"
case 3:
status = "PendingDeactivation"
case 4:
status = "Deactivated"
case 5:
status = "PendingActivation"
case 6:
status = "PendingBlacklisting"
case 7:
status = "Blacklisted"
default:
status = "Unknown"
if status, ok := nodeApproveStatus[nodeStatus]; ok {
return status
}
return status
return "Unknown"
}
//Init initializes PermissionAPI with eth client, permission contract and org key management control
@ -130,7 +123,7 @@ func (p *PermissionAPI) Init(ethClnt *ethclient.Client, key *ecdsa.PrivateKey) e
return nil
}
// Returns the list of Nodes and status of each
// Returns the list of Nodes and status of each
func (s *PermissionAPI) PermissionNodeList() []nodeStatus {
auth := bind.NewKeyedTransactor(s.key)
ps := &pbind.PermissionsSession{
@ -147,14 +140,14 @@ func (s *PermissionAPI) PermissionNodeList() []nodeStatus {
}
// get the total number of nodes on the contract
nodeCnt, err := ps.GetNumberOfNodes()
nodeStatArr := make([]nodeStatus, nodeCnt.Uint64())
nodeCntI := nodeCnt.Int64()
nodeStatArr := make([]nodeStatus, nodeCntI)
// loop for each index and get the node details from the contract
if err == nil {
i := int64(0)
for nodeCnt.Cmp(big.NewInt(i)) > 0{
for i < nodeCntI {
nodeDtls, _ := ps.GetNodeDetails(big.NewInt(i))
nodeStatArr[i].Name = "enode://"+ nodeDtls.EnodeId + "@" +nodeDtls.IpAddrPort
nodeStatArr[i].Name = "enode://" + nodeDtls.EnodeId + "@" + nodeDtls.IpAddrPort
nodeStatArr[i].Name += "?discport=" + nodeDtls.DiscPort
if len(nodeDtls.RaftPort) > 0 {
nodeStatArr[i].Name += "&raftport" + nodeDtls.RaftPort
@ -253,7 +246,7 @@ func (s *PermissionAPI) executePermAction(action PermAction, args txArgs) ExecSt
tx, err = ps.RemoveVoter(args.voter)
case ProposeNode:
if !checkVoterExists(ps){
if !checkVoterExists(ps) {
return voterErr
}
node, err = discover.ParseNode(args.nodeId)
@ -271,7 +264,7 @@ func (s *PermissionAPI) executePermAction(action PermAction, args txArgs) ExecSt
tx, err = ps.ProposeNode(enodeID, ipAddrPort, discPort, raftPort)
case ApproveNode:
if !checkIsVoter(ps, args.txa.From){
if !checkIsVoter(ps, args.txa.From) {
return voterErr
}
node, err = discover.ParseNode(args.nodeId)
@ -283,7 +276,7 @@ func (s *PermissionAPI) executePermAction(action PermAction, args txArgs) ExecSt
tx, err = ps.ApproveNode(enodeID)
case ProposeNodeDeactivation:
if !checkVoterExists(ps){
if !checkVoterExists(ps) {
return voterErr
}
node, err = discover.ParseNode(args.nodeId)
@ -295,7 +288,7 @@ func (s *PermissionAPI) executePermAction(action PermAction, args txArgs) ExecSt
tx, err = ps.ProposeDeactivation(enodeID)
case ApproveNodeDeactivation:
if !checkIsVoter(ps, args.txa.From){
if !checkIsVoter(ps, args.txa.From) {
return voterErr
}
node, err = discover.ParseNode(args.nodeId)
@ -307,7 +300,7 @@ func (s *PermissionAPI) executePermAction(action PermAction, args txArgs) ExecSt
tx, err = ps.DeactivateNode(enodeID)
case ProposeNodeActivation:
if !checkVoterExists(ps){
if !checkVoterExists(ps) {
return voterErr
}
node, err = discover.ParseNode(args.nodeId)
@ -319,7 +312,7 @@ func (s *PermissionAPI) executePermAction(action PermAction, args txArgs) ExecSt
tx, err = ps.ProposeNodeActivation(enodeID)
case ApproveNodeActivation:
if !checkIsVoter(ps, args.txa.From){
if !checkIsVoter(ps, args.txa.From) {
return voterErr
}
node, err = discover.ParseNode(args.nodeId)
@ -331,7 +324,7 @@ func (s *PermissionAPI) executePermAction(action PermAction, args txArgs) ExecSt
tx, err = ps.ActivateNode(enodeID)
case ProposeNodeBlacklisting:
if !checkVoterExists(ps){
if !checkVoterExists(ps) {
return voterErr
}
node, err = discover.ParseNode(args.nodeId)
@ -348,7 +341,7 @@ func (s *PermissionAPI) executePermAction(action PermAction, args txArgs) ExecSt
tx, err = ps.ProposeNodeBlacklisting(enodeID, ipAddrPort, discPort, raftPort)
case ApproveNodeBlacklisting:
if !checkIsVoter(ps, args.txa.From){
if !checkIsVoter(ps, args.txa.From) {
return voterErr
}
node, err = discover.ParseNode(args.nodeId)
@ -427,6 +420,7 @@ func checkIsVoter(ps *pbind.PermissionsSession, acctId common.Address) bool {
}
return false
}
// newPermSession creates a new permission contract session
func (s *PermissionAPI) newPermSession(w accounts.Wallet, txa ethapi.SendTxArgs) *pbind.PermissionsSession {
frmAcct, transactOpts, gasLimit, gasPrice, nonce := s.getTxParams(txa, w)

View File

@ -23,6 +23,7 @@ type OrgStruct struct {
OrgId string
Keys []string
}
var DefaultAccess = FullAccess
const acctMapLimit = 100

View File

@ -35,6 +35,7 @@ import (
istanbulBackend "github.com/ethereum/go-ethereum/consensus/istanbul/backend"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/bloombits"
"github.com/ethereum/go-ethereum/core/quorum"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
@ -52,7 +53,6 @@ import (
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/core/quorum"
)
type LesServer interface {
@ -275,14 +275,13 @@ func CreateConsensusEngine(ctx *node.ServiceContext, config *Config, chainConfig
func (s *Ethereum) APIs() []rpc.API {
apis := ethapi.GetAPIs(s.APIBackend)
//TODO add perm service
// Append any APIs exposed explicitly by the consensus engine
apis = append(apis, s.engine.APIs(s.BlockChain())...)
// Append all the local APIs and return
return append(apis, []rpc.API{
apis = append(apis, []rpc.API{
{
Namespace: "eth",
Version: "1.0",
@ -328,13 +327,51 @@ func (s *Ethereum) APIs() []rpc.API {
Public: true,
},
{
Namespace: "quorum",
Namespace: "quorumNodeMgmt",
Version: "1.0",
Service: quorum.NewPermissionAPI(s.txPool, s.accountManager),
Public: true,
},
{
Namespace: "quorumAcctMgmt",
Version: "1.0",
Service: quorum.NewPermissionAPI(s.txPool, s.accountManager),
Public: true,
},
{
Namespace: "quorumKeyMgmt",
Version: "1.0",
Service: quorum.NewPermissionAPI(s.txPool, s.accountManager),
Public: true,
},
}...)
if s.config.EnableNodePermission {
apis = append(apis, []rpc.API{
{
Namespace: "quorumNodeMgmt",
Version: "1.0",
Service: quorum.NewPermissionAPI(s.txPool, s.accountManager),
Public: true,
},
{
Namespace: "quorumAcctMgmt",
Version: "1.0",
Service: quorum.NewPermissionAPI(s.txPool, s.accountManager),
Public: true,
},
}...)
}
apis = append(apis, []rpc.API{
{
Namespace: "quorumKeyMgmt",
Version: "1.0",
Service: quorum.NewPermissionAPI(s.txPool, s.accountManager),
Public: true,
},
}...)
return apis
}
func (s *Ethereum) ResetWithGenesisBlock(gb *types.Block) {

View File

@ -18,21 +18,23 @@
package web3ext
var Modules = map[string]string{
"admin": Admin_JS,
"chequebook": Chequebook_JS,
"clique": Clique_JS,
"debug": Debug_JS,
"eth": Eth_JS,
"miner": Miner_JS,
"net": Net_JS,
"personal": Personal_JS,
"rpc": RPC_JS,
"shh": Shh_JS,
"swarmfs": SWARMFS_JS,
"txpool": TxPool_JS,
"raft": Raft_JS,
"istanbul": Istanbul_JS,
"quorum": QUORUM_JS,
"admin": Admin_JS,
"chequebook": Chequebook_JS,
"clique": Clique_JS,
"debug": Debug_JS,
"eth": Eth_JS,
"miner": Miner_JS,
"net": Net_JS,
"personal": Personal_JS,
"rpc": RPC_JS,
"shh": Shh_JS,
"swarmfs": SWARMFS_JS,
"txpool": TxPool_JS,
"raft": Raft_JS,
"istanbul": Istanbul_JS,
"quorumNodeMgmt": QUORUM_NODE_JS,
"quorumAcctMgmt": QUORUM_ACCT_JS,
"quorumKeyMgmt": QUORUM_KEY_JS,
}
const Chequebook_JS = `
@ -683,100 +685,124 @@ web3._extend({
})
`
const QUORUM_JS = `
const QUORUM_NODE_JS = `
web3._extend({
property: 'quorum',
property: 'quorumNodeMgmt',
methods:
[
new web3._extend.Method({
name: 'addVoter',
call: 'quorum_addVoter',
call: 'quorumNodeMgmt_addVoter',
params: 2,
inputFormatter: [web3._extend.formatters.inputAddressFormatter,web3._extend.formatters.inputTransactionFormatter]
}),
new web3._extend.Method({
name: 'removeVoter',
call: 'quorum_removeVoter',
call: 'quorumNodeMgmt_removeVoter',
params: 2,
inputFormatter: [web3._extend.formatters.inputAddressFormatter,web3._extend.formatters.inputTransactionFormatter]
}),
new web3._extend.Method({
name: 'proposeNode',
call: 'quorum_proposeNode',
call: 'quorumNodeMgmt_proposeNode',
params: 2,
inputFormatter: [null,web3._extend.formatters.inputTransactionFormatter]
}),
new web3._extend.Method({
name: 'approveNode',
call: 'quorum_approveNode',
call: 'quorumNodeMgmt_approveNode',
params: 2,
inputFormatter: [null,web3._extend.formatters.inputTransactionFormatter]
}),
new web3._extend.Method({
name: 'proposeNodeDeactivation',
call: 'quorum_proposeNodeDeactivation',
call: 'quorumNodeMgmt_proposeNodeDeactivation',
params: 2,
inputFormatter: [null,web3._extend.formatters.inputTransactionFormatter]
}),
new web3._extend.Method({
name: 'approveNodeDeactivation',
call: 'quorum_approveNodeDeactivation',
call: 'quorumNodeMgmt_approveNodeDeactivation',
params: 2,
inputFormatter: [null,web3._extend.formatters.inputTransactionFormatter]
}),
new web3._extend.Method({
name: 'proposeNodeActivation',
call: 'quorum_proposeNodeActivation',
call: 'quorumNodeMgmt_proposeNodeActivation',
params: 2,
inputFormatter: [null,web3._extend.formatters.inputTransactionFormatter]
}),
new web3._extend.Method({
name: 'approveNodeActivation',
call: 'quorum_approveNodeActivation',
call: 'quorumNodeMgmt_approveNodeActivation',
params: 2,
inputFormatter: [null,web3._extend.formatters.inputTransactionFormatter]
}),
new web3._extend.Method({
name: 'proposeNodeBlacklisting',
call: 'quorum_proposeNodeBlacklisting',
call: 'quorumNodeMgmt_proposeNodeBlacklisting',
params: 2,
inputFormatter: [null,web3._extend.formatters.inputTransactionFormatter]
}),
new web3._extend.Method({
name: 'approveNodeBlacklisting',
call: 'quorum_approveNodeBlacklisting',
call: 'quorumNodeMgmt_approveNodeBlacklisting',
params: 2,
inputFormatter: [null,web3._extend.formatters.inputTransactionFormatter]
}),
new web3._extend.Method({
name: 'setAccountAccess',
call: 'quorum_setAccountAccess',
params: 3,
inputFormatter: [web3._extend.formatters.inputAddressFormatter,null,web3._extend.formatters.inputTransactionFormatter]
}),
new web3._extend.Method({
name: 'addOrgKey',
call: 'quorum_addOrgKey',
params: 3,
inputFormatter: [null,null,web3._extend.formatters.inputTransactionFormatter]
}),
new web3._extend.Method({
name: 'removeOrgKey',
call: 'quorum_removeOrgKey',
params: 3,
inputFormatter: [null,null,web3._extend.formatters.inputTransactionFormatter]
}),
],
properties:
[
new web3._extend.Property({
name: 'permissionNodeList',
getter: 'quorum_permissionNodeList'
getter: 'quorumNodeMgmt_permissionNodeList'
}),
]
})
`
const QUORUM_ACCT_JS = `
web3._extend({
property: 'quorumAcctMgmt',
methods:
[
new web3._extend.Method({
name: 'setAccountAccess',
call: 'quorumAcctMgmt_setAccountAccess',
params: 3,
inputFormatter: [web3._extend.formatters.inputAddressFormatter,null,web3._extend.formatters.inputTransactionFormatter]
}),
],
properties:
[
]
})
`
const QUORUM_KEY_JS = `
web3._extend({
property: 'quorumKeyMgmt',
methods:
[
new web3._extend.Method({
name: 'addOrgKey',
call: 'quorumKeyMgmt_addOrgKey',
params: 3,
inputFormatter: [null,null,web3._extend.formatters.inputTransactionFormatter]
}),
new web3._extend.Method({
name: 'removeOrgKey',
call: 'quorumKeyMgmt_removeOrgKey',
params: 3,
inputFormatter: [null,null,web3._extend.formatters.inputTransactionFormatter]
}),
],
properties:
[
]
})
`
const Istanbul_JS = `
web3._extend({
property: 'istanbul',