quorum/controls/permission/permission.go

540 lines
16 KiB
Go
Raw Normal View History

package permission
2018-07-12 03:00:19 -07:00
import (
2018-10-30 23:42:29 -07:00
"crypto/ecdsa"
"encoding/json"
2018-11-13 00:15:28 -08:00
"errors"
2018-11-14 02:24:28 -08:00
"fmt"
2018-07-12 03:00:19 -07:00
"io/ioutil"
"math/big"
"os"
2018-10-31 22:45:16 -07:00
"path/filepath"
"sync"
2018-07-12 03:00:19 -07:00
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/cmd/utils"
2018-10-31 22:45:16 -07:00
"github.com/ethereum/go-ethereum/controls"
pbind "github.com/ethereum/go-ethereum/controls/bind/permission"
2018-10-31 22:45:16 -07:00
"github.com/ethereum/go-ethereum/core/types"
"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"
"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"
"github.com/ethereum/go-ethereum/raft"
2018-07-12 03:00:19 -07:00
)
const (
PERMISSIONED_CONFIG = "permissioned-nodes.json"
BLACKLIST_CONFIG = "disallowed-nodes.json"
)
2018-07-13 18:22:43 -07:00
type NodeOperation uint8
const (
NodeAdd NodeOperation = iota
NodeDelete
)
type PermissionCtrl struct {
2018-11-14 02:24:28 -08:00
node *node.Node
ethClnt *ethclient.Client
eth *eth.Ethereum
isRaft bool
2018-11-13 00:15:28 -08:00
permissionedMode bool
2018-11-14 02:24:28 -08:00
key *ecdsa.PrivateKey
dataDir string
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-11-13 00:15:28 -08:00
func NewQuorumPermissionCtrl(stack *node.Node, permissionedMode, isRaft bool) (*PermissionCtrl, error) {
2018-08-05 22:26:29 -07:00
// Create a new ethclient to for interfacing with the contract
stateReader, e, err := controls.CreateEthClient(stack)
2018-08-05 22:26:29 -07:00
if err != nil {
2019-02-13 01:42:59 -08:00
log.Error("Unable to create ethereum client for permissions check", "err", err)
return nil, err
}
// 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 {
2019-02-13 01:42:59 -08:00
log.Error("Permissions not enabled for the network", "err", err)
2018-11-02 03:42:14 -07:00
return nil, err
}
2018-11-13 00:15:28 -08:00
return &PermissionCtrl{stack, stateReader, e, isRaft, permissionedMode, 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 {
// Permissions initialization
2018-11-02 03:42:14 -07:00
if err := p.init(); err != nil {
2019-02-13 01:42:59 -08:00
log.Error("Permissions init failed", "err", err)
2018-11-02 03:42:14 -07:00
return err
}
// Monitors node addition and decativation from network
p.manageNodePermissions()
2018-10-31 22:45:16 -07:00
// Monitors account level persmissions update from smart contarct
p.manageAccountPermissions()
2018-11-02 03:42:14 -07:00
return nil
}
2018-07-13 18:22:43 -07:00
2019-02-12 20:31:11 -08:00
// Sets the initial values for the network
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-11-04 19:28:33 -08:00
// call populates the account permissions based on past history
if err := p.populateAcctPermissions(); err != nil {
return err
}
2018-11-02 03:42:14 -07:00
2019-02-11 17:54:13 -08:00
// set the default access to ReadOnly
types.SetDefaultAccess()
return nil
}
2018-11-02 03:42:14 -07:00
// Manages node addition, decavtivation and activation from network
func (p *PermissionCtrl) manageNodePermissions() {
2018-07-13 18:22:43 -07:00
//monitor for new nodes addition via smart contract
go p.monitorNewNodeAdd()
2019-02-12 20:31:11 -08:00
//monitor for nodes deletion via smart contract
go p.monitorNodeDeactivation()
2018-08-31 04:35:35 -07:00
2018-11-07 04:50:49 -08:00
//monitor for nodes activation from deactivation status
2018-11-02 03:42:14 -07:00
go p.monitorNodeActivation()
2018-08-31 04:35:35 -07:00
//monitor for nodes blacklisting via smart contract
go p.monitorNodeBlacklisting()
2018-07-13 18:22:43 -07:00
}
2019-02-12 20:31:11 -08:00
// 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
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 {
select {
case nodeAddEvent = <-ch:
p.updatePermissionedNodes(nodeAddEvent.EnodeId, nodeAddEvent.IpAddrPort, nodeAddEvent.DiscPort, nodeAddEvent.RaftPort, NodeAdd)
}
}
2018-07-13 18:22:43 -07:00
}
2019-02-12 20:31:11 -08:00
// Listens on the channel for new node deactivation via smart contract
// and removes the same from permissioned-nodes.json
func (p *PermissionCtrl) monitorNodeDeactivation() {
2018-10-30 00:59:08 -07:00
ch := make(chan *pbind.PermissionsNodeDeactivated)
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:
p.updatePermissionedNodes(newNodeDeleteEvent.EnodeId, newNodeDeleteEvent.IpAddrPort, newNodeDeleteEvent.DiscPort, newNodeDeleteEvent.RaftPort, NodeDelete)
}
2018-08-16 20:20:33 -07:00
}
}
2018-08-05 22:26:29 -07:00
2019-02-12 20:31:11 -08:00
// Listnes on the channel for any node activation via smart contract
// and adds the same permissioned-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
}
2019-02-12 20:31:11 -08:00
// Listens on the channel for node blacklisting via smart contract and
2018-11-02 03:42:14 -07:00
// 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.updatePermissionedNodes(newNodeBlacklistEvent.EnodeId, newNodeBlacklistEvent.IpAddrPort, newNodeBlacklistEvent.DiscPort, newNodeBlacklistEvent.RaftPort, NodeDelete)
2018-11-02 03:42:14 -07:00
p.updateDisallowedNodes(newNodeBlacklistEvent)
2018-08-31 04:35:35 -07:00
}
2018-11-02 03:42:14 -07:00
}
2018-08-31 04:35:35 -07:00
}
2018-11-07 04:50:49 -08:00
2019-02-12 20:31:11 -08:00
// Populates the new node information into the permissioned-nodes.json file
func (p *PermissionCtrl) updatePermissionedNodes(enodeId, ipAddrPort, discPort, raftPort string, operation NodeOperation) {
log.Debug("updatePermissionedNodes", "DataDir", p.dataDir, "file", PERMISSIONED_CONFIG)
path := filepath.Join(p.dataDir, PERMISSIONED_CONFIG)
if _, err := os.Stat(path); err != nil {
2019-02-13 01:42:59 -08:00
log.Error("Read Error for permissioned-nodes.json file. This is because 'permissioned' flag is specified but no permissioned-nodes.json file is present", "err", err)
2019-02-11 17:54:13 -08:00
return
}
// Load the nodes from the config file
blob, err := ioutil.ReadFile(path)
if err != nil {
log.Error("updatePermissionedNodes: Failed to access permissioned-nodes.json", "err", err)
return
}
nodelist := []string{}
if err := json.Unmarshal(blob, &nodelist); err != nil {
log.Error("updatePermissionedNodes: Failed to load nodes list", "err", err)
2019-02-11 17:54:13 -08:00
return
}
newEnodeId := p.formatEnodeId(enodeId, ipAddrPort, discPort, raftPort)
// logic to update the permissioned-nodes.json file based on action
index := 0
recExists := false
for i, enodeId := range nodelist {
if enodeId == newEnodeId {
index = i
recExists = true
break
}
}
if operation == NodeAdd {
if !recExists {
nodelist = append(nodelist, newEnodeId)
2018-08-16 20:20:33 -07:00
}
} else {
if recExists {
nodelist = append(nodelist[:index], nodelist[index+1:]...)
}
p.disconnectNode(newEnodeId)
}
mu := sync.RWMutex{}
blob, _ = json.Marshal(nodelist)
mu.Lock()
2019-02-11 17:54:13 -08:00
if err := ioutil.WriteFile(path, blob, 0644); err != nil {
log.Error("updatePermissionedNodes: Error writing new node info to file", "err", err)
}
mu.Unlock()
}
2018-08-31 04:35:35 -07:00
2019-02-12 20:31:11 -08:00
//this function populates the black listed node information into the disallowed-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 {
2019-02-13 01:42:59 -08: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 {
2019-02-13 01:42:59 -08:00
log.Error("Failed to create disallowed-nodes.json file", "err", err)
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)
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()
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()
// Disconnect the peer if it is already connected
p.disconnectNode(newEnodeId)
2018-08-31 04:35:35 -07:00
}
// Manages account level permissions update
2018-11-02 03:42:14 -07:00
func (p *PermissionCtrl) manageAccountPermissions() {
//monitor for nodes deletiin via smart contract
go p.monitorAccountPermissions()
2018-11-02 03:42:14 -07:00
return
}
2019-02-12 20:31:11 -08:00
// populates the nodes list from permissioned-nodes.json into the permissions smart contract
func (p *PermissionCtrl) populatePermissionedNodes() error {
opts := &bind.FilterOpts{}
2018-11-04 19:28:33 -08:00
pastAddEvent, err := p.pm.PermissionsFilterer.FilterNodeApproved(opts)
2018-11-05 07:44:23 -08:00
if err == nil {
2018-11-02 03:42:14 -07:00
recExists := true
for recExists {
recExists = pastAddEvent.Next()
if recExists {
p.updatePermissionedNodes(pastAddEvent.Event.EnodeId, pastAddEvent.Event.IpAddrPort, pastAddEvent.Event.DiscPort, pastAddEvent.Event.RaftPort, NodeAdd)
}
}
}
opts = &bind.FilterOpts{}
2018-11-04 19:28:33 -08:00
pastDelEvent, err := p.pm.PermissionsFilterer.FilterNodeDeactivated(opts)
2018-11-05 07:44:23 -08:00
if err == nil {
2018-11-02 03:42:14 -07:00
recExists := true
for recExists {
recExists = pastDelEvent.Next()
if recExists {
p.updatePermissionedNodes(pastDelEvent.Event.EnodeId, pastDelEvent.Event.IpAddrPort, pastDelEvent.Event.DiscPort, pastDelEvent.Event.RaftPort, NodeDelete)
}
}
}
return nil
}
2019-02-12 20:31:11 -08:00
// populates the account permissions cache from past account access update events
func (p *PermissionCtrl) populateAcctPermissions() error {
opts := &bind.FilterOpts{}
2018-11-04 19:28:33 -08:00
pastEvents, err := p.pm.PermissionsFilterer.FilterAccountAccessModified(opts)
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-11-02 03:42:14 -07:00
return nil
}
2019-02-12 20:31:11 -08:00
// Monitors permissions changes at acount level and uodate the account permissions cache
func (p *PermissionCtrl) monitorAccountPermissions() {
2018-10-30 00:59:08 -07:00
ch := make(chan *pbind.PermissionsAccountAccessModified)
opts := &bind.WatchOpts{}
var blockNumber uint64 = 1
opts.Start = &blockNumber
2018-10-30 00:59:08 -07:00
var newEvent *pbind.PermissionsAccountAccessModified
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)
}
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-09-19 18:51:36 -07:00
// Disconnect the node from the network
func (p *PermissionCtrl) disconnectNode(enodeId string) {
if p.isRaft {
2018-09-19 18:51:36 -07:00
var raftService *raft.RaftService
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
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 {
newEnodeId := "enode://" + enodeId + "@" + ipAddrPort + "?discport=" + discPort
2018-11-02 03:42:14 -07:00
if p.isRaft {
newEnodeId += "&raftport=" + raftPort
2018-09-19 22:55:57 -07:00
}
return newEnodeId
}
2019-02-12 20:31:11 -08:00
// Thus function checks if the its the initial network boot up and if yes
// populates the initial network enode details from static-nodes.json into
// smart contracts. Sets the accounts access to full access for the initial
// initial list of accounts as given in genesis.json file
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,
CallOpts: bind.CallOpts{
Pending: true,
},
TransactOpts: bind.TransactOpts{
From: auth.From,
Signer: auth.Signer,
GasLimit: 4700000,
GasPrice: big.NewInt(0),
},
}
tx, err := permissionsSession.GetNetworkBootStatus()
if err != nil {
// handle the scenario of no contract code.
2019-02-11 17:54:13 -08:00
if err.Error() == "no contract code at given address" {
return err
}
log.Warn("Failed to retrieve network boot status ", "err", err)
}
2018-11-02 03:42:14 -07:00
2018-11-13 00:15:28 -08:00
if tx && !p.permissionedMode {
// Network is initialized with permissions and node is joining in a non-permissioned
// option. stop the node from coming up
utils.Fatalf("Joining a permissioned network in non-permissioned mode. Bring up geth with --permissioned.")
2018-11-13 00:15:28 -08:00
}
2018-11-14 02:24:28 -08:00
if !p.permissionedMode {
2018-11-13 00:15:28 -08:00
return errors.New("Node started in non-permissioned mode")
}
if tx != true {
// Ensure that there is at least one account given as a part of genesis.json
// which will have full access. If not throw a fatal error
// Do not want a network with no access
initAcctCnt, err := permissionsSession.GetInitAccountsCount()
if err == nil && initAcctCnt.Cmp(big.NewInt(0)) == 0 {
2019-02-06 22:35:22 -08:00
utils.Fatalf("Permissioned network being brought up with zero accounts having full access. Add permissioned full access accounts in genesis.json and bring up the network")
}
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-11-07 04:50:49 -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
2018-11-02 03:42:14 -07:00
}
// update network status to boot completed
err = p.updateNetworkStatus(permissionsSession)
if err != nil {
return err
}
2018-11-02 03:42:14 -07:00
}
return nil
}
// Reads the node list from static-nodes.json and populates into the contract
2018-11-07 04:50:49 -08:00
func (p *PermissionCtrl) populateStaticNodesToContract(permissionsSession *pbind.PermissionsSession) error {
2018-11-02 03:42:14 -07:00
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-11-02 03:42:14 -07:00
log.Trace("Adding node to permissions contract", "enodeID", enodeID)
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-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
}
2019-02-12 20:31:11 -08:00
// Invokes the initAccounts function of smart contract to set the initial
// set of accounts access to full access
2018-11-02 03:42:14 -07:00
func (p *PermissionCtrl) populateInitAccountAccess(permissionsSession *pbind.PermissionsSession) error {
_, err := permissionsSession.InitAccounts()
if err != nil {
log.Error("calling init accounts failed", "err", err)
return err
2018-11-02 03:42:14 -07:00
}
return nil
}
2019-02-12 20:31:11 -08:00
// updates network boot status to true
2018-11-07 04:50:49 -08:00
func (p *PermissionCtrl) updateNetworkStatus(permissionsSession *pbind.PermissionsSession) error {
2018-11-02 03:42:14 -07:00
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-11-02 03:42:14 -07:00
return nil
}