github.com/elastos/Elastos.ELA.SideChain.ETH@v0.2.2/chainbridge-core/chains/evm/aribiters/arbitermanager.go (about)

     1  package aribiters
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"fmt"
     7  	"math/big"
     8  	"sort"
     9  	"sync"
    10  
    11  	"github.com/elastos/Elastos.ELA.SideChain.ESC/common"
    12  	"github.com/elastos/Elastos.ELA.SideChain.ESC/crypto"
    13  
    14  	"github.com/elastos/Elastos.ELA/dpos/p2p/peer"
    15  )
    16  
    17  type CollectionInfo struct {
    18  	NextTotalCount    int
    19  	List              [][]byte
    20  	Signatures        map[peer.PID][]byte
    21  	CurrentTotalCount int
    22  }
    23  
    24  type ArbiterManager struct {
    25  	nextTotalCount    int
    26  	currentTotalCount int
    27  	arbiters          map[peer.PID][]byte
    28  	signatures        map[peer.PID][]byte
    29  
    30  	collectionBox     *CollectionInfo
    31  	consensusArbiters *CollectionInfo
    32  	mtx               sync.RWMutex
    33  }
    34  
    35  func CreateArbiterManager() *ArbiterManager {
    36  	manager := &ArbiterManager{
    37  		signatures:        make(map[peer.PID][]byte, 0),
    38  		arbiters:          make(map[peer.PID][]byte, 0),
    39  		collectionBox:     new(CollectionInfo),
    40  		consensusArbiters: new(CollectionInfo),
    41  	}
    42  	manager.consensusArbiters.List = make([][]byte, 0)
    43  	return manager
    44  }
    45  
    46  func (a *ArbiterManager) SetTotalCount(nowTotalCount, nextTotalCount int) {
    47  	a.currentTotalCount = nowTotalCount
    48  	a.nextTotalCount = nextTotalCount
    49  }
    50  
    51  func (a *ArbiterManager) GetCurrentTotalCount() int {
    52  	return a.currentTotalCount
    53  }
    54  
    55  func (a *ArbiterManager) GetNextTotalCount() int {
    56  	return a.nextTotalCount
    57  }
    58  
    59  func (a *ArbiterManager) AddArbiter(pid peer.PID, arbiter []byte) error {
    60  	if a.HasArbiterByPID(pid) {
    61  		return errors.New(fmt.Sprintf("AddArbiter failed, has added this arbiter:%s", common.Bytes2Hex(arbiter)))
    62  	}
    63  	a.mtx.Lock()
    64  	defer a.mtx.Unlock()
    65  	a.arbiters[pid] = arbiter
    66  	return nil
    67  }
    68  
    69  func (a *ArbiterManager) AddCurrentArbiter(arbiter []byte) error {
    70  	if a.HasCurrentArbiter(arbiter) {
    71  		return errors.New(fmt.Sprintf("AddCurrentArbiter failed, has added this current arbiter:%s", common.Bytes2Hex(arbiter)))
    72  	}
    73  	a.mtx.Lock()
    74  	defer a.mtx.Unlock()
    75  	a.consensusArbiters.List = append(a.consensusArbiters.List, arbiter)
    76  	sort.Slice(a.consensusArbiters.List, func(i, j int) bool {
    77  		return bytes.Compare(a.consensusArbiters.List[i][:], a.consensusArbiters.List[j][:]) < 0
    78  	})
    79  	return nil
    80  }
    81  
    82  func (a *ArbiterManager) HasCurrentArbiter(signer []byte) bool {
    83  	a.mtx.Lock()
    84  	defer a.mtx.Unlock()
    85  	for _, arbiter := range a.consensusArbiters.List {
    86  		if bytes.Equal(signer, arbiter) {
    87  			return true
    88  		}
    89  	}
    90  	return false
    91  }
    92  
    93  func (a *ArbiterManager) HasArbiterByPID(pid peer.PID) bool {
    94  	a.mtx.Lock()
    95  	defer a.mtx.Unlock()
    96  	return len(a.arbiters[pid]) > 0
    97  }
    98  
    99  func (a *ArbiterManager) HasArbiter(arbiter []byte) bool {
   100  	a.mtx.Lock()
   101  	defer a.mtx.Unlock()
   102  
   103  	for _, arb := range a.arbiters {
   104  		if bytes.Equal(arb, arbiter) {
   105  			return true
   106  		}
   107  	}
   108  	return false
   109  }
   110  
   111  func (a *ArbiterManager) RemoveArbiter(arbiter []byte) {
   112  	a.mtx.Lock()
   113  	defer a.mtx.Unlock()
   114  	for index, item := range a.arbiters {
   115  		if bytes.Equal(item, arbiter) {
   116  			delete(a.arbiters, index)
   117  			break
   118  		}
   119  	}
   120  }
   121  
   122  func (a *ArbiterManager) GetArbiterList() [][]byte {
   123  	a.mtx.Lock()
   124  	defer a.mtx.Unlock()
   125  	list := make([][]byte, 0)
   126  	for _, item := range a.arbiters {
   127  		list = append(list, item)
   128  	}
   129  	sort.Slice(list, func(i, j int) bool {
   130  		return bytes.Compare(list[i][:], list[j][:]) < 0
   131  	})
   132  	return list
   133  }
   134  
   135  func (a *ArbiterManager) Clear() {
   136  	a.mtx.Lock()
   137  	defer a.mtx.Unlock()
   138  	a.arbiters = make(map[peer.PID][]byte, 0)
   139  	a.signatures = make(map[peer.PID][]byte, 0)
   140  	a.consensusArbiters.List = make([][]byte, 0)
   141  }
   142  
   143  func (a *ArbiterManager) HashArbiterList(hashSalt *big.Int) (common.Hash, error) {
   144  	arbiters := a.GetArbiterList()
   145  	data := make([]byte, 0)
   146  	for _, arbiter := range arbiters {
   147  		escssaPUb, err := crypto.DecompressPubkey(arbiter)
   148  		if err != nil {
   149  			return common.Hash{}, err
   150  		}
   151  		addr := crypto.PubkeyToAddress(*escssaPUb)
   152  		data = append(data, addr.Bytes()...)
   153  	}
   154  	total := new(big.Int).SetUint64(uint64(a.nextTotalCount))
   155  	totalBytes := common.LeftPadBytes(total.Bytes(), 32)
   156  	data = append(data, totalBytes...)
   157  
   158  	saltBytes := common.LeftPadBytes(hashSalt.Bytes(), 32)
   159  	data = append(data, saltBytes...)
   160  	return crypto.Keccak256Hash(data), nil
   161  }
   162  
   163  func (a *ArbiterManager) AddSignature(pid peer.PID, signature []byte) error {
   164  	a.mtx.Lock()
   165  	defer a.mtx.Unlock()
   166  	if len(a.signatures[pid]) > 0 {
   167  		return errors.New(fmt.Sprintf("all ready add this signature:%s", pid.String()))
   168  	}
   169  	a.signatures[pid] = signature
   170  	return nil
   171  }
   172  
   173  func (a *ArbiterManager) GetSignatures() map[peer.PID][]byte {
   174  	a.mtx.Lock()
   175  	defer a.mtx.Unlock()
   176  	return a.signatures
   177  }
   178  
   179  func (a *ArbiterManager) HasSignature(pid []byte) bool {
   180  	a.mtx.Lock()
   181  	defer a.mtx.Unlock()
   182  	var peer peer.PID
   183  	copy(peer[:], pid)
   184  	return len(a.signatures[peer]) > 0
   185  }
   186  
   187  func (a *ArbiterManager) FilterArbiters(peers [][]byte) [][]byte {
   188  	list := make([][]byte, 0)
   189  	for _, p := range peers {
   190  		list = append(list, p)
   191  	}
   192  	if len(a.arbiters) <= 0 {
   193  		return list
   194  	}
   195  	for i := 0; i < len(list); {
   196  		for peer, _ := range a.arbiters {
   197  			if bytes.Equal(list[i], peer[:]) {
   198  				list = append(list[:i], list[i+1:]...)
   199  				i--
   200  				break
   201  			}
   202  		}
   203  		i++
   204  	}
   205  	return list
   206  }
   207  
   208  func (a *ArbiterManager) FilterSignatures(peers [][]byte) [][]byte {
   209  	list := make([][]byte, 0)
   210  	for _, p := range peers {
   211  		list = append(list, p)
   212  	}
   213  	if len(a.signatures) <= 0 {
   214  		return list
   215  	}
   216  	for i := 0; i < len(list); {
   217  		for peer, _ := range a.signatures {
   218  			if bytes.Equal(list[i], peer[:]) {
   219  				list = append(list[:i], list[i+1:]...)
   220  				i--
   221  				break
   222  			}
   223  		}
   224  		i++
   225  	}
   226  	return list
   227  }
   228  
   229  func (a *ArbiterManager) SaveToCollection() {
   230  	a.mtx.Lock()
   231  	defer a.mtx.Unlock()
   232  
   233  	a.collectionBox.List = make([][]byte, 0)
   234  	a.collectionBox.Signatures = make(map[peer.PID][]byte, 0)
   235  	a.collectionBox.NextTotalCount = a.nextTotalCount
   236  	a.collectionBox.CurrentTotalCount = a.currentTotalCount
   237  
   238  	for _, item := range a.arbiters {
   239  		a.collectionBox.List = append(a.collectionBox.List, item)
   240  	}
   241  	sort.Slice(a.collectionBox.List, func(i, j int) bool {
   242  		return bytes.Compare(a.collectionBox.List[i][:], a.collectionBox.List[j][:]) < 0
   243  	})
   244  
   245  	for key, value := range a.signatures {
   246  		a.collectionBox.Signatures[key] = value
   247  	}
   248  }
   249  
   250  func (a *ArbiterManager) GetCollection() CollectionInfo {
   251  	return *a.collectionBox
   252  }
   253  
   254  func (a *ArbiterManager) GetConsensusArbiters() CollectionInfo {
   255  	return *a.consensusArbiters
   256  }