quorum/controls/cluster/cluster.go

189 lines
4.9 KiB
Go
Raw Normal View History

2018-09-28 01:15:59 -07:00
package cluster
import (
"crypto/ecdsa"
"math/big"
2018-09-28 01:15:59 -07:00
"github.com/ethereum/go-ethereum/accounts/abi/bind"
2019-02-11 17:54:13 -08:00
"github.com/ethereum/go-ethereum/controls"
pbind "github.com/ethereum/go-ethereum/controls/bind/cluster"
"github.com/ethereum/go-ethereum/core/types"
2018-09-28 01:15:59 -07:00
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/node"
2019-02-11 17:54:13 -08:00
"github.com/ethereum/go-ethereum/params"
2018-09-28 01:15:59 -07:00
)
type OrgKeyCtrl struct {
ethClient *ethclient.Client
key *ecdsa.PrivateKey
km *pbind.Cluster
}
2019-02-12 20:31:11 -08:00
// Creates the controls structure for org key management
func NewOrgKeyCtrl(node *node.Node) (*OrgKeyCtrl, error) {
stateReader, _, err := controls.CreateEthClient(node)
2018-09-28 01:15:59 -07:00
if err != nil {
2019-02-13 01:42:59 -08:00
log.Error("Unable to create ethereum client for cluster check", "err", err)
return nil, err
2018-09-28 01:15:59 -07:00
}
// check if permissioning contract is there at address. If not return from here
km, err := pbind.NewCluster(params.QuorumPrivateKeyManagementContract, stateReader)
if err != nil {
2019-02-13 01:42:59 -08:00
log.Error("Permissions not enabled for the network", "err", err)
return nil, err
}
return &OrgKeyCtrl{stateReader, node.GetNodeKey(), km}, nil
}
2018-09-28 01:15:59 -07:00
2019-02-12 20:31:11 -08:00
// starts the org key management services
func (k *OrgKeyCtrl) Start() error {
2018-10-30 00:59:08 -07:00
_, err := pbind.NewClusterFilterer(params.QuorumPrivateKeyManagementContract, k.ethClient)
if err != nil {
2019-02-13 01:42:59 -08:00
log.Error("Cluster not enabled for the network", "err", err)
2018-09-28 01:15:59 -07:00
return nil
}
2019-02-12 20:31:11 -08:00
// check if permissioning contract is there at address. If not return from here
err = k.checkIfContractExists()
2019-02-11 17:54:13 -08:00
if err != nil {
return err
}
2019-02-12 20:31:11 -08:00
// start the service
k.manageClusterKeys()
return nil
}
2019-02-12 20:31:11 -08:00
// checks if the contract is deployed for org key management
2019-02-11 17:54:13 -08:00
func (k *OrgKeyCtrl) checkIfContractExists() error {
auth := bind.NewKeyedTransactor(k.key)
clusterSession := &pbind.ClusterSession{
Contract: k.km,
CallOpts: bind.CallOpts{
Pending: true,
},
TransactOpts: bind.TransactOpts{
From: auth.From,
Signer: auth.Signer,
GasLimit: 4700000,
GasPrice: big.NewInt(0),
},
}
2019-02-12 20:31:11 -08:00
// dummy call to contrat to check if the contract is deployed
_, err := clusterSession.CheckOrgContractExists()
if err != nil {
return err
}
return nil
2018-09-28 01:15:59 -07:00
}
2019-02-12 20:31:11 -08:00
// in case of geth restart firts checks for historical key update events and
// populates the cache, then starts the key change monitoring service
func (k *OrgKeyCtrl) manageClusterKeys() {
2018-09-28 01:15:59 -07:00
//call populate nodes to populate the nodes into contract
if err := k.populatePrivateKeys(); err != nil {
return
2018-09-28 01:15:59 -07:00
}
//monitor for nodes deletiin via smart contract
k.monitorKeyChanges()
2018-09-28 01:15:59 -07:00
}
2019-02-12 20:31:11 -08:00
// populates cache based on the historical key change events.
func (k *OrgKeyCtrl) populatePrivateKeys() error {
2018-10-30 00:59:08 -07:00
cluster, err := pbind.NewClusterFilterer(params.QuorumPrivateKeyManagementContract, k.ethClient)
2018-09-28 01:15:59 -07:00
if err != nil {
2019-02-13 01:42:59 -08:00
log.Error("Failed to monitor node delete", "err", err)
2018-09-28 01:15:59 -07:00
return err
}
opts := &bind.FilterOpts{}
2018-10-02 01:28:55 -07:00
pastAddEvents, err := cluster.FilterOrgKeyAdded(opts)
2018-09-28 01:15:59 -07:00
if err != nil && err.Error() == "no contract code at given address" {
return err
}
2018-09-28 01:15:59 -07:00
recExists := true
for recExists {
2018-10-02 01:28:55 -07:00
recExists = pastAddEvents.Next()
2018-09-28 01:15:59 -07:00
if recExists {
types.AddOrgKey(pastAddEvents.Event.OrgId, pastAddEvents.Event.TmKey)
2018-10-02 01:28:55 -07:00
}
}
opts = &bind.FilterOpts{}
2019-02-11 17:54:13 -08:00
pastDeleteEvents, _ := cluster.FilterOrgKeyDeleted(opts)
2018-10-02 01:28:55 -07:00
recExists = true
for recExists {
recExists = pastDeleteEvents.Next()
if recExists {
types.DeleteOrgKey(pastDeleteEvents.Event.OrgId, pastDeleteEvents.Event.TmKey)
2018-09-28 01:15:59 -07:00
}
}
return nil
}
2019-02-12 20:31:11 -08:00
// service to monitor key change events
func (k *OrgKeyCtrl) monitorKeyChanges() {
go k.monitorKeyAdd()
2018-10-02 01:28:55 -07:00
go k.monitorKeyDelete()
2018-10-02 01:28:55 -07:00
}
2019-02-12 20:31:11 -08:00
// monitors for new key added event and updates caches based on the same
func (k *OrgKeyCtrl) monitorKeyAdd() {
2018-10-30 00:59:08 -07:00
cluster, err := pbind.NewClusterFilterer(params.QuorumPrivateKeyManagementContract, k.ethClient)
2018-09-28 01:15:59 -07:00
if err != nil {
log.Error("Failed to monitor key action", "err", err)
2018-09-28 01:15:59 -07:00
}
2018-10-30 00:59:08 -07:00
ch := make(chan *pbind.ClusterOrgKeyAdded)
2018-09-28 01:15:59 -07:00
opts := &bind.WatchOpts{}
var blockNumber uint64 = 1
opts.Start = &blockNumber
2018-10-30 00:59:08 -07:00
var newEvent *pbind.ClusterOrgKeyAdded
2018-09-28 01:15:59 -07:00
2018-10-02 01:28:55 -07:00
_, err = cluster.WatchOrgKeyAdded(opts, ch)
2018-09-28 01:15:59 -07:00
if err != nil {
2018-10-02 01:28:55 -07:00
log.Info("Failed WatchOrgKeyDeleted: %v", err)
2018-09-28 01:15:59 -07:00
}
for {
select {
case newEvent = <-ch:
types.AddOrgKey(newEvent.OrgId, newEvent.TmKey)
2018-09-28 01:15:59 -07:00
}
}
2018-09-28 01:15:59 -07:00
}
2019-02-12 20:31:11 -08:00
// monitors for new key delete event and updates caches based on the same
func (k *OrgKeyCtrl) monitorKeyDelete() {
2018-10-30 00:59:08 -07:00
cluster, err := pbind.NewClusterFilterer(params.QuorumPrivateKeyManagementContract, k.ethClient)
2018-10-02 01:28:55 -07:00
if err != nil {
log.Error("Failed to monitor key action", "err", err)
2018-10-02 01:28:55 -07:00
}
2018-10-30 00:59:08 -07:00
ch := make(chan *pbind.ClusterOrgKeyDeleted)
2018-10-02 01:28:55 -07:00
opts := &bind.WatchOpts{}
var blockNumber uint64 = 1
opts.Start = &blockNumber
2018-10-30 00:59:08 -07:00
var newEvent *pbind.ClusterOrgKeyDeleted
2018-10-02 01:28:55 -07:00
_, err = cluster.WatchOrgKeyDeleted(opts, ch)
if err != nil {
log.Info("Failed WatchOrgKeyDeleted: %v", err)
}
2018-09-28 01:15:59 -07:00
2018-10-02 01:28:55 -07:00
for {
select {
case newEvent = <-ch:
types.DeleteOrgKey(newEvent.OrgId, newEvent.TmKey)
2018-10-02 01:28:55 -07:00
}
}
2018-10-02 01:28:55 -07:00
}