From 74c02b0354cad4158f4a61cfafa451c5461dda1a Mon Sep 17 00:00:00 2001 From: wanwiset25 Date: Fri, 17 Oct 2025 20:52:31 +0400 Subject: [PATCH 1/2] initial implementation --- consensus/XDPoS/utils/pool.go | 57 ++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/consensus/XDPoS/utils/pool.go b/consensus/XDPoS/utils/pool.go index 9c09a8ba53bd..dab9d66f7d6f 100644 --- a/consensus/XDPoS/utils/pool.go +++ b/consensus/XDPoS/utils/pool.go @@ -1,9 +1,11 @@ package utils import ( + "encoding/json" "sync" "github.com/XinFinOrg/XDPoSChain/common" + "github.com/XinFinOrg/XDPoSChain/log" ) type PoolObj interface { @@ -21,8 +23,9 @@ func NewPool() *Pool { objList: make(map[string]map[common.Hash]PoolObj), } } + func (p *Pool) Get() map[string]map[common.Hash]PoolObj { - return p.objList + return p.getSnapshot() } func (p *Pool) Add(obj PoolObj) (int, map[common.Hash]PoolObj) { @@ -36,10 +39,13 @@ func (p *Pool) Add(obj PoolObj) (int, map[common.Hash]PoolObj) { } objListKeyed[obj.Hash()] = obj numOfItems := len(objListKeyed) - return numOfItems, objListKeyed + safeCopy := p.getSafePoolObjMap(objListKeyed) + return numOfItems, safeCopy } func (p *Pool) Size(obj PoolObj) int { + p.lock.Lock() + defer p.lock.Unlock() poolKey := obj.PoolKey() objListKeyed, ok := p.objList[poolKey] if !ok { @@ -84,8 +90,8 @@ func (p *Pool) Clear() { } func (p *Pool) GetObjsByKey(poolKey string) []PoolObj { - p.lock.Lock() - defer p.lock.Unlock() + p.lock.RLock() + defer p.lock.RUnlock() objListKeyed, ok := p.objList[poolKey] if !ok { @@ -95,7 +101,48 @@ func (p *Pool) GetObjsByKey(poolKey string) []PoolObj { cnt := 0 for _, obj := range objListKeyed { objList[cnt] = obj - cnt += 1 + cnt++ } return objList } + +func (p *Pool) getSnapshot() map[string]map[common.Hash]PoolObj { + p.lock.RLock() + defer p.lock.RUnlock() + + data, err := json.Marshal(p.objList) + if err != nil { + // This should never happen + log.Error("[getSafeCopy] Error while marshalling pool object list", "error", err) + return make(map[string]map[common.Hash]PoolObj) + } + + var dataCopy map[string]map[common.Hash]PoolObj + err = json.Unmarshal(data, &dataCopy) + if err != nil { + // This should never happen + log.Error("[getSafeCopy] Error while unmarshalling pool object list", "error", err) + return make(map[string]map[common.Hash]PoolObj) + } + + return dataCopy +} + +func (p *Pool) getSafePoolObjMap(objMap map[common.Hash]PoolObj) map[common.Hash]PoolObj { + data, err := json.Marshal(objMap) + if err != nil { + // This should never happen + log.Error("[getSafeCopy] Error while marshalling pool object list", "error", err) + return make(map[common.Hash]PoolObj) + } + + var dataCopy map[common.Hash]PoolObj + err = json.Unmarshal(data, &dataCopy) + if err != nil { + // This should never happen + log.Error("[getSafeCopy] Error while unmarshalling pool object list", "error", err) + return make(map[common.Hash]PoolObj) + } + + return dataCopy +} From 2702bce9080061a2cebd17e6a38119f9cd4c8d2c Mon Sep 17 00:00:00 2001 From: wanwiset25 Date: Tue, 21 Oct 2025 23:44:28 +0700 Subject: [PATCH 2/2] fix --- consensus/XDPoS/utils/pool.go | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/consensus/XDPoS/utils/pool.go b/consensus/XDPoS/utils/pool.go index dab9d66f7d6f..869459f8dc4e 100644 --- a/consensus/XDPoS/utils/pool.go +++ b/consensus/XDPoS/utils/pool.go @@ -25,6 +25,8 @@ func NewPool() *Pool { } func (p *Pool) Get() map[string]map[common.Hash]PoolObj { + p.lock.RLock() + defer p.lock.RUnlock() return p.getSnapshot() } @@ -100,16 +102,14 @@ func (p *Pool) GetObjsByKey(poolKey string) []PoolObj { objList := make([]PoolObj, len(objListKeyed)) cnt := 0 for _, obj := range objListKeyed { - objList[cnt] = obj + objList[cnt] = p.getSafePoolObj(obj) cnt++ } return objList } +// caller should hold lock func (p *Pool) getSnapshot() map[string]map[common.Hash]PoolObj { - p.lock.RLock() - defer p.lock.RUnlock() - data, err := json.Marshal(p.objList) if err != nil { // This should never happen @@ -128,6 +128,7 @@ func (p *Pool) getSnapshot() map[string]map[common.Hash]PoolObj { return dataCopy } +// caller should hold lock func (p *Pool) getSafePoolObjMap(objMap map[common.Hash]PoolObj) map[common.Hash]PoolObj { data, err := json.Marshal(objMap) if err != nil { @@ -144,5 +145,25 @@ func (p *Pool) getSafePoolObjMap(objMap map[common.Hash]PoolObj) map[common.Hash return make(map[common.Hash]PoolObj) } - return dataCopy + return dataCopy +} + +// caller should hold lock +func (p *Pool) getSafePoolObj(obj PoolObj) PoolObj { + data, err := json.Marshal(obj) + if err != nil { + // This should never happen + log.Error("[getSafeCopy] Error while marshalling pool object list", "error", err) + return nil + } + + var dataCopy PoolObj + err = json.Unmarshal(data, &dataCopy) + if err != nil { + // This should never happen + log.Error("[getSafeCopy] Error while unmarshalling pool object list", "error", err) + return nil + } + + return dataCopy }