Save/load blocks from p2pool.cache
This commit is contained in:
parent
d59a78c25d
commit
a46d182aa8
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -1 +1,3 @@
|
||||||
.idea
|
.idea
|
||||||
|
p2pool.cache
|
||||||
|
p2pool_peers.txt
|
|
@ -24,7 +24,6 @@ func main() {
|
||||||
moneroRpcPort := flag.Uint("rpc-port", 18081, "monerod RPC API port number")
|
moneroRpcPort := flag.Uint("rpc-port", 18081, "monerod RPC API port number")
|
||||||
moneroZmqPort := flag.Uint("zmq-port", 18083, "monerod ZMQ pub port number")
|
moneroZmqPort := flag.Uint("zmq-port", 18083, "monerod ZMQ pub port number")
|
||||||
p2pListen := flag.String("p2p", fmt.Sprintf("0.0.0.0:%d", currentConsensus.DefaultPort()), "IP:port for p2p server to listen on.")
|
p2pListen := flag.String("p2p", fmt.Sprintf("0.0.0.0:%d", currentConsensus.DefaultPort()), "IP:port for p2p server to listen on.")
|
||||||
//TODO: zmq
|
|
||||||
addPeers := flag.String("addpeers", "", "Comma-separated list of IP:port of other p2pool nodes to connect to")
|
addPeers := flag.String("addpeers", "", "Comma-separated list of IP:port of other p2pool nodes to connect to")
|
||||||
peerList := flag.String("peer-list", "p2pool_peers.txt", "Either a path or an URL to obtain peer lists from. If it is a path, new peers will be saved to this path")
|
peerList := flag.String("peer-list", "p2pool_peers.txt", "Either a path or an URL to obtain peer lists from. If it is a path, new peers will be saved to this path")
|
||||||
consensusConfigFile := flag.String("config", "", "Name of the p2pool config file")
|
consensusConfigFile := flag.String("config", "", "Name of the p2pool config file")
|
||||||
|
@ -34,6 +33,8 @@ func main() {
|
||||||
inPeers := flag.Uint64("in-peers", 10, "Maximum number of incoming connections for p2p server (any value between 10 and 450)")
|
inPeers := flag.Uint64("in-peers", 10, "Maximum number of incoming connections for p2p server (any value between 10 and 450)")
|
||||||
p2pExternalPort := flag.Uint64("p2p-external-port", 0, "Port number that your router uses for mapping to your local p2p port. Use it if you are behind a NAT and still want to accept incoming connections")
|
p2pExternalPort := flag.Uint64("p2p-external-port", 0, "Port number that your router uses for mapping to your local p2p port. Use it if you are behind a NAT and still want to accept incoming connections")
|
||||||
|
|
||||||
|
noCache := flag.Bool("no-cache", false, "Disable p2pool.cache")
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
client.SetDefaultClientSettings(fmt.Sprintf("http://%s:%d", *moneroHost, *moneroRpcPort))
|
client.SetDefaultClientSettings(fmt.Sprintf("http://%s:%d", *moneroHost, *moneroRpcPort))
|
||||||
|
@ -73,6 +74,10 @@ func main() {
|
||||||
settings["in-peers"] = strconv.FormatUint(*inPeers, 10)
|
settings["in-peers"] = strconv.FormatUint(*inPeers, 10)
|
||||||
settings["external-port"] = strconv.FormatUint(*p2pExternalPort, 10)
|
settings["external-port"] = strconv.FormatUint(*p2pExternalPort, 10)
|
||||||
|
|
||||||
|
if !*noCache {
|
||||||
|
settings["cache"] = "p2pool.cache"
|
||||||
|
}
|
||||||
|
|
||||||
if p2pool, err := p2pool2.NewP2Pool(currentConsensus, settings); err != nil {
|
if p2pool, err := p2pool2.NewP2Pool(currentConsensus, settings); err != nil {
|
||||||
log.Fatalf("Could not start p2pool: %s", err)
|
log.Fatalf("Could not start p2pool: %s", err)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -14,6 +14,8 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Api
|
||||||
|
// Deprecated
|
||||||
type Api struct {
|
type Api struct {
|
||||||
db *database.Database
|
db *database.Database
|
||||||
path string
|
path string
|
||||||
|
|
21
p2pool/cache/cache.go
vendored
Normal file
21
p2pool/cache/cache.go
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
package cache
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.gammaspectra.live/P2Pool/p2pool-observer/p2pool/p2p"
|
||||||
|
"git.gammaspectra.live/P2Pool/p2pool-observer/p2pool/sidechain"
|
||||||
|
"git.gammaspectra.live/P2Pool/p2pool-observer/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Cache interface {
|
||||||
|
Store(block *sidechain.PoolBlock)
|
||||||
|
}
|
||||||
|
|
||||||
|
type HeapCache interface {
|
||||||
|
Cache
|
||||||
|
LoadAll(s *p2p.Server)
|
||||||
|
}
|
||||||
|
|
||||||
|
type AddressableCache interface {
|
||||||
|
Remove(hash types.Hash)
|
||||||
|
Load(hash types.Hash) *sidechain.PoolBlock
|
||||||
|
}
|
116
p2pool/cache/legacy/legacy.go
vendored
Normal file
116
p2pool/cache/legacy/legacy.go
vendored
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
package legacy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"git.gammaspectra.live/P2Pool/p2pool-observer/p2pool/p2p"
|
||||||
|
"git.gammaspectra.live/P2Pool/p2pool-observer/p2pool/sidechain"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const blockSize = 96 * 1024
|
||||||
|
const numBlocks = 4608
|
||||||
|
const cacheSize = blockSize * numBlocks
|
||||||
|
|
||||||
|
type Cache struct {
|
||||||
|
f *os.File
|
||||||
|
flushRunning atomic.Bool
|
||||||
|
storeIndex atomic.Uint32
|
||||||
|
loadingStarted sync.Once
|
||||||
|
loadingInProgress atomic.Bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCache(path string) (*Cache, error) {
|
||||||
|
if f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0666); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
if _, err = f.Seek(cacheSize-1, io.SeekStart); err != nil {
|
||||||
|
_ = f.Close()
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
//create sparse file
|
||||||
|
if _, err = f.Write([]byte{0}); err != nil {
|
||||||
|
_ = f.Close()
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Cache{
|
||||||
|
f: f,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Cache) Store(block *sidechain.PoolBlock) {
|
||||||
|
if c.loadingInProgress.Load() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if blob, err := block.MarshalBinary(); err != nil {
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
if (len(blob) + 4) > blockSize {
|
||||||
|
//block too big
|
||||||
|
return
|
||||||
|
}
|
||||||
|
storeIndex := (c.storeIndex.Add(1) % numBlocks) * blockSize
|
||||||
|
_, _ = c.f.WriteAt(binary.LittleEndian.AppendUint32(nil, uint32(len(blob))), int64(storeIndex))
|
||||||
|
_, _ = c.f.WriteAt(blob, int64(storeIndex)+4)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Cache) LoadAll(s *p2p.Server) {
|
||||||
|
c.loadingStarted.Do(func() {
|
||||||
|
c.loadingInProgress.Store(true)
|
||||||
|
defer c.loadingInProgress.Store(false)
|
||||||
|
log.Print("[Cache] Loading cached blocks")
|
||||||
|
|
||||||
|
var blobLen [4]byte
|
||||||
|
buf := make([]byte, 0, blockSize)
|
||||||
|
|
||||||
|
var blocksLoaded int
|
||||||
|
for i := 0; i < numBlocks; i++ {
|
||||||
|
storeIndex := (c.storeIndex.Add(1) % numBlocks) * blockSize
|
||||||
|
|
||||||
|
if _, err := c.f.ReadAt(blobLen[:], int64(storeIndex)); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
blobLength := binary.LittleEndian.Uint32(blobLen[:])
|
||||||
|
if (blobLength + 4) > blockSize {
|
||||||
|
//block too big
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, err := c.f.ReadAt(buf[:blobLength], int64(storeIndex)+4); err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
block := &sidechain.PoolBlock{
|
||||||
|
NetworkType: s.Consensus().NetworkType,
|
||||||
|
LocalTimestamp: uint64(time.Now().Unix()),
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := block.UnmarshalBinary(buf[:blobLength]); err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
s.AddCachedBlock(block)
|
||||||
|
|
||||||
|
blocksLoaded++
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[Cache] Loaded %d cached blocks", blocksLoaded)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Cache) Close() {
|
||||||
|
_ = c.f.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Cache) Flush() {
|
||||||
|
if !c.flushRunning.Swap(true) {
|
||||||
|
defer c.flushRunning.Store(false)
|
||||||
|
_ = c.f.Sync()
|
||||||
|
}
|
||||||
|
}
|
|
@ -128,6 +128,16 @@ func (c *Client) SendMissingBlockRequest(hash types.Hash) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if b := c.Owner.GetCachedBlock(hash); b != nil {
|
||||||
|
log.Printf("[P2PClient] Using cached block for id = %s", hash.String())
|
||||||
|
if missingBlocks, err := c.Owner.SideChain().AddPoolBlockExternal(b); err == nil {
|
||||||
|
for _, id := range missingBlocks {
|
||||||
|
c.SendMissingBlockRequest(id)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// do not re-request hashes that have been requested
|
// do not re-request hashes that have been requested
|
||||||
if !c.RequestedHashes.PushUnique(hash) {
|
if !c.RequestedHashes.PushUnique(hash) {
|
||||||
return
|
return
|
||||||
|
@ -194,7 +204,7 @@ func (c *Client) SendPeerListRequest() {
|
||||||
MessageId: MessagePeerListRequest,
|
MessageId: MessagePeerListRequest,
|
||||||
})
|
})
|
||||||
c.LastPeerListRequestTimestamp.Store(uint64(time.Now().UnixMicro()))
|
c.LastPeerListRequestTimestamp.Store(uint64(time.Now().UnixMicro()))
|
||||||
log.Printf("[P2PClient] Sending PEER_LIST_REQUEST to %s", c.AddressPort.String())
|
//log.Printf("[P2PClient] Sending PEER_LIST_REQUEST to %s", c.AddressPort.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) SendPeerListResponse(list []netip.AddrPort) {
|
func (c *Client) SendPeerListResponse(list []netip.AddrPort) {
|
||||||
|
@ -394,15 +404,6 @@ func (c *Client) OnConnection() {
|
||||||
isChainTipBlockRequest := false
|
isChainTipBlockRequest := false
|
||||||
if c.chainTipBlockRequest.Swap(false) {
|
if c.chainTipBlockRequest.Swap(false) {
|
||||||
isChainTipBlockRequest = true
|
isChainTipBlockRequest = true
|
||||||
if expectedBlockId == types.ZeroHash {
|
|
||||||
peerHeight := block.Main.Coinbase.GenHeight
|
|
||||||
ourHeight := c.Owner.MainChain().GetMinerDataTip().Height
|
|
||||||
|
|
||||||
if (peerHeight + 2) < ourHeight {
|
|
||||||
c.Ban(DefaultBanTime, fmt.Errorf("mining on top of a stale block (mainchain peer height %d, expected >= %d)", peerHeight, ourHeight))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//TODO: stale block
|
//TODO: stale block
|
||||||
|
|
||||||
log.Printf("[P2PClient] Peer %s tip is at id = %s, height = %d, main height = %d", c.AddressPort.String(), types.HashFromBytes(block.CoinbaseExtra(sidechain.SideTemplateId)), block.Side.Height, block.Main.Coinbase.GenHeight)
|
log.Printf("[P2PClient] Peer %s tip is at id = %s, height = %d, main height = %d", c.AddressPort.String(), types.HashFromBytes(block.CoinbaseExtra(sidechain.SideTemplateId)), block.Side.Height, block.Main.Coinbase.GenHeight)
|
||||||
|
@ -411,6 +412,13 @@ func (c *Client) OnConnection() {
|
||||||
c.Ban(DefaultBanTime, fmt.Errorf("expected block id = %s, got %s", expectedBlockId, types.ZeroHash.String()))
|
c.Ban(DefaultBanTime, fmt.Errorf("expected block id = %s, got %s", expectedBlockId, types.ZeroHash.String()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
peerHeight := block.Main.Coinbase.GenHeight
|
||||||
|
ourHeight := c.Owner.MainChain().GetMinerDataTip().Height
|
||||||
|
|
||||||
|
if (peerHeight + 2) < ourHeight {
|
||||||
|
c.Ban(DefaultBanTime, fmt.Errorf("mining on top of a stale block (mainchain peer height %d, expected >= %d)", peerHeight, ourHeight))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
c.SendPeerListRequest()
|
c.SendPeerListRequest()
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"git.gammaspectra.live/P2Pool/p2pool-observer/p2pool/mainchain"
|
"git.gammaspectra.live/P2Pool/p2pool-observer/p2pool/mainchain"
|
||||||
"git.gammaspectra.live/P2Pool/p2pool-observer/p2pool/sidechain"
|
"git.gammaspectra.live/P2Pool/p2pool-observer/p2pool/sidechain"
|
||||||
p2pooltypes "git.gammaspectra.live/P2Pool/p2pool-observer/p2pool/types"
|
p2pooltypes "git.gammaspectra.live/P2Pool/p2pool-observer/p2pool/types"
|
||||||
|
"git.gammaspectra.live/P2Pool/p2pool-observer/types"
|
||||||
"git.gammaspectra.live/P2Pool/p2pool-observer/utils"
|
"git.gammaspectra.live/P2Pool/p2pool-observer/utils"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
"log"
|
"log"
|
||||||
|
@ -54,6 +55,9 @@ type Server struct {
|
||||||
clientsLock sync.RWMutex
|
clientsLock sync.RWMutex
|
||||||
clients []*Client
|
clients []*Client
|
||||||
|
|
||||||
|
cachedBlocksLock sync.RWMutex
|
||||||
|
cachedBlocks map[types.Hash]*sidechain.PoolBlock
|
||||||
|
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,6 +80,7 @@ func NewServer(p2pool P2PoolInterface, listenAddress string, externalListenPort
|
||||||
peerId: binary.LittleEndian.Uint64(peerId),
|
peerId: binary.LittleEndian.Uint64(peerId),
|
||||||
MaxOutgoingPeers: utils.Min(utils.Max(maxOutgoingPeers, 10), 450),
|
MaxOutgoingPeers: utils.Min(utils.Max(maxOutgoingPeers, 10), 450),
|
||||||
MaxIncomingPeers: utils.Min(utils.Max(maxIncomingPeers, 10), 450),
|
MaxIncomingPeers: utils.Min(utils.Max(maxIncomingPeers, 10), 450),
|
||||||
|
cachedBlocks: make(map[types.Hash]*sidechain.PoolBlock, p2pool.Consensus().ChainWindowSize*3),
|
||||||
versionInformation: PeerVersionInformation{SoftwareId: SoftwareIdGoObserver, SoftwareVersion: CurrentSoftwareVersion, Protocol: SupportedProtocolVersion},
|
versionInformation: PeerVersionInformation{SoftwareId: SoftwareIdGoObserver, SoftwareVersion: CurrentSoftwareVersion, Protocol: SupportedProtocolVersion},
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
}
|
}
|
||||||
|
@ -142,7 +147,7 @@ func (s *Server) updatePeerList() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) updateClientConnections() {
|
func (s *Server) updateClientConnections() {
|
||||||
log.Printf("clients %d len %d", s.NumOutgoingConnections.Load(), len(s.Clients()))
|
//log.Printf("clients %d len %d", s.NumOutgoingConnections.Load(), len(s.Clients()))
|
||||||
currentPeers := uint32(s.NumOutgoingConnections.Load())
|
currentPeers := uint32(s.NumOutgoingConnections.Load())
|
||||||
peerList := s.PeerList()
|
peerList := s.PeerList()
|
||||||
for currentPeers < s.MaxOutgoingPeers && len(peerList) > 0 {
|
for currentPeers < s.MaxOutgoingPeers && len(peerList) > 0 {
|
||||||
|
@ -161,13 +166,48 @@ func (s *Server) updateClientConnections() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) AddCachedBlock(block *sidechain.PoolBlock) {
|
||||||
|
s.cachedBlocksLock.Lock()
|
||||||
|
defer s.cachedBlocksLock.Unlock()
|
||||||
|
|
||||||
|
if s.cachedBlocks == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
s.cachedBlocks[block.SideTemplateId(s.p2pool.Consensus())] = block
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) ClearCachedBlocks() {
|
||||||
|
s.cachedBlocksLock.Lock()
|
||||||
|
defer s.cachedBlocksLock.Unlock()
|
||||||
|
|
||||||
|
s.cachedBlocks = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) GetCachedBlock(hash types.Hash) *sidechain.PoolBlock {
|
||||||
|
s.cachedBlocksLock.RLock()
|
||||||
|
defer s.cachedBlocksLock.RUnlock()
|
||||||
|
|
||||||
|
return s.cachedBlocks[hash]
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) DownloadMissingBlocks() {
|
func (s *Server) DownloadMissingBlocks() {
|
||||||
clientList := s.Clients()
|
clientList := s.Clients()
|
||||||
|
|
||||||
if len(clientList) == 0 {
|
if len(clientList) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s.cachedBlocksLock.RLock()
|
||||||
|
defer s.cachedBlocksLock.RUnlock()
|
||||||
|
|
||||||
for _, h := range s.SideChain().GetMissingBlocks() {
|
for _, h := range s.SideChain().GetMissingBlocks() {
|
||||||
|
if b, ok := s.cachedBlocks[h]; ok {
|
||||||
|
if _, err := s.SideChain().AddPoolBlockExternal(b); err == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
clientList[unsafeRandom.Intn(len(clientList))].SendUniqueBlockRequest(h)
|
clientList[unsafeRandom.Intn(len(clientList))].SendUniqueBlockRequest(h)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,11 +238,15 @@ func (s *Server) Listen() (err error) {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
for range time.Tick(time.Second * 60) {
|
for range time.Tick(time.Second) {
|
||||||
if s.close.Load() {
|
if s.close.Load() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if s.SideChain().PreCalcFinished() {
|
||||||
|
s.ClearCachedBlocks()
|
||||||
|
}
|
||||||
|
|
||||||
s.DownloadMissingBlocks()
|
s.DownloadMissingBlocks()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
|
@ -9,6 +9,8 @@ import (
|
||||||
"git.gammaspectra.live/P2Pool/p2pool-observer/monero/client"
|
"git.gammaspectra.live/P2Pool/p2pool-observer/monero/client"
|
||||||
"git.gammaspectra.live/P2Pool/p2pool-observer/monero/client/zmq"
|
"git.gammaspectra.live/P2Pool/p2pool-observer/monero/client/zmq"
|
||||||
"git.gammaspectra.live/P2Pool/p2pool-observer/monero/transaction"
|
"git.gammaspectra.live/P2Pool/p2pool-observer/monero/transaction"
|
||||||
|
"git.gammaspectra.live/P2Pool/p2pool-observer/p2pool/cache"
|
||||||
|
"git.gammaspectra.live/P2Pool/p2pool-observer/p2pool/cache/legacy"
|
||||||
"git.gammaspectra.live/P2Pool/p2pool-observer/p2pool/mainchain"
|
"git.gammaspectra.live/P2Pool/p2pool-observer/p2pool/mainchain"
|
||||||
"git.gammaspectra.live/P2Pool/p2pool-observer/p2pool/p2p"
|
"git.gammaspectra.live/P2Pool/p2pool-observer/p2pool/p2p"
|
||||||
"git.gammaspectra.live/P2Pool/p2pool-observer/p2pool/sidechain"
|
"git.gammaspectra.live/P2Pool/p2pool-observer/p2pool/sidechain"
|
||||||
|
@ -24,6 +26,7 @@ type P2Pool struct {
|
||||||
consensus *sidechain.Consensus
|
consensus *sidechain.Consensus
|
||||||
sidechain *sidechain.SideChain
|
sidechain *sidechain.SideChain
|
||||||
mainchain *mainchain.MainChain
|
mainchain *mainchain.MainChain
|
||||||
|
cache cache.HeapCache
|
||||||
server *p2p.Server
|
server *p2p.Server
|
||||||
|
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
|
@ -76,6 +79,12 @@ func NewP2Pool(consensus *sidechain.Consensus, settings map[string]string) (*P2P
|
||||||
return nil, errors.New("could not create MainChain")
|
return nil, errors.New("could not create MainChain")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cachePath, ok := settings["cache"]; ok {
|
||||||
|
if pool.cache, err = legacy.NewCache(cachePath); err != nil {
|
||||||
|
return nil, fmt.Errorf("could not create cache: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if addr, ok := settings["listen"]; ok {
|
if addr, ok := settings["listen"]; ok {
|
||||||
listenAddress = addr
|
listenAddress = addr
|
||||||
}
|
}
|
||||||
|
@ -265,6 +274,12 @@ func (p *P2Pool) Run() (err error) {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
//TODO: move peer list loading here
|
||||||
|
|
||||||
|
if p.cache != nil {
|
||||||
|
p.cache.LoadAll(p.Server())
|
||||||
|
}
|
||||||
|
|
||||||
p.started.Store(true)
|
p.started.Store(true)
|
||||||
|
|
||||||
if err = p.Server().Listen(); err != nil {
|
if err = p.Server().Listen(); err != nil {
|
||||||
|
@ -381,6 +396,16 @@ func (p *P2Pool) SubmitBlock(b *block.Block) {
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *P2Pool) Store(block *sidechain.PoolBlock) {
|
||||||
|
if p.cache != nil {
|
||||||
|
p.cache.Store(block)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *P2Pool) ClearCachedBlocks() {
|
||||||
|
p.server.ClearCachedBlocks()
|
||||||
|
}
|
||||||
|
|
||||||
func (p *P2Pool) Started() bool {
|
func (p *P2Pool) Started() bool {
|
||||||
return p.started.Load()
|
return p.started.Load()
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,8 @@ func (c *SideChain) compressedBlockId(block *PoolBlock) []byte {
|
||||||
|
|
||||||
func (c *SideChain) saveBlock(block *PoolBlock) {
|
func (c *SideChain) saveBlock(block *PoolBlock) {
|
||||||
go func() {
|
go func() {
|
||||||
|
c.server.Store(block)
|
||||||
|
|
||||||
//TODO: make this a worker with a queue?
|
//TODO: make this a worker with a queue?
|
||||||
|
|
||||||
if !block.Verified.Load() || block.Invalid.Load() {
|
if !block.Verified.Load() || block.Invalid.Load() {
|
||||||
|
|
|
@ -44,6 +44,8 @@ type P2PoolInterface interface {
|
||||||
SubmitBlock(block *mainblock.Block)
|
SubmitBlock(block *mainblock.Block)
|
||||||
GetChainMainTip() *ChainMain
|
GetChainMainTip() *ChainMain
|
||||||
GetMinerDataTip() *p2pooltypes.MinerData
|
GetMinerDataTip() *p2pooltypes.MinerData
|
||||||
|
Store(block *PoolBlock)
|
||||||
|
ClearCachedBlocks()
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChainMain struct {
|
type ChainMain struct {
|
||||||
|
|
Loading…
Reference in a new issue