mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-20 11:46:44 +00:00
Remove duplicate rawdb accessors and incompatible p2p files
This commit is contained in:
parent
9ba57ca27f
commit
8bf39caa1a
3 changed files with 0 additions and 692 deletions
|
|
@ -1,209 +0,0 @@
|
||||||
// Copyright 2021 XDC Network
|
|
||||||
// This file is part of the XDC library.
|
|
||||||
|
|
||||||
package rawdb
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
)
|
|
||||||
|
|
||||||
// XDC-specific database key prefixes
|
|
||||||
var (
|
|
||||||
validatorSetPrefix = []byte("xdc-validators-")
|
|
||||||
epochDataPrefix = []byte("xdc-epoch-")
|
|
||||||
penaltyPrefix = []byte("xdc-penalty-")
|
|
||||||
checkpointPrefix = []byte("xdc-checkpoint-")
|
|
||||||
snapshotPrefix = []byte("xdc-snapshot-")
|
|
||||||
tradingStatePrefix = []byte("xdcx-trading-")
|
|
||||||
lendingStatePrefix = []byte("xdcx-lending-")
|
|
||||||
)
|
|
||||||
|
|
||||||
// encodeBlockNumber encodes a block number as big endian uint64
|
|
||||||
func encodeBlockNumber(number uint64) []byte {
|
|
||||||
enc := make([]byte, 8)
|
|
||||||
binary.BigEndian.PutUint64(enc, number)
|
|
||||||
return enc
|
|
||||||
}
|
|
||||||
|
|
||||||
// validatorSetKey returns the key for validator set at block number
|
|
||||||
func validatorSetKey(number uint64) []byte {
|
|
||||||
return append(validatorSetPrefix, encodeBlockNumber(number)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// epochDataKey returns the key for epoch data
|
|
||||||
func epochDataKey(epoch uint64) []byte {
|
|
||||||
return append(epochDataPrefix, encodeBlockNumber(epoch)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// penaltyKey returns the key for a penalty record
|
|
||||||
func penaltyKey(validator common.Address, block uint64) []byte {
|
|
||||||
key := append(penaltyPrefix, validator.Bytes()...)
|
|
||||||
return append(key, encodeBlockNumber(block)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// checkpointKey returns the key for a checkpoint
|
|
||||||
func checkpointKey(number uint64) []byte {
|
|
||||||
return append(checkpointPrefix, encodeBlockNumber(number)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// snapshotKey returns the key for a snapshot
|
|
||||||
func snapshotKey(hash common.Hash) []byte {
|
|
||||||
return append(snapshotPrefix, hash.Bytes()...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteValidatorSet writes the validator set for a block
|
|
||||||
func WriteValidatorSet(db ethdb.KeyValueWriter, number uint64, validators []common.Address) error {
|
|
||||||
data := make([]byte, len(validators)*common.AddressLength)
|
|
||||||
for i, v := range validators {
|
|
||||||
copy(data[i*common.AddressLength:], v.Bytes())
|
|
||||||
}
|
|
||||||
return db.Put(validatorSetKey(number), data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadValidatorSet reads the validator set for a block
|
|
||||||
func ReadValidatorSet(db ethdb.KeyValueReader, number uint64) []common.Address {
|
|
||||||
data, err := db.Get(validatorSetKey(number))
|
|
||||||
if err != nil || len(data) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
count := len(data) / common.AddressLength
|
|
||||||
validators := make([]common.Address, count)
|
|
||||||
for i := 0; i < count; i++ {
|
|
||||||
validators[i] = common.BytesToAddress(data[i*common.AddressLength : (i+1)*common.AddressLength])
|
|
||||||
}
|
|
||||||
return validators
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteValidatorSet deletes the validator set for a block
|
|
||||||
func DeleteValidatorSet(db ethdb.KeyValueWriter, number uint64) error {
|
|
||||||
return db.Delete(validatorSetKey(number))
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteEpochData writes epoch data
|
|
||||||
func WriteEpochData(db ethdb.KeyValueWriter, epoch uint64, data []byte) error {
|
|
||||||
return db.Put(epochDataKey(epoch), data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadEpochData reads epoch data
|
|
||||||
func ReadEpochData(db ethdb.KeyValueReader, epoch uint64) []byte {
|
|
||||||
data, err := db.Get(epochDataKey(epoch))
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteEpochData deletes epoch data
|
|
||||||
func DeleteEpochData(db ethdb.KeyValueWriter, epoch uint64) error {
|
|
||||||
return db.Delete(epochDataKey(epoch))
|
|
||||||
}
|
|
||||||
|
|
||||||
// WritePenalty writes a penalty record
|
|
||||||
func WritePenalty(db ethdb.KeyValueWriter, validator common.Address, block uint64, amount uint64) error {
|
|
||||||
data := encodeBlockNumber(amount)
|
|
||||||
return db.Put(penaltyKey(validator, block), data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadPenalty reads a penalty record
|
|
||||||
func ReadPenalty(db ethdb.KeyValueReader, validator common.Address, block uint64) uint64 {
|
|
||||||
data, err := db.Get(penaltyKey(validator, block))
|
|
||||||
if err != nil || len(data) != 8 {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return binary.BigEndian.Uint64(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeletePenalty deletes a penalty record
|
|
||||||
func DeletePenalty(db ethdb.KeyValueWriter, validator common.Address, block uint64) error {
|
|
||||||
return db.Delete(penaltyKey(validator, block))
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteCheckpoint writes a checkpoint
|
|
||||||
func WriteCheckpoint(db ethdb.KeyValueWriter, number uint64, hash common.Hash) error {
|
|
||||||
return db.Put(checkpointKey(number), hash.Bytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadCheckpoint reads a checkpoint
|
|
||||||
func ReadCheckpoint(db ethdb.KeyValueReader, number uint64) common.Hash {
|
|
||||||
data, err := db.Get(checkpointKey(number))
|
|
||||||
if err != nil || len(data) != common.HashLength {
|
|
||||||
return common.Hash{}
|
|
||||||
}
|
|
||||||
return common.BytesToHash(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteCheckpoint deletes a checkpoint
|
|
||||||
func DeleteCheckpoint(db ethdb.KeyValueWriter, number uint64) error {
|
|
||||||
return db.Delete(checkpointKey(number))
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteXDPoSSnapshot writes an XDPoS snapshot
|
|
||||||
func WriteXDPoSSnapshot(db ethdb.KeyValueWriter, hash common.Hash, data []byte) error {
|
|
||||||
return db.Put(snapshotKey(hash), data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadXDPoSSnapshot reads an XDPoS snapshot
|
|
||||||
func ReadXDPoSSnapshot(db ethdb.KeyValueReader, hash common.Hash) []byte {
|
|
||||||
data, err := db.Get(snapshotKey(hash))
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteXDPoSSnapshot deletes an XDPoS snapshot
|
|
||||||
func DeleteXDPoSSnapshot(db ethdb.KeyValueWriter, hash common.Hash) error {
|
|
||||||
return db.Delete(snapshotKey(hash))
|
|
||||||
}
|
|
||||||
|
|
||||||
// HasXDPoSSnapshot checks if a snapshot exists
|
|
||||||
func HasXDPoSSnapshot(db ethdb.KeyValueReader, hash common.Hash) bool {
|
|
||||||
has, _ := db.Has(snapshotKey(hash))
|
|
||||||
return has
|
|
||||||
}
|
|
||||||
|
|
||||||
// XDCx Trading State
|
|
||||||
|
|
||||||
// tradingStateKey returns the key for trading state
|
|
||||||
func tradingStateKey(root common.Hash) []byte {
|
|
||||||
return append(tradingStatePrefix, root.Bytes()...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteTradingStateRoot writes the trading state root for a block
|
|
||||||
func WriteTradingStateRoot(db ethdb.KeyValueWriter, blockHash, tradingRoot common.Hash) error {
|
|
||||||
return db.Put(tradingStateKey(blockHash), tradingRoot.Bytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadTradingStateRoot reads the trading state root for a block
|
|
||||||
func ReadTradingStateRoot(db ethdb.KeyValueReader, blockHash common.Hash) common.Hash {
|
|
||||||
data, err := db.Get(tradingStateKey(blockHash))
|
|
||||||
if err != nil || len(data) != common.HashLength {
|
|
||||||
return common.Hash{}
|
|
||||||
}
|
|
||||||
return common.BytesToHash(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// XDCx Lending State
|
|
||||||
|
|
||||||
// lendingStateKey returns the key for lending state
|
|
||||||
func lendingStateKey(root common.Hash) []byte {
|
|
||||||
return append(lendingStatePrefix, root.Bytes()...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteLendingStateRoot writes the lending state root for a block
|
|
||||||
func WriteLendingStateRoot(db ethdb.KeyValueWriter, blockHash, lendingRoot common.Hash) error {
|
|
||||||
return db.Put(lendingStateKey(blockHash), lendingRoot.Bytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadLendingStateRoot reads the lending state root for a block
|
|
||||||
func ReadLendingStateRoot(db ethdb.KeyValueReader, blockHash common.Hash) common.Hash {
|
|
||||||
data, err := db.Get(lendingStateKey(blockHash))
|
|
||||||
if err != nil || len(data) != common.HashLength {
|
|
||||||
return common.Hash{}
|
|
||||||
}
|
|
||||||
return common.BytesToHash(data)
|
|
||||||
}
|
|
||||||
262
p2p/dial_xdc.go
262
p2p/dial_xdc.go
|
|
@ -1,262 +0,0 @@
|
||||||
// Copyright 2023 The XDC Network Authors
|
|
||||||
// This file is part of the XDC Network library.
|
|
||||||
//
|
|
||||||
// The XDC Network library is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
|
|
||||||
package p2p
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"github.com/ethereum/go-ethereum/log"
|
|
||||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
|
||||||
)
|
|
||||||
|
|
||||||
// XDCDialScheduler extends the dial scheduler with masternode prioritization
|
|
||||||
type XDCDialScheduler struct {
|
|
||||||
mu sync.Mutex
|
|
||||||
masternodeNodes map[enode.ID]*enode.Node
|
|
||||||
priorityQueue []*enode.Node
|
|
||||||
dialer NodeDialer
|
|
||||||
maxDialing int
|
|
||||||
dialingCount int
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewXDCDialScheduler creates a new XDC dial scheduler
|
|
||||||
func NewXDCDialScheduler(dialer NodeDialer, maxDialing int) *XDCDialScheduler {
|
|
||||||
return &XDCDialScheduler{
|
|
||||||
masternodeNodes: make(map[enode.ID]*enode.Node),
|
|
||||||
priorityQueue: make([]*enode.Node, 0),
|
|
||||||
dialer: dialer,
|
|
||||||
maxDialing: maxDialing,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetMasternodes sets the current masternode list
|
|
||||||
func (s *XDCDialScheduler) SetMasternodes(nodes []*enode.Node) {
|
|
||||||
s.mu.Lock()
|
|
||||||
defer s.mu.Unlock()
|
|
||||||
|
|
||||||
s.masternodeNodes = make(map[enode.ID]*enode.Node)
|
|
||||||
s.priorityQueue = make([]*enode.Node, 0, len(nodes))
|
|
||||||
|
|
||||||
for _, node := range nodes {
|
|
||||||
s.masternodeNodes[node.ID()] = node
|
|
||||||
s.priorityQueue = append(s.priorityQueue, node)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debug("Updated dial scheduler masternode list", "count", len(nodes))
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsMasternode checks if a node ID is a masternode
|
|
||||||
func (s *XDCDialScheduler) IsMasternode(id enode.ID) bool {
|
|
||||||
s.mu.Lock()
|
|
||||||
defer s.mu.Unlock()
|
|
||||||
|
|
||||||
_, exists := s.masternodeNodes[id]
|
|
||||||
return exists
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetPriorityNode returns the next priority node to dial
|
|
||||||
func (s *XDCDialScheduler) GetPriorityNode() *enode.Node {
|
|
||||||
s.mu.Lock()
|
|
||||||
defer s.mu.Unlock()
|
|
||||||
|
|
||||||
if len(s.priorityQueue) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
node := s.priorityQueue[0]
|
|
||||||
s.priorityQueue = s.priorityQueue[1:]
|
|
||||||
return node
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddPriorityNode adds a node to the priority queue
|
|
||||||
func (s *XDCDialScheduler) AddPriorityNode(node *enode.Node) {
|
|
||||||
s.mu.Lock()
|
|
||||||
defer s.mu.Unlock()
|
|
||||||
|
|
||||||
// Don't add duplicates
|
|
||||||
for _, n := range s.priorityQueue {
|
|
||||||
if n.ID() == node.ID() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
s.priorityQueue = append(s.priorityQueue, node)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DialContext dials a node with context
|
|
||||||
func (s *XDCDialScheduler) DialContext(ctx context.Context, node *enode.Node) (Conn, error) {
|
|
||||||
s.mu.Lock()
|
|
||||||
if s.dialingCount >= s.maxDialing {
|
|
||||||
s.mu.Unlock()
|
|
||||||
return nil, errTooManyPeers
|
|
||||||
}
|
|
||||||
s.dialingCount++
|
|
||||||
s.mu.Unlock()
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
s.mu.Lock()
|
|
||||||
s.dialingCount--
|
|
||||||
s.mu.Unlock()
|
|
||||||
}()
|
|
||||||
|
|
||||||
return s.dialer.Dial(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
var errTooManyPeers = &DiscReason{DiscTooManyPeers}
|
|
||||||
|
|
||||||
// MasternodeDialer dials masternodes with priority
|
|
||||||
type MasternodeDialer struct {
|
|
||||||
scheduler *XDCDialScheduler
|
|
||||||
interval time.Duration
|
|
||||||
quit chan struct{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewMasternodeDialer creates a new masternode dialer
|
|
||||||
func NewMasternodeDialer(scheduler *XDCDialScheduler, interval time.Duration) *MasternodeDialer {
|
|
||||||
return &MasternodeDialer{
|
|
||||||
scheduler: scheduler,
|
|
||||||
interval: interval,
|
|
||||||
quit: make(chan struct{}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start starts the masternode dialing loop
|
|
||||||
func (d *MasternodeDialer) Start() {
|
|
||||||
go d.loop()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop stops the masternode dialer
|
|
||||||
func (d *MasternodeDialer) Stop() {
|
|
||||||
close(d.quit)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *MasternodeDialer) loop() {
|
|
||||||
ticker := time.NewTicker(d.interval)
|
|
||||||
defer ticker.Stop()
|
|
||||||
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-ticker.C:
|
|
||||||
d.dialNext()
|
|
||||||
case <-d.quit:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *MasternodeDialer) dialNext() {
|
|
||||||
node := d.scheduler.GetPriorityNode()
|
|
||||||
if node == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
_, err := d.scheduler.DialContext(ctx, node)
|
|
||||||
if err != nil {
|
|
||||||
log.Debug("Failed to dial masternode", "id", node.ID(), "err", err)
|
|
||||||
// Re-add to queue for retry
|
|
||||||
d.scheduler.AddPriorityNode(node)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// PeerPriority defines peer priority levels
|
|
||||||
type PeerPriority int
|
|
||||||
|
|
||||||
const (
|
|
||||||
PriorityNormal PeerPriority = iota
|
|
||||||
PriorityMasternode
|
|
||||||
PriorityValidator
|
|
||||||
)
|
|
||||||
|
|
||||||
// XDCPeerSelector selects peers based on priority
|
|
||||||
type XDCPeerSelector struct {
|
|
||||||
mu sync.RWMutex
|
|
||||||
peers map[enode.ID]PeerPriority
|
|
||||||
maxPeers int
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewXDCPeerSelector creates a new peer selector
|
|
||||||
func NewXDCPeerSelector(maxPeers int) *XDCPeerSelector {
|
|
||||||
return &XDCPeerSelector{
|
|
||||||
peers: make(map[enode.ID]PeerPriority),
|
|
||||||
maxPeers: maxPeers,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPriority sets the priority for a peer
|
|
||||||
func (s *XDCPeerSelector) SetPriority(id enode.ID, priority PeerPriority) {
|
|
||||||
s.mu.Lock()
|
|
||||||
defer s.mu.Unlock()
|
|
||||||
s.peers[id] = priority
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetPriority gets the priority for a peer
|
|
||||||
func (s *XDCPeerSelector) GetPriority(id enode.ID) PeerPriority {
|
|
||||||
s.mu.RLock()
|
|
||||||
defer s.mu.RUnlock()
|
|
||||||
return s.peers[id]
|
|
||||||
}
|
|
||||||
|
|
||||||
// ShouldConnect determines if we should connect to a peer
|
|
||||||
func (s *XDCPeerSelector) ShouldConnect(id enode.ID, priority PeerPriority) bool {
|
|
||||||
s.mu.RLock()
|
|
||||||
defer s.mu.RUnlock()
|
|
||||||
|
|
||||||
// Always accept masternodes and validators
|
|
||||||
if priority >= PriorityMasternode {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Count by priority
|
|
||||||
normalCount := 0
|
|
||||||
for _, p := range s.peers {
|
|
||||||
if p == PriorityNormal {
|
|
||||||
normalCount++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reserve slots for high priority peers
|
|
||||||
reservedSlots := s.maxPeers / 3
|
|
||||||
maxNormal := s.maxPeers - reservedSlots
|
|
||||||
|
|
||||||
return normalCount < maxNormal
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemovePeer removes a peer from the selector
|
|
||||||
func (s *XDCPeerSelector) RemovePeer(id enode.ID) {
|
|
||||||
s.mu.Lock()
|
|
||||||
defer s.mu.Unlock()
|
|
||||||
delete(s.peers, id)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetMasternodePeers returns all masternode peers
|
|
||||||
func (s *XDCPeerSelector) GetMasternodePeers() []enode.ID {
|
|
||||||
s.mu.RLock()
|
|
||||||
defer s.mu.RUnlock()
|
|
||||||
|
|
||||||
var result []enode.ID
|
|
||||||
for id, priority := range s.peers {
|
|
||||||
if priority >= PriorityMasternode {
|
|
||||||
result = append(result, id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
// MasternodeAddressToNodeID converts a masternode address to enode ID
|
|
||||||
// This is a placeholder - actual implementation would use the masternode registry
|
|
||||||
func MasternodeAddressToNodeID(addr common.Address) enode.ID {
|
|
||||||
// In practice, this would look up the enode from the masternode registry
|
|
||||||
return enode.ID{}
|
|
||||||
}
|
|
||||||
|
|
@ -1,221 +0,0 @@
|
||||||
// Copyright 2023 The XDC Network Authors
|
|
||||||
// This file is part of the XDC Network library.
|
|
||||||
//
|
|
||||||
// The XDC Network library is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
|
|
||||||
package p2p
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"github.com/ethereum/go-ethereum/log"
|
|
||||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrAddPairPeer is returned when adding a paired peer (not an error, signals pairing)
|
|
||||||
ErrAddPairPeer = errors.New("add pair peer")
|
|
||||||
|
|
||||||
// ErrMasternodeNotFound is returned when masternode is not in the list
|
|
||||||
ErrMasternodeNotFound = errors.New("masternode not found")
|
|
||||||
)
|
|
||||||
|
|
||||||
// MasternodeConfig contains XDPoS masternode configuration
|
|
||||||
type MasternodeConfig struct {
|
|
||||||
// Enable masternode mode
|
|
||||||
Enabled bool
|
|
||||||
|
|
||||||
// Masternode account address
|
|
||||||
Address common.Address
|
|
||||||
|
|
||||||
// Priority dial for masternodes
|
|
||||||
PriorityDial bool
|
|
||||||
|
|
||||||
// Max masternode peers
|
|
||||||
MaxMasternodePeers int
|
|
||||||
}
|
|
||||||
|
|
||||||
// MasternodeManager manages masternode peer connections
|
|
||||||
type MasternodeManager struct {
|
|
||||||
mu sync.RWMutex
|
|
||||||
masternodes map[common.Address]*enode.Node
|
|
||||||
active map[common.Address]bool
|
|
||||||
config *MasternodeConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewMasternodeManager creates a new masternode manager
|
|
||||||
func NewMasternodeManager(config *MasternodeConfig) *MasternodeManager {
|
|
||||||
if config == nil {
|
|
||||||
config = &MasternodeConfig{
|
|
||||||
MaxMasternodePeers: 50,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return &MasternodeManager{
|
|
||||||
masternodes: make(map[common.Address]*enode.Node),
|
|
||||||
active: make(map[common.Address]bool),
|
|
||||||
config: config,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateMasternodes updates the masternode list
|
|
||||||
func (m *MasternodeManager) UpdateMasternodes(nodes map[common.Address]*enode.Node) {
|
|
||||||
m.mu.Lock()
|
|
||||||
defer m.mu.Unlock()
|
|
||||||
|
|
||||||
// Clear old list
|
|
||||||
m.masternodes = make(map[common.Address]*enode.Node)
|
|
||||||
|
|
||||||
// Add new masternodes
|
|
||||||
for addr, node := range nodes {
|
|
||||||
m.masternodes[addr] = node
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Info("Updated masternode list", "count", len(m.masternodes))
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetMasternodes returns the current masternode list
|
|
||||||
func (m *MasternodeManager) GetMasternodes() map[common.Address]*enode.Node {
|
|
||||||
m.mu.RLock()
|
|
||||||
defer m.mu.RUnlock()
|
|
||||||
|
|
||||||
result := make(map[common.Address]*enode.Node)
|
|
||||||
for addr, node := range m.masternodes {
|
|
||||||
result[addr] = node
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsMasternode checks if an address is a masternode
|
|
||||||
func (m *MasternodeManager) IsMasternode(addr common.Address) bool {
|
|
||||||
m.mu.RLock()
|
|
||||||
defer m.mu.RUnlock()
|
|
||||||
|
|
||||||
_, exists := m.masternodes[addr]
|
|
||||||
return exists
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetActive marks a masternode as active/inactive
|
|
||||||
func (m *MasternodeManager) SetActive(addr common.Address, active bool) {
|
|
||||||
m.mu.Lock()
|
|
||||||
defer m.mu.Unlock()
|
|
||||||
|
|
||||||
m.active[addr] = active
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsActive checks if a masternode is active
|
|
||||||
func (m *MasternodeManager) IsActive(addr common.Address) bool {
|
|
||||||
m.mu.RLock()
|
|
||||||
defer m.mu.RUnlock()
|
|
||||||
|
|
||||||
return m.active[addr]
|
|
||||||
}
|
|
||||||
|
|
||||||
// ActiveCount returns the count of active masternodes
|
|
||||||
func (m *MasternodeManager) ActiveCount() int {
|
|
||||||
m.mu.RLock()
|
|
||||||
defer m.mu.RUnlock()
|
|
||||||
|
|
||||||
count := 0
|
|
||||||
for _, active := range m.active {
|
|
||||||
if active {
|
|
||||||
count++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetMasternodeNode gets the enode for a masternode address
|
|
||||||
func (m *MasternodeManager) GetMasternodeNode(addr common.Address) *enode.Node {
|
|
||||||
m.mu.RLock()
|
|
||||||
defer m.mu.RUnlock()
|
|
||||||
|
|
||||||
return m.masternodes[addr]
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetMasternodeAddresses returns all masternode addresses
|
|
||||||
func (m *MasternodeManager) GetMasternodeAddresses() []common.Address {
|
|
||||||
m.mu.RLock()
|
|
||||||
defer m.mu.RUnlock()
|
|
||||||
|
|
||||||
addrs := make([]common.Address, 0, len(m.masternodes))
|
|
||||||
for addr := range m.masternodes {
|
|
||||||
addrs = append(addrs, addr)
|
|
||||||
}
|
|
||||||
return addrs
|
|
||||||
}
|
|
||||||
|
|
||||||
// PrioritizeMasternodes returns nodes that should be prioritized for connection
|
|
||||||
func (m *MasternodeManager) PrioritizeMasternodes() []*enode.Node {
|
|
||||||
m.mu.RLock()
|
|
||||||
defer m.mu.RUnlock()
|
|
||||||
|
|
||||||
nodes := make([]*enode.Node, 0)
|
|
||||||
for addr, node := range m.masternodes {
|
|
||||||
if !m.active[addr] && node != nil {
|
|
||||||
nodes = append(nodes, node)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nodes
|
|
||||||
}
|
|
||||||
|
|
||||||
// XDCServerConfig extends server config with XDPoS options
|
|
||||||
type XDCServerConfig struct {
|
|
||||||
// Base server config
|
|
||||||
Config
|
|
||||||
|
|
||||||
// Masternode configuration
|
|
||||||
Masternode *MasternodeConfig
|
|
||||||
|
|
||||||
// Whether to accept non-masternode peers
|
|
||||||
AcceptNonMasternode bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// XDCDialer implements a dialer that prioritizes masternodes
|
|
||||||
type XDCDialer struct {
|
|
||||||
manager *MasternodeManager
|
|
||||||
dialer NodeDialer
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewXDCDialer creates a new XDC dialer
|
|
||||||
func NewXDCDialer(manager *MasternodeManager, dialer NodeDialer) *XDCDialer {
|
|
||||||
return &XDCDialer{
|
|
||||||
manager: manager,
|
|
||||||
dialer: dialer,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dial attempts to dial a node, prioritizing masternodes
|
|
||||||
func (d *XDCDialer) Dial(dest *enode.Node) (Conn, error) {
|
|
||||||
// TODO: Implement priority dialing for masternodes
|
|
||||||
return d.dialer.Dial(dest)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PeerHook is called when a peer connects or disconnects
|
|
||||||
type PeerHook func(peer *Peer, added bool)
|
|
||||||
|
|
||||||
// XDCPeerHooks contains hooks for XDPoS peer events
|
|
||||||
type XDCPeerHooks struct {
|
|
||||||
OnConnect PeerHook
|
|
||||||
OnDisconnect PeerHook
|
|
||||||
}
|
|
||||||
|
|
||||||
// MasternodePeerInfo contains masternode-specific peer info
|
|
||||||
type MasternodePeerInfo struct {
|
|
||||||
Address common.Address `json:"address"`
|
|
||||||
IsMaster bool `json:"isMaster"`
|
|
||||||
Epoch uint64 `json:"epoch"`
|
|
||||||
IsValidator bool `json:"isValidator"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetMasternodePeerInfo extracts masternode info from a peer
|
|
||||||
func GetMasternodePeerInfo(peer *Peer) *MasternodePeerInfo {
|
|
||||||
// This would be extracted from peer handshake data
|
|
||||||
return &MasternodePeerInfo{
|
|
||||||
IsMaster: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in a new issue