mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-08 22:14:29 +00:00
consensus: implement DeepCopy() in PoolObj, close XFN-04 (#1723)
* add DeepCopy() for PoolObj * PoolObj: use deepcopies and optimize locks * optimize code
This commit is contained in:
parent
845137849d
commit
7aaa541db1
2 changed files with 90 additions and 6 deletions
|
|
@ -10,6 +10,7 @@ type PoolObj interface {
|
||||||
Hash() common.Hash
|
Hash() common.Hash
|
||||||
PoolKey() string
|
PoolKey() string
|
||||||
GetSigner() common.Address
|
GetSigner() common.Address
|
||||||
|
DeepCopy() interface{}
|
||||||
}
|
}
|
||||||
type Pool struct {
|
type Pool struct {
|
||||||
objList map[string]map[common.Hash]PoolObj
|
objList map[string]map[common.Hash]PoolObj
|
||||||
|
|
@ -22,7 +23,17 @@ func NewPool() *Pool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func (p *Pool) Get() map[string]map[common.Hash]PoolObj {
|
func (p *Pool) Get() map[string]map[common.Hash]PoolObj {
|
||||||
return p.objList
|
p.lock.RLock()
|
||||||
|
defer p.lock.RUnlock()
|
||||||
|
dataCopy := make(map[string]map[common.Hash]PoolObj, len(p.objList))
|
||||||
|
for k1, v1 := range p.objList {
|
||||||
|
dataCopy[k1] = make(map[common.Hash]PoolObj, len(v1))
|
||||||
|
for k2, v2 := range v1 {
|
||||||
|
dataCopy[k1][k2] = v2.DeepCopy().(PoolObj)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dataCopy
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Pool) Add(obj PoolObj) (int, map[common.Hash]PoolObj) {
|
func (p *Pool) Add(obj PoolObj) (int, map[common.Hash]PoolObj) {
|
||||||
|
|
@ -36,10 +47,18 @@ func (p *Pool) Add(obj PoolObj) (int, map[common.Hash]PoolObj) {
|
||||||
}
|
}
|
||||||
objListKeyed[obj.Hash()] = obj
|
objListKeyed[obj.Hash()] = obj
|
||||||
numOfItems := len(objListKeyed)
|
numOfItems := len(objListKeyed)
|
||||||
return numOfItems, objListKeyed
|
|
||||||
|
dataCopy := make(map[common.Hash]PoolObj, len(objListKeyed))
|
||||||
|
for k, v := range objListKeyed {
|
||||||
|
dataCopy[k] = v.DeepCopy().(PoolObj)
|
||||||
|
}
|
||||||
|
|
||||||
|
return numOfItems, dataCopy
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Pool) Size(obj PoolObj) int {
|
func (p *Pool) Size(obj PoolObj) int {
|
||||||
|
p.lock.RLock()
|
||||||
|
defer p.lock.RUnlock()
|
||||||
poolKey := obj.PoolKey()
|
poolKey := obj.PoolKey()
|
||||||
objListKeyed, ok := p.objList[poolKey]
|
objListKeyed, ok := p.objList[poolKey]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
@ -84,8 +103,8 @@ func (p *Pool) Clear() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Pool) GetObjsByKey(poolKey string) []PoolObj {
|
func (p *Pool) GetObjsByKey(poolKey string) []PoolObj {
|
||||||
p.lock.Lock()
|
p.lock.RLock()
|
||||||
defer p.lock.Unlock()
|
defer p.lock.RUnlock()
|
||||||
|
|
||||||
objListKeyed, ok := p.objList[poolKey]
|
objListKeyed, ok := p.objList[poolKey]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
@ -94,8 +113,8 @@ func (p *Pool) GetObjsByKey(poolKey string) []PoolObj {
|
||||||
objList := make([]PoolObj, len(objListKeyed))
|
objList := make([]PoolObj, len(objListKeyed))
|
||||||
cnt := 0
|
cnt := 0
|
||||||
for _, obj := range objListKeyed {
|
for _, obj := range objListKeyed {
|
||||||
objList[cnt] = obj
|
objList[cnt] = obj.DeepCopy().(PoolObj)
|
||||||
cnt += 1
|
cnt++
|
||||||
}
|
}
|
||||||
return objList
|
return objList
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,12 @@ import (
|
||||||
type Round uint64
|
type Round uint64
|
||||||
type Signature []byte
|
type Signature []byte
|
||||||
|
|
||||||
|
func (s Signature) DeepCopy() interface{} {
|
||||||
|
cpy := make([]byte, len(s))
|
||||||
|
copy(cpy, s)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
// Block Info struct in XDPoS 2.0, used for vote message, etc.
|
// Block Info struct in XDPoS 2.0, used for vote message, etc.
|
||||||
type BlockInfo struct {
|
type BlockInfo struct {
|
||||||
Hash common.Hash `json:"hash"`
|
Hash common.Hash `json:"hash"`
|
||||||
|
|
@ -27,6 +33,20 @@ type Vote struct {
|
||||||
GapNumber uint64 `json:"gapNumber"`
|
GapNumber uint64 `json:"gapNumber"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *Vote) DeepCopy() interface{} {
|
||||||
|
proposedBlockInfoCopy := &BlockInfo{
|
||||||
|
Hash: v.ProposedBlockInfo.Hash,
|
||||||
|
Round: v.ProposedBlockInfo.Round,
|
||||||
|
Number: new(big.Int).Set(v.ProposedBlockInfo.Number),
|
||||||
|
}
|
||||||
|
return &Vote{
|
||||||
|
signer: v.signer,
|
||||||
|
ProposedBlockInfo: proposedBlockInfoCopy,
|
||||||
|
Signature: v.Signature.DeepCopy().(Signature),
|
||||||
|
GapNumber: v.GapNumber,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (v *Vote) Hash() common.Hash {
|
func (v *Vote) Hash() common.Hash {
|
||||||
return rlpHash(v)
|
return rlpHash(v)
|
||||||
}
|
}
|
||||||
|
|
@ -52,6 +72,15 @@ type Timeout struct {
|
||||||
GapNumber uint64
|
GapNumber uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Timeout) DeepCopy() interface{} {
|
||||||
|
return &Timeout{
|
||||||
|
signer: t.signer,
|
||||||
|
Round: t.Round,
|
||||||
|
Signature: t.Signature.DeepCopy().(Signature),
|
||||||
|
GapNumber: t.GapNumber,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (t *Timeout) Hash() common.Hash {
|
func (t *Timeout) Hash() common.Hash {
|
||||||
return rlpHash(t)
|
return rlpHash(t)
|
||||||
}
|
}
|
||||||
|
|
@ -75,6 +104,42 @@ type SyncInfo struct {
|
||||||
HighestTimeoutCert *TimeoutCert
|
HighestTimeoutCert *TimeoutCert
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *SyncInfo) DeepCopy() interface{} {
|
||||||
|
var highestQCCopy *QuorumCert
|
||||||
|
if s.HighestQuorumCert != nil {
|
||||||
|
sigsCopy := make([]Signature, len(s.HighestQuorumCert.Signatures))
|
||||||
|
for i, sig := range s.HighestQuorumCert.Signatures {
|
||||||
|
sigsCopy[i] = sig.DeepCopy().(Signature)
|
||||||
|
}
|
||||||
|
highestQCCopy = &QuorumCert{
|
||||||
|
ProposedBlockInfo: &BlockInfo{
|
||||||
|
Hash: s.HighestQuorumCert.ProposedBlockInfo.Hash,
|
||||||
|
Round: s.HighestQuorumCert.ProposedBlockInfo.Round,
|
||||||
|
Number: new(big.Int).Set(s.HighestQuorumCert.ProposedBlockInfo.Number),
|
||||||
|
},
|
||||||
|
Signatures: sigsCopy,
|
||||||
|
GapNumber: s.HighestQuorumCert.GapNumber,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var highestTimeoutCopy *TimeoutCert
|
||||||
|
if s.HighestTimeoutCert != nil {
|
||||||
|
sigsCopy := make([]Signature, len(s.HighestTimeoutCert.Signatures))
|
||||||
|
for i, sig := range s.HighestTimeoutCert.Signatures {
|
||||||
|
sigsCopy[i] = sig.DeepCopy().(Signature)
|
||||||
|
}
|
||||||
|
highestTimeoutCopy = &TimeoutCert{
|
||||||
|
Round: s.HighestTimeoutCert.Round,
|
||||||
|
Signatures: sigsCopy,
|
||||||
|
GapNumber: s.HighestTimeoutCert.GapNumber,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &SyncInfo{
|
||||||
|
HighestQuorumCert: highestQCCopy,
|
||||||
|
HighestTimeoutCert: highestTimeoutCopy,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (s *SyncInfo) Hash() common.Hash {
|
func (s *SyncInfo) Hash() common.Hash {
|
||||||
return rlpHash(s)
|
return rlpHash(s)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue