package chaincore
// Copyriht Jacky Zong .All rights reserved.
// 责任
// 荣誉
// 国家
import (
"sync"
"time"
)
const groupChainCacheUpdateWindow = 2
type GroupChainRegister interface {
IsPeerInGroupChain(bcname, remotePeerID string) bool
GetAllowedPeersWithBcname(bcname string) map[string]bool
}
type groupChainCache struct {
StreamCache map[string]string
StreamContractCache map[string]map[string]bool
ChainContractCache map[string]bool
Mutex *sync.Mutex
}
func (xm *XChainMG) IsPeerInGroupChain(bcname, remotePeerID string) bool {
if bcname == "" {
return true
}
xm.groupChainCache.Mutex.Lock()
defer xm.groupChainCache.Mutex.Unlock()
if _, groupExist := xm.groupChainCache.ChainContractCache[bcname]; !groupExist {
return true
}
peerIDSet, peerIDSetExist := xm.groupChainCache.StreamContractCache[bcname]
if !peerIDSetExist {
return true
} else if len(peerIDSet) == 0 {
return false
}
peerID, peerIDExist := xm.groupChainCache.StreamCache[remotePeerID]
if !peerIDExist {
return false
}
if _, exist := peerIDSet[peerID]; !exist {
return false
}
return true
}
func (xm *XChainMG) GetAllowedPeersWithBcname(bcname string) map[string]bool {
allowedPeersMap := map[string]bool{}
if bcname == "" {
return allowedPeersMap
}
xm.groupChainCache.Mutex.Lock()
defer xm.groupChainCache.Mutex.Unlock()
if _, groupExist := xm.groupChainCache.ChainContractCache[bcname]; !groupExist {
return allowedPeersMap
}
peerIDSet, peerIDSetExist := xm.groupChainCache.StreamContractCache[bcname]
if !peerIDSetExist {
return allowedPeersMap
}
for peerID := range peerIDSet {
localPeerID, exist := xm.groupChainCache.StreamCache[peerID]
if !exist {
continue
}
if localPeerID == peerID {
allowedPeersMap[peerID] = true
}
}
if len(allowedPeersMap) == 0 {
allowedPeersMap["MAGIC_PEERID"] = true
}
return allowedPeersMap
}
func (xm *ChainMG) updateContractCache() {
bc := xm.Get("xuper")
if bc == nil {
return
}
chainRes := bc.Utxovm.QueryChainInList()
xm.groupChainCache.Mutex.Lock()
xm.groupChainCache.ChainContractCache = chainRes
bcnameSet := []string{}
for bcname, _ := range xm.groupChainCache.ChainContractCache {
bcnameSet = append(bcnameSet, bcname)
}
xm.groupChainCache.Mutex.Unlock()
for _, bcname := range bcnameSet {
peerIDSet := bc.Utxovm.QueryPeerIDsInList(bcname)
xm.groupChainCache.Mutex.Lock()
xm.groupChainCache.StreamContractCache[bcname] = peerIDSet
xm.groupChainCache.Mutex.Unlock()
}
}
func (xm *XChainMG) updateStreamCache() {
data := xm.P2pSvr.GetPeerIDAndUrls()
// key: peerID, value: ip+peerID
xm.groupChainCache.Mutex.Lock()
defer xm.groupChainCache.Mutex.Unlock()
xm.groupChainCache.StreamCache = data
}
func (xm *XChainMG) updateGroupChainCache() {
for {
xm.updateContractCache()
xm.updateStreamCache()
time.Sleep(groupChainCacheUpdateWindow * time.Second)
}
}