consensus/cmd/archivetoarchive/archivetoarchive.go

99 lines
2.9 KiB
Go

package main
import (
"context"
"flag"
"fmt"
"git.gammaspectra.live/P2Pool/p2pool-observer/monero/client"
"git.gammaspectra.live/P2Pool/p2pool-observer/p2pool/cache/archive"
"git.gammaspectra.live/P2Pool/p2pool-observer/p2pool/sidechain"
"git.gammaspectra.live/P2Pool/p2pool-observer/types"
"github.com/floatdrop/lru"
"log"
"math"
"os"
)
func main() {
inputConsensus := flag.String("consensus", "config.json", "Input config.json consensus file")
inputArchive := flag.String("input", "", "Input path for archive database")
outputArchive := flag.String("output", "", "Output path for archive database")
moneroHost := flag.String("host", "127.0.0.1", "IP address of your Monero node")
moneroRpcPort := flag.Uint("rpc-port", 18081, "monerod RPC API port number")
flag.Parse()
client.SetDefaultClientSettings(fmt.Sprintf("http://%s:%d", *moneroHost, *moneroRpcPort))
cf, err := os.ReadFile(*inputConsensus)
consensus, err := sidechain.NewConsensusFromJSON(cf)
if err != nil {
log.Panic(err)
}
difficultyCache := lru.New[uint64, types.Difficulty](1024)
getDifficultyByHeight := func(height uint64) types.Difficulty {
if v := difficultyCache.Get(height); v == nil {
if r, err := client.GetDefaultClient().GetBlockHeaderByHeight(height, context.Background()); err == nil {
d := types.DifficultyFrom64(r.BlockHeader.Difficulty)
difficultyCache.Set(height, d)
return d
}
return types.ZeroDifficulty
} else {
return *v
}
}
inputCache, err := archive.NewCache(*inputArchive, consensus, getDifficultyByHeight)
if err != nil {
log.Panic(err)
}
defer inputCache.Close()
outputCache, err := archive.NewCache(*outputArchive, consensus, getDifficultyByHeight)
if err != nil {
log.Panic(err)
}
defer outputCache.Close()
derivationCache := sidechain.NewDerivationCache()
blockCache := lru.New[types.Hash, *sidechain.PoolBlock](int(consensus.ChainWindowSize * 2))
getByTemplateId := func(h types.Hash) *sidechain.PoolBlock {
if v := blockCache.Get(h); v == nil {
if bs := inputCache.LoadByTemplateId(h); len(bs) != 0 {
blockCache.Set(h, bs[0])
return bs[0]
} else if bs = outputCache.LoadByTemplateId(h); len(bs) != 0 {
blockCache.Set(h, bs[0])
return bs[0]
} else {
return nil
}
} else {
return *v
}
}
preAllocatedShares := make(sidechain.Shares, consensus.ChainWindowSize*2)
for i := range preAllocatedShares {
preAllocatedShares[i] = &sidechain.Share{}
}
for blocksAtHeight := range inputCache.ScanHeights(0, math.MaxUint64) {
for i, b := range blocksAtHeight {
if _, err := b.PreProcessBlock(consensus, derivationCache, preAllocatedShares, getDifficultyByHeight, getByTemplateId); err != nil {
log.Printf("error processing block %s at %d, %s", types.HashFromBytes(b.CoinbaseExtra(sidechain.SideTemplateId)), b.Side.Height, err)
} else {
outputCache.Store(b)
if i == 0 {
blockCache.Set(types.HashFromBytes(b.CoinbaseExtra(sidechain.SideTemplateId)), b)
}
}
}
}
}