feat(*): add delete vp node feature
This commit is contained in:
parent
7ab92d6f2b
commit
131b086563
|
@ -2,8 +2,6 @@ package grpc
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/meshplus/bitxhub-model/pb"
|
||||
)
|
||||
|
||||
|
@ -17,13 +15,3 @@ func GetChainStatus(cbs *ChainBrokerService) (*pb.Response, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
func GetValidators(cbs *ChainBrokerService) (*pb.Response, error) {
|
||||
addresses := cbs.genesis.Addresses
|
||||
v, err := json.Marshal(addresses)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pb.Response{
|
||||
Data: v,
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/meshplus/bitxhub-model/pb"
|
||||
)
|
||||
|
||||
|
@ -16,13 +14,3 @@ func GetNetworkMeta(cbs *ChainBrokerService) (*pb.Response, error) {
|
|||
Data: data,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (cbs *ChainBrokerService) DelVPNode(ctx context.Context, req *pb.DelVPNodeRequest) (*pb.Response, error) {
|
||||
data, err := cbs.api.Network().DelVPNode(req.Pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pb.Response{
|
||||
Data: data,
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/meshplus/bitxhub-model/pb"
|
||||
"github.com/meshplus/bitxhub/pkg/peermgr"
|
||||
)
|
||||
|
||||
func GetValidators(cbs *ChainBrokerService) (*pb.Response, error) {
|
||||
addresses := cbs.genesis.Addresses
|
||||
v, err := json.Marshal(addresses)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pb.Response{
|
||||
Data: v,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (cbs *ChainBrokerService) DelVPNode(ctx context.Context, req *pb.DelVPNodeRequest) (*pb.Response, error) {
|
||||
delPid := req.Pid
|
||||
peersBytes,_ := cbs.api.Network().PeerInfo()
|
||||
peers := make(map[uint64]*peermgr.VPInfo)
|
||||
err := json.Unmarshal(peersBytes,&peers)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var isExist bool
|
||||
var delID uint64
|
||||
for id, peer := range peers {
|
||||
if peer.IPAddr == delPid {
|
||||
isExist = true
|
||||
delID = id
|
||||
break
|
||||
}
|
||||
}
|
||||
// If self isn't vp, rejects the rpc request and returns error.
|
||||
if !isExist {
|
||||
return nil, fmt.Errorf("can't find pid %s from consentor or pid illegal",delPid)
|
||||
}
|
||||
|
||||
if err := cbs.api.Broker().OrderReady(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// if there're only 4 vp nodes, we don't support delete request, return error;
|
||||
if len(peers) == 4 {
|
||||
return nil, errors.New("can't delete node as there're only 4 vp nodes")
|
||||
}
|
||||
|
||||
// TODO (YH): don't support delete primary node
|
||||
if err := cbs.api.Broker().DelVPNode(delID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pb.Response {
|
||||
Data: nil,
|
||||
},nil
|
||||
}
|
|
@ -25,6 +25,7 @@ var clientCMD = cli.Command{
|
|||
receiptCMD(),
|
||||
txCMD(),
|
||||
validatorsCMD(),
|
||||
delVPNodeCMD(),
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -39,3 +39,30 @@ func getValidators(ctx *cli.Context) error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func delVPNodeCMD() cli.Command {
|
||||
return cli.Command{
|
||||
Name: "delVPNode",
|
||||
Usage: "delete a vp node",
|
||||
Action: delVPNode,
|
||||
}
|
||||
}
|
||||
|
||||
func delVPNode(ctx *cli.Context) error {
|
||||
if ctx.NArg() < 1 {
|
||||
return fmt.Errorf("please input pid")
|
||||
}
|
||||
|
||||
url, err := getURL(ctx, "delvpnode/"+ctx.Args().Get(0))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
data, err := httpGet(url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println(string(data))
|
||||
return nil
|
||||
}
|
|
@ -40,13 +40,15 @@ type BrokerAPI interface {
|
|||
// OrderReady
|
||||
OrderReady() error
|
||||
|
||||
// DelVPNode delete a vp node by given id.
|
||||
DelVPNode(delID uint64) error
|
||||
|
||||
FetchSignsFromOtherPeers(content string, typ pb.GetMultiSignsRequest_Type) map[string][]byte
|
||||
GetSign(content string, typ pb.GetMultiSignsRequest_Type) (string, []byte, error)
|
||||
}
|
||||
|
||||
type NetworkAPI interface {
|
||||
PeerInfo() ([]byte, error)
|
||||
DelVPNode(pid string) ([]byte, error)
|
||||
}
|
||||
|
||||
type ChainAPI interface {
|
||||
|
|
|
@ -279,3 +279,7 @@ func (b *BrokerAPI) getSign(content string) (string, []byte, error) {
|
|||
func (b BrokerAPI) GetPendingNonceByAccount(account string) uint64 {
|
||||
return b.bxh.Order.GetPendingNonceByAccount(account)
|
||||
}
|
||||
|
||||
func (b BrokerAPI) DelVPNode(delID uint64) error {
|
||||
return b.bxh.Order.DelNode(delID)
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ type Node struct {
|
|||
justElected bool
|
||||
isRestart bool
|
||||
|
||||
// TODO (YH): refactor
|
||||
ctx context.Context // context
|
||||
haltC chan struct{} // exit signal
|
||||
|
||||
|
@ -655,6 +656,12 @@ func (n *Node) writeAppliedIndex(index uint64) {
|
|||
n.storage.Put(appliedDbKey, buf)
|
||||
}
|
||||
|
||||
// GetPendingNonceByAccount gets pending nonce by given account.
|
||||
func (n *Node) GetPendingNonceByAccount(account string) uint64 {
|
||||
return n.mempool.GetPendingNonceByAccount(account)
|
||||
}
|
||||
|
||||
// DelNode sends a delete vp request by given id.
|
||||
func (n *Node) DelNode(delID uint64) error {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -130,7 +130,11 @@ func (mpm *mockPeerMgr)AddNode(newNodeID uint64, vpInfo *peermgr.VPInfo) {}
|
|||
|
||||
func (mpm *mockPeerMgr)DelNode(delID uint64){}
|
||||
|
||||
func (mpm *mockPeerMgr)UpdateRouter(vpInfos map[uint64]*peermgr.VPInfo) {}
|
||||
func (mpm *mockPeerMgr)UpdateRouter(vpInfos map[uint64]*peermgr.VPInfo, isNew bool) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (mpm *mockPeerMgr)Disconnect(vpInfos map[uint64]*peermgr.VPInfo) {}
|
||||
|
||||
func (mpm *mockPeerMgr) Peers() map[uint64]*peermgr.VPInfo {
|
||||
peers := make(map[uint64]*peermgr.VPInfo, 3)
|
||||
|
|
|
@ -2,7 +2,6 @@ package order
|
|||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/meshplus/bitxhub-kit/types"
|
||||
"github.com/meshplus/bitxhub-model/pb"
|
||||
)
|
||||
|
@ -35,4 +34,7 @@ type Order interface {
|
|||
|
||||
// GetPendingNonce will return the latest pending nonce of a given account
|
||||
GetPendingNonceByAccount(account string) uint64
|
||||
|
||||
// DelNode sends a delete vp request by given id.
|
||||
DelNode(delID uint64) error
|
||||
}
|
||||
|
|
|
@ -57,6 +57,10 @@ func (n *Node) GetPendingNonceByAccount(account string) uint64 {
|
|||
return n.mempool.GetPendingNonceByAccount(account)
|
||||
}
|
||||
|
||||
func (n *Node) DelNode(delID uint64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *Node) Prepare(tx *pb.Transaction) error {
|
||||
if err := n.Ready(); err != nil {
|
||||
return err
|
||||
|
|
|
@ -9,8 +9,9 @@ import (
|
|||
|
||||
type notifiee struct {
|
||||
peers map[uint64]*VPInfo
|
||||
// TODO (Peer): keep access goroutine safety
|
||||
newPeer string
|
||||
mu sync.Mutex
|
||||
mu sync.RWMutex
|
||||
logger logrus.FieldLogger
|
||||
}
|
||||
|
||||
|
@ -28,11 +29,10 @@ func (n *notifiee) ListenClose(network network.Network, multiaddr ma.Multiaddr)
|
|||
}
|
||||
|
||||
func (n *notifiee) Connected(network network.Network, conn network.Conn) {
|
||||
n.mu.Lock()
|
||||
defer n.mu.Unlock()
|
||||
peers := n.getPeers()
|
||||
newAddr := conn.RemotePeer().String()
|
||||
// check if the newAddr has already in peers.
|
||||
for _, p := range n.peers {
|
||||
for _, p := range peers {
|
||||
if p.IPAddr == newAddr {
|
||||
return
|
||||
}
|
||||
|
@ -52,3 +52,15 @@ func (n *notifiee) OpenedStream(network network.Network, stream network.Stream)
|
|||
|
||||
func (n *notifiee) ClosedStream(network network.Network, stream network.Stream) {
|
||||
}
|
||||
|
||||
func (n *notifiee) getPeers() map[uint64]*VPInfo {
|
||||
n.mu.RLock()
|
||||
defer n.mu.RUnlock()
|
||||
return n.peers
|
||||
}
|
||||
|
||||
func (n *notifiee) setPeers(peers map[uint64]*VPInfo) {
|
||||
n.mu.Lock()
|
||||
defer n.mu.Unlock()
|
||||
n.peers = peers
|
||||
}
|
||||
|
|
|
@ -37,9 +37,15 @@ type PeerManager interface {
|
|||
// SubscribeOrderMessage
|
||||
SubscribeOrderMessage(ch chan<- events.OrderMessageEvent) event.Subscription
|
||||
|
||||
// AddNode adds a vp peer.
|
||||
AddNode(newNodeID uint64, vpInfo *VPInfo)
|
||||
|
||||
// DelNode deletes a vp peer.
|
||||
DelNode(delID uint64)
|
||||
|
||||
UpdateRouter (vpInfos map[uint64]*VPInfo)
|
||||
// UpdateRouter update the local router to quorum router.
|
||||
UpdateRouter (vpInfos map[uint64]*VPInfo, isNew bool) bool
|
||||
|
||||
// Disconnect disconnect with all vp peers.
|
||||
Disconnect(vpInfos map[uint64]*VPInfo)
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package peermgr
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/meshplus/bitxhub-kit/types"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
|
@ -12,6 +11,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
"github.com/libp2p/go-libp2p-core/protocol"
|
||||
"github.com/meshplus/bitxhub-kit/types"
|
||||
"github.com/meshplus/bitxhub-model/pb"
|
||||
"github.com/meshplus/bitxhub/internal/ledger"
|
||||
"github.com/meshplus/bitxhub/internal/model"
|
||||
|
@ -32,10 +32,10 @@ type Swarm struct {
|
|||
p2p network.Network
|
||||
logger logrus.FieldLogger
|
||||
|
||||
routers map[uint64]*VPInfo // trace the vp nodes
|
||||
multiAddrs map[uint64]*peer.AddrInfo
|
||||
connectedPeers sync.Map
|
||||
notifiee *notifiee
|
||||
routers map[uint64]*VPInfo // trace the vp nodes
|
||||
multiAddrs map[uint64]*peer.AddrInfo
|
||||
connectedPeers sync.Map
|
||||
notifiee *notifiee
|
||||
|
||||
ledger ledger.Ledger
|
||||
orderMessageFeed event.Feed
|
||||
|
@ -59,8 +59,8 @@ func New(repoConfig *repo.Repo, logger logrus.FieldLogger, ledger ledger.Ledger)
|
|||
keyAddr := *types.NewAddressByStr(repo.AllAddresses.Addresses[i])
|
||||
IpInfo := repo.NetworkConfig.VpNodes[node.ID]
|
||||
vpInfo := &VPInfo{
|
||||
KeyAddr: keyAddr.String(),
|
||||
IPAddr: IpInfo.ID.String(),
|
||||
KeyAddr: keyAddr.String(),
|
||||
IPAddr: IpInfo.ID.String(),
|
||||
}
|
||||
validators[node.ID] = vpInfo
|
||||
}
|
||||
|
@ -72,8 +72,8 @@ func New(repoConfig *repo.Repo, logger logrus.FieldLogger, ledger ledger.Ledger)
|
|||
}
|
||||
IpInfo := repo.NetworkConfig.VpNodes[node.ID]
|
||||
addInfo := &peer.AddrInfo{
|
||||
ID:IpInfo.ID,
|
||||
Addrs:IpInfo.Addrs,
|
||||
ID: IpInfo.ID,
|
||||
Addrs: IpInfo.Addrs,
|
||||
}
|
||||
multiAddrs[node.ID] = addInfo
|
||||
}
|
||||
|
@ -104,10 +104,10 @@ func New(repoConfig *repo.Repo, logger logrus.FieldLogger, ledger ledger.Ledger)
|
|||
p2p: p2p,
|
||||
logger: logger,
|
||||
ledger: ledger,
|
||||
enablePing: repoConfig.Config.Ping.Enable,
|
||||
pingTimeout: repoConfig.Config.Ping.Duration,
|
||||
routers: peers,
|
||||
multiAddrs: multiAddrs,
|
||||
enablePing: repo.Config.Ping.Enable,
|
||||
pingTimeout: repo.Config.Ping.Duration,
|
||||
routers: validators,
|
||||
multiAddrs: multiAddrs,
|
||||
connectedPeers: sync.Map{},
|
||||
notifiee: notifiee,
|
||||
ctx: ctx,
|
||||
|
@ -202,6 +202,8 @@ func (swarm *Swarm) Ping() {
|
|||
return true
|
||||
})
|
||||
swarm.logger.WithFields(fields).Info("ping time")
|
||||
case <-swarm.ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -269,7 +271,6 @@ func (swarm *Swarm) Broadcast(msg *pb.Message) error {
|
|||
|
||||
// if we are in adding node but hasn't finished updateN, new node hash will be temporarily recorded
|
||||
// in swarm.notifiee.newPeer.
|
||||
// TODO (Peer): keep access goroutine safety
|
||||
if swarm.notifiee.newPeer != "" {
|
||||
swarm.logger.Debugf("Broadcast to new peer %s", swarm.notifiee.newPeer)
|
||||
addrs = append(addrs, swarm.notifiee.newPeer)
|
||||
|
@ -284,12 +285,12 @@ func (swarm *Swarm) Broadcast(msg *pb.Message) error {
|
|||
}
|
||||
|
||||
func (swarm *Swarm) Peers() map[uint64]*VPInfo {
|
||||
return swarm.routers
|
||||
return swarm.notifiee.getPeers()
|
||||
}
|
||||
|
||||
func (swarm *Swarm) OtherPeers() map[uint64]*peer.AddrInfo {
|
||||
addrInfos := make(map[uint64]*peer.AddrInfo)
|
||||
for id, addr := range swarm.Peers() {
|
||||
for id, addr := range swarm.notifiee.getPeers() {
|
||||
if id == swarm.localID {
|
||||
continue
|
||||
}
|
||||
|
@ -350,16 +351,15 @@ func (swarm *Swarm) findPeer(id uint64) (string, error) {
|
|||
if swarm.routers[id] != nil {
|
||||
return swarm.routers[id].IPAddr, nil
|
||||
}
|
||||
swarm.notifiee.mu.Lock()
|
||||
newPeerAddr := swarm.notifiee.newPeer
|
||||
swarm.notifiee.mu.Unlock()
|
||||
// new node id should be len(swarm.peers)+1,
|
||||
if uint64(len(swarm.routers)+1) == id && newPeerAddr != "" {
|
||||
// new node id should be len(swarm.peers)+1
|
||||
if uint64(len(swarm.routers)+1) == id && swarm.notifiee.newPeer != "" {
|
||||
return newPeerAddr, nil
|
||||
}
|
||||
return "", fmt.Errorf("wrong id: %d", id)
|
||||
}
|
||||
|
||||
// todo (YH): persist config and update connectedPeers and multiAddrs info?
|
||||
func (swarm *Swarm) AddNode(newNodeID uint64, vpInfo *VPInfo) {
|
||||
if _, ok := swarm.routers[newNodeID]; ok {
|
||||
swarm.logger.Warningf("VP[ID: %d, IpAddr: %s] has already exist in routing table", newNodeID, vpInfo.IPAddr)
|
||||
|
@ -367,31 +367,82 @@ func (swarm *Swarm) AddNode(newNodeID uint64, vpInfo *VPInfo) {
|
|||
}
|
||||
swarm.logger.Infof("Add vp[ID: %d, IpAddr: %s] into routing table", newNodeID, vpInfo.IPAddr)
|
||||
swarm.routers[newNodeID] = vpInfo
|
||||
for index, p := range swarm.routers {
|
||||
swarm.logger.Debugf("=====ID: %d, Addr: %v=====", index+1, p)
|
||||
for id, p := range swarm.routers {
|
||||
swarm.logger.Debugf("=====ID: %d, Addr: %v=====", id, p)
|
||||
}
|
||||
|
||||
// update notifiee info
|
||||
swarm.notifiee.mu.Lock()
|
||||
swarm.notifiee.peers[newNodeID] = vpInfo
|
||||
swarm.notifiee.setPeers(swarm.routers)
|
||||
if swarm.notifiee.newPeer == vpInfo.IPAddr {
|
||||
swarm.logger.Info("Clear notifiee newPeer info")
|
||||
swarm.notifiee.newPeer = ""
|
||||
} else {
|
||||
swarm.logger.Warningf("Received vpInfo %v, but it doesn't equal to notifiee newPeer %s", vpInfo, swarm.notifiee.newPeer)
|
||||
}
|
||||
swarm.notifiee.mu.Unlock()
|
||||
}
|
||||
|
||||
func (swarm *Swarm) DelNode(delID uint64) {
|
||||
|
||||
if delID == swarm.localID {
|
||||
// deleted node itself will exit the cluster
|
||||
swarm.reset()
|
||||
_ = swarm.p2p.Stop()
|
||||
_ = swarm.Stop()
|
||||
return
|
||||
}
|
||||
var (
|
||||
delNode *VPInfo
|
||||
ok bool
|
||||
)
|
||||
if delNode, ok = swarm.routers[delID]; !ok {
|
||||
swarm.logger.Warningf("Can't find vp node %d from routing table ", delID)
|
||||
return
|
||||
}
|
||||
swarm.logger.Infof("Delete node [ID: %d, peerInfo: %v] ", delID, delNode)
|
||||
delete(swarm.routers, delID)
|
||||
delete(swarm.multiAddrs, delID)
|
||||
swarm.connectedPeers.Delete(delID)
|
||||
for id, p := range swarm.routers {
|
||||
swarm.logger.Debugf("=====ID: %d, Addr: %v=====", id, p)
|
||||
}
|
||||
// update notifiee info
|
||||
swarm.notifiee.setPeers(swarm.routers)
|
||||
}
|
||||
|
||||
func (swarm *Swarm) UpdateRouter(vpInfos map[uint64]*VPInfo) {
|
||||
func (swarm *Swarm) UpdateRouter(vpInfos map[uint64]*VPInfo, isNew bool) bool {
|
||||
swarm.logger.Infof("Update router: %+v", vpInfos)
|
||||
swarm.routers = vpInfos
|
||||
// check if self is exist in the routing table, and if not, exit the cluster
|
||||
var isExist bool
|
||||
for id, _ := range vpInfos {
|
||||
if id == swarm.localID {
|
||||
isExist = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !isExist && !isNew {
|
||||
// deleted node itself will exit the cluster
|
||||
swarm.reset()
|
||||
_ = swarm.p2p.Stop()
|
||||
_ = swarm.Stop()
|
||||
return true
|
||||
}
|
||||
// update notifiee info
|
||||
swarm.notifiee.mu.Lock()
|
||||
swarm.notifiee.peers = vpInfos
|
||||
swarm.notifiee.mu.Unlock()
|
||||
swarm.notifiee.setPeers(vpInfos)
|
||||
return false
|
||||
}
|
||||
|
||||
func (swarm *Swarm) reset() {
|
||||
swarm.routers = nil
|
||||
swarm.multiAddrs = nil
|
||||
swarm.connectedPeers = sync.Map{}
|
||||
swarm.notifiee.setPeers(nil)
|
||||
}
|
||||
|
||||
func (swarm *Swarm) Disconnect(vpInfos map[uint64]*VPInfo) {
|
||||
for id, info := range vpInfos {
|
||||
if err := swarm.p2p.Disconnect(info.IPAddr); err != nil {
|
||||
swarm.logger.Errorf("Disconnect peer %s failed, err: %s", err.Error())
|
||||
}
|
||||
swarm.logger.Infof("Disconnect peer [ID: %d, Pid: %s]", id, info.IPAddr)
|
||||
}
|
||||
swarm.logger.Infof("======== NOTE!!! THIS NODE HAS BEEN DELETED!!!")
|
||||
}
|
||||
|
|
|
@ -24,3 +24,4 @@ func UnMasherVPInfo(vpInfoBytes []byte) (*VPInfo, error) {
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
halN1RQDWQ1PFJ+SMLb13joI5YiZ3K8Pd3aO+xgl6FQ=
|
||||
tkdxQ+F/iJJjBE9s9GPcNxd6xFJsTDmno0QZhFcCSi8=
|
||||
-----END EC PRIVATE KEY-----
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICWTCCAf+gAwIBAgIDCUHDMAoGCCqGSM49BAMCMIGaMQswCQYDVQQGEwJDTjER
|
||||
MIICWjCCAf+gAwIBAgIDDhFLMAoGCCqGSM49BAMCMIGaMQswCQYDVQQGEwJDTjER
|
||||
MA8GA1UECBMIWmhlSmlhbmcxETAPBgNVBAcTCEhhbmdaaG91MR8wDQYDVQQJEwZz
|
||||
dHJlZXQwDgYDVQQJEwdhZGRyZXNzMQ8wDQYDVQQREwYzMjQwMDAxDzANBgNVBAoT
|
||||
BkFnZW5jeTEQMA4GA1UECxMHQml0WEh1YjEQMA4GA1UEAxMHQml0WEh1YjAgFw0y
|
||||
MDA4MTEwNTA3MTRaGA8yMDcwMDczMDA1MDcxNFowgZkxCzAJBgNVBAYTAkNOMREw
|
||||
MDA4MTEwNTA3MTNaGA8yMDcwMDczMDA1MDcxM1owgZkxCzAJBgNVBAYTAkNOMREw
|
||||
DwYDVQQIEwhaaGVKaWFuZzERMA8GA1UEBxMISGFuZ1pob3UxHzANBgNVBAkTBnN0
|
||||
cmVldDAOBgNVBAkTB2FkZHJlc3MxDzANBgNVBBETBjMyNDAwMDEOMAwGA1UEChMF
|
||||
Tm9kZTMxEDAOBgNVBAsTB0JpdFhIdWIxEDAOBgNVBAMTB0JpdFhIdWIwWTATBgcq
|
||||
hkjOPQIBBggqhkjOPQMBBwNCAAQ9IPBBKkqSwWkwDdK+ARw2qlBmBD9bF8HJ0z3P
|
||||
XeKaTmnnEBJu1e0vjHl+uQGBz5x1ulBRVeq4xhmkZtPZByO+ozEwLzAOBgNVHQ8B
|
||||
Tm9kZTExEDAOBgNVBAsTB0JpdFhIdWIxEDAOBgNVBAMTB0JpdFhIdWIwWTATBgcq
|
||||
hkjOPQIBBggqhkjOPQMBBwNCAATgjTYEnavxerFuEKJ8C39QUY12xh/TC2E5V7ni
|
||||
nmQcOgDDRv5HW4sskTSm/WX2D0BMzwb7XE5ATyoDeM9qcurDozEwLzAOBgNVHQ8B
|
||||
Af8EBAMCAaYwDwYDVR0lBAgwBgYEVR0lADAMBgNVHRMBAf8EAjAAMAoGCCqGSM49
|
||||
BAMCA0gAMEUCIQCMgYSwQ9go1jjAcC4SxpJl4moA8Ba/GEb0qwFPaNmSCwIgDEOo
|
||||
UpUSNYEQJvahR4BxxVLOBf/CNlKhAGBVNKTccxk=
|
||||
BAMCA0kAMEYCIQD5Oz1xJvFgzYm/lTzoaO/i0ayPVRgSdBwvK6hEICo5lAIhAMtG
|
||||
aswjd2wVA4zB5GPEmJ/tvPUnxrlOAU67AQMYR4zf
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIMQcu7NXkY6TE+7xNTSo8CTKG4Tp20CcWAAEVtRQAjlioAoGCCqGSM49
|
||||
AwEHoUQDQgAEPSDwQSpKksFpMA3SvgEcNqpQZgQ/WxfBydM9z13imk5p5xASbtXt
|
||||
L4x5frkBgc+cdbpQUVXquMYZpGbT2Qcjvg==
|
||||
MHcCAQEEIJjph6szT64kRmvzyZYWYaonaFVsvTZwRLqeV20wo2D3oAoGCCqGSM49
|
||||
AwEHoUQDQgAE4I02BJ2r8XqxbhCifAt/UFGNdsYf0wthOVe54p5kHDoAw0b+R1uL
|
||||
LJE0pv1l9g9ATM8G+1xOQE8qA3jPanLqww==
|
||||
-----END EC PRIVATE KEY-----
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
cu/PS7DoowDT5H5qEPYwvNVA3pM/Ae1TgIl/xeENyV0=
|
||||
BcNwjTDCxyxLNjFKQfMAc6sY6iJs+Ma59WZyC/4uhjE=
|
||||
-----END EC PRIVATE KEY-----
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICWTCCAf+gAwIBAgIDCGR3MAoGCCqGSM49BAMCMIGaMQswCQYDVQQGEwJDTjER
|
||||
MIICWjCCAf+gAwIBAgIDC8pcMAoGCCqGSM49BAMCMIGaMQswCQYDVQQGEwJDTjER
|
||||
MA8GA1UECBMIWmhlSmlhbmcxETAPBgNVBAcTCEhhbmdaaG91MR8wDQYDVQQJEwZz
|
||||
dHJlZXQwDgYDVQQJEwdhZGRyZXNzMQ8wDQYDVQQREwYzMjQwMDAxDzANBgNVBAoT
|
||||
BkFnZW5jeTEQMA4GA1UECxMHQml0WEh1YjEQMA4GA1UEAxMHQml0WEh1YjAgFw0y
|
||||
MDA4MTEwNTA3MTRaGA8yMDcwMDczMDA1MDcxNFowgZkxCzAJBgNVBAYTAkNOMREw
|
||||
MDA4MTEwNTA3MTNaGA8yMDcwMDczMDA1MDcxM1owgZkxCzAJBgNVBAYTAkNOMREw
|
||||
DwYDVQQIEwhaaGVKaWFuZzERMA8GA1UEBxMISGFuZ1pob3UxHzANBgNVBAkTBnN0
|
||||
cmVldDAOBgNVBAkTB2FkZHJlc3MxDzANBgNVBBETBjMyNDAwMDEOMAwGA1UEChMF
|
||||
Tm9kZTQxEDAOBgNVBAsTB0JpdFhIdWIxEDAOBgNVBAMTB0JpdFhIdWIwWTATBgcq
|
||||
hkjOPQIBBggqhkjOPQMBBwNCAARN1y/FhZpSg1kpXF38szDNRXdPkqoc8oRKdGzv
|
||||
3HdhtBdUO7jXe2xNaWVtNMGXVo+NuBi5t9qEoo+euxfnjlc9ozEwLzAOBgNVHQ8B
|
||||
Tm9kZTIxEDAOBgNVBAsTB0JpdFhIdWIxEDAOBgNVBAMTB0JpdFhIdWIwWTATBgcq
|
||||
hkjOPQIBBggqhkjOPQMBBwNCAARhGDBod719hBcz/lpLtEh8GsqzDhm1ZbjdaTsM
|
||||
GivsjOHRk9iEkwDtXmsMvYn3yOIq2RR60T7/G2swBzuZiZWxozEwLzAOBgNVHQ8B
|
||||
Af8EBAMCAaYwDwYDVR0lBAgwBgYEVR0lADAMBgNVHRMBAf8EAjAAMAoGCCqGSM49
|
||||
BAMCA0gAMEUCIQCbsG7E158uzqYCzrrnrr2Xsnz7f5cFA2o4SXAF7R/IyAIgSxYS
|
||||
MGj0g0OBcxJqwTyyvF2FFOhlWjF9nq2eYK/rlzI=
|
||||
BAMCA0kAMEYCIQDrX3znEJ6zkhUhPN37LY5eurrCs7Brp/TQ/2geHdZLQAIhALxb
|
||||
Gk39mUrJ/4z/dVGwFYccWZB8UOV1M4iuN6ypF+Sc
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIFWx/9axMGfzqOO/T3OEBXZNli6dkX/9m+o1GjnEX+I1oAoGCCqGSM49
|
||||
AwEHoUQDQgAETdcvxYWaUoNZKVxd/LMwzUV3T5KqHPKESnRs79x3YbQXVDu413ts
|
||||
TWllbTTBl1aPjbgYubfahKKPnrsX545XPQ==
|
||||
MHcCAQEEICI2QiahAMKtO9tD9VnxZ2J3jvFt+/vTAtcAQzUcIPoXoAoGCCqGSM49
|
||||
AwEHoUQDQgAEYRgwaHe9fYQXM/5aS7RIfBrKsw4ZtWW43Wk7DBor7Izh0ZPYhJMA
|
||||
7V5rDL2J98jiKtkUetE+/xtrMAc7mYmVsQ==
|
||||
-----END EC PRIVATE KEY-----
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
tkdxQ+F/iJJjBE9s9GPcNxd6xFJsTDmno0QZhFcCSi8=
|
||||
halN1RQDWQ1PFJ+SMLb13joI5YiZ3K8Pd3aO+xgl6FQ=
|
||||
-----END EC PRIVATE KEY-----
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICWjCCAf+gAwIBAgIDDhFLMAoGCCqGSM49BAMCMIGaMQswCQYDVQQGEwJDTjER
|
||||
MIICWTCCAf+gAwIBAgIDCUHDMAoGCCqGSM49BAMCMIGaMQswCQYDVQQGEwJDTjER
|
||||
MA8GA1UECBMIWmhlSmlhbmcxETAPBgNVBAcTCEhhbmdaaG91MR8wDQYDVQQJEwZz
|
||||
dHJlZXQwDgYDVQQJEwdhZGRyZXNzMQ8wDQYDVQQREwYzMjQwMDAxDzANBgNVBAoT
|
||||
BkFnZW5jeTEQMA4GA1UECxMHQml0WEh1YjEQMA4GA1UEAxMHQml0WEh1YjAgFw0y
|
||||
MDA4MTEwNTA3MTNaGA8yMDcwMDczMDA1MDcxM1owgZkxCzAJBgNVBAYTAkNOMREw
|
||||
MDA4MTEwNTA3MTRaGA8yMDcwMDczMDA1MDcxNFowgZkxCzAJBgNVBAYTAkNOMREw
|
||||
DwYDVQQIEwhaaGVKaWFuZzERMA8GA1UEBxMISGFuZ1pob3UxHzANBgNVBAkTBnN0
|
||||
cmVldDAOBgNVBAkTB2FkZHJlc3MxDzANBgNVBBETBjMyNDAwMDEOMAwGA1UEChMF
|
||||
Tm9kZTExEDAOBgNVBAsTB0JpdFhIdWIxEDAOBgNVBAMTB0JpdFhIdWIwWTATBgcq
|
||||
hkjOPQIBBggqhkjOPQMBBwNCAATgjTYEnavxerFuEKJ8C39QUY12xh/TC2E5V7ni
|
||||
nmQcOgDDRv5HW4sskTSm/WX2D0BMzwb7XE5ATyoDeM9qcurDozEwLzAOBgNVHQ8B
|
||||
Tm9kZTMxEDAOBgNVBAsTB0JpdFhIdWIxEDAOBgNVBAMTB0JpdFhIdWIwWTATBgcq
|
||||
hkjOPQIBBggqhkjOPQMBBwNCAAQ9IPBBKkqSwWkwDdK+ARw2qlBmBD9bF8HJ0z3P
|
||||
XeKaTmnnEBJu1e0vjHl+uQGBz5x1ulBRVeq4xhmkZtPZByO+ozEwLzAOBgNVHQ8B
|
||||
Af8EBAMCAaYwDwYDVR0lBAgwBgYEVR0lADAMBgNVHRMBAf8EAjAAMAoGCCqGSM49
|
||||
BAMCA0kAMEYCIQD5Oz1xJvFgzYm/lTzoaO/i0ayPVRgSdBwvK6hEICo5lAIhAMtG
|
||||
aswjd2wVA4zB5GPEmJ/tvPUnxrlOAU67AQMYR4zf
|
||||
BAMCA0gAMEUCIQCMgYSwQ9go1jjAcC4SxpJl4moA8Ba/GEb0qwFPaNmSCwIgDEOo
|
||||
UpUSNYEQJvahR4BxxVLOBf/CNlKhAGBVNKTccxk=
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIJjph6szT64kRmvzyZYWYaonaFVsvTZwRLqeV20wo2D3oAoGCCqGSM49
|
||||
AwEHoUQDQgAE4I02BJ2r8XqxbhCifAt/UFGNdsYf0wthOVe54p5kHDoAw0b+R1uL
|
||||
LJE0pv1l9g9ATM8G+1xOQE8qA3jPanLqww==
|
||||
MHcCAQEEIMQcu7NXkY6TE+7xNTSo8CTKG4Tp20CcWAAEVtRQAjlioAoGCCqGSM49
|
||||
AwEHoUQDQgAEPSDwQSpKksFpMA3SvgEcNqpQZgQ/WxfBydM9z13imk5p5xASbtXt
|
||||
L4x5frkBgc+cdbpQUVXquMYZpGbT2Qcjvg==
|
||||
-----END EC PRIVATE KEY-----
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
BcNwjTDCxyxLNjFKQfMAc6sY6iJs+Ma59WZyC/4uhjE=
|
||||
cu/PS7DoowDT5H5qEPYwvNVA3pM/Ae1TgIl/xeENyV0=
|
||||
-----END EC PRIVATE KEY-----
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICWjCCAf+gAwIBAgIDC8pcMAoGCCqGSM49BAMCMIGaMQswCQYDVQQGEwJDTjER
|
||||
MIICWTCCAf+gAwIBAgIDCGR3MAoGCCqGSM49BAMCMIGaMQswCQYDVQQGEwJDTjER
|
||||
MA8GA1UECBMIWmhlSmlhbmcxETAPBgNVBAcTCEhhbmdaaG91MR8wDQYDVQQJEwZz
|
||||
dHJlZXQwDgYDVQQJEwdhZGRyZXNzMQ8wDQYDVQQREwYzMjQwMDAxDzANBgNVBAoT
|
||||
BkFnZW5jeTEQMA4GA1UECxMHQml0WEh1YjEQMA4GA1UEAxMHQml0WEh1YjAgFw0y
|
||||
MDA4MTEwNTA3MTNaGA8yMDcwMDczMDA1MDcxM1owgZkxCzAJBgNVBAYTAkNOMREw
|
||||
MDA4MTEwNTA3MTRaGA8yMDcwMDczMDA1MDcxNFowgZkxCzAJBgNVBAYTAkNOMREw
|
||||
DwYDVQQIEwhaaGVKaWFuZzERMA8GA1UEBxMISGFuZ1pob3UxHzANBgNVBAkTBnN0
|
||||
cmVldDAOBgNVBAkTB2FkZHJlc3MxDzANBgNVBBETBjMyNDAwMDEOMAwGA1UEChMF
|
||||
Tm9kZTIxEDAOBgNVBAsTB0JpdFhIdWIxEDAOBgNVBAMTB0JpdFhIdWIwWTATBgcq
|
||||
hkjOPQIBBggqhkjOPQMBBwNCAARhGDBod719hBcz/lpLtEh8GsqzDhm1ZbjdaTsM
|
||||
GivsjOHRk9iEkwDtXmsMvYn3yOIq2RR60T7/G2swBzuZiZWxozEwLzAOBgNVHQ8B
|
||||
Tm9kZTQxEDAOBgNVBAsTB0JpdFhIdWIxEDAOBgNVBAMTB0JpdFhIdWIwWTATBgcq
|
||||
hkjOPQIBBggqhkjOPQMBBwNCAARN1y/FhZpSg1kpXF38szDNRXdPkqoc8oRKdGzv
|
||||
3HdhtBdUO7jXe2xNaWVtNMGXVo+NuBi5t9qEoo+euxfnjlc9ozEwLzAOBgNVHQ8B
|
||||
Af8EBAMCAaYwDwYDVR0lBAgwBgYEVR0lADAMBgNVHRMBAf8EAjAAMAoGCCqGSM49
|
||||
BAMCA0kAMEYCIQDrX3znEJ6zkhUhPN37LY5eurrCs7Brp/TQ/2geHdZLQAIhALxb
|
||||
Gk39mUrJ/4z/dVGwFYccWZB8UOV1M4iuN6ypF+Sc
|
||||
BAMCA0gAMEUCIQCbsG7E158uzqYCzrrnrr2Xsnz7f5cFA2o4SXAF7R/IyAIgSxYS
|
||||
MGj0g0OBcxJqwTyyvF2FFOhlWjF9nq2eYK/rlzI=
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEICI2QiahAMKtO9tD9VnxZ2J3jvFt+/vTAtcAQzUcIPoXoAoGCCqGSM49
|
||||
AwEHoUQDQgAEYRgwaHe9fYQXM/5aS7RIfBrKsw4ZtWW43Wk7DBor7Izh0ZPYhJMA
|
||||
7V5rDL2J98jiKtkUetE+/xtrMAc7mYmVsQ==
|
||||
MHcCAQEEIFWx/9axMGfzqOO/T3OEBXZNli6dkX/9m+o1GjnEX+I1oAoGCCqGSM49
|
||||
AwEHoUQDQgAETdcvxYWaUoNZKVxd/LMwzUV3T5KqHPKESnRs79x3YbQXVDu413ts
|
||||
TWllbTTBl1aPjbgYubfahKKPnrsX545XPQ==
|
||||
-----END EC PRIVATE KEY-----
|
||||
|
|
Loading…
Reference in New Issue