2018-10-29 19:41:01 -07:00
|
|
|
package permission
|
2018-07-12 03:00:19 -07:00
|
|
|
|
|
|
|
import (
|
2018-10-30 23:42:29 -07:00
|
|
|
"crypto/ecdsa"
|
2018-07-16 03:34:20 -07:00
|
|
|
"encoding/json"
|
2018-10-31 22:45:16 -07:00
|
|
|
"fmt"
|
2018-07-12 03:00:19 -07:00
|
|
|
"io/ioutil"
|
2018-10-24 03:21:21 -07:00
|
|
|
"math/big"
|
2018-07-16 03:34:20 -07:00
|
|
|
"os"
|
2018-10-31 22:45:16 -07:00
|
|
|
"path/filepath"
|
2018-08-12 23:55:58 -07:00
|
|
|
"sync"
|
2018-07-12 03:00:19 -07:00
|
|
|
|
|
|
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
2018-10-31 22:45:16 -07:00
|
|
|
"github.com/ethereum/go-ethereum/controls"
|
|
|
|
pbind "github.com/ethereum/go-ethereum/controls/bind"
|
|
|
|
"github.com/ethereum/go-ethereum/core/types"
|
2018-10-24 03:21:21 -07:00
|
|
|
"github.com/ethereum/go-ethereum/eth"
|
2018-07-12 03:00:19 -07:00
|
|
|
"github.com/ethereum/go-ethereum/ethclient"
|
|
|
|
"github.com/ethereum/go-ethereum/log"
|
|
|
|
"github.com/ethereum/go-ethereum/node"
|
2018-10-24 03:21:21 -07:00
|
|
|
"github.com/ethereum/go-ethereum/p2p"
|
2018-09-19 18:51:36 -07:00
|
|
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
2018-10-31 22:45:16 -07:00
|
|
|
"github.com/ethereum/go-ethereum/params"
|
2018-09-18 23:55:41 -07:00
|
|
|
"github.com/ethereum/go-ethereum/raft"
|
2018-07-12 03:00:19 -07:00
|
|
|
)
|
2018-10-29 19:41:01 -07:00
|
|
|
|
2018-07-16 03:34:20 -07:00
|
|
|
const (
|
|
|
|
PERMISSIONED_CONFIG = "permissioned-nodes.json"
|
2018-10-29 19:41:01 -07:00
|
|
|
BLACKLIST_CONFIG = "disallowed-nodes.json"
|
2018-07-16 03:34:20 -07:00
|
|
|
)
|
2018-07-13 18:22:43 -07:00
|
|
|
|
2018-08-12 19:00:35 -07:00
|
|
|
type NodeOperation uint8
|
2018-10-29 19:41:01 -07:00
|
|
|
|
2018-08-12 19:00:35 -07:00
|
|
|
const (
|
|
|
|
NodeAdd NodeOperation = iota
|
|
|
|
NodeDelete
|
|
|
|
)
|
|
|
|
|
2018-10-29 19:41:01 -07:00
|
|
|
type PermissionCtrl struct {
|
|
|
|
node *node.Node
|
|
|
|
ethClnt *ethclient.Client
|
|
|
|
eth *eth.Ethereum
|
|
|
|
isRaft bool
|
2018-10-30 23:42:29 -07:00
|
|
|
key *ecdsa.PrivateKey
|
2018-11-02 03:42:14 -07:00
|
|
|
dataDir string
|
2018-11-04 19:28:33 -08:00
|
|
|
pm *pbind.Permissions
|
2018-10-25 21:33:23 -07:00
|
|
|
}
|
|
|
|
|
2018-10-31 19:55:40 -07:00
|
|
|
// Creates the controls structure for permissions
|
2018-10-30 23:42:29 -07:00
|
|
|
func NewQuorumPermissionCtrl(stack *node.Node, isRaft bool) (*PermissionCtrl, error) {
|
2018-08-05 22:26:29 -07:00
|
|
|
// Create a new ethclient to for interfacing with the contract
|
2018-10-24 03:21:21 -07:00
|
|
|
stateReader, e, err := controls.CreateEthClient(stack)
|
2018-08-05 22:26:29 -07:00
|
|
|
if err != nil {
|
2018-10-29 19:41:01 -07:00
|
|
|
log.Error("Unable to create ethereum client for permissions check : ", "err", err)
|
|
|
|
return nil, err
|
2018-08-12 19:00:35 -07:00
|
|
|
}
|
2018-10-29 19:41:01 -07:00
|
|
|
|
|
|
|
// check if permissioning contract is there at address. If not return from here
|
2018-11-04 19:28:33 -08:00
|
|
|
pm, err := pbind.NewPermissions(params.QuorumPermissionsContract, stateReader)
|
2018-11-02 03:42:14 -07:00
|
|
|
if err != nil {
|
2018-10-29 19:41:01 -07:00
|
|
|
log.Error("Permissions not enabled for the network : ", "err", err)
|
2018-11-02 03:42:14 -07:00
|
|
|
return nil, err
|
2018-10-29 19:41:01 -07:00
|
|
|
}
|
2018-10-25 22:38:56 -07:00
|
|
|
|
2018-11-04 19:28:33 -08:00
|
|
|
return &PermissionCtrl{stack, stateReader, e, isRaft, stack.GetNodeKey(), stack.DataDir(), pm}, nil
|
2018-11-02 03:42:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// Starts the node permissioning and account access control monitoring
|
|
|
|
func (p *PermissionCtrl) Start() error {
|
|
|
|
// At node level update QuorumPermissions to indicate new permissioning is in use
|
|
|
|
server := p.node.Server()
|
|
|
|
server.QuorumPermissions = true
|
|
|
|
|
2018-10-25 22:38:56 -07:00
|
|
|
// Permissions initialization
|
2018-11-02 03:42:14 -07:00
|
|
|
if err := p.init(); err != nil {
|
|
|
|
log.Error("Permissions init failed : ", "err", err)
|
|
|
|
return err
|
|
|
|
}
|
2018-10-25 22:38:56 -07:00
|
|
|
|
2018-08-12 19:00:35 -07:00
|
|
|
// Monitors node addition and decativation from network
|
2018-10-29 19:41:01 -07:00
|
|
|
p.manageNodePermissions()
|
2018-08-12 19:00:35 -07:00
|
|
|
|
2018-10-31 22:45:16 -07:00
|
|
|
// Monitors account level persmissions update from smart contarct
|
2018-10-29 19:41:01 -07:00
|
|
|
p.manageAccountPermissions()
|
2018-11-02 03:42:14 -07:00
|
|
|
|
2018-08-12 19:00:35 -07:00
|
|
|
return nil
|
|
|
|
}
|
2018-07-13 18:22:43 -07:00
|
|
|
|
2018-10-25 22:38:56 -07:00
|
|
|
// This functions updates the initial values for the network
|
2018-10-29 19:41:01 -07:00
|
|
|
func (p *PermissionCtrl) init() error {
|
2018-11-02 03:42:14 -07:00
|
|
|
// populate the initial list of permissioned nodes and account accesses
|
|
|
|
if err := p.populateInitPermission(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2018-10-25 22:38:56 -07:00
|
|
|
|
2018-11-04 19:28:33 -08:00
|
|
|
// call populates the account permissions based on past history
|
|
|
|
if err := p.populateAcctPermissions(); err != nil {
|
2018-10-25 22:38:56 -07:00
|
|
|
return err
|
|
|
|
}
|
2018-11-02 03:42:14 -07:00
|
|
|
|
2018-11-04 19:28:33 -08:00
|
|
|
// call populates the node details from contract to KnownNodes
|
|
|
|
if err := p.populatePermissionedNodes(); err != nil {
|
2018-10-25 22:38:56 -07:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-11-02 03:42:14 -07:00
|
|
|
// Manages node addition, decavtivation and activation from network
|
2018-10-29 19:41:01 -07:00
|
|
|
func (p *PermissionCtrl) manageNodePermissions() {
|
2018-10-24 03:21:21 -07:00
|
|
|
|
2018-07-13 18:22:43 -07:00
|
|
|
//monitor for new nodes addition via smart contract
|
2018-10-29 19:41:01 -07:00
|
|
|
go p.monitorNewNodeAdd()
|
2018-07-26 00:46:53 -07:00
|
|
|
|
|
|
|
//monitor for nodes deletiin via smart contract
|
2018-10-29 19:41:01 -07:00
|
|
|
go p.monitorNodeDeactivation()
|
2018-08-31 04:35:35 -07:00
|
|
|
|
2018-11-02 03:42:14 -07:00
|
|
|
//monitor for nodes activation from deactivation status
|
|
|
|
go p.monitorNodeActivation()
|
|
|
|
|
2018-08-31 04:35:35 -07:00
|
|
|
//monitor for nodes blacklisting via smart contract
|
2018-10-29 19:41:01 -07:00
|
|
|
go p.monitorNodeBlacklisting()
|
2018-07-13 18:22:43 -07:00
|
|
|
}
|
|
|
|
|
2018-08-12 19:00:35 -07:00
|
|
|
// This functions listens on the channel for new node approval via smart contract and
|
2018-07-13 18:22:43 -07:00
|
|
|
// adds the same into permissioned-nodes.json
|
2018-10-29 19:41:01 -07:00
|
|
|
func (p *PermissionCtrl) monitorNewNodeAdd() {
|
2018-10-30 00:59:08 -07:00
|
|
|
ch := make(chan *pbind.PermissionsNodeApproved, 1)
|
2018-07-13 18:22:43 -07:00
|
|
|
|
|
|
|
opts := &bind.WatchOpts{}
|
|
|
|
var blockNumber uint64 = 1
|
|
|
|
opts.Start = &blockNumber
|
2018-10-30 00:59:08 -07:00
|
|
|
var nodeAddEvent *pbind.PermissionsNodeApproved
|
2018-07-13 18:22:43 -07:00
|
|
|
|
2018-11-04 19:28:33 -08:00
|
|
|
_, err := p.pm.PermissionsFilterer.WatchNodeApproved(opts, ch)
|
2018-08-16 20:20:33 -07:00
|
|
|
if err != nil {
|
|
|
|
log.Info("Failed WatchNodeApproved: %v", err)
|
|
|
|
}
|
|
|
|
for {
|
2018-08-12 23:55:58 -07:00
|
|
|
select {
|
|
|
|
case nodeAddEvent = <-ch:
|
2018-10-29 19:41:01 -07:00
|
|
|
p.updatePermissionedNodes(nodeAddEvent.EnodeId, nodeAddEvent.IpAddrPort, nodeAddEvent.DiscPort, nodeAddEvent.RaftPort, NodeAdd)
|
2018-08-12 23:55:58 -07:00
|
|
|
}
|
2018-10-29 19:41:01 -07:00
|
|
|
}
|
2018-07-13 18:22:43 -07:00
|
|
|
}
|
|
|
|
|
2018-08-12 19:00:35 -07:00
|
|
|
// This functions listens on the channel for new node approval via smart contract and
|
2018-07-26 00:46:53 -07:00
|
|
|
// adds the same into permissioned-nodes.json
|
2018-10-29 19:41:01 -07:00
|
|
|
func (p *PermissionCtrl) monitorNodeDeactivation() {
|
2018-10-30 00:59:08 -07:00
|
|
|
ch := make(chan *pbind.PermissionsNodeDeactivated)
|
2018-07-26 00:46:53 -07:00
|
|
|
|
|
|
|
opts := &bind.WatchOpts{}
|
|
|
|
var blockNumber uint64 = 1
|
|
|
|
opts.Start = &blockNumber
|
2018-10-30 00:59:08 -07:00
|
|
|
var newNodeDeleteEvent *pbind.PermissionsNodeDeactivated
|
2018-11-04 19:28:33 -08:00
|
|
|
_, err := p.pm.PermissionsFilterer.WatchNodeDeactivated(opts, ch)
|
2018-08-16 20:20:33 -07:00
|
|
|
if err != nil {
|
|
|
|
log.Info("Failed NodeDeactivated: %v", err)
|
|
|
|
}
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case newNodeDeleteEvent = <-ch:
|
2018-10-29 19:41:01 -07:00
|
|
|
p.updatePermissionedNodes(newNodeDeleteEvent.EnodeId, newNodeDeleteEvent.IpAddrPort, newNodeDeleteEvent.DiscPort, newNodeDeleteEvent.RaftPort, NodeDelete)
|
|
|
|
}
|
2018-07-26 00:46:53 -07:00
|
|
|
|
2018-08-16 20:20:33 -07:00
|
|
|
}
|
2018-07-26 00:46:53 -07:00
|
|
|
}
|
2018-08-05 22:26:29 -07:00
|
|
|
|
2018-08-31 04:35:35 -07:00
|
|
|
// This function listnes on the channel for any node blacklisting event via smart contract
|
|
|
|
// and adds the same disallowed-nodes.json
|
2018-11-02 03:42:14 -07:00
|
|
|
func (p *PermissionCtrl) monitorNodeActivation() {
|
|
|
|
ch := make(chan *pbind.PermissionsNodeActivated, 1)
|
|
|
|
|
|
|
|
opts := &bind.WatchOpts{}
|
|
|
|
var blockNumber uint64 = 1
|
|
|
|
opts.Start = &blockNumber
|
|
|
|
var nodeActivatedEvent *pbind.PermissionsNodeActivated
|
|
|
|
|
2018-11-04 19:28:33 -08:00
|
|
|
_, err := p.pm.PermissionsFilterer.WatchNodeActivated(opts, ch)
|
2018-08-31 04:35:35 -07:00
|
|
|
if err != nil {
|
2018-11-02 03:42:14 -07:00
|
|
|
log.Info("Failed WatchNodeActivated: %v", err)
|
|
|
|
}
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case nodeActivatedEvent = <-ch:
|
|
|
|
p.updatePermissionedNodes(nodeActivatedEvent.EnodeId, nodeActivatedEvent.IpAddrPort, nodeActivatedEvent.DiscPort, nodeActivatedEvent.RaftPort, NodeAdd)
|
|
|
|
}
|
2018-08-31 04:35:35 -07:00
|
|
|
}
|
2018-11-02 03:42:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// This functions listens on the channel for node blacklisting via smart contract and
|
|
|
|
// adds the same into disallowed-nodes.json
|
|
|
|
func (p *PermissionCtrl) monitorNodeBlacklisting() {
|
|
|
|
ch := make(chan *pbind.PermissionsNodeBlacklisted)
|
2018-08-31 04:35:35 -07:00
|
|
|
|
|
|
|
opts := &bind.WatchOpts{}
|
|
|
|
var blockNumber uint64 = 1
|
|
|
|
opts.Start = &blockNumber
|
2018-11-02 03:42:14 -07:00
|
|
|
var newNodeBlacklistEvent *pbind.PermissionsNodeBlacklisted
|
2018-08-31 04:35:35 -07:00
|
|
|
|
2018-11-04 19:28:33 -08:00
|
|
|
_, err := p.pm.PermissionsFilterer.WatchNodeBlacklisted(opts, ch)
|
2018-08-31 04:35:35 -07:00
|
|
|
if err != nil {
|
2018-11-02 03:42:14 -07:00
|
|
|
log.Info("Failed NodeBlacklisting: %v", err)
|
2018-08-31 04:35:35 -07:00
|
|
|
}
|
|
|
|
for {
|
|
|
|
select {
|
2018-11-02 03:42:14 -07:00
|
|
|
case newNodeBlacklistEvent = <-ch:
|
|
|
|
p.updateDisallowedNodes(newNodeBlacklistEvent)
|
2018-08-31 04:35:35 -07:00
|
|
|
}
|
2018-11-02 03:42:14 -07:00
|
|
|
|
2018-10-29 19:41:01 -07:00
|
|
|
}
|
2018-08-31 04:35:35 -07:00
|
|
|
}
|
2018-07-16 03:34:20 -07:00
|
|
|
//this function populates the new node information into the permissioned-nodes.json file
|
2018-10-29 19:41:01 -07:00
|
|
|
func (p *PermissionCtrl) updatePermissionedNodes(enodeId, ipAddrPort, discPort, raftPort string, operation NodeOperation) {
|
2018-11-02 03:42:14 -07:00
|
|
|
newEnodeId := p.formatEnodeId(enodeId, ipAddrPort, discPort, raftPort)
|
2018-07-16 03:34:20 -07:00
|
|
|
|
2018-10-25 22:38:56 -07:00
|
|
|
//new logic to update the server KnownNodes variable for permissioning
|
2018-10-31 22:45:16 -07:00
|
|
|
server := p.node.Server()
|
2018-10-25 22:38:56 -07:00
|
|
|
newNode, err := discover.ParseNode(newEnodeId)
|
|
|
|
if err != nil {
|
|
|
|
log.Error("updatePermissionedNodes: Node URL", "url", newEnodeId, "err", err)
|
2018-07-16 03:34:20 -07:00
|
|
|
}
|
2018-08-12 23:55:58 -07:00
|
|
|
|
2018-10-31 22:45:16 -07:00
|
|
|
if operation == NodeAdd {
|
2018-10-25 22:38:56 -07:00
|
|
|
// Add the new enode id to server.KnownNodes
|
|
|
|
server.KnownNodes = append(server.KnownNodes, newNode)
|
2018-08-12 23:55:58 -07:00
|
|
|
} else {
|
2018-10-25 22:38:56 -07:00
|
|
|
// delete the new enode id from server.KnownNodes
|
2018-08-16 20:20:33 -07:00
|
|
|
index := 0
|
2018-10-25 22:38:56 -07:00
|
|
|
for i, node := range server.KnownNodes {
|
2018-10-31 22:45:16 -07:00
|
|
|
if node.ID == newNode.ID {
|
2018-08-16 20:20:33 -07:00
|
|
|
index = i
|
|
|
|
}
|
|
|
|
}
|
2018-10-29 19:41:01 -07:00
|
|
|
server.KnownNodes = append(server.KnownNodes[:index], server.KnownNodes[index+1:]...)
|
2018-11-02 03:42:14 -07:00
|
|
|
p.disconnectNode(newEnodeId)
|
2018-07-26 00:46:53 -07:00
|
|
|
}
|
2018-07-16 03:34:20 -07:00
|
|
|
|
2018-08-12 19:00:35 -07:00
|
|
|
}
|
2018-08-31 04:35:35 -07:00
|
|
|
|
|
|
|
//this function populates the new node information into the permissioned-nodes.json file
|
2018-10-30 00:59:08 -07:00
|
|
|
func (p *PermissionCtrl) updateDisallowedNodes(nodeBlacklistEvent *pbind.PermissionsNodeBlacklisted) {
|
2018-11-02 03:42:14 -07:00
|
|
|
log.Debug("updateDisallowedNodes", "DataDir", p.dataDir, "file", BLACKLIST_CONFIG)
|
2018-08-31 04:35:35 -07:00
|
|
|
|
2018-09-02 23:59:45 -07:00
|
|
|
fileExisted := true
|
2018-11-02 03:42:14 -07:00
|
|
|
path := filepath.Join(p.dataDir, BLACKLIST_CONFIG)
|
2018-09-02 23:59:45 -07:00
|
|
|
// Check if the file is existing. If the file is not existing create the file
|
2018-08-31 04:35:35 -07:00
|
|
|
if _, err := os.Stat(path); err != nil {
|
2018-10-29 19:41:01 -07:00
|
|
|
log.Error("Read Error for disallowed-nodes.json file.", "err", err)
|
2018-08-31 04:35:35 -07:00
|
|
|
if _, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR, 0644); err != nil {
|
|
|
|
log.Error("Failed to create disallowed-nodes.json file ", "err", err)
|
2018-10-29 19:41:01 -07:00
|
|
|
return
|
2018-08-31 04:35:35 -07:00
|
|
|
}
|
2018-09-02 23:59:45 -07:00
|
|
|
fileExisted = false
|
2018-08-31 04:35:35 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
nodelist := []string{}
|
2018-09-02 23:59:45 -07:00
|
|
|
// Load the nodes from the config file
|
|
|
|
if fileExisted == true {
|
|
|
|
blob, err := ioutil.ReadFile(path)
|
|
|
|
if err != nil {
|
|
|
|
log.Error("updateDisallowedNodes Failed to access disallowed-nodes.json", "err", err)
|
|
|
|
return
|
|
|
|
}
|
2018-10-31 22:45:16 -07:00
|
|
|
if blob != nil {
|
2018-09-02 23:59:45 -07:00
|
|
|
if err := json.Unmarshal(blob, &nodelist); err != nil {
|
|
|
|
log.Error("updateDisallowedNodes: Failed to load nodes list", "err", err)
|
2018-10-29 19:41:01 -07:00
|
|
|
return
|
2018-09-02 23:59:45 -07:00
|
|
|
}
|
2018-08-31 04:35:35 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-02 03:42:14 -07:00
|
|
|
newEnodeId := p.formatEnodeId(nodeBlacklistEvent.EnodeId, nodeBlacklistEvent.IpAddrPort, nodeBlacklistEvent.DiscPort, nodeBlacklistEvent.RaftPort)
|
2018-08-31 04:35:35 -07:00
|
|
|
nodelist = append(nodelist, newEnodeId)
|
|
|
|
mu := sync.RWMutex{}
|
2018-09-02 23:59:45 -07:00
|
|
|
blob, _ := json.Marshal(nodelist)
|
2018-08-31 04:35:35 -07:00
|
|
|
mu.Lock()
|
2018-10-29 19:41:01 -07:00
|
|
|
if err := ioutil.WriteFile(path, blob, 0644); err != nil {
|
2018-08-31 04:35:35 -07:00
|
|
|
log.Error("updateDisallowedNodes: Error writing new node info to file", "err", err)
|
|
|
|
}
|
|
|
|
mu.Unlock()
|
2018-09-17 22:52:46 -07:00
|
|
|
|
|
|
|
// Disconnect the peer if it is already connected
|
2018-10-29 19:41:01 -07:00
|
|
|
p.disconnectNode(newEnodeId)
|
2018-08-31 04:35:35 -07:00
|
|
|
}
|
|
|
|
|
2018-08-12 19:00:35 -07:00
|
|
|
// Manages account level permissions update
|
2018-11-02 03:42:14 -07:00
|
|
|
func (p *PermissionCtrl) manageAccountPermissions() {
|
2018-08-12 19:00:35 -07:00
|
|
|
//monitor for nodes deletiin via smart contract
|
2018-10-29 19:41:01 -07:00
|
|
|
go p.monitorAccountPermissions()
|
2018-11-02 03:42:14 -07:00
|
|
|
|
|
|
|
return
|
2018-08-12 19:00:35 -07:00
|
|
|
}
|
2018-10-29 19:41:01 -07:00
|
|
|
|
2018-10-25 22:38:56 -07:00
|
|
|
// populates the nodes list from permissioned-nodes.json into the permissions
|
|
|
|
// smart contract
|
2018-10-29 19:41:01 -07:00
|
|
|
func (p *PermissionCtrl) populatePermissionedNodes() error {
|
2018-10-25 22:38:56 -07:00
|
|
|
opts := &bind.FilterOpts{}
|
2018-11-04 19:28:33 -08:00
|
|
|
pastAddEvent, err := p.pm.PermissionsFilterer.FilterNodeApproved(opts)
|
2018-10-25 22:38:56 -07:00
|
|
|
|
2018-11-02 03:42:14 -07:00
|
|
|
if err != nil {
|
|
|
|
recExists := true
|
|
|
|
for recExists {
|
|
|
|
recExists = pastAddEvent.Next()
|
|
|
|
if recExists {
|
|
|
|
p.updatePermissionedNodes(pastAddEvent.Event.EnodeId, pastAddEvent.Event.IpAddrPort, pastAddEvent.Event.DiscPort, pastAddEvent.Event.RaftPort, NodeAdd)
|
|
|
|
}
|
2018-10-25 22:38:56 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
opts = &bind.FilterOpts{}
|
2018-11-04 19:28:33 -08:00
|
|
|
pastDelEvent, err := p.pm.PermissionsFilterer.FilterNodeDeactivated(opts)
|
2018-11-02 03:42:14 -07:00
|
|
|
if err != nil {
|
|
|
|
recExists := true
|
|
|
|
for recExists {
|
|
|
|
recExists = pastDelEvent.Next()
|
|
|
|
if recExists {
|
|
|
|
p.updatePermissionedNodes(pastDelEvent.Event.EnodeId, pastDelEvent.Event.IpAddrPort, pastDelEvent.Event.DiscPort, pastDelEvent.Event.RaftPort, NodeDelete)
|
|
|
|
}
|
2018-10-25 22:38:56 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
2018-08-12 19:00:35 -07:00
|
|
|
|
|
|
|
// populates the nodes list from permissioned-nodes.json into the permissions
|
|
|
|
// smart contract
|
2018-10-29 19:41:01 -07:00
|
|
|
func (p *PermissionCtrl) populateAcctPermissions() error {
|
2018-08-12 19:00:35 -07:00
|
|
|
opts := &bind.FilterOpts{}
|
2018-11-04 19:28:33 -08:00
|
|
|
pastEvents, err := p.pm.PermissionsFilterer.FilterAccountAccessModified(opts)
|
2018-08-12 19:00:35 -07:00
|
|
|
|
2018-11-04 19:28:33 -08:00
|
|
|
if err == nil {
|
2018-11-02 03:42:14 -07:00
|
|
|
recExists := true
|
|
|
|
for recExists {
|
|
|
|
recExists = pastEvents.Next()
|
|
|
|
if recExists {
|
|
|
|
types.AddAccountAccess(pastEvents.Event.Address, pastEvents.Event.Access)
|
|
|
|
}
|
2018-08-12 19:00:35 -07:00
|
|
|
}
|
|
|
|
}
|
2018-11-02 03:42:14 -07:00
|
|
|
|
2018-08-12 19:00:35 -07:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Monitors permissions changes at acount level and uodate the global permissions
|
|
|
|
// map with the same
|
2018-10-29 19:41:01 -07:00
|
|
|
func (p *PermissionCtrl) monitorAccountPermissions() {
|
2018-10-30 00:59:08 -07:00
|
|
|
ch := make(chan *pbind.PermissionsAccountAccessModified)
|
2018-08-12 19:00:35 -07:00
|
|
|
|
|
|
|
opts := &bind.WatchOpts{}
|
|
|
|
var blockNumber uint64 = 1
|
|
|
|
opts.Start = &blockNumber
|
2018-10-30 00:59:08 -07:00
|
|
|
var newEvent *pbind.PermissionsAccountAccessModified
|
2018-08-12 19:00:35 -07:00
|
|
|
|
2018-11-04 19:28:33 -08:00
|
|
|
_, err := p.pm.PermissionsFilterer.WatchAccountAccessModified(opts, ch)
|
2018-08-16 20:20:33 -07:00
|
|
|
if err != nil {
|
|
|
|
log.Info("Failed NewNodeProposed: %v", err)
|
|
|
|
}
|
2018-08-12 19:00:35 -07:00
|
|
|
|
|
|
|
for {
|
2018-08-16 20:20:33 -07:00
|
|
|
select {
|
|
|
|
case newEvent = <-ch:
|
2018-09-05 19:40:21 -07:00
|
|
|
types.AddAccountAccess(newEvent.Address, newEvent.Access)
|
2018-08-12 19:00:35 -07:00
|
|
|
}
|
2018-10-29 19:41:01 -07:00
|
|
|
}
|
2018-07-16 03:34:20 -07:00
|
|
|
}
|
2018-09-19 18:51:36 -07:00
|
|
|
|
|
|
|
// Disconnect the node from the network
|
2018-10-29 19:41:01 -07:00
|
|
|
func (p *PermissionCtrl) disconnectNode(enodeId string) {
|
|
|
|
if p.isRaft {
|
2018-09-19 18:51:36 -07:00
|
|
|
var raftService *raft.RaftService
|
2018-10-29 19:41:01 -07:00
|
|
|
if err := p.node.Service(&raftService); err == nil {
|
2018-09-19 18:51:36 -07:00
|
|
|
raftApi := raft.NewPublicRaftAPI(raftService)
|
|
|
|
|
|
|
|
//get the raftId for the given enodeId
|
|
|
|
raftId, err := raftApi.GetRaftId(enodeId)
|
|
|
|
if err == nil {
|
|
|
|
raftApi.RemovePeer(raftId)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Istanbul - disconnect the peer
|
2018-10-29 19:41:01 -07:00
|
|
|
server := p.node.Server()
|
2018-09-19 18:51:36 -07:00
|
|
|
if server != nil {
|
|
|
|
node, err := discover.ParseNode(enodeId)
|
|
|
|
if err == nil {
|
|
|
|
server.RemovePeer(node)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-09-19 22:55:57 -07:00
|
|
|
|
|
|
|
// helper function to format EnodeId
|
2018-11-02 03:42:14 -07:00
|
|
|
func (p *PermissionCtrl) formatEnodeId(enodeId, ipAddrPort, discPort, raftPort string) string {
|
2018-09-19 22:55:57 -07:00
|
|
|
newEnodeId := "enode://" + enodeId + "@" + ipAddrPort + "?discPort=" + discPort
|
2018-11-02 03:42:14 -07:00
|
|
|
if p.isRaft {
|
2018-10-29 19:41:01 -07:00
|
|
|
newEnodeId += "&raftport=" + raftPort
|
2018-09-19 22:55:57 -07:00
|
|
|
}
|
|
|
|
return newEnodeId
|
|
|
|
}
|
2018-10-29 19:41:01 -07:00
|
|
|
|
2018-10-24 03:21:21 -07:00
|
|
|
//populates the nodes list from permissioned-nodes.json into the permissions
|
|
|
|
//smart contract
|
2018-11-02 03:42:14 -07:00
|
|
|
func (p *PermissionCtrl) populateInitPermission() error {
|
2018-10-30 23:42:29 -07:00
|
|
|
auth := bind.NewKeyedTransactor(p.key)
|
2018-10-30 00:59:08 -07:00
|
|
|
permissionsSession := &pbind.PermissionsSession{
|
2018-11-04 19:28:33 -08:00
|
|
|
Contract: p.pm,
|
2018-10-24 03:21:21 -07:00
|
|
|
CallOpts: bind.CallOpts{
|
|
|
|
Pending: true,
|
|
|
|
},
|
|
|
|
TransactOpts: bind.TransactOpts{
|
|
|
|
From: auth.From,
|
|
|
|
Signer: auth.Signer,
|
2018-10-25 22:38:56 -07:00
|
|
|
GasLimit: 4700000,
|
2018-10-24 03:21:21 -07:00
|
|
|
GasPrice: big.NewInt(0),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2018-10-25 22:38:56 -07:00
|
|
|
tx, err := permissionsSession.GetNetworkBootStatus()
|
|
|
|
if err != nil {
|
|
|
|
log.Warn("Failed to udpate network boot status ", "err", err)
|
|
|
|
}
|
2018-11-02 03:42:14 -07:00
|
|
|
|
2018-10-25 22:38:56 -07:00
|
|
|
if tx != true {
|
2018-11-04 19:28:33 -08:00
|
|
|
// populate initial account access to full access
|
|
|
|
err = p.populateInitAccountAccess(permissionsSession)
|
2018-11-02 03:42:14 -07:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2018-10-25 22:38:56 -07:00
|
|
|
|
2018-11-04 19:28:33 -08:00
|
|
|
// populate the initial node list from static-nodes.json
|
|
|
|
err := p.populateStaticNodesToContract(permissionsSession)
|
2018-11-02 03:42:14 -07:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// update network status to boot completed
|
|
|
|
err = p.updateNetworkStatus(permissionsSession)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Reads the node list from static-nodes.json and populates into the contract
|
|
|
|
func (p *PermissionCtrl) populateStaticNodesToContract( permissionsSession *pbind.PermissionsSession ) error {
|
|
|
|
nodes := p2p.ParsePermissionedNodes(p.dataDir)
|
|
|
|
for _, node := range nodes {
|
|
|
|
|
|
|
|
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
|
2018-10-24 03:21:21 -07:00
|
|
|
|
2018-11-02 03:42:14 -07:00
|
|
|
log.Trace("Adding node to permissions contract", "enodeID", enodeID)
|
2018-10-24 03:21:21 -07:00
|
|
|
|
2018-11-02 03:42:14 -07:00
|
|
|
nonce := p.eth.TxPool().Nonce(permissionsSession.TransactOpts.From)
|
|
|
|
permissionsSession.TransactOpts.Nonce = new(big.Int).SetUint64(nonce)
|
2018-10-24 03:21:21 -07:00
|
|
|
|
2018-11-02 03:42:14 -07:00
|
|
|
tx, err := permissionsSession.ProposeNode(enodeID, ipAddrPort, discPort, raftPort)
|
|
|
|
if err != nil {
|
|
|
|
log.Warn("Failed to propose node", "err", err)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
log.Debug("Transaction pending", "tx hash", tx.Hash())
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
2018-10-24 03:21:21 -07:00
|
|
|
|
2018-11-02 03:42:14 -07:00
|
|
|
// Reads the acount from geth keystore and grants full access to these accounts
|
|
|
|
func (p *PermissionCtrl) populateInitAccountAccess(permissionsSession *pbind.PermissionsSession) error {
|
|
|
|
acctman := p.node.AccountManager()
|
|
|
|
for _, wallet := range acctman.Wallets() {
|
|
|
|
for _, account := range wallet.Accounts() {
|
2018-10-29 19:41:01 -07:00
|
|
|
nonce := p.eth.TxPool().Nonce(permissionsSession.TransactOpts.From)
|
2018-10-25 22:38:56 -07:00
|
|
|
permissionsSession.TransactOpts.Nonce = new(big.Int).SetUint64(nonce)
|
2018-10-24 03:21:21 -07:00
|
|
|
|
2018-11-02 03:42:14 -07:00
|
|
|
_, err := permissionsSession.UpdateAccountAccess(account.Address, uint8(types.FullAccess))
|
2018-10-25 22:38:56 -07:00
|
|
|
if err != nil {
|
2018-11-02 03:42:14 -07:00
|
|
|
return err
|
2018-10-25 22:38:56 -07:00
|
|
|
}
|
|
|
|
}
|
2018-11-02 03:42:14 -07:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
2018-10-24 03:21:21 -07:00
|
|
|
|
2018-11-02 03:42:14 -07:00
|
|
|
// update network boot status to true
|
|
|
|
func (p *PermissionCtrl) updateNetworkStatus( permissionsSession *pbind.PermissionsSession ) error {
|
|
|
|
nonce := p.eth.TxPool().Nonce(permissionsSession.TransactOpts.From)
|
|
|
|
permissionsSession.TransactOpts.Nonce = new(big.Int).SetUint64(nonce)
|
|
|
|
_, err := permissionsSession.UpdateNetworkBootStatus()
|
|
|
|
if err != nil {
|
|
|
|
log.Warn("Failed to udpate network boot status ", "err", err)
|
|
|
|
return err
|
2018-10-24 03:21:21 -07:00
|
|
|
}
|
2018-11-02 03:42:14 -07:00
|
|
|
return nil
|
2018-10-24 03:21:21 -07:00
|
|
|
}
|