create git

This commit is contained in:
lzx
2025-09-03 16:00:42 +08:00
commit 953a76439a
55 changed files with 29879 additions and 0 deletions

85
internal/gbt/coin/coin.go Normal file
View File

@@ -0,0 +1,85 @@
// coin.go
package coin
import (
"pool/internal/db"
monero_rpc "pool/internal/gbt/monero/rpc"
"pool/internal/gbt/tari"
"pool/internal/utility"
"github.com/btcsuite/btcd/rpcclient"
"github.com/redis/go-redis/v9"
"github.com/zeromq/goczmq"
"go.uber.org/zap"
"gopkg.in/natefinch/lumberjack.v2"
)
type RpcConfig struct {
Host string `json:"host"`
Testnet string `json:"testnet"`
Type string `json:"type"`
User string `json:"user"`
Pass string `json:"pass"`
ZmqSub string `json:"zmqsub"`
Timeout int `json:"timeout"`
}
type ZmqConfig struct {
Pub string `json:"pub"`
Sub string `json:"sub"`
}
type ProfitConfig struct {
Push string `json:"push"`
}
type GbtConfig struct {
Rpc RpcConfig `json:"rpc"`
Zmq ZmqConfig `json:"zmq"`
Redis utility.RedisConfig `json:"redis"`
Profit ProfitConfig `json:"profit"`
Zaplog zap.Config `json:"zap"`
Logrotae utility.LogRotateConfig `json:"logrotate"`
}
type GbtContext struct {
DbCtx *db.DbContext
NodeSubCh *goczmq.Sock
PubCh *goczmq.Sock
SubCh *goczmq.Sock
MoneroNewBlockPubCh *goczmq.Sock // monero gbt有新块产生时发送消息队列
MoneroNewBlockSubCh *goczmq.Sock // 模仿自带zmq通知的币
PushCh *goczmq.Sock
Started bool
Config GbtConfig
Client *rpcclient.Client
MoneroClinet *monero_rpc.HttpClient
TariClient *tari.BaseNodeClient
MoneroAddr string // monero报块地址
TariAddr string // tari报块地址
ExitNotifyChan chan bool
ExitGbtChan chan bool
ExitBlockChan chan bool
//AlivingChan chan bool
FlagAliving int32
FlagAlivingExit int32
Log *zap.Logger
LogR *lumberjack.Logger
RedisClient *redis.Client
Coin string
MinerAddrs []string
MinerAddrIndex int
/*Blocks int64
Reward float64
Fee float64*/
}

198
internal/gbt/dbif/dbif.go Normal file
View File

@@ -0,0 +1,198 @@
// dbif.go
package dbif
import (
"pool/internal/db"
"pool/internal/gbt/coin"
"time"
)
func NotifyBlkDetailSuccess(gbt *coin.GbtContext, height int64, hash string, nonce string, subidx int64) {
var msg db.BlkDetail_db_msg
msg.Id = 0
msg.Msg = "blk_detail"
msg.Date = time.Now()
msg.MinerType = gbt.Coin
msg.Height = height
msg.Hash = hash
msg.Success = 1
msg.Nonce = nonce
msg.SubIdx = subidx
//gbt.DbCtx.BlkDetail_ch <- msg
db.Save_blk_detail(gbt.DbCtx, &msg)
}
/*func NotifyMinerSuccess(gbt *coin.GbtContext, user string, miner string, minerid string, height int64, hash string, nonce string, subidx int64, reward float64, fee float64) {
var msg db.Miner_db_msg
msg.Id = 0
msg.Msg = "miner"
msg.Date = time.Now()
msg.MinerType = gbt.Coin
msg.User = user
msg.Miner = miner
msg.Index = minerid
msg.Height = height
msg.Hash = hash
msg.Success = 1
msg.Nonce = nonce
msg.SubIdx = subidx
msg.Reward = reward
msg.Fee = fee
gbt.DbCtx.Miner_ch <- msg
}*/
/*func NotifyUsersBlkStatsSuccess(gbt *coin.GbtContext, user string, height int64, hash string, nonce string, subidx int64, reward float64, fee float64) {
var msg db.UsersBlkStats_db_msg
msg.Id = 0
msg.Msg = "users_blkstats"
msg.Date = time.Now()
msg.MinerType = gbt.Coin
msg.User = user
msg.Height = height
msg.Hash = hash
msg.Success = 1
msg.Nonce = nonce
msg.SubIdx = subidx
msg.Reward = reward
msg.Fee = fee
gbt.DbCtx.UsersBlkStats_ch <- msg
}*/
func NotifyPoolBlkStatsSuccess(gbt *coin.GbtContext, height int64, hash string, nonce string, subidx int64, reward float64, fee float64) {
var msg db.PoolBlkStats_db_msg
msg.Id = 0
msg.Msg = "pool_blkstats"
msg.Date = time.Now()
msg.MinerType = gbt.Coin
msg.Height = height
msg.Hash = hash
msg.Success = 1
msg.Nonce = nonce
msg.SubIdx = subidx
msg.Submit = ""
msg.Reward = reward
msg.Fee = fee
gbt.DbCtx.PoolBlkStats_ch <- msg
}
/*func NotifyMinerSubmitResult(gbt *coin.GbtContext, user string, miner string, minerid string, height int64, hash string, result string, nonce string, subidx int64) {
var msg db.Miner_db_msg
msg.Id = 0
msg.Msg = "miner"
msg.Date = time.Now()
msg.MinerType = gbt.Coin
msg.User = user
msg.Miner = miner
msg.Index = minerid
msg.Height = height
msg.Hash = hash
msg.Submit = result
msg.Nonce = nonce
msg.SubIdx = subidx
gbt.DbCtx.Miner_ch <- msg
}*/
/*func NotifyUsersBlkStatsSubmitResult(gbt *coin.GbtContext, user string, height int64, hash string, result string, nonce string, subidx int64) {
var msg db.UsersBlkStats_db_msg
msg.Id = 0
msg.Msg = "users_blkstats"
msg.Date = time.Now()
msg.MinerType = gbt.Coin
msg.User = user
msg.Height = height
msg.Hash = hash
msg.Submit = result
msg.Nonce = nonce
msg.SubIdx = subidx
gbt.DbCtx.UsersBlkStats_ch <- msg
}*/
func NotifyPoolBlkStatsSubmitResult(gbt *coin.GbtContext, height int64, hash string, result string, nonce string, subidx int64) {
var msg db.PoolBlkStats_db_msg
msg.Id = 0
msg.Msg = "pool_blkstats"
msg.Date = time.Now()
msg.MinerType = gbt.Coin
msg.Height = height
msg.Hash = hash
msg.Submit = result
msg.Nonce = nonce
msg.SubIdx = subidx
gbt.DbCtx.PoolBlkStats_ch <- msg
}
func NotifyBlkNewDb(gbt *coin.GbtContext, height int64, hash string, success bool, nonce string, subidx int64) {
var msg db.BlkNew_db_msg
msg.Id = 0
msg.Msg = "blk_new"
msg.Date = time.Now()
msg.MinerType = gbt.Coin
msg.Height = height
msg.Hash = hash
if success {
msg.Success = 1
} else {
msg.Success = 0
}
msg.Nonce = nonce
msg.SubIdx = subidx
gbt.DbCtx.BlkNew_ch <- msg
}
/*func NotifyBlockStat(gbt *coin.GbtContext, user string, miner string, minerid string, reward float64, fee float64) {
var miners_msg db.Miners_db_msg
miners_msg.Id = 0
miners_msg.Msg = "miners"
miners_msg.Date = time.Now()
miners_msg.MinerType = gbt.Coin
miners_msg.User = user
miners_msg.Miner = miner
miners_msg.Index = minerid
gbt.DbCtx.Miners_ch <- miners_msg
var users_msg db.Users_db_msg
users_msg.Id = 0
users_msg.Msg = "users"
users_msg.Date = time.Now()
users_msg.MinerType = gbt.Coin
users_msg.User = user
gbt.DbCtx.Users_ch <- users_msg
var pool_msg db.Pool_db_msg
pool_msg.Id = 0
pool_msg.Msg = "pool"
pool_msg.Date = time.Now()
pool_msg.MinerType = gbt.Coin
pool_msg.Reward = reward
pool_msg.Fee = fee
gbt.DbCtx.Pool_ch <- pool_msg
}*/

300
internal/gbt/gbt.go Normal file
View File

@@ -0,0 +1,300 @@
// gbt.go
package gbt
import (
"encoding/json"
"fmt"
"log"
"io/ioutil"
"pool/internal/db"
"sync/atomic"
//"pool/internal/cache"
"pool/internal/gbt/coin"
monero_rpc "pool/internal/gbt/monero/rpc"
"pool/internal/gbt/tari"
"pool/internal/gbt/tari/sha3x"
"pool/internal/utility"
"os"
"os/signal"
"syscall"
"time"
"github.com/btcsuite/btcd/rpcclient"
"github.com/redis/go-redis/v9"
"go.uber.org/zap"
)
var logg *zap.Logger
var GbtCtx coin.GbtContext
func InitConfig(config *coin.GbtConfig) {
data, err := ioutil.ReadFile("gbt.conf")
if err != nil {
panic(err.Error())
}
if err = json.Unmarshal(data, &config); err != nil {
panic(err.Error())
}
}
func InitClient(gbt *coin.GbtContext) error {
fmt.Println(gbt.Coin)
switch gbt.Coin {
case "monero":
url := "http://" + gbt.Config.Rpc.Host
rpcClient := monero_rpc.NewHttpClient(url, 10*time.Second)
gbt.MoneroClinet = rpcClient
gbt.MoneroAddr = gbt.Config.Rpc.User
case "sha3x":
url := gbt.Config.Rpc.Host
grpcClient, err := tari.NewBaseNodeClient(url)
if err != nil {
fmt.Println("tari创建grpc服务失败", err)
return err
}
gbt.TariClient = grpcClient
gbt.TariAddr = gbt.Config.Rpc.Host
default:
var config rpcclient.ConnConfig
if gbt.Config.Rpc.Type == "testnet" {
config.Host = gbt.Config.Rpc.Testnet
} else {
config.Host = gbt.Config.Rpc.Host
}
config.User = gbt.Config.Rpc.User
config.Pass = gbt.Config.Rpc.Pass
config.HTTPPostMode = true
config.DisableTLS = true
client, err := rpcclient.New(&config, nil)
if err != nil {
logg.Info("[gbt]", zap.String("rpcclient new ", err.Error()))
return err
}
gbt.Client = client
blockCount, err := client.GetBlockCount()
if err != nil {
logg.Info("[gbt]", zap.String("GetBlockCount ", err.Error()))
return err
}
logg.Info("[gbt]", zap.Int64("Block count ", blockCount))
}
return nil
}
/*func GbtLivingHandler(gbt *coin.GbtContext) {
timer := time.NewTimer(time.Duration(600) * time.Second)
for {
select {
case aliving := <-gbt.AlivingChan:
if !aliving {
timer.Stop()
//log.Println("gbt aliving", aliving)
return
} else {
timer.Reset(time.Duration(600) * time.Second)
}
case <-time.After(time.Duration(600) * time.Second):
gbt.ExitGbtChan <- true
return
}
}
}*/
func GbtLivingHandler(gbt *coin.GbtContext) {
var to_cnt int = 0
for {
flagAliving := atomic.LoadInt32(&(gbt.FlagAliving))
flagExit := atomic.LoadInt32(&(gbt.FlagAlivingExit))
if flagExit == 1 {
logg.Error("[server]", zap.String("GbtLivingHandler exited", "exit"))
break
}
if flagAliving == 0 {
//if to_cnt > 240 {
if to_cnt > gbt.Config.Rpc.Timeout*3/1000 {
logg.Error("[server]", zap.String("GbtLivingHandler exited", "timer expired"))
cmd := "killall gbt_" + gbt.Coin + " &"
utility.ExecShellCmd(cmd)
gbt.ExitGbtChan <- true
break
}
to_cnt++
} else {
to_cnt = 0
atomic.StoreInt32(&(gbt.FlagAliving), 0)
}
time.Sleep(time.Second)
}
}
type coinobj struct {
Coin string
Init func(GbtCtx *coin.GbtContext, DbCtx *db.DbContext)
Start func()
Stop func()
}
var coinobjs = []coinobj{
// {Coin: "nexa", Init: nexa.Init, Start: nexa.Start, Stop: nexa.Stop},
// {Coin: "monero", Init: monero.Init, Start: monero.Start, Stop: monero.Stop},
{Coin: "sha3x", Init: sha3x.Init, Start: sha3x.Start, Stop: sha3x.Stop},
}
func register_signal(dbctx *db.DbContext) {
signal_ch := make(chan os.Signal, 1)
signal.Notify(signal_ch, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
go signal_handle(signal_ch, dbctx)
}
func signal_handle(signal_ch chan os.Signal, dbctx *db.DbContext) {
for s := range signal_ch {
switch s {
case syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT:
log.Println("stop!")
dbctx.AppExit <- true
default:
//fmt.Println("other signal", s)
}
}
}
/*func LoadCache(gbt *coin.GbtContext) {
val := cache.LoadPoolCache(gbt.RedisClient, gbt.Coin, "blocks")
if val != nil {
if intVal, ok := val.(int64); ok {
gbt.Blocks = intVal
}
}
val_f := cache.LoadPoolCache(gbt.RedisClient, gbt.Coin, "rewards")
if val_f != nil {
if fVal, ok := val_f.(float64); ok {
gbt.Reward = fVal
}
}
val_f = cache.LoadPoolCache(gbt.RedisClient, gbt.Coin, "fee")
if val_f != nil {
if fVal, ok := val_f.(float64); ok {
gbt.Fee = fVal
}
}
}*/
func Start(Coin string, DbCtx *db.DbContext) {
GbtCtx.DbCtx = DbCtx
GbtCtx.Coin = Coin
atomic.StoreInt32(&(GbtCtx.FlagAliving), 0)
atomic.StoreInt32(&(GbtCtx.FlagAlivingExit), 0)
InitConfig(&GbtCtx.Config)
l, lr, err := utility.InitLogg(&(GbtCtx.Config.Zaplog), &(GbtCtx.Config.Logrotae), Coin, "gbt")
logg = l
//defer logg.Sync()
GbtCtx.Log = l
GbtCtx.LogR = lr
GbtCtx.RedisClient = redis.NewClient(&redis.Options{
Addr: GbtCtx.Config.Redis.Addr,
Password: GbtCtx.Config.Redis.Password,
DB: GbtCtx.Config.Redis.DB,
})
register_signal(DbCtx)
GbtCtx.PubCh = utility.InitZmqPub(GbtCtx.Config.Zmq.Pub)
GbtCtx.SubCh = utility.InitZmqSub(GbtCtx.Config.Zmq.Sub, "blk"+Coin)
GbtCtx.MoneroNewBlockPubCh = utility.InitZmqPub(GbtCtx.Config.Rpc.ZmqSub)
GbtCtx.MoneroNewBlockSubCh = utility.InitZmqSub(GbtCtx.Config.Rpc.ZmqSub, "hashblock")
//GbtCtx.PushCh = utility.InitZmqPush(GbtCtx.Config.Profit.Push)
for {
err = InitClient(&GbtCtx)
if err != nil {
logg.Error("[gbt]", zap.String("InitClient", err.Error()))
time.Sleep(time.Duration(5) * time.Second)
continue
}
break
}
if len(GbtCtx.Config.Rpc.ZmqSub) > 0 {
GbtCtx.NodeSubCh = utility.InitZmqSub(GbtCtx.Config.Rpc.ZmqSub, utility.BITCOIND_ZMQ_HASHBLOCK)
}
GbtCtx.Started = true
GbtCtx.ExitGbtChan = make(chan bool, 256)
//GbtCtx.AlivingChan = make(chan bool, 256)
GbtCtx.MinerAddrs = db.GetAddressFromTable(DbCtx)
GbtCtx.MinerAddrIndex = 0
//LoadCache(&GbtCtx)
for _, coinobj := range coinobjs {
if coinobj.Coin == Coin {
coinobj.Init(&GbtCtx, DbCtx)
go coinobj.Start()
break
}
}
go GbtLivingHandler(&GbtCtx)
<-DbCtx.AppExit
}
func Stop(Coin string) {
GbtCtx.Started = false
GbtCtx.ExitGbtChan <- true
//GbtCtx.AlivingChan <- false
atomic.StoreInt32(&(GbtCtx.FlagAlivingExit), 1)
for _, coinobj := range coinobjs {
if coinobj.Coin == Coin {
coinobj.Stop()
break
}
}
//time.Sleep(1 * time.Second)
defer close(GbtCtx.ExitGbtChan)
//defer close(GbtCtx.AlivingChan)
if GbtCtx.NodeSubCh != nil {
defer GbtCtx.NodeSubCh.Destroy()
}
if GbtCtx.PubCh != nil {
defer GbtCtx.PubCh.Destroy()
}
if GbtCtx.SubCh != nil {
defer GbtCtx.SubCh.Destroy()
}
/*if GbtCtx.PushCh != nil {
defer GbtCtx.PushCh.Destroy()
}*/
defer GbtCtx.RedisClient.Close()
defer logg.Sync()
}

View File

@@ -0,0 +1,495 @@
package monero
import (
"crypto/rand"
"database/sql"
"encoding/hex"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"math"
"pool/internal/db"
"pool/internal/gbt/coin"
"pool/internal/gbt/dbif"
"pool/internal/msg"
"pool/internal/utility"
"sync/atomic"
"time"
"go.uber.org/zap"
)
const GBT_MONERO_VERSION string = "monero v1.0"
type MoneroAddrConfig struct {
Addr string `json:"addr"`
}
type MoneroConfig struct {
Monero MoneroAddrConfig `json:"nexa"`
}
type GetBlockTemplateResponse struct {
ID string `json:"id"`
Jsonrpc string `json:"jsonrpc"`
Result msg.MoneroStratumJob `json:"result"`
Error *RpcError `json:"error,omitempty"`
}
type RpcError struct {
Code int `json:"code"`
Message string `json:"message"`
}
// RPCError 用于描述 RPC 返回的错误
type RPCError struct {
Code int `json:"code"`
Message string `json:"message"`
}
// 通用 RPC 响应结构
type MoneroRPCResponse[T any] struct {
ID string `json:"id"`
Jsonrpc string `json:"jsonrpc"`
Result *T `json:"result,omitempty"` // 成功时使用
Error *RPCError `json:"error,omitempty"` // 失败时使用
}
type SubmitSuccess struct {
BlockId string `json:"block_id"`
Status string `json:"status"`
Untrusted bool `json:"untrusted"`
}
type GbtMoneroContext struct {
Config MoneroConfig
GbtCtx *coin.GbtContext
last_time time.Time
last_gbt msg.MoneroStratumJob
last_blockhash string
last_height uint32
Submits float64
addressIndex int
Target []byte
Header []byte
last_body string
new_block_chan chan int
new_block_index int
}
var logg *zap.Logger
var GbtMoneroCtx GbtMoneroContext
func configInit(config *MoneroConfig) {
data, err := ioutil.ReadFile("gbt.conf")
if err != nil {
panic(err.Error())
}
if err = json.Unmarshal(data, &config); err != nil {
panic(err.Error())
}
}
func Init(GbtCtx *coin.GbtContext, DbCtx *db.DbContext) {
GbtMoneroCtx.GbtCtx = GbtCtx
GbtMoneroCtx.last_height = 0
configInit(&GbtMoneroCtx.Config)
GbtMoneroCtx.Target = make([]byte, 32)
GbtMoneroCtx.Header = make([]byte, 49)
GbtMoneroCtx.last_time = time.Now()
logg = GbtCtx.Log
GbtMoneroCtx.new_block_chan = make(chan int, 256)
GbtMoneroCtx.new_block_index = 0
logg.Info("[gbt]", zap.String("gbt_monero_version", GBT_MONERO_VERSION))
}
func Start() {
go gbt_running(&GbtMoneroCtx)
go gbt_notify_running(&GbtMoneroCtx)
go submit_block_running(&GbtMoneroCtx)
}
func Stop() {
defer close(GbtMoneroCtx.new_block_chan)
}
type BlockCheckData struct {
Height int
Nonce string
User string
Miner string
MinerId string
Hash string
SubIdx int
}
type GetBlockHeaderResp struct {
Id string `json:"id"`
Jsonrpc string `json:"jsonrpc"`
Error any `json:"error"`
Result GetBlockHeaderMsg `json:"result"`
}
type GetBlockHeaderMsg struct {
Result struct {
BlockHeader struct {
Nonce uint64 `json:"nonce"`
PowHash string `json:"pow_hash"`
Reward uint64 `json:"reward"`
} `json:"block_header"`
Status string `json:"status"`
Untrusted bool `json:"untrusted"`
} `json:"result"`
}
func update_block_confirm(gbt *GbtMoneroContext) {
db, err := sql.Open("sqlite3", "./blocks.db")
if err != nil {
//log.Printf("Error opening database: %v", err)
logg.Error("[gbt]", zap.String("Error opening database", err.Error()))
return
}
defer db.Close()
query := "SELECT user,miner,minerid,height,nonce,hash,subidx FROM blocks WHERE checked=0 AND created_at >= datetime('now', '-30 minutes') order by id desc limit 2"
rows, err := db.Query(query)
if err != nil {
//log.Printf("Error executing query from blocks: %v", err)
logg.Error("[gbt]", zap.String("Error executing query from blocks:", err.Error()))
return
}
defer rows.Close()
var blocks []BlockCheckData
for rows.Next() {
var height int
var nonce string
var user string
var miner string
var minerid string
var hash string
var subidx int
if err := rows.Scan(&user, &miner, &minerid, &height, &nonce, &hash, &subidx); err != nil {
//log.Printf("Error scanning row in blocks: %v", err)
logg.Error("[gbt]", zap.String("Error scanning row in blocks:", err.Error()))
return
}
var blockdata BlockCheckData
blockdata.Height = height
blockdata.Nonce = nonce
blockdata.User = user
blockdata.Miner = miner
blockdata.MinerId = minerid
blockdata.Hash = hash
blockdata.SubIdx = subidx
blocks = append(blocks, blockdata)
//fmt.Printf("blocks - Height: %d, Nonce: %d\n", height, nonce)
//log.Printf("update block height %d nonce %s, subidx %d, user %s", height, nonce, subidx, user+"."+miner+"_"+minerid)
}
for _, block := range blocks {
var blockHeaderResp GetBlockHeaderResp
resp, err := gbt.GbtCtx.MoneroClinet.GetBlockByHash(block.Hash)
err = json.Unmarshal(resp, &blockHeaderResp)
if err != nil {
logg.Error("[gbt]", zap.String("getblockheader Unmarshal ", fmt.Sprint(block.Height)+" "+err.Error()))
continue
}
if blockHeaderResp.Error != nil {
fmt.Println("[check block]:", blockHeaderResp.Error)
update_sql := `UPDATE blocks SET checked = 2 WHERE height = ? AND nonce = ? AND checked = 0`
_, err = db.Exec(update_sql, block.Height, block.Nonce)
if err != nil {
//log.Printf("Error updating blk_new: %v", err)
logg.Error("[gbt]", zap.String("Error updating blk_new:", err.Error()))
}
return
}
blockHeader := blockHeaderResp.Result
block_height := int64(block.Height)
// nonceHex := fmt.Sprintf("%x", block.Nonce)
dbif.NotifyPoolBlkStatsSuccess(gbt.GbtCtx, block_height, "", block.Nonce, int64(block.SubIdx), float64(blockHeader.Result.BlockHeader.Reward)/math.Pow(10, 12), 0)
dbif.NotifyBlkDetailSuccess(gbt.GbtCtx, block_height, "", block.Nonce, int64(block.SubIdx))
dbif.NotifyBlkNewDb(gbt.GbtCtx, block_height, block.Hash, true, block.Nonce, int64(block.SubIdx))
updateSQL := `UPDATE blocks SET checked = 1 WHERE height = ? AND nonce = ? AND checked = 0`
_, err = db.Exec(updateSQL, block.Height, block.Nonce)
if err != nil {
//log.Printf("Error updating blk_new: %v", err)
logg.Error("[gbt]", zap.String("Error updating blk_new:", err.Error()))
continue
}
logg.Warn("[gbt]", zap.String("update block success:", fmt.Sprint(block.Height)+" "+block.Nonce))
}
}
func randomxJobId() string {
// 生成4个字节
bytes := make([]byte, 4)
_, err := rand.Read(bytes)
if err != nil {
panic(err)
}
// 转成 hex 字符串
hexStr := hex.EncodeToString(bytes)
return hexStr
}
var start_count int = 0
var start_height uint64 = 0
func gbt_running(gbt *GbtMoneroContext) {
ticker := time.NewTicker(1000 * time.Millisecond)
defer ticker.Stop()
for gbt.GbtCtx.Started {
select {
case <-ticker.C:
resp, err := gbt.GbtCtx.MoneroClinet.GetBlockTemplate(gbt.GbtCtx.MoneroAddr, 0)
if err != nil {
fmt.Println("调用失败:", err)
continue
}
if resp != nil {
if gbt.GbtCtx.PubCh == nil {
gbt.GbtCtx.PubCh = utility.InitZmqPub(gbt.GbtCtx.Config.Zmq.Pub)
}
if gbt.GbtCtx.PubCh != nil {
var responseJson GetBlockTemplateResponse
err = json.Unmarshal(resp, &responseJson)
if err != nil {
fmt.Println("[gbt]:get block template response to json error\n", err)
return
}
sendJobMonero := func(job msg.MoneroStratumJob) {
for trycnt := 0; trycnt < 3; trycnt++ {
job.JobId = randomxJobId()
bt, err := json.Marshal(job)
if err != nil {
fmt.Println(err)
return
}
err = gbt.GbtCtx.PubCh.SendMessage([][]byte{[]byte("jobmonero"), bt})
if err != nil {
if !gbt.GbtCtx.Started {
return
}
logg.Warn("[gbt]", zap.String("job", err.Error()))
} else {
logg.Warn("[gbt]", zap.String("job", "sent"))
start_height = job.Height
start_count = 0
break
}
}
atomic.StoreInt32(&(gbt.GbtCtx.FlagAliving), 1)
}
if responseJson.Result.Height != start_height {
// 高度变化,先发 hashblock
if start_height != 0 {
topic := []byte("hashblock")
_msg := []byte("")
_ = gbt.GbtCtx.MoneroNewBlockPubCh.SendMessage([][]byte{topic, _msg})
}
// 再发 jobmonero
sendJobMonero(responseJson.Result)
} else if start_count >= 30 {
// 高度未变,但计数达到阈值,只发 jobmonero
sendJobMonero(responseJson.Result)
} else {
start_count += 1
}
} else {
logg.Warn("[gbt]", zap.String("job ", "sent failed! PubCh nil"))
}
} else {
atomic.StoreInt32(&(gbt.GbtCtx.FlagAliving), 1)
}
case blkIdx := <-gbt.new_block_chan:
log.Println("new block chan", blkIdx)
update_block_confirm(gbt)
case <-gbt.GbtCtx.ExitGbtChan:
logg.Error("[gbt]", zap.String("gbt", "exit"))
return
}
}
}
func gbt_notify_running(gbt *GbtMoneroContext) {
for {
if !gbt.GbtCtx.Started {
break
}
if gbt.GbtCtx.MoneroNewBlockSubCh == nil {
gbt.GbtCtx.MoneroNewBlockSubCh = utility.InitZmqSub(gbt.GbtCtx.Config.Rpc.ZmqSub, utility.BITCOIND_ZMQ_HASHBLOCK)
}
if gbt.GbtCtx.MoneroNewBlockSubCh != nil {
// fmt.Println("gbt_notify_running 开始接收消息")
cmsg_sub, err := gbt.GbtCtx.MoneroNewBlockSubCh.RecvMessage()
if err != nil {
if !gbt.GbtCtx.Started {
break
}
gbt.GbtCtx.MoneroNewBlockSubCh.SetSubscribe(utility.BITCOIND_ZMQ_HASHBLOCK)
gbt.GbtCtx.MoneroNewBlockSubCh.Connect(gbt.GbtCtx.Config.Rpc.ZmqSub)
continue
}
if len(cmsg_sub) >= 2 {
if string(cmsg_sub[0]) == "hashblock" {
GbtMoneroCtx.new_block_index = GbtMoneroCtx.new_block_index + 1
//log.Println("gbt_notify_running", hex.EncodeToString(cmsg_sub[1]), GbtNexaCtx.new_block_index)
gbt.new_block_chan <- GbtMoneroCtx.new_block_index
}
}
} else {
logg.Error("[gbt]", zap.String("notify", "NodeSubCh fail!"))
time.Sleep(time.Duration(1) * time.Second)
}
}
}
func submit_block_running(block *GbtMoneroContext) {
logg.Info("[block]", zap.String("submit_block_running", "Start."))
for {
if !block.GbtCtx.Started {
break
}
if block.GbtCtx.SubCh == nil {
block.GbtCtx.SubCh = utility.InitZmqSub(block.GbtCtx.Config.Zmq.Sub, "blk"+block.GbtCtx.Coin)
}
if block.GbtCtx.SubCh != nil {
cmsg_sub, err := block.GbtCtx.SubCh.RecvMessage()
if err != nil {
if !block.GbtCtx.Started {
break
}
time.Sleep(time.Duration(1) * time.Second)
block.GbtCtx.SubCh.SetSubscribe("blk" + block.GbtCtx.Coin)
block.GbtCtx.SubCh.Connect(block.GbtCtx.Config.Zmq.Sub)
continue
}
if len(cmsg_sub) >= 2 {
if string(cmsg_sub[0]) == "blkmonero" {
cmsg := cmsg_sub[1]
//block data
msgb := make([]byte, len(cmsg)-16)
copy(msgb, cmsg)
var moneroblock msg.BlockMoneroMsg
if err := json.Unmarshal(msgb, &moneroblock); err != nil {
//block.Consumer.MarkOffset(cmsg, "")
logg.Error("[block]", zap.String("failed to Unmarshal job", err.Error()))
continue
}
// heightb, err := hex.DecodeString(string(cmsg[len(msgb) : len(msgb)+8]))
// if err != nil {
// //block.Consumer.MarkOffset(cmsg, "")
// logg.Error("[block]", zap.String("failed to decode height", err.Error()))
// continue
// }
var height uint32 = uint32(moneroblock.Height)
logg.Warn("[block]", zap.Uint32("height", height))
if height <= block.last_height {
continue
}
block.last_height = height
indexb, err1 := hex.DecodeString(string(cmsg[len(msgb)+8:]))
if err1 != nil {
logg.Error("[block]", zap.String("failed to decode index", err1.Error()))
continue
}
var index uint32 = utility.ByteToUint32(indexb)
logg.Warn("[block]", zap.Uint32("index", index))
logg.Debug("[block]", zap.String("msg", string(cmsg)), zap.String("blk", string(msgb)))
result, _ := block.GbtCtx.MoneroClinet.SubmitBlock(moneroblock.Header)
var submitResp MoneroRPCResponse[SubmitSuccess]
if err2 := json.Unmarshal(result, &submitResp); err2 != nil {
logg.Error("[submit block]", zap.String("unmarshal error", err2.Error()))
return
}
if submitResp.Error != nil {
logg.Error("[submit block]", zap.String("submit failed reason", submitResp.Error.Message))
return
}
if submitResp.Result != nil {
logg.Info("[submit block]", zap.String("submit status", submitResp.Result.Status))
}
logg.Info("[block]", zap.String("result", string(result)))
//}
blockHash, success_msg := submitResp.Result.BlockId, submitResp.Result.Status
// nonceHex := fmt.Sprintf("%x", moneroblock.Nonce)
dbif.NotifyPoolBlkStatsSubmitResult(block.GbtCtx, int64(height), blockHash, success_msg, moneroblock.Nonce, moneroblock.SubIdx)
block.Submits += 1
//log.Printf("[block] height %d subidx %d nonce %s\n", height, nexablock.SubIdx, nexablock.Nonce)
logg.Warn("[block]", zap.Float64("total submits", block.Submits), zap.Int64("SubIdx", moneroblock.SubIdx))
// nonce, err := strconv.ParseUint(moneroblock.Nonce, 16, 32)
// if err != nil {
// return
// }
new_block_into_db(block, moneroblock.User, moneroblock.Miner, moneroblock.Index, int64(height), moneroblock.Nonce, blockHash, moneroblock.SubIdx)
}
}
} else {
logg.Error("[block]", zap.String("block", "SubCh failed! retry"))
time.Sleep(time.Duration(1) * time.Second)
}
}
}
func new_block_into_db(block *GbtMoneroContext, user string, miner string, minerid string, height int64, nonce string, hash string, subidx int64) bool {
db, err := sql.Open("sqlite3", "./blocks.db")
if err != nil {
log.Printf("Error opening database: %v", err)
return false
}
defer db.Close()
createTableSQL := `
CREATE TABLE IF NOT EXISTS blocks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user TEXT NOT NULL,
miner TEXT NOT NULL,
minerid TEXT NOT NULL,
height INTEGER,
nonce TEXT NOT NULL,
hash TEXT NOT NULL,
subidx INTEGER,
checked INTEGER,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);`
_, err = db.Exec(createTableSQL)
if err != nil {
log.Printf("Error creating table: %v", err)
return false
}
insertSQL := `INSERT INTO blocks (user, miner, minerid, height, nonce, checked, hash, subidx) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`
_, err = db.Exec(insertSQL, user, miner, minerid, height, nonce, 0, hash, subidx)
if err != nil {
log.Printf("Error inserting data from blocks %s: %v", fmt.Sprint(height), err)
return false
}
return true
}

View File

@@ -0,0 +1,179 @@
package monero_rpc
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"time"
)
// HttpClient 封装
type HttpClient struct {
Client *http.Client
Url string
}
func NewHttpClient(url string, timeout time.Duration) *HttpClient {
return &HttpClient{
Client: &http.Client{
Timeout: timeout,
},
Url: url,
}
}
// GET 请求params 可为 nil
func (hc *HttpClient) Get(api string, params map[string]interface{}, headers map[string]string) ([]byte, error) {
rawURL := hc.Url + "/json_rpc" + api
// 处理 URL 参数
if params != nil {
u, err := url.Parse(rawURL)
if err != nil {
return nil, err
}
q := u.Query()
for k, v := range params {
q.Set(k, fmt.Sprintf("%v", v))
}
u.RawQuery = q.Encode()
rawURL = u.String()
}
// 创建请求
req, err := http.NewRequest("GET", rawURL, nil)
if err != nil {
return nil, err
}
// 设置头
for k, v := range headers {
req.Header.Set(k, v)
}
// 发送请求
resp, err := hc.Client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
return io.ReadAll(resp.Body)
}
// POST 请求params 可为 nil
func (hc *HttpClient) Post(api string, params interface{}, headers map[string]string) ([]byte, error) {
rawURL := hc.Url + "/json_rpc" + api
var body io.Reader
if params != nil {
jsonBytes, err := json.Marshal(params)
if err != nil {
return nil, err
}
body = bytes.NewBuffer(jsonBytes)
}
req, err := http.NewRequest("POST", rawURL, body)
if err != nil {
return nil, err
}
// 设置默认 Content-Type
if _, ok := headers["Content-Type"]; !ok {
req.Header.Set("Content-Type", "application/json")
}
// 设置额外头
for k, v := range headers {
req.Header.Set(k, v)
}
resp, err := hc.Client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
return io.ReadAll(resp.Body)
}
type RPCRequest struct {
JsonRPC string `json:"jsonrpc"`
ID string `json:"id"`
Method string `json:"method"`
Params interface{} `json:"params"`
}
func (hc *HttpClient) GetBlockTemplate(address string, size int) ([]byte, error) {
params := map[string]any{
"wallet_address": address,
"reserve_size": size,
}
req := RPCRequest{
JsonRPC: "2.0",
ID: "0",
Method: "get_block_template",
Params: params,
}
resp, err := hc.Post("", req, nil)
if err != nil {
fmt.Println("[gbt]: getblocktemplate error:", err)
return nil, err
}
return resp, nil
}
func (hc *HttpClient) GetBlockHeader(height uint64) ([]byte, error) {
params := map[string]any{
"height": height,
"fill_pow_hash": true,
}
req := RPCRequest{
JsonRPC: "2.0",
ID: "0",
Method: "get_block_header_by_height",
Params: params,
}
resp, err := hc.Post("", req, nil)
if err != nil {
fmt.Println("[gbt]: getblockheader error:", err)
return nil, err
}
return resp, nil
}
func (hc *HttpClient) GetBlockByHash(hash string) ([]byte, error) {
params := map[string]any{
"hash": hash,
}
req := RPCRequest{
JsonRPC: "2.0",
ID: "0",
Method: "get_block_header_by_hash",
Params: params,
}
resp, err := hc.Post("", req, nil)
if err != nil {
fmt.Println("[gbt]: getblockheader error:", err)
return nil, err
}
return resp, nil
}
func (hc *HttpClient) SubmitBlock(blob string) ([]byte, error) {
params := []string{blob}
req := RPCRequest{
JsonRPC: "2.0",
ID: "0",
Method: "submit_block",
Params: params,
}
resp, err := hc.Post("", req, nil)
if err != nil {
fmt.Println("[gbt]: getblockheader error:", err)
return nil, err
}
return resp, nil
}

627
internal/gbt/nexa/nexa.go Normal file
View File

@@ -0,0 +1,627 @@
// nexa.go
package nexa
import (
"encoding/binary"
"encoding/hex"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"sync/atomic"
//"pool/internal/cache"
"pool/internal/db"
"pool/internal/gbt/coin"
"pool/internal/gbt/dbif"
"pool/internal/msg"
"pool/internal/utility"
"time"
"database/sql"
//"github.com/btcsuite/btcd/rpcclient"
_ "github.com/mattn/go-sqlite3"
"go.uber.org/zap"
)
const GBT_NEXA_VERSION string = "nexa v2.0m"
type NexaAddrConfig struct {
Addr string `json:"addr"`
}
type NexaConfig struct {
Nexa NexaAddrConfig `json:"nexa"`
}
type GbtNexaContext struct {
Config NexaConfig
GbtCtx *coin.GbtContext
last_time time.Time
last_gbt GbtNexaMsg
last_blockhash string
last_height uint32
Submits float64
addressIndex int
Target []byte
Header []byte
last_body string
new_block_chan chan int
new_block_index int
}
var logg *zap.Logger
var GbtNexaCtx GbtNexaContext
type GbtNexaMsg struct {
Id uint64 `json:"id"`
HeaderCommitment string `json:"headerCommitment"`
NBits string `json:"nBits"`
}
type GetBlockHeaderMsg struct {
Height int `json:"height"`
Nonce string `json:"nonce"`
Confirmations int `json:"confirmations"`
}
type GetBlockStatsMsg struct {
Height int `json:"height"`
Subsidy float64 `json:"subsidy"`
Totalfee float64 `json:"totalfee"`
}
type BlockCheckData struct {
Height int
Nonce string
User string
Miner string
MinerId string
Hash string
SubIdx int
}
/*type NewBlockMsg struct {
Height int `json:"height"`
Nonce int `json:"nonce"`
}*/
type PushBlkNewMsg struct {
Coin string `json:"coin"`
Height int `json:"height"`
Nonce string `json:"nonce"`
}
func update_block_confirm(gbt *GbtNexaContext) {
db, err := sql.Open("sqlite3", "./blocks.db")
if err != nil {
//log.Printf("Error opening database: %v", err)
logg.Error("[gbt]", zap.String("Error opening database", err.Error()))
return
}
defer db.Close()
query := "SELECT user,miner,minerid,height,nonce,hash,subidx FROM blocks WHERE checked=0 AND created_at >= datetime('now', '-30 minutes') order by id desc limit 2"
rows, err := db.Query(query)
if err != nil {
//log.Printf("Error executing query from blocks: %v", err)
logg.Error("[gbt]", zap.String("Error executing query from blocks:", err.Error()))
return
}
defer rows.Close()
var blocks []BlockCheckData
for rows.Next() {
var height int
var nonce string
var user string
var miner string
var minerid string
var hash string
var subidx int
if err := rows.Scan(&user, &miner, &minerid, &height, &nonce, &hash, &subidx); err != nil {
//log.Printf("Error scanning row in blocks: %v", err)
logg.Error("[gbt]", zap.String("Error scanning row in blocks:", err.Error()))
return
}
var blockdata BlockCheckData
blockdata.Height = height
blockdata.Nonce = nonce
blockdata.User = user
blockdata.Miner = miner
blockdata.MinerId = minerid
blockdata.Hash = hash
blockdata.SubIdx = subidx
blocks = append(blocks, blockdata)
//fmt.Printf("blocks - Height: %d, Nonce: %d\n", height, nonce)
//log.Printf("update block height %d nonce %s, subidx %d, user %s", height, nonce, subidx, user+"."+miner+"_"+minerid)
}
for _, block := range blocks {
block_hash, err := gbt.GbtCtx.Client.GetBlockHash(int64(block.Height))
if err != nil {
logg.Info("[gbt]", zap.String("GetBlockHash ", err.Error()))
continue
}
rawmsgs := make([]json.RawMessage, 1)
param_str := `"` + block_hash.String() + `"`
rawmsgs[0] = json.RawMessage(param_str)
result, err := gbt.GbtCtx.Client.RawRequest("getblockheader", rawmsgs)
if err != nil {
//log.Printf("getblockheader %s", err.Error())
logg.Error("[gbt]", zap.String("getblockheader", err.Error()))
continue
}
//log.Printf("getblockheader %d %s:%v", block.Height, block_hash, result)
var blockHeader GetBlockHeaderMsg
err = json.Unmarshal(result, &blockHeader)
if err != nil {
//log.Printf("getblockheader Unmarshal %s", err.Error())
logg.Error("[gbt]", zap.String("getblockheader Unmarshal ", fmt.Sprint(block.Height)+" "+err.Error()))
continue
}
rawmsgs_stats := make([]json.RawMessage, 1)
rawmsgs_stats[0] = json.RawMessage(param_str)
result_stats, err := gbt.GbtCtx.Client.RawRequest("getblockstats", rawmsgs_stats)
if err != nil {
//log.Printf("getblockstats %s", err.Error())
logg.Error("[gbt]", zap.String("getblockstats", err.Error()))
continue
}
//log.Printf("getblockheader %d %s:%v", block.Height, block_hash, result)
var blockStats GetBlockStatsMsg
err = json.Unmarshal(result_stats, &blockStats)
if err != nil {
//log.Printf("getblockstats Unmarshal %s", err.Error())
logg.Error("[gbt]", zap.String("getblockstats Unmarshal ", fmt.Sprint(block.Height)+" "+err.Error()))
continue
}
if blockHeader.Confirmations > 3 {
//log.Printf("cmp block: %d %s vs %s %s", block.Height, block.Nonce, string(result), blockHeader.Nonce)
//log.Printf("cmp block: %d %s %s_%s_%s vs %s\n", block.Height, block.Nonce, block.User, block.Miner, block.MinerId, blockHeader.Nonce)
if blockHeader.Nonce == block.Nonce {
block_height := int64(block.Height)
/*dbif.NotifyMinerSuccess(gbt.GbtCtx, block.User, block.Miner, block.MinerId, block_height, "", block.Nonce, int64(block.SubIdx), blockStats.Subsidy, blockStats.Totalfee)
dbif.NotifyUsersBlkStatsSuccess(gbt.GbtCtx, block.User, block_height, "", block.Nonce, int64(block.SubIdx), blockStats.Subsidy, blockStats.Totalfee)*/
dbif.NotifyPoolBlkStatsSuccess(gbt.GbtCtx, block_height, "", block.Nonce, int64(block.SubIdx), blockStats.Subsidy, blockStats.Totalfee)
dbif.NotifyBlkDetailSuccess(gbt.GbtCtx, block_height, "", block.Nonce, int64(block.SubIdx))
/*dbif.NotifyBlockStat(gbt.GbtCtx, block.User, block.Miner, block.MinerId, blockStats.Subsidy, blockStats.Totalfee)*/
//dbif.NotifyBlkNewSuccess(gbt.GbtCtx, block_height, "", block.Nonce, -1)
dbif.NotifyBlkNewDb(gbt.GbtCtx, block_height, block.Hash, true, block.Nonce, int64(block.SubIdx))
//gbt.GbtCtx.Blocks += 1
//cache.StorePoolCache(gbt.GbtCtx.RedisClient, gbt.GbtCtx.Coin, "blocks", gbt.GbtCtx.Blocks)
//gbt.GbtCtx.Reward += blockStats.Subsidy
//cache.StorePoolCache(gbt.GbtCtx.RedisClient, gbt.GbtCtx.Coin, "reward", gbt.GbtCtx.Reward)
//gbt.GbtCtx.Fee += blockStats.Totalfee
//cache.StorePoolCache(gbt.GbtCtx.RedisClient, gbt.GbtCtx.Coin, "fee", gbt.GbtCtx.Fee)
/*var pushmsg PushBlkNewMsg
pushmsg.Coin = gbt.GbtCtx.Coin
pushmsg.Height = block.Height
pushmsg.Nonce = block.Nonce
jsonData, err := json.Marshal(pushmsg)
if err != nil {
//log.Printf("Failed to marshal JSON: %v", err)
logg.Error("[gbt]", zap.String("Failed to marshal JSON:", err.Error()))
continue
}
if gbt.GbtCtx.PushCh == nil {
gbt.GbtCtx.PushCh = utility.InitZmqPush(gbt.GbtCtx.Config.Profit.Push)
}
if gbt.GbtCtx.PushCh != nil {
err = gbt.GbtCtx.PushCh.SendMessage([][]byte{[]byte("blk_new"), jsonData})
if err != nil {
//log.Printf("Failed to send data: %v", err)
logg.Error("[gbt]", zap.String("Failed to SendMessage:", err.Error()))
continue
}
}*/
updateSQL := `UPDATE blocks SET checked = 1 WHERE height = ? AND nonce = ? AND checked = 0`
_, err = db.Exec(updateSQL, block.Height, block.Nonce)
if err != nil {
//log.Printf("Error updating blk_new: %v", err)
logg.Error("[gbt]", zap.String("Error updating blk_new:", err.Error()))
continue
}
//log.Printf("update block success: %d %s", block.Height, block.Nonce)
logg.Warn("[gbt]", zap.String("update block success:", fmt.Sprint(block.Height)+" "+block.Nonce))
}
}
}
}
func get_gbt_msg(gbt *GbtNexaContext) []byte {
height, err := gbt.GbtCtx.Client.GetBlockCount()
if err != nil {
logg.Info("[gbt]", zap.String("GetBlockCount ", err.Error()))
return nil
}
height = height + 1
rawmsgs := make([]json.RawMessage, 3)
param_str1 := `"` + "1000" + `"`
param_str2 := `"` + gbt.Config.Nexa.Addr + `"`
if len(gbt.GbtCtx.MinerAddrs) > 0 {
param_str2 = `"` + gbt.GbtCtx.MinerAddrs[gbt.GbtCtx.MinerAddrIndex] + `"`
gbt.GbtCtx.MinerAddrIndex = gbt.GbtCtx.MinerAddrIndex + 1
if gbt.GbtCtx.MinerAddrIndex >= len(gbt.GbtCtx.MinerAddrs) {
gbt.GbtCtx.MinerAddrIndex = 0
}
}
param_str3 := `"` + " / m2pool.com / " + `"`
//logg.Debug("[gbt]", zap.String("option", param_str))
rawmsgs[0] = json.RawMessage(param_str1)
rawmsgs[1] = json.RawMessage(param_str2)
rawmsgs[2] = json.RawMessage(param_str3)
result, err := gbt.GbtCtx.Client.RawRequest("getminingcandidate", rawmsgs)
//log.Printf("[gbt] getminingcandidate %v %s\n", err, result)
if err != nil {
logg.Error("[gbt]", zap.String("getminingcandidate", err.Error()))
return nil
}
var rxmsg GbtNexaMsg
err = json.Unmarshal(result, &rxmsg)
if err != nil {
logg.Error("[gbt]", zap.String("getminingcandidate", err.Error()))
return nil
}
gbtstr := fmt.Sprintf("[gbt] height %d, id %d, header %s, nBits %s", height, rxmsg.Id, rxmsg.HeaderCommitment, rxmsg.NBits)
//logg.Debug("[gbt]", zap.String(" ", gbtstr))
if rxmsg.Id == gbt.last_gbt.Id {
return nil
}
gbt.last_gbt = rxmsg
gbt.last_time = time.Now()
nbits_b, _ := hex.DecodeString(rxmsg.NBits)
var nbits_i uint32 = binary.BigEndian.Uint32(nbits_b)
bigdiff := utility.CompactToBig(nbits_i)
targetdiff := fmt.Sprintf("%064x", bigdiff.Bytes())
//logg.Debug("[gbt]", zap.String("target", targetdiff))
logg.Debug("[gbt]", zap.String(" ", gbtstr), zap.String("target", targetdiff))
var job msg.NexaStratumJob
job.Id = rxmsg.Id
job.Header = utility.Reverse_string(rxmsg.HeaderCommitment)
job.NBits = rxmsg.NBits
job.CurTime = uint64(time.Now().Unix())
job.Height = uint32(height)
job.Nonce = ""
job.Target = targetdiff
job.Extranonce1 = ""
job.Extranonce2_size = 8
job.Extranonce2 = ""
body, err := json.Marshal(job)
if err != nil {
logg.Error("[gbt]", zap.String("failed to Marshal jobmsg", err.Error()))
return nil
}
return body
}
func gbt_notify_running(gbt *GbtNexaContext) {
for {
if !gbt.GbtCtx.Started {
break
}
if gbt.GbtCtx.NodeSubCh == nil {
gbt.GbtCtx.NodeSubCh = utility.InitZmqSub(gbt.GbtCtx.Config.Rpc.ZmqSub, utility.BITCOIND_ZMQ_HASHBLOCK)
}
if gbt.GbtCtx.NodeSubCh != nil {
cmsg_sub, err := gbt.GbtCtx.NodeSubCh.RecvMessage()
if err != nil {
if !gbt.GbtCtx.Started {
break
}
gbt.GbtCtx.NodeSubCh.SetSubscribe(utility.BITCOIND_ZMQ_HASHBLOCK)
gbt.GbtCtx.NodeSubCh.Connect(gbt.GbtCtx.Config.Rpc.ZmqSub)
continue
}
if len(cmsg_sub) >= 2 {
if string(cmsg_sub[0]) == "hashblock" {
GbtNexaCtx.new_block_index = GbtNexaCtx.new_block_index + 1
//log.Println("gbt_notify_running", hex.EncodeToString(cmsg_sub[1]), GbtNexaCtx.new_block_index)
gbt.new_block_chan <- GbtNexaCtx.new_block_index
}
}
} else {
logg.Error("[gbt]", zap.String("notify", "NodeSubCh fail!"))
time.Sleep(time.Duration(1) * time.Second)
}
}
}
func gbt_running(gbt *GbtNexaContext) {
gbtmsg := get_gbt_msg(gbt)
if gbtmsg != nil {
if gbt.GbtCtx.PubCh == nil {
gbt.GbtCtx.PubCh = utility.InitZmqPub(gbt.GbtCtx.Config.Zmq.Pub)
}
if gbt.GbtCtx.PubCh != nil {
for trycnt := 0; trycnt < 3; trycnt++ {
err := gbt.GbtCtx.PubCh.SendMessage([][]byte{[]byte("jobnexa"), gbtmsg})
if err != nil {
if !gbt.GbtCtx.Started {
return
}
//gbt.GbtCtx.PubCh.Bind(gbt.GbtCtx.Config.Zmq.Pub)
logg.Warn("[gbt]", zap.String("job ", err.Error()))
} else {
//gbt.GbtCtx.PubCh.SendChan <- [][]byte{[]byte("jobnexa"), gbtmsg}
logg.Warn("[gbt]", zap.String("job ", "sent"))
break
}
}
//gbt.GbtCtx.AlivingChan <- true
atomic.StoreInt32(&(gbt.GbtCtx.FlagAliving), 1)
} else {
logg.Warn("[gbt]", zap.String("job ", "sent failed! PubCh nil"))
}
} else {
atomic.StoreInt32(&(gbt.GbtCtx.FlagAliving), 1)
}
timer := time.NewTimer(time.Duration(gbt.GbtCtx.Config.Rpc.Timeout) * time.Millisecond)
defer timer.Stop()
for {
if !gbt.GbtCtx.Started {
break
}
new_block_notify := false
select {
case blk_idx := <-gbt.new_block_chan:
log.Println("new block chan", blk_idx)
new_block_notify = true
if !timer.Stop() {
<-timer.C
}
timer.Reset(time.Duration(gbt.GbtCtx.Config.Rpc.Timeout) * time.Millisecond)
case <-gbt.GbtCtx.ExitGbtChan:
logg.Error("[gbt]", zap.String("gbt", "exit"))
return
case <-time.After(time.Duration(gbt.GbtCtx.Config.Rpc.Timeout) * time.Millisecond):
log.Println("poll gbt timeout")
timer.Reset(time.Duration(gbt.GbtCtx.Config.Rpc.Timeout) * time.Millisecond)
}
/*if check_bestblockhash(gbt) {*/
gbtmsg := get_gbt_msg(gbt)
if gbtmsg != nil {
//check_preblock(gbt, DbCtx)
if gbt.GbtCtx.PubCh == nil {
gbt.GbtCtx.PubCh = utility.InitZmqPub(gbt.GbtCtx.Config.Zmq.Pub)
}
if gbt.GbtCtx.PubCh != nil {
for trycnt := 0; trycnt < 3; trycnt++ {
err := gbt.GbtCtx.PubCh.SendMessage([][]byte{[]byte("jobnexa"), gbtmsg})
if err != nil {
logg.Warn("[gbt]", zap.String("job ", err.Error()))
continue
} else {
//gbt.GbtCtx.PubCh.SendChan <- [][]byte{[]byte("jobnexa"), gbtmsg}
logg.Warn("[gbt]", zap.String("job ", "sent"))
break
}
}
//gbt.GbtCtx.AlivingChan <- true
atomic.StoreInt32(&(gbt.GbtCtx.FlagAliving), 1)
} else {
logg.Warn("[gbt]", zap.String("job ", "sent failed! PubCh nil"))
}
} else {
atomic.StoreInt32(&(gbt.GbtCtx.FlagAliving), 1)
}
if new_block_notify {
update_block_confirm(gbt)
}
}
}
func nexaInit(config *NexaConfig) {
data, err := ioutil.ReadFile("gbt.conf")
if err != nil {
panic(err.Error())
}
if err = json.Unmarshal(data, &config); err != nil {
panic(err.Error())
}
}
func Init(GbtCtx *coin.GbtContext, DbCtx *db.DbContext) {
GbtNexaCtx.GbtCtx = GbtCtx
GbtNexaCtx.last_height = 0
nexaInit(&GbtNexaCtx.Config)
GbtNexaCtx.Target = make([]byte, 32)
GbtNexaCtx.Header = make([]byte, 49)
GbtNexaCtx.last_time = time.Now()
logg = GbtCtx.Log
GbtNexaCtx.new_block_chan = make(chan int, 256)
GbtNexaCtx.new_block_index = 0
logg.Info("[gbt]", zap.String("gbt_nexa_version", GBT_NEXA_VERSION))
rawmsgs := make([]json.RawMessage, 1)
pool_tag := " / m2pool.com / "
param_str := `"` + pool_tag + `"`
rawmsgs[0] = json.RawMessage(param_str)
_, err := GbtNexaCtx.GbtCtx.Client.RawRequest("setminercomment", rawmsgs)
if err != nil {
//log.Printf("setminercomment %s", err.Error())
logg.Error("[gbt]", zap.String("setminercomment", err.Error()))
}
}
func Start() {
go gbt_running(&GbtNexaCtx)
go gbt_notify_running(&GbtNexaCtx)
go submit_block_running(&GbtNexaCtx)
}
func Stop() {
defer close(GbtNexaCtx.new_block_chan)
}
func new_block_into_db(block *GbtNexaContext, user string, miner string, minerid string, height int64, nonce string, hash string, subidx int64) bool {
db, err := sql.Open("sqlite3", "./blocks.db")
if err != nil {
log.Printf("Error opening database: %v", err)
return false
}
defer db.Close()
createTableSQL := `
CREATE TABLE IF NOT EXISTS blocks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user TEXT NOT NULL,
miner TEXT NOT NULL,
minerid TEXT NOT NULL,
height INTEGER,
nonce TEXT NOT NULL,
hash TEXT NOT NULL,
subidx INTEGER,
checked INTEGER,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);`
_, err = db.Exec(createTableSQL)
if err != nil {
log.Printf("Error creating table: %v", err)
return false
}
insertSQL := `INSERT INTO blocks (user, miner, minerid, height, nonce, checked, hash, subidx) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`
_, err = db.Exec(insertSQL, user, miner, minerid, height, nonce, 0, hash, subidx)
if err != nil {
log.Printf("Error inserting data from blocks %s: %v", fmt.Sprint(height), err)
return false
}
return true
}
func submit_block_running(block *GbtNexaContext) {
logg.Info("[block]", zap.String("submit_block_running", "Start."))
for {
if !block.GbtCtx.Started {
break
}
if block.GbtCtx.SubCh == nil {
block.GbtCtx.SubCh = utility.InitZmqSub(block.GbtCtx.Config.Zmq.Sub, "blk"+block.GbtCtx.Coin)
}
if block.GbtCtx.SubCh != nil {
cmsg_sub, err := block.GbtCtx.SubCh.RecvMessage()
if err != nil {
if !block.GbtCtx.Started {
break
}
time.Sleep(time.Duration(1) * time.Second)
/*block.GbtCtx.SubCh.Destroy()
block.GbtCtx.SubCh = nil*/
block.GbtCtx.SubCh.SetSubscribe("blk" + block.GbtCtx.Coin)
block.GbtCtx.SubCh.Connect(block.GbtCtx.Config.Zmq.Sub)
//block.GbtCtx.SubCh.Destroy()
//block.GbtCtx.SubCh = utility.InitZmqSub(block.GbtCtx.Config.Zmq.Sub, "blk"+block.GbtCtx.Coin)
continue
}
//log.Println(cmsg_sub, len(cmsg_sub), block.GbtCtx.SubCh)
if len(cmsg_sub) >= 2 {
if string(cmsg_sub[0]) == "blknexa" {
cmsg := cmsg_sub[1]
//block data
msgb := make([]byte, len(cmsg)-16)
copy(msgb, cmsg)
//height
//heightb := make([]byte, 4)
heightb, err := hex.DecodeString(string(cmsg[len(msgb) : len(msgb)+8]))
if err != nil {
//block.Consumer.MarkOffset(cmsg, "")
logg.Error("[block]", zap.String("failed to decode height", err.Error()))
continue
}
var height uint32 = utility.ByteToUint32(heightb)
logg.Warn("[block]", zap.Uint32("height", height))
if height <= block.last_height {
continue
}
block.last_height = height
//index
//indexb := make([]byte, 4)
indexb, err1 := hex.DecodeString(string(cmsg[len(msgb)+8:]))
if err1 != nil {
//block.Consumer.MarkOffset(cmsg, "")
logg.Error("[block]", zap.String("failed to decode index", err1.Error()))
continue
}
//copy(indexb, cmsg.Value[len(msgb)+4:])
var index uint32 = utility.ByteToUint32(indexb)
logg.Warn("[block]", zap.Uint32("index", index))
logg.Debug("[block]", zap.String("msg", string(cmsg)), zap.String("blk", string(msgb)))
var nexablock msg.BlockNexaMsg
if err := json.Unmarshal(msgb, &nexablock); err != nil {
//block.Consumer.MarkOffset(cmsg, "")
logg.Error("[block]", zap.String("failed to Unmarshal job", err.Error()))
continue
}
blk := fmt.Sprintf(`{"id":%d,"nonce":"%s"}`, nexablock.Id, nexablock.Nonce)
rawmsgs := make([]json.RawMessage, 1)
logg.Info("[block]", zap.String("blk", blk))
rawmsgs[0] = json.RawMessage(blk)
//var last_result json.RawMessage
//for i := 0; i < len(block.Client); i++ {
result, err := block.GbtCtx.Client.RawRequest("submitminingsolution", rawmsgs)
if err != nil {
logg.Error("[block]", zap.String("submitminingsolution", err.Error()))
} else {
//last_result = result
}
logg.Info("[block]", zap.String("result", string(result)))
//}
/*dbif.NotifyMinerSubmitResult(block.GbtCtx, nexablock.User, nexablock.Miner, nexablock.Index, int64(height), nexablock.Pow, string(result), nexablock.Nonce, nexablock.SubIdx)
dbif.NotifyUsersBlkStatsSubmitResult(block.GbtCtx, nexablock.User, int64(height), nexablock.Pow, string(result), nexablock.Nonce, nexablock.SubIdx)*/
dbif.NotifyPoolBlkStatsSubmitResult(block.GbtCtx, int64(height), nexablock.Pow, string(result), nexablock.Nonce, nexablock.SubIdx)
block.Submits += 1
//log.Printf("[block] height %d subidx %d nonce %s\n", height, nexablock.SubIdx, nexablock.Nonce)
logg.Warn("[block]", zap.Float64("total submits", block.Submits), zap.Int64("SubIdx", nexablock.SubIdx))
new_block_into_db(block, nexablock.User, nexablock.Miner, nexablock.Index, int64(height), nexablock.Nonce, nexablock.Pow, nexablock.SubIdx)
}
}
} else {
logg.Error("[block]", zap.String("block", "SubCh failed! retry"))
time.Sleep(time.Duration(1) * time.Second)
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,600 @@
// Copyright 2020. The Tari Project
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
// following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
// disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
// following disclaimer in the documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
// products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto3";
import "types.proto";
import "transaction.proto";
import "block.proto";
import "network.proto";
import "sidechain_types.proto";
package tari.rpc;
// The gRPC interface for interacting with the base node.
service BaseNode {
// Lists headers in the current best chain
rpc ListHeaders(ListHeadersRequest) returns (stream BlockHeaderResponse);
// Get header by hash
rpc GetHeaderByHash(GetHeaderByHashRequest) returns (BlockHeaderResponse);
// Returns blocks in the current best chain. Currently only supports querying by height
rpc GetBlocks(GetBlocksRequest) returns (stream HistoricalBlock);
// Returns the block timing for the chain heights
rpc GetBlockTiming(HeightRequest) returns (BlockTimingResponse);
// Returns the network Constants
rpc GetConstants(BlockHeight) returns (ConsensusConstants);
// Returns Block Sizes
rpc GetBlockSize (BlockGroupRequest) returns (BlockGroupResponse);
// Returns Block Fees
rpc GetBlockFees (BlockGroupRequest) returns (BlockGroupResponse);
// Get Version
rpc GetVersion(Empty) returns (StringValue);
// Check for new updates
rpc CheckForUpdates(Empty) returns (SoftwareUpdate);
// Get coins in circulation
rpc GetTokensInCirculation(GetBlocksRequest) returns (stream ValueAtHeightResponse);
// Get network difficulties
rpc GetNetworkDifficulty(HeightRequest) returns (stream NetworkDifficultyResponse);
// Get the block template
rpc GetNewBlockTemplate(NewBlockTemplateRequest) returns (NewBlockTemplateResponse);
// Construct a new block from a provided template
rpc GetNewBlock(NewBlockTemplate) returns (GetNewBlockResult);
// Construct a new block from a provided template
rpc GetNewBlockWithCoinbases(GetNewBlockWithCoinbasesRequest) returns (GetNewBlockResult);
// Construct a new block from a provided template
rpc GetNewBlockTemplateWithCoinbases(GetNewBlockTemplateWithCoinbasesRequest) returns (GetNewBlockResult);
// Construct a new block and header blob from a provided template
rpc GetNewBlockBlob(NewBlockTemplate) returns (GetNewBlockBlobResult);
// Submit a new block for propagation
rpc SubmitBlock(Block) returns (SubmitBlockResponse);
// Submit a new mined block blob for propagation
rpc SubmitBlockBlob(BlockBlobRequest) returns (SubmitBlockResponse);
// Submit a transaction for propagation
rpc SubmitTransaction(SubmitTransactionRequest) returns (SubmitTransactionResponse);
// Get the base node sync information
rpc GetSyncInfo(Empty) returns (SyncInfoResponse);
// Get the base node sync information
rpc GetSyncProgress(Empty) returns (SyncProgressResponse);
// Get the base node tip information
rpc GetTipInfo(Empty) returns (TipInfoResponse);
// Search for blocks containing the specified kernels
rpc SearchKernels(SearchKernelsRequest) returns (stream HistoricalBlock);
// Search for blocks containing the specified commitments
rpc SearchUtxos(SearchUtxosRequest) returns (stream HistoricalBlock);
// Fetch any utxos that exist in the main chain
rpc FetchMatchingUtxos(FetchMatchingUtxosRequest) returns (stream FetchMatchingUtxosResponse);
// get all peers from the base node
rpc GetPeers(GetPeersRequest) returns (stream GetPeersResponse);
rpc GetMempoolTransactions(GetMempoolTransactionsRequest) returns (stream GetMempoolTransactionsResponse);
rpc TransactionState(TransactionStateRequest) returns (TransactionStateResponse);
// This returns the node's network identity
rpc Identify (Empty) returns (NodeIdentity);
// Get Base Node network connectivity status
rpc GetNetworkStatus(Empty) returns (NetworkStatusResponse);
// List currently connected peers
rpc ListConnectedPeers(Empty) returns (ListConnectedPeersResponse);
// Get mempool stats
rpc GetMempoolStats(Empty) returns (MempoolStatsResponse);
// Get VNs
rpc GetActiveValidatorNodes(GetActiveValidatorNodesRequest) returns (stream GetActiveValidatorNodesResponse);
rpc GetShardKey(GetShardKeyRequest) returns (GetShardKeyResponse);
// Get templates
rpc GetTemplateRegistrations(GetTemplateRegistrationsRequest) returns (stream GetTemplateRegistrationResponse);
rpc GetSideChainUtxos(GetSideChainUtxosRequest) returns (stream GetSideChainUtxosResponse);
rpc GetNetworkState(GetNetworkStateRequest) returns (GetNetworkStateResponse);
// PayRef (Payment Reference) lookup for block explorers and external services
rpc SearchPaymentReferences(SearchPaymentReferencesRequest) returns (stream PaymentReferenceResponse);
}
message GetAssetMetadataRequest {
bytes asset_public_key = 1;
}
message GetAssetMetadataResponse {
string name = 2;
string description =3;
string image = 4;
bytes owner_commitment = 5;
OutputFeatures features = 6;
uint64 mined_height = 7;
bytes mined_in_block = 8;
}
message ListAssetRegistrationsRequest {
uint64 offset = 2;
uint64 count = 3;
}
message ListAssetRegistrationsResponse {
bytes asset_public_key = 1;
bytes unique_id = 2;
bytes owner_commitment = 3;
uint64 mined_height = 4;
bytes mined_in_block = 5;
OutputFeatures features = 6;
bytes script = 7;
}
message GetTokensRequest {
bytes asset_public_key = 1;
// Optionally get a set of specific unique_ids
repeated bytes unique_ids = 2;
}
message GetTokensResponse {
bytes unique_id = 1;
bytes asset_public_key = 2;
bytes owner_commitment = 3;
bytes mined_in_block = 4;
uint64 mined_height = 5;
OutputFeatures features = 6;
bytes script = 7;
}
message SubmitBlockResponse {
bytes block_hash = 1;
}
message BlockBlobRequest{
bytes header_blob = 1;
bytes body_blob = 2;
}
/// return type of GetTipInfo
message TipInfoResponse {
MetaData metadata = 1;
bool initial_sync_achieved = 2;
BaseNodeState base_node_state = 3;
bool failed_checkpoints = 4;
}
enum BaseNodeState{
START_UP = 0;
HEADER_SYNC = 1;
HORIZON_SYNC = 2;
CONNECTING = 3;
BLOCK_SYNC = 4;
LISTENING = 5;
SYNC_FAILED = 6;
}
/// return type of GetNewBlockTemplate
message NewBlockTemplateResponse {
NewBlockTemplate new_block_template = 1;
bool initial_sync_achieved = 3;
MinerData miner_data = 4;
}
/// return type of NewBlockTemplateRequest
message NewBlockTemplateRequest{
PowAlgo algo = 1;
//This field should be moved to optional once optional keyword is standard
uint64 max_weight = 2;
}
/// return type of NewBlockTemplateRequest
message GetNewBlockTemplateWithCoinbasesRequest{
PowAlgo algo = 1;
//This field should be moved to optional once optional keyword is standard
uint64 max_weight = 2;
repeated NewBlockCoinbase coinbases = 3;
}
/// request type of GetNewBlockWithCoinbasesRequest
message GetNewBlockWithCoinbasesRequest{
NewBlockTemplate new_template = 1;
repeated NewBlockCoinbase coinbases = 2;
}
message NewBlockCoinbase{
string address = 1;
uint64 value = 2;
bool stealth_payment= 3;
bool revealed_value_proof= 4;
bytes coinbase_extra =5;
}
// Network difficulty response
message NetworkDifficultyResponse {
uint64 difficulty = 1;
uint64 estimated_hash_rate = 2;
uint64 height = 3;
uint64 timestamp = 4;
uint64 pow_algo = 5;
uint64 sha3x_estimated_hash_rate = 6;
uint64 monero_randomx_estimated_hash_rate = 7;
uint64 tari_randomx_estimated_hash_rate = 10;
uint64 num_coinbases = 8;
repeated bytes coinbase_extras = 9;
}
// A generic single value response for a specific height
message ValueAtHeightResponse {
// uint64 circulating_supply = 1; // No longer used
// uint64 spendable_supply = 2; // No longer used
uint64 height = 3;
uint64 mined_rewards = 4;
uint64 spendable_rewards = 5;
uint64 spendable_pre_mine = 6;
uint64 total_spendable = 7;
}
// A generic uint value
message IntegerValue {
uint64 value = 1;
}
// A generic String value
message StringValue {
string value = 1;
}
/// GetBlockSize / GetBlockFees Request
/// Either the starting and ending heights OR the from_tip param must be specified
message BlockGroupRequest {
// The height from the chain tip (optional)
uint64 from_tip = 1;
// The starting height (optional)
uint64 start_height = 2;
// The ending height (optional)
uint64 end_height = 3;
/// The type of calculation required (optional)
/// Defaults to median
/// median, mean, quartile, quantile
CalcType calc_type = 4;
}
/// GetBlockSize / GetBlockFees Response
message BlockGroupResponse {
repeated double value = 1;
CalcType calc_type = 2;
}
enum CalcType {
MEAN = 0;
MEDIAN = 1;
QUANTILE = 2;
QUARTILE = 3;
}
// The request used for querying a function that requires a height, either between 2 points or from the chain tip
// If start_height and end_height are set and > 0, they take precedence, otherwise from_tip is used
message HeightRequest {
// The height from the chain tip (optional)
uint64 from_tip = 1;
// The starting height (optional)
uint64 start_height = 2;
// The ending height (optional)
uint64 end_height = 3;
}
// The return type of the rpc GetBlockTiming
message BlockTimingResponse {
uint64 max = 1;
uint64 min = 2;
double avg = 3;
}
// Request that returns a header based by hash
message GetHeaderByHashRequest {
// The hash of the block header
bytes hash = 1;
}
message BlockHeaderResponse {
// The block header
BlockHeader header = 1;
// The number of blocks from the tip of this block (a.k.a depth)
uint64 confirmations = 2;
// The block reward i.e mining reward + fees
uint64 reward = 3;
// Achieved difficulty
uint64 difficulty = 4;
// The number of transactions contained in the block
uint32 num_transactions = 5;
}
// The request used for querying headers from the base node. The parameters `from_height` and `num_headers` can be used
// to page through the current best chain.
message ListHeadersRequest {
// The height to start at. Depending on sorting, will either default to use the tip or genesis block, for `SORTING_DESC`
// and `SORTING_ASC` respectively, if a value is not provided. The first header returned will be at this height
// followed by `num_headers` - 1 headers in the direction specified by `sorting`. If greater than the current tip,
// the current tip will be used.
uint64 from_height = 1;
// The number of headers to return. If not specified, it will default to 10
uint64 num_headers = 2;
// The ordering to return the headers in. If not specified will default to SORTING_DESC. Note that if `from_height`
// is not specified or is 0, if `sorting` is SORTING_DESC, the tip will be used as `from_height`, otherwise the
// block at height 0 will be used.
Sorting sorting = 3;
}
// The request used for querying blocks in the base node's current best chain. Currently only querying by height is
// available. Multiple blocks may be queried.e.g. [189092,100023,122424]. The order in which they are returned is not
// guaranteed.
message GetBlocksRequest {
repeated uint64 heights = 1;
}
// The return type of the rpc GetBlocks. Blocks are not guaranteed to be returned in the order requested.
message GetBlocksResponse {
repeated HistoricalBlock blocks = 1;
}
enum Sorting {
SORTING_DESC = 0;
SORTING_ASC = 1;
}
message MetaData {
// The current chain height, or the block number of the longest valid chain, or `None` if there is no chain
uint64 best_block_height = 1;
// The block hash of the current tip of the longest valid chain, or `None` for an empty chain
bytes best_block_hash = 2;
// The current geometric mean of the pow of the chain tip, or `None` if there is no chain
bytes accumulated_difficulty = 5;
// This is the min height this node can provide complete blocks for. A 0 here means this node is archival and can provide complete blocks for every height.
uint64 pruned_height = 6;
uint64 timestamp = 7;
}
message SyncInfoResponse {
uint64 tip_height = 1;
uint64 local_height = 2;
repeated bytes peer_node_id = 3;
}
message SyncProgressResponse {
uint64 tip_height = 1;
uint64 local_height = 2;
SyncState state = 3;
string short_desc = 4;
uint64 initial_connected_peers = 5;
}
enum SyncState {
STARTUP = 0;
HEADER_STARTING = 1;
HEADER = 2;
BLOCK_STARTING = 3;
BLOCK = 4;
DONE = 5;
}
// This is the message that is returned for a miner after it asks for a new block.
message GetNewBlockResult{
// This is the header hash of the completed block
bytes block_hash = 1;
// This is the completed block
Block block = 2;
bytes merge_mining_hash =3;
bytes tari_unique_id =4;
MinerData miner_data = 5;
bytes vm_key = 6;
}
// This is the message that is returned for a miner after it asks for a new block.
message GetNewBlockBlobResult{
// This is the header hash of the completed block
bytes block_hash = 1;
// This is the completed block's header
bytes header = 2;
// This is the completed block's body
bytes block_body = 3;
bytes merge_mining_hash =4;
bytes utxo_mr = 5;
bytes tari_unique_id =6;
}
// This is mining data for the miner asking for a new block
message MinerData{
PowAlgo algo = 1;
uint64 target_difficulty = 2;
uint64 reward = 3;
// bytes merge_mining_hash =4;
uint64 total_fees = 5;
}
// This is the request type for the Search Kernels rpc
message SearchKernelsRequest{
repeated Signature signatures = 1;
}
// This is the request type for the Search Utxo rpc
message SearchUtxosRequest{
repeated bytes commitments = 1;
}
message FetchMatchingUtxosRequest {
repeated bytes hashes = 1;
}
message FetchMatchingUtxosResponse {
TransactionOutput output = 1;
}
// This is the request type of the get all peers rpc call
message GetPeersResponse{
Peer peer = 1;
}
message GetPeersRequest{}
message SubmitTransactionRequest {
Transaction transaction = 1;
}
message SubmitTransactionResponse {
SubmitTransactionResult result =1;
}
enum SubmitTransactionResult {
NONE = 0;
ACCEPTED = 1;
NOT_PROCESSABLE_AT_THIS_TIME = 2;
ALREADY_MINED = 3;
REJECTED = 4;
}
message GetMempoolTransactionsRequest {
}
message GetMempoolTransactionsResponse {
Transaction transaction = 1;
}
message TransactionStateRequest {
Signature excess_sig = 1;
}
message TransactionStateResponse {
TransactionLocation result =1;
}
enum TransactionLocation {
UNKNOWN = 0;
MEMPOOL = 1;
MINED = 2;
NOT_STORED = 3;
}
message MempoolStatsResponse {
uint64 unconfirmed_txs = 2;
uint64 reorg_txs = 3;
uint64 unconfirmed_weight = 4;
}
message GetActiveValidatorNodesRequest {
uint64 height = 1;
}
message GetActiveValidatorNodesResponse {
bytes shard_key = 1;
bytes public_key = 2;
}
message GetShardKeyRequest {
uint64 height = 1;
bytes public_key = 2;
}
message GetShardKeyResponse {
bytes shard_key = 1;
bool found = 2;
}
message GetTemplateRegistrationsRequest {
bytes start_hash = 1;
uint64 count = 2;
}
message GetTemplateRegistrationResponse {
bytes utxo_hash = 1;
TemplateRegistration registration = 2;
}
message BlockInfo {
uint64 height = 1;
bytes hash = 2;
bytes next_block_hash = 3;
}
message GetSideChainUtxosRequest {
bytes start_hash = 1;
uint64 count = 2;
}
message GetSideChainUtxosResponse {
BlockInfo block_info = 1;
repeated TransactionOutput outputs = 2;
}
message GetNetworkStateRequest {
}
message GetNetworkStateResponse {
// metadata
MetaData metadata = 1;
// has the base node synced
bool initial_sync_achieved = 2;
//current state of the base node
BaseNodeState base_node_state = 3;
// do we have failed checkpoints
bool failed_checkpoints = 4;
// The block reward of the next tip
uint64 reward = 5;
// estimate sha3x hash rate
uint64 sha3x_estimated_hash_rate = 6;
// estimate randomx hash rate
uint64 monero_randomx_estimated_hash_rate = 7;
uint64 tari_randomx_estimated_hash_rate = 10;
// number of connections
uint64 num_connections = 8;
//liveness results
repeated LivenessResult liveness_results = 9;
}
message LivenessResult{
// node id
bytes peer_node_id = 1;
// time to discover
uint64 discover_latency = 2;
// Dial latency
uint64 ping_latency = 3;
}
// PayRef (Payment Reference) search and lookup messages
// Request to search for outputs by payment reference
message SearchPaymentReferencesRequest {
// Payment reference as hex string (64 characters)
repeated string payment_reference_hex = 1;
repeated bytes payment_reference_bytes = 2;
// Optional: include spent outputs in results
bool include_spent = 3;
}
// Response containing payment reference match
message PaymentReferenceResponse {
// The payment reference that was found
string payment_reference_hex = 1;
// Block height where the output was mined
uint64 block_height = 2;
// Block hash where the output was mined
bytes block_hash = 3;
// Timestamp when the output was mined
uint64 mined_timestamp = 4;
// Output commitment (32 bytes)
bytes commitment = 5;
// Whether this output has been spent
bool is_spent = 6;
// Height where output was spent (if spent)
uint64 spent_height = 7;
// Block hash where output was spent (if spent)
bytes spent_block_hash = 8;
// Transaction output amount will be 0 for non set a
uint64 min_value_promise = 9;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,142 @@
// Copyright 2020. The Tari Project
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
// following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
// disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
// following disclaimer in the documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
// products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto3";
package tari.rpc;
import "transaction.proto";
// The BlockHeader contains all the metadata for the block, including proof of work, a link to the previous block
// and the transaction kernels.
message BlockHeader {
// The hash of the block
bytes hash = 1;
// Version of the block
uint32 version = 2;
// Height of this block since the genesis block (height 0)
uint64 height = 3;
// Hash of the block previous to this in the chain.
bytes prev_hash = 4;
// Timestamp at which the block was built.
uint64 timestamp = 5;
// This is the UTXO merkle root of the outputs in the blockchain
bytes output_mr = 6;
// This is the merkle root of all outputs in this block
bytes block_output_mr = 7;
// This is the MMR root of the kernels
bytes kernel_mr = 8;
// This is the Merkle root of the inputs in this block
bytes input_mr = 9;
// Total accumulated sum of kernel offsets since genesis block. We can derive the kernel offset sum for *this*
// block from the total kernel offset of the previous block header.
bytes total_kernel_offset = 10;
// Nonce increment used to mine this block.
uint64 nonce = 11;
// Proof of work metadata
ProofOfWork pow = 12;
// Kernel MMR size
uint64 kernel_mmr_size = 13;
// Output MMR size
uint64 output_mmr_size = 14;
// Sum of script offsets for all kernels in this block.
bytes total_script_offset = 15;
// Merkle root of validator nodes
bytes validator_node_mr = 16;
// Validator size
uint64 validator_node_size = 17;
}
// The proof of work data structure that is included in the block header.
message ProofOfWork {
// The algorithm used to mine this block
// 0 = Monero
// 1 = Sha3X
uint64 pow_algo = 1;
// Supplemental proof of work data. For example for Sha3x, this would be empty (only the block header is
// required), but for Monero merge mining we need the Monero block header and RandomX seed hash.
bytes pow_data = 4;
}
//This is used to request the which pow algo should be used with the block template
message PowAlgo {
// The permitted pow algorithms
enum PowAlgos {
POW_ALGOS_RANDOMXM = 0; // Accessible as `grpc::pow_algo::PowAlgos::RandomxM`
POW_ALGOS_SHA3X = 1; // Accessible as `grpc::pow_algo::PowAlgos::Sha3x`
POW_ALGOS_RANDOMXT = 2; // Accessible as `grpc::pow_algo::PowAlgos::RandomxT`
}
// The pow algo to use
PowAlgos pow_algo = 1;
}
// A Minotari block. Blocks are linked together into a blockchain.
message Block {
// The BlockHeader contains all the metadata for the block, including proof of work, a link to the previous block
// and the transaction kernels.
BlockHeader header = 1;
// The components of the block or transaction. The same struct can be used for either, since in Mimblewimble,
// blocks consist of inputs, outputs and kernels, rather than transactions.
AggregateBody body = 2;
}
// The representation of a historical block in the blockchain. It is essentially identical to a protocol-defined
// block but contains some extra metadata that clients such as Block Explorers will find interesting.
message HistoricalBlock {
// The number of blocks that have been mined since this block, including this one. The current tip will have one
// confirmation.
uint64 confirmations = 1;
// The underlying block
Block block = 2;
}
// The NewBlockHeaderTemplate is used for the construction of a new mine-able block. It contains all the metadata for the block that the Base Node is able to complete on behalf of a Miner.
message NewBlockHeaderTemplate {
// Version of the block
uint32 version = 1;
// Height of this block since the genesis block (height 0)
uint64 height = 2;
// Hash of the block previous to this in the chain.
bytes prev_hash = 3;
// Total accumulated sum of kernel offsets since genesis block. We can derive the kernel offset sum for *this*
// block from the total kernel offset of the previous block header.
bytes total_kernel_offset = 4;
// Proof of work metadata
ProofOfWork pow = 5;
// Sum of script offsets for all kernels in this block.
bytes total_script_offset = 7;
}
// The new block template is used constructing a new partial block, allowing a miner to added the coinbase utxo and as a final step the Base node to add the MMR roots to the header.
message NewBlockTemplate {
// The NewBlockHeaderTemplate is used for the construction of a new mineable block. It contains all the metadata for
// the block that the Base Node is able to complete on behalf of a Miner.
NewBlockHeaderTemplate header = 1;
// This flag indicates if the inputs, outputs and kernels have been sorted internally, that is, the sort() method
// has been called. This may be false even if all components are sorted.
AggregateBody body = 2;
// Sometimes the mempool has not synced to the latest tip, this flag indicates if the mempool is out of sync.
// In most cases the next call to get_new_block_template will return a block with the mempool in sync.
bool is_mempool_in_sync = 3;
}

View File

@@ -0,0 +1,783 @@
// Copyright 2020. The Tari Project
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
// following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
// disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
// following disclaimer in the documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
// products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.6
// protoc v3.6.1
// source: block.proto
package block
import (
transaction "pool/internal/gbt/tari/proto/transaction"
reflect "reflect"
sync "sync"
unsafe "unsafe"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// The permitted pow algorithms
type PowAlgo_PowAlgos int32
const (
PowAlgo_POW_ALGOS_RANDOMXM PowAlgo_PowAlgos = 0 // Accessible as `grpc::pow_algo::PowAlgos::RandomxM`
PowAlgo_POW_ALGOS_SHA3X PowAlgo_PowAlgos = 1 // Accessible as `grpc::pow_algo::PowAlgos::Sha3x`
PowAlgo_POW_ALGOS_RANDOMXT PowAlgo_PowAlgos = 2 // Accessible as `grpc::pow_algo::PowAlgos::RandomxT`
)
// Enum value maps for PowAlgo_PowAlgos.
var (
PowAlgo_PowAlgos_name = map[int32]string{
0: "POW_ALGOS_RANDOMXM",
1: "POW_ALGOS_SHA3X",
2: "POW_ALGOS_RANDOMXT",
}
PowAlgo_PowAlgos_value = map[string]int32{
"POW_ALGOS_RANDOMXM": 0,
"POW_ALGOS_SHA3X": 1,
"POW_ALGOS_RANDOMXT": 2,
}
)
func (x PowAlgo_PowAlgos) Enum() *PowAlgo_PowAlgos {
p := new(PowAlgo_PowAlgos)
*p = x
return p
}
func (x PowAlgo_PowAlgos) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (PowAlgo_PowAlgos) Descriptor() protoreflect.EnumDescriptor {
return file_block_proto_enumTypes[0].Descriptor()
}
func (PowAlgo_PowAlgos) Type() protoreflect.EnumType {
return &file_block_proto_enumTypes[0]
}
func (x PowAlgo_PowAlgos) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use PowAlgo_PowAlgos.Descriptor instead.
func (PowAlgo_PowAlgos) EnumDescriptor() ([]byte, []int) {
return file_block_proto_rawDescGZIP(), []int{2, 0}
}
// The BlockHeader contains all the metadata for the block, including proof of work, a link to the previous block
// and the transaction kernels.
type BlockHeader struct {
state protoimpl.MessageState `protogen:"open.v1"`
// The hash of the block
Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"`
// Version of the block
Version uint32 `protobuf:"varint,2,opt,name=version,proto3" json:"version,omitempty"`
// Height of this block since the genesis block (height 0)
Height uint64 `protobuf:"varint,3,opt,name=height,proto3" json:"height,omitempty"`
// Hash of the block previous to this in the chain.
PrevHash []byte `protobuf:"bytes,4,opt,name=prev_hash,json=prevHash,proto3" json:"prev_hash,omitempty"`
// Timestamp at which the block was built.
Timestamp uint64 `protobuf:"varint,5,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
// This is the UTXO merkle root of the outputs in the blockchain
OutputMr []byte `protobuf:"bytes,6,opt,name=output_mr,json=outputMr,proto3" json:"output_mr,omitempty"`
// This is the merkle root of all outputs in this block
BlockOutputMr []byte `protobuf:"bytes,7,opt,name=block_output_mr,json=blockOutputMr,proto3" json:"block_output_mr,omitempty"`
// This is the MMR root of the kernels
KernelMr []byte `protobuf:"bytes,8,opt,name=kernel_mr,json=kernelMr,proto3" json:"kernel_mr,omitempty"`
// This is the Merkle root of the inputs in this block
InputMr []byte `protobuf:"bytes,9,opt,name=input_mr,json=inputMr,proto3" json:"input_mr,omitempty"`
// Total accumulated sum of kernel offsets since genesis block. We can derive the kernel offset sum for *this*
// block from the total kernel offset of the previous block header.
TotalKernelOffset []byte `protobuf:"bytes,10,opt,name=total_kernel_offset,json=totalKernelOffset,proto3" json:"total_kernel_offset,omitempty"`
// Nonce increment used to mine this block.
Nonce uint64 `protobuf:"varint,11,opt,name=nonce,proto3" json:"nonce,omitempty"`
// Proof of work metadata
Pow *ProofOfWork `protobuf:"bytes,12,opt,name=pow,proto3" json:"pow,omitempty"`
// Kernel MMR size
KernelMmrSize uint64 `protobuf:"varint,13,opt,name=kernel_mmr_size,json=kernelMmrSize,proto3" json:"kernel_mmr_size,omitempty"`
// Output MMR size
OutputMmrSize uint64 `protobuf:"varint,14,opt,name=output_mmr_size,json=outputMmrSize,proto3" json:"output_mmr_size,omitempty"`
// Sum of script offsets for all kernels in this block.
TotalScriptOffset []byte `protobuf:"bytes,15,opt,name=total_script_offset,json=totalScriptOffset,proto3" json:"total_script_offset,omitempty"`
// Merkle root of validator nodes
ValidatorNodeMr []byte `protobuf:"bytes,16,opt,name=validator_node_mr,json=validatorNodeMr,proto3" json:"validator_node_mr,omitempty"`
// Validator size
ValidatorNodeSize uint64 `protobuf:"varint,17,opt,name=validator_node_size,json=validatorNodeSize,proto3" json:"validator_node_size,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *BlockHeader) Reset() {
*x = BlockHeader{}
mi := &file_block_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *BlockHeader) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*BlockHeader) ProtoMessage() {}
func (x *BlockHeader) ProtoReflect() protoreflect.Message {
mi := &file_block_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use BlockHeader.ProtoReflect.Descriptor instead.
func (*BlockHeader) Descriptor() ([]byte, []int) {
return file_block_proto_rawDescGZIP(), []int{0}
}
func (x *BlockHeader) GetHash() []byte {
if x != nil {
return x.Hash
}
return nil
}
func (x *BlockHeader) GetVersion() uint32 {
if x != nil {
return x.Version
}
return 0
}
func (x *BlockHeader) GetHeight() uint64 {
if x != nil {
return x.Height
}
return 0
}
func (x *BlockHeader) GetPrevHash() []byte {
if x != nil {
return x.PrevHash
}
return nil
}
func (x *BlockHeader) GetTimestamp() uint64 {
if x != nil {
return x.Timestamp
}
return 0
}
func (x *BlockHeader) GetOutputMr() []byte {
if x != nil {
return x.OutputMr
}
return nil
}
func (x *BlockHeader) GetBlockOutputMr() []byte {
if x != nil {
return x.BlockOutputMr
}
return nil
}
func (x *BlockHeader) GetKernelMr() []byte {
if x != nil {
return x.KernelMr
}
return nil
}
func (x *BlockHeader) GetInputMr() []byte {
if x != nil {
return x.InputMr
}
return nil
}
func (x *BlockHeader) GetTotalKernelOffset() []byte {
if x != nil {
return x.TotalKernelOffset
}
return nil
}
func (x *BlockHeader) GetNonce() uint64 {
if x != nil {
return x.Nonce
}
return 0
}
func (x *BlockHeader) GetPow() *ProofOfWork {
if x != nil {
return x.Pow
}
return nil
}
func (x *BlockHeader) GetKernelMmrSize() uint64 {
if x != nil {
return x.KernelMmrSize
}
return 0
}
func (x *BlockHeader) GetOutputMmrSize() uint64 {
if x != nil {
return x.OutputMmrSize
}
return 0
}
func (x *BlockHeader) GetTotalScriptOffset() []byte {
if x != nil {
return x.TotalScriptOffset
}
return nil
}
func (x *BlockHeader) GetValidatorNodeMr() []byte {
if x != nil {
return x.ValidatorNodeMr
}
return nil
}
func (x *BlockHeader) GetValidatorNodeSize() uint64 {
if x != nil {
return x.ValidatorNodeSize
}
return 0
}
// The proof of work data structure that is included in the block header.
type ProofOfWork struct {
state protoimpl.MessageState `protogen:"open.v1"`
// The algorithm used to mine this block
//
// 0 = Monero
// 1 = Sha3X
PowAlgo uint64 `protobuf:"varint,1,opt,name=pow_algo,json=powAlgo,proto3" json:"pow_algo,omitempty"`
// Supplemental proof of work data. For example for Sha3x, this would be empty (only the block header is
// required), but for Monero merge mining we need the Monero block header and RandomX seed hash.
PowData []byte `protobuf:"bytes,4,opt,name=pow_data,json=powData,proto3" json:"pow_data,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ProofOfWork) Reset() {
*x = ProofOfWork{}
mi := &file_block_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ProofOfWork) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ProofOfWork) ProtoMessage() {}
func (x *ProofOfWork) ProtoReflect() protoreflect.Message {
mi := &file_block_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ProofOfWork.ProtoReflect.Descriptor instead.
func (*ProofOfWork) Descriptor() ([]byte, []int) {
return file_block_proto_rawDescGZIP(), []int{1}
}
func (x *ProofOfWork) GetPowAlgo() uint64 {
if x != nil {
return x.PowAlgo
}
return 0
}
func (x *ProofOfWork) GetPowData() []byte {
if x != nil {
return x.PowData
}
return nil
}
// This is used to request the which pow algo should be used with the block template
type PowAlgo struct {
state protoimpl.MessageState `protogen:"open.v1"`
// The pow algo to use
PowAlgo PowAlgo_PowAlgos `protobuf:"varint,1,opt,name=pow_algo,json=powAlgo,proto3,enum=tari.rpc.PowAlgo_PowAlgos" json:"pow_algo,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *PowAlgo) Reset() {
*x = PowAlgo{}
mi := &file_block_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *PowAlgo) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*PowAlgo) ProtoMessage() {}
func (x *PowAlgo) ProtoReflect() protoreflect.Message {
mi := &file_block_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use PowAlgo.ProtoReflect.Descriptor instead.
func (*PowAlgo) Descriptor() ([]byte, []int) {
return file_block_proto_rawDescGZIP(), []int{2}
}
func (x *PowAlgo) GetPowAlgo() PowAlgo_PowAlgos {
if x != nil {
return x.PowAlgo
}
return PowAlgo_POW_ALGOS_RANDOMXM
}
// A Minotari block. Blocks are linked together into a blockchain.
type Block struct {
state protoimpl.MessageState `protogen:"open.v1"`
// The BlockHeader contains all the metadata for the block, including proof of work, a link to the previous block
// and the transaction kernels.
Header *BlockHeader `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"`
// The components of the block or transaction. The same struct can be used for either, since in Mimblewimble,
// blocks consist of inputs, outputs and kernels, rather than transactions.
Body *transaction.AggregateBody `protobuf:"bytes,2,opt,name=body,proto3" json:"body,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Block) Reset() {
*x = Block{}
mi := &file_block_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Block) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Block) ProtoMessage() {}
func (x *Block) ProtoReflect() protoreflect.Message {
mi := &file_block_proto_msgTypes[3]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Block.ProtoReflect.Descriptor instead.
func (*Block) Descriptor() ([]byte, []int) {
return file_block_proto_rawDescGZIP(), []int{3}
}
func (x *Block) GetHeader() *BlockHeader {
if x != nil {
return x.Header
}
return nil
}
func (x *Block) GetBody() *transaction.AggregateBody {
if x != nil {
return x.Body
}
return nil
}
// The representation of a historical block in the blockchain. It is essentially identical to a protocol-defined
// block but contains some extra metadata that clients such as Block Explorers will find interesting.
type HistoricalBlock struct {
state protoimpl.MessageState `protogen:"open.v1"`
// The number of blocks that have been mined since this block, including this one. The current tip will have one
// confirmation.
Confirmations uint64 `protobuf:"varint,1,opt,name=confirmations,proto3" json:"confirmations,omitempty"`
// The underlying block
Block *Block `protobuf:"bytes,2,opt,name=block,proto3" json:"block,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *HistoricalBlock) Reset() {
*x = HistoricalBlock{}
mi := &file_block_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *HistoricalBlock) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*HistoricalBlock) ProtoMessage() {}
func (x *HistoricalBlock) ProtoReflect() protoreflect.Message {
mi := &file_block_proto_msgTypes[4]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use HistoricalBlock.ProtoReflect.Descriptor instead.
func (*HistoricalBlock) Descriptor() ([]byte, []int) {
return file_block_proto_rawDescGZIP(), []int{4}
}
func (x *HistoricalBlock) GetConfirmations() uint64 {
if x != nil {
return x.Confirmations
}
return 0
}
func (x *HistoricalBlock) GetBlock() *Block {
if x != nil {
return x.Block
}
return nil
}
// The NewBlockHeaderTemplate is used for the construction of a new mine-able block. It contains all the metadata for the block that the Base Node is able to complete on behalf of a Miner.
type NewBlockHeaderTemplate struct {
state protoimpl.MessageState `protogen:"open.v1"`
// Version of the block
Version uint32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"`
// Height of this block since the genesis block (height 0)
Height uint64 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"`
// Hash of the block previous to this in the chain.
PrevHash []byte `protobuf:"bytes,3,opt,name=prev_hash,json=prevHash,proto3" json:"prev_hash,omitempty"`
// Total accumulated sum of kernel offsets since genesis block. We can derive the kernel offset sum for *this*
// block from the total kernel offset of the previous block header.
TotalKernelOffset []byte `protobuf:"bytes,4,opt,name=total_kernel_offset,json=totalKernelOffset,proto3" json:"total_kernel_offset,omitempty"`
// Proof of work metadata
Pow *ProofOfWork `protobuf:"bytes,5,opt,name=pow,proto3" json:"pow,omitempty"`
// Sum of script offsets for all kernels in this block.
TotalScriptOffset []byte `protobuf:"bytes,7,opt,name=total_script_offset,json=totalScriptOffset,proto3" json:"total_script_offset,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *NewBlockHeaderTemplate) Reset() {
*x = NewBlockHeaderTemplate{}
mi := &file_block_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *NewBlockHeaderTemplate) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*NewBlockHeaderTemplate) ProtoMessage() {}
func (x *NewBlockHeaderTemplate) ProtoReflect() protoreflect.Message {
mi := &file_block_proto_msgTypes[5]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use NewBlockHeaderTemplate.ProtoReflect.Descriptor instead.
func (*NewBlockHeaderTemplate) Descriptor() ([]byte, []int) {
return file_block_proto_rawDescGZIP(), []int{5}
}
func (x *NewBlockHeaderTemplate) GetVersion() uint32 {
if x != nil {
return x.Version
}
return 0
}
func (x *NewBlockHeaderTemplate) GetHeight() uint64 {
if x != nil {
return x.Height
}
return 0
}
func (x *NewBlockHeaderTemplate) GetPrevHash() []byte {
if x != nil {
return x.PrevHash
}
return nil
}
func (x *NewBlockHeaderTemplate) GetTotalKernelOffset() []byte {
if x != nil {
return x.TotalKernelOffset
}
return nil
}
func (x *NewBlockHeaderTemplate) GetPow() *ProofOfWork {
if x != nil {
return x.Pow
}
return nil
}
func (x *NewBlockHeaderTemplate) GetTotalScriptOffset() []byte {
if x != nil {
return x.TotalScriptOffset
}
return nil
}
// The new block template is used constructing a new partial block, allowing a miner to added the coinbase utxo and as a final step the Base node to add the MMR roots to the header.
type NewBlockTemplate struct {
state protoimpl.MessageState `protogen:"open.v1"`
// The NewBlockHeaderTemplate is used for the construction of a new mineable block. It contains all the metadata for
// the block that the Base Node is able to complete on behalf of a Miner.
Header *NewBlockHeaderTemplate `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"`
// This flag indicates if the inputs, outputs and kernels have been sorted internally, that is, the sort() method
// has been called. This may be false even if all components are sorted.
Body *transaction.AggregateBody `protobuf:"bytes,2,opt,name=body,proto3" json:"body,omitempty"`
// Sometimes the mempool has not synced to the latest tip, this flag indicates if the mempool is out of sync.
// In most cases the next call to get_new_block_template will return a block with the mempool in sync.
IsMempoolInSync bool `protobuf:"varint,3,opt,name=is_mempool_in_sync,json=isMempoolInSync,proto3" json:"is_mempool_in_sync,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *NewBlockTemplate) Reset() {
*x = NewBlockTemplate{}
mi := &file_block_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *NewBlockTemplate) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*NewBlockTemplate) ProtoMessage() {}
func (x *NewBlockTemplate) ProtoReflect() protoreflect.Message {
mi := &file_block_proto_msgTypes[6]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use NewBlockTemplate.ProtoReflect.Descriptor instead.
func (*NewBlockTemplate) Descriptor() ([]byte, []int) {
return file_block_proto_rawDescGZIP(), []int{6}
}
func (x *NewBlockTemplate) GetHeader() *NewBlockHeaderTemplate {
if x != nil {
return x.Header
}
return nil
}
func (x *NewBlockTemplate) GetBody() *transaction.AggregateBody {
if x != nil {
return x.Body
}
return nil
}
func (x *NewBlockTemplate) GetIsMempoolInSync() bool {
if x != nil {
return x.IsMempoolInSync
}
return false
}
var File_block_proto protoreflect.FileDescriptor
const file_block_proto_rawDesc = "" +
"\n" +
"\vblock.proto\x12\btari.rpc\x1a\x11transaction.proto\"\xd6\x04\n" +
"\vBlockHeader\x12\x12\n" +
"\x04hash\x18\x01 \x01(\fR\x04hash\x12\x18\n" +
"\aversion\x18\x02 \x01(\rR\aversion\x12\x16\n" +
"\x06height\x18\x03 \x01(\x04R\x06height\x12\x1b\n" +
"\tprev_hash\x18\x04 \x01(\fR\bprevHash\x12\x1c\n" +
"\ttimestamp\x18\x05 \x01(\x04R\ttimestamp\x12\x1b\n" +
"\toutput_mr\x18\x06 \x01(\fR\boutputMr\x12&\n" +
"\x0fblock_output_mr\x18\a \x01(\fR\rblockOutputMr\x12\x1b\n" +
"\tkernel_mr\x18\b \x01(\fR\bkernelMr\x12\x19\n" +
"\binput_mr\x18\t \x01(\fR\ainputMr\x12.\n" +
"\x13total_kernel_offset\x18\n" +
" \x01(\fR\x11totalKernelOffset\x12\x14\n" +
"\x05nonce\x18\v \x01(\x04R\x05nonce\x12'\n" +
"\x03pow\x18\f \x01(\v2\x15.tari.rpc.ProofOfWorkR\x03pow\x12&\n" +
"\x0fkernel_mmr_size\x18\r \x01(\x04R\rkernelMmrSize\x12&\n" +
"\x0foutput_mmr_size\x18\x0e \x01(\x04R\routputMmrSize\x12.\n" +
"\x13total_script_offset\x18\x0f \x01(\fR\x11totalScriptOffset\x12*\n" +
"\x11validator_node_mr\x18\x10 \x01(\fR\x0fvalidatorNodeMr\x12.\n" +
"\x13validator_node_size\x18\x11 \x01(\x04R\x11validatorNodeSize\"C\n" +
"\vProofOfWork\x12\x19\n" +
"\bpow_algo\x18\x01 \x01(\x04R\apowAlgo\x12\x19\n" +
"\bpow_data\x18\x04 \x01(\fR\apowData\"\x91\x01\n" +
"\aPowAlgo\x125\n" +
"\bpow_algo\x18\x01 \x01(\x0e2\x1a.tari.rpc.PowAlgo.PowAlgosR\apowAlgo\"O\n" +
"\bPowAlgos\x12\x16\n" +
"\x12POW_ALGOS_RANDOMXM\x10\x00\x12\x13\n" +
"\x0fPOW_ALGOS_SHA3X\x10\x01\x12\x16\n" +
"\x12POW_ALGOS_RANDOMXT\x10\x02\"c\n" +
"\x05Block\x12-\n" +
"\x06header\x18\x01 \x01(\v2\x15.tari.rpc.BlockHeaderR\x06header\x12+\n" +
"\x04body\x18\x02 \x01(\v2\x17.tari.rpc.AggregateBodyR\x04body\"^\n" +
"\x0fHistoricalBlock\x12$\n" +
"\rconfirmations\x18\x01 \x01(\x04R\rconfirmations\x12%\n" +
"\x05block\x18\x02 \x01(\v2\x0f.tari.rpc.BlockR\x05block\"\xf0\x01\n" +
"\x16NewBlockHeaderTemplate\x12\x18\n" +
"\aversion\x18\x01 \x01(\rR\aversion\x12\x16\n" +
"\x06height\x18\x02 \x01(\x04R\x06height\x12\x1b\n" +
"\tprev_hash\x18\x03 \x01(\fR\bprevHash\x12.\n" +
"\x13total_kernel_offset\x18\x04 \x01(\fR\x11totalKernelOffset\x12'\n" +
"\x03pow\x18\x05 \x01(\v2\x15.tari.rpc.ProofOfWorkR\x03pow\x12.\n" +
"\x13total_script_offset\x18\a \x01(\fR\x11totalScriptOffset\"\xa6\x01\n" +
"\x10NewBlockTemplate\x128\n" +
"\x06header\x18\x01 \x01(\v2 .tari.rpc.NewBlockHeaderTemplateR\x06header\x12+\n" +
"\x04body\x18\x02 \x01(\v2\x17.tari.rpc.AggregateBodyR\x04body\x12+\n" +
"\x12is_mempool_in_sync\x18\x03 \x01(\bR\x0fisMempoolInSyncB$Z\"pool/internal/gbt/tari/block;blockb\x06proto3"
var (
file_block_proto_rawDescOnce sync.Once
file_block_proto_rawDescData []byte
)
func file_block_proto_rawDescGZIP() []byte {
file_block_proto_rawDescOnce.Do(func() {
file_block_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_block_proto_rawDesc), len(file_block_proto_rawDesc)))
})
return file_block_proto_rawDescData
}
var file_block_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_block_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
var file_block_proto_goTypes = []any{
(PowAlgo_PowAlgos)(0), // 0: tari.rpc.PowAlgo.PowAlgos
(*BlockHeader)(nil), // 1: tari.rpc.BlockHeader
(*ProofOfWork)(nil), // 2: tari.rpc.ProofOfWork
(*PowAlgo)(nil), // 3: tari.rpc.PowAlgo
(*Block)(nil), // 4: tari.rpc.Block
(*HistoricalBlock)(nil), // 5: tari.rpc.HistoricalBlock
(*NewBlockHeaderTemplate)(nil), // 6: tari.rpc.NewBlockHeaderTemplate
(*NewBlockTemplate)(nil), // 7: tari.rpc.NewBlockTemplate
(*transaction.AggregateBody)(nil), // 8: tari.rpc.AggregateBody
}
var file_block_proto_depIdxs = []int32{
2, // 0: tari.rpc.BlockHeader.pow:type_name -> tari.rpc.ProofOfWork
0, // 1: tari.rpc.PowAlgo.pow_algo:type_name -> tari.rpc.PowAlgo.PowAlgos
1, // 2: tari.rpc.Block.header:type_name -> tari.rpc.BlockHeader
8, // 3: tari.rpc.Block.body:type_name -> tari.rpc.AggregateBody
4, // 4: tari.rpc.HistoricalBlock.block:type_name -> tari.rpc.Block
2, // 5: tari.rpc.NewBlockHeaderTemplate.pow:type_name -> tari.rpc.ProofOfWork
6, // 6: tari.rpc.NewBlockTemplate.header:type_name -> tari.rpc.NewBlockHeaderTemplate
8, // 7: tari.rpc.NewBlockTemplate.body:type_name -> tari.rpc.AggregateBody
8, // [8:8] is the sub-list for method output_type
8, // [8:8] is the sub-list for method input_type
8, // [8:8] is the sub-list for extension type_name
8, // [8:8] is the sub-list for extension extendee
0, // [0:8] is the sub-list for field type_name
}
func init() { file_block_proto_init() }
func file_block_proto_init() {
if File_block_proto != nil {
return
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_block_proto_rawDesc), len(file_block_proto_rawDesc)),
NumEnums: 1,
NumMessages: 7,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_block_proto_goTypes,
DependencyIndexes: file_block_proto_depIdxs,
EnumInfos: file_block_proto_enumTypes,
MessageInfos: file_block_proto_msgTypes,
}.Build()
File_block_proto = out.File
file_block_proto_goTypes = nil
file_block_proto_depIdxs = nil
}

View File

@@ -0,0 +1,790 @@
// Copyright 2020. The Tari Project
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
// following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
// disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
// following disclaimer in the documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
// products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.6
// protoc v3.6.1
// source: network.proto
package net_work
import (
_ "github.com/golang/protobuf/ptypes/timestamp"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type ConnectivityStatus int32
const (
ConnectivityStatus_Initializing ConnectivityStatus = 0
ConnectivityStatus_Online ConnectivityStatus = 1
ConnectivityStatus_Degraded ConnectivityStatus = 2
ConnectivityStatus_Offline ConnectivityStatus = 3
)
// Enum value maps for ConnectivityStatus.
var (
ConnectivityStatus_name = map[int32]string{
0: "Initializing",
1: "Online",
2: "Degraded",
3: "Offline",
}
ConnectivityStatus_value = map[string]int32{
"Initializing": 0,
"Online": 1,
"Degraded": 2,
"Offline": 3,
}
)
func (x ConnectivityStatus) Enum() *ConnectivityStatus {
p := new(ConnectivityStatus)
*p = x
return p
}
func (x ConnectivityStatus) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (ConnectivityStatus) Descriptor() protoreflect.EnumDescriptor {
return file_network_proto_enumTypes[0].Descriptor()
}
func (ConnectivityStatus) Type() protoreflect.EnumType {
return &file_network_proto_enumTypes[0]
}
func (x ConnectivityStatus) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use ConnectivityStatus.Descriptor instead.
func (ConnectivityStatus) EnumDescriptor() ([]byte, []int) {
return file_network_proto_rawDescGZIP(), []int{0}
}
type NodeIdentity struct {
state protoimpl.MessageState `protogen:"open.v1"`
PublicKey []byte `protobuf:"bytes,1,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"`
PublicAddresses []string `protobuf:"bytes,2,rep,name=public_addresses,json=publicAddresses,proto3" json:"public_addresses,omitempty"`
NodeId []byte `protobuf:"bytes,3,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *NodeIdentity) Reset() {
*x = NodeIdentity{}
mi := &file_network_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *NodeIdentity) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*NodeIdentity) ProtoMessage() {}
func (x *NodeIdentity) ProtoReflect() protoreflect.Message {
mi := &file_network_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use NodeIdentity.ProtoReflect.Descriptor instead.
func (*NodeIdentity) Descriptor() ([]byte, []int) {
return file_network_proto_rawDescGZIP(), []int{0}
}
func (x *NodeIdentity) GetPublicKey() []byte {
if x != nil {
return x.PublicKey
}
return nil
}
func (x *NodeIdentity) GetPublicAddresses() []string {
if x != nil {
return x.PublicAddresses
}
return nil
}
func (x *NodeIdentity) GetNodeId() []byte {
if x != nil {
return x.NodeId
}
return nil
}
type Peer struct {
state protoimpl.MessageState `protogen:"open.v1"`
// / Public key of the peer
PublicKey []byte `protobuf:"bytes,1,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"`
// / NodeId of the peer
NodeId []byte `protobuf:"bytes,2,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"`
// / Peer's addresses
Addresses []*Address `protobuf:"bytes,3,rep,name=addresses,proto3" json:"addresses,omitempty"`
// / Last connection attempt to peer
LastConnection uint64 `protobuf:"varint,4,opt,name=last_connection,json=lastConnection,proto3" json:"last_connection,omitempty"`
// / Flags for the peer.
Flags uint32 `protobuf:"varint,5,opt,name=flags,proto3" json:"flags,omitempty"`
BannedUntil uint64 `protobuf:"varint,6,opt,name=banned_until,json=bannedUntil,proto3" json:"banned_until,omitempty"`
BannedReason string `protobuf:"bytes,7,opt,name=banned_reason,json=bannedReason,proto3" json:"banned_reason,omitempty"`
OfflineAt uint64 `protobuf:"varint,8,opt,name=offline_at,json=offlineAt,proto3" json:"offline_at,omitempty"`
// / Features supported by the peer
Features uint32 `protobuf:"varint,9,opt,name=features,proto3" json:"features,omitempty"`
// / used as information for more efficient protocol negotiation.
SupportedProtocols [][]byte `protobuf:"bytes,11,rep,name=supported_protocols,json=supportedProtocols,proto3" json:"supported_protocols,omitempty"`
// / User agent advertised by the peer
UserAgent string `protobuf:"bytes,12,opt,name=user_agent,json=userAgent,proto3" json:"user_agent,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Peer) Reset() {
*x = Peer{}
mi := &file_network_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Peer) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Peer) ProtoMessage() {}
func (x *Peer) ProtoReflect() protoreflect.Message {
mi := &file_network_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Peer.ProtoReflect.Descriptor instead.
func (*Peer) Descriptor() ([]byte, []int) {
return file_network_proto_rawDescGZIP(), []int{1}
}
func (x *Peer) GetPublicKey() []byte {
if x != nil {
return x.PublicKey
}
return nil
}
func (x *Peer) GetNodeId() []byte {
if x != nil {
return x.NodeId
}
return nil
}
func (x *Peer) GetAddresses() []*Address {
if x != nil {
return x.Addresses
}
return nil
}
func (x *Peer) GetLastConnection() uint64 {
if x != nil {
return x.LastConnection
}
return 0
}
func (x *Peer) GetFlags() uint32 {
if x != nil {
return x.Flags
}
return 0
}
func (x *Peer) GetBannedUntil() uint64 {
if x != nil {
return x.BannedUntil
}
return 0
}
func (x *Peer) GetBannedReason() string {
if x != nil {
return x.BannedReason
}
return ""
}
func (x *Peer) GetOfflineAt() uint64 {
if x != nil {
return x.OfflineAt
}
return 0
}
func (x *Peer) GetFeatures() uint32 {
if x != nil {
return x.Features
}
return 0
}
func (x *Peer) GetSupportedProtocols() [][]byte {
if x != nil {
return x.SupportedProtocols
}
return nil
}
func (x *Peer) GetUserAgent() string {
if x != nil {
return x.UserAgent
}
return ""
}
type NetworkStatusResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
Status ConnectivityStatus `protobuf:"varint,1,opt,name=status,proto3,enum=tari.rpc.ConnectivityStatus" json:"status,omitempty"`
AvgLatencyMs uint32 `protobuf:"varint,2,opt,name=avg_latency_ms,json=avgLatencyMs,proto3" json:"avg_latency_ms,omitempty"`
NumNodeConnections uint32 `protobuf:"varint,3,opt,name=num_node_connections,json=numNodeConnections,proto3" json:"num_node_connections,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *NetworkStatusResponse) Reset() {
*x = NetworkStatusResponse{}
mi := &file_network_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *NetworkStatusResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*NetworkStatusResponse) ProtoMessage() {}
func (x *NetworkStatusResponse) ProtoReflect() protoreflect.Message {
mi := &file_network_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use NetworkStatusResponse.ProtoReflect.Descriptor instead.
func (*NetworkStatusResponse) Descriptor() ([]byte, []int) {
return file_network_proto_rawDescGZIP(), []int{2}
}
func (x *NetworkStatusResponse) GetStatus() ConnectivityStatus {
if x != nil {
return x.Status
}
return ConnectivityStatus_Initializing
}
func (x *NetworkStatusResponse) GetAvgLatencyMs() uint32 {
if x != nil {
return x.AvgLatencyMs
}
return 0
}
func (x *NetworkStatusResponse) GetNumNodeConnections() uint32 {
if x != nil {
return x.NumNodeConnections
}
return 0
}
type Address struct {
state protoimpl.MessageState `protogen:"open.v1"`
Address []byte `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
LastSeen string `protobuf:"bytes,2,opt,name=last_seen,json=lastSeen,proto3" json:"last_seen,omitempty"`
ConnectionAttempts uint32 `protobuf:"varint,3,opt,name=connection_attempts,json=connectionAttempts,proto3" json:"connection_attempts,omitempty"`
AvgLatency *AverageLatency `protobuf:"bytes,5,opt,name=avg_latency,json=avgLatency,proto3" json:"avg_latency,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Address) Reset() {
*x = Address{}
mi := &file_network_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Address) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Address) ProtoMessage() {}
func (x *Address) ProtoReflect() protoreflect.Message {
mi := &file_network_proto_msgTypes[3]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Address.ProtoReflect.Descriptor instead.
func (*Address) Descriptor() ([]byte, []int) {
return file_network_proto_rawDescGZIP(), []int{3}
}
func (x *Address) GetAddress() []byte {
if x != nil {
return x.Address
}
return nil
}
func (x *Address) GetLastSeen() string {
if x != nil {
return x.LastSeen
}
return ""
}
func (x *Address) GetConnectionAttempts() uint32 {
if x != nil {
return x.ConnectionAttempts
}
return 0
}
func (x *Address) GetAvgLatency() *AverageLatency {
if x != nil {
return x.AvgLatency
}
return nil
}
type AverageLatency struct {
state protoimpl.MessageState `protogen:"open.v1"`
Latency uint64 `protobuf:"varint,1,opt,name=latency,proto3" json:"latency,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *AverageLatency) Reset() {
*x = AverageLatency{}
mi := &file_network_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *AverageLatency) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AverageLatency) ProtoMessage() {}
func (x *AverageLatency) ProtoReflect() protoreflect.Message {
mi := &file_network_proto_msgTypes[4]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AverageLatency.ProtoReflect.Descriptor instead.
func (*AverageLatency) Descriptor() ([]byte, []int) {
return file_network_proto_rawDescGZIP(), []int{4}
}
func (x *AverageLatency) GetLatency() uint64 {
if x != nil {
return x.Latency
}
return 0
}
type ListConnectedPeersResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
ConnectedPeers []*Peer `protobuf:"bytes,1,rep,name=connected_peers,json=connectedPeers,proto3" json:"connected_peers,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ListConnectedPeersResponse) Reset() {
*x = ListConnectedPeersResponse{}
mi := &file_network_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ListConnectedPeersResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListConnectedPeersResponse) ProtoMessage() {}
func (x *ListConnectedPeersResponse) ProtoReflect() protoreflect.Message {
mi := &file_network_proto_msgTypes[5]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ListConnectedPeersResponse.ProtoReflect.Descriptor instead.
func (*ListConnectedPeersResponse) Descriptor() ([]byte, []int) {
return file_network_proto_rawDescGZIP(), []int{5}
}
func (x *ListConnectedPeersResponse) GetConnectedPeers() []*Peer {
if x != nil {
return x.ConnectedPeers
}
return nil
}
type SoftwareUpdate struct {
state protoimpl.MessageState `protogen:"open.v1"`
HasUpdate bool `protobuf:"varint,1,opt,name=has_update,json=hasUpdate,proto3" json:"has_update,omitempty"`
Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"`
Sha string `protobuf:"bytes,3,opt,name=sha,proto3" json:"sha,omitempty"`
DownloadUrl string `protobuf:"bytes,4,opt,name=download_url,json=downloadUrl,proto3" json:"download_url,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *SoftwareUpdate) Reset() {
*x = SoftwareUpdate{}
mi := &file_network_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *SoftwareUpdate) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SoftwareUpdate) ProtoMessage() {}
func (x *SoftwareUpdate) ProtoReflect() protoreflect.Message {
mi := &file_network_proto_msgTypes[6]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use SoftwareUpdate.ProtoReflect.Descriptor instead.
func (*SoftwareUpdate) Descriptor() ([]byte, []int) {
return file_network_proto_rawDescGZIP(), []int{6}
}
func (x *SoftwareUpdate) GetHasUpdate() bool {
if x != nil {
return x.HasUpdate
}
return false
}
func (x *SoftwareUpdate) GetVersion() string {
if x != nil {
return x.Version
}
return ""
}
func (x *SoftwareUpdate) GetSha() string {
if x != nil {
return x.Sha
}
return ""
}
func (x *SoftwareUpdate) GetDownloadUrl() string {
if x != nil {
return x.DownloadUrl
}
return ""
}
type GetIdentityRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *GetIdentityRequest) Reset() {
*x = GetIdentityRequest{}
mi := &file_network_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *GetIdentityRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetIdentityRequest) ProtoMessage() {}
func (x *GetIdentityRequest) ProtoReflect() protoreflect.Message {
mi := &file_network_proto_msgTypes[7]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetIdentityRequest.ProtoReflect.Descriptor instead.
func (*GetIdentityRequest) Descriptor() ([]byte, []int) {
return file_network_proto_rawDescGZIP(), []int{7}
}
type GetIdentityResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
PublicKey []byte `protobuf:"bytes,1,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"`
PublicAddress string `protobuf:"bytes,2,opt,name=public_address,json=publicAddress,proto3" json:"public_address,omitempty"`
NodeId []byte `protobuf:"bytes,3,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *GetIdentityResponse) Reset() {
*x = GetIdentityResponse{}
mi := &file_network_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *GetIdentityResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*GetIdentityResponse) ProtoMessage() {}
func (x *GetIdentityResponse) ProtoReflect() protoreflect.Message {
mi := &file_network_proto_msgTypes[8]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetIdentityResponse.ProtoReflect.Descriptor instead.
func (*GetIdentityResponse) Descriptor() ([]byte, []int) {
return file_network_proto_rawDescGZIP(), []int{8}
}
func (x *GetIdentityResponse) GetPublicKey() []byte {
if x != nil {
return x.PublicKey
}
return nil
}
func (x *GetIdentityResponse) GetPublicAddress() string {
if x != nil {
return x.PublicAddress
}
return ""
}
func (x *GetIdentityResponse) GetNodeId() []byte {
if x != nil {
return x.NodeId
}
return nil
}
var File_network_proto protoreflect.FileDescriptor
const file_network_proto_rawDesc = "" +
"\n" +
"\rnetwork.proto\x12\btari.rpc\x1a\x1fgoogle/protobuf/timestamp.proto\"q\n" +
"\fNodeIdentity\x12\x1d\n" +
"\n" +
"public_key\x18\x01 \x01(\fR\tpublicKey\x12)\n" +
"\x10public_addresses\x18\x02 \x03(\tR\x0fpublicAddresses\x12\x17\n" +
"\anode_id\x18\x03 \x01(\fR\x06nodeId\"\x81\x03\n" +
"\x04Peer\x12\x1d\n" +
"\n" +
"public_key\x18\x01 \x01(\fR\tpublicKey\x12\x17\n" +
"\anode_id\x18\x02 \x01(\fR\x06nodeId\x12/\n" +
"\taddresses\x18\x03 \x03(\v2\x11.tari.rpc.AddressR\taddresses\x12'\n" +
"\x0flast_connection\x18\x04 \x01(\x04R\x0elastConnection\x12\x14\n" +
"\x05flags\x18\x05 \x01(\rR\x05flags\x12!\n" +
"\fbanned_until\x18\x06 \x01(\x04R\vbannedUntil\x12#\n" +
"\rbanned_reason\x18\a \x01(\tR\fbannedReason\x12\x1d\n" +
"\n" +
"offline_at\x18\b \x01(\x04R\tofflineAt\x12\x1a\n" +
"\bfeatures\x18\t \x01(\rR\bfeatures\x12/\n" +
"\x13supported_protocols\x18\v \x03(\fR\x12supportedProtocols\x12\x1d\n" +
"\n" +
"user_agent\x18\f \x01(\tR\tuserAgent\"\xa5\x01\n" +
"\x15NetworkStatusResponse\x124\n" +
"\x06status\x18\x01 \x01(\x0e2\x1c.tari.rpc.ConnectivityStatusR\x06status\x12$\n" +
"\x0eavg_latency_ms\x18\x02 \x01(\rR\favgLatencyMs\x120\n" +
"\x14num_node_connections\x18\x03 \x01(\rR\x12numNodeConnections\"\xac\x01\n" +
"\aAddress\x12\x18\n" +
"\aaddress\x18\x01 \x01(\fR\aaddress\x12\x1b\n" +
"\tlast_seen\x18\x02 \x01(\tR\blastSeen\x12/\n" +
"\x13connection_attempts\x18\x03 \x01(\rR\x12connectionAttempts\x129\n" +
"\vavg_latency\x18\x05 \x01(\v2\x18.tari.rpc.AverageLatencyR\n" +
"avgLatency\"*\n" +
"\x0eAverageLatency\x12\x18\n" +
"\alatency\x18\x01 \x01(\x04R\alatency\"U\n" +
"\x1aListConnectedPeersResponse\x127\n" +
"\x0fconnected_peers\x18\x01 \x03(\v2\x0e.tari.rpc.PeerR\x0econnectedPeers\"~\n" +
"\x0eSoftwareUpdate\x12\x1d\n" +
"\n" +
"has_update\x18\x01 \x01(\bR\thasUpdate\x12\x18\n" +
"\aversion\x18\x02 \x01(\tR\aversion\x12\x10\n" +
"\x03sha\x18\x03 \x01(\tR\x03sha\x12!\n" +
"\fdownload_url\x18\x04 \x01(\tR\vdownloadUrl\"\x14\n" +
"\x12GetIdentityRequest\"t\n" +
"\x13GetIdentityResponse\x12\x1d\n" +
"\n" +
"public_key\x18\x01 \x01(\fR\tpublicKey\x12%\n" +
"\x0epublic_address\x18\x02 \x01(\tR\rpublicAddress\x12\x17\n" +
"\anode_id\x18\x03 \x01(\fR\x06nodeId*M\n" +
"\x12ConnectivityStatus\x12\x10\n" +
"\fInitializing\x10\x00\x12\n" +
"\n" +
"\x06Online\x10\x01\x12\f\n" +
"\bDegraded\x10\x02\x12\v\n" +
"\aOffline\x10\x03B*Z(pool/internal/gbt/tari/net_work;net_workb\x06proto3"
var (
file_network_proto_rawDescOnce sync.Once
file_network_proto_rawDescData []byte
)
func file_network_proto_rawDescGZIP() []byte {
file_network_proto_rawDescOnce.Do(func() {
file_network_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_network_proto_rawDesc), len(file_network_proto_rawDesc)))
})
return file_network_proto_rawDescData
}
var file_network_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_network_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
var file_network_proto_goTypes = []any{
(ConnectivityStatus)(0), // 0: tari.rpc.ConnectivityStatus
(*NodeIdentity)(nil), // 1: tari.rpc.NodeIdentity
(*Peer)(nil), // 2: tari.rpc.Peer
(*NetworkStatusResponse)(nil), // 3: tari.rpc.NetworkStatusResponse
(*Address)(nil), // 4: tari.rpc.Address
(*AverageLatency)(nil), // 5: tari.rpc.AverageLatency
(*ListConnectedPeersResponse)(nil), // 6: tari.rpc.ListConnectedPeersResponse
(*SoftwareUpdate)(nil), // 7: tari.rpc.SoftwareUpdate
(*GetIdentityRequest)(nil), // 8: tari.rpc.GetIdentityRequest
(*GetIdentityResponse)(nil), // 9: tari.rpc.GetIdentityResponse
}
var file_network_proto_depIdxs = []int32{
4, // 0: tari.rpc.Peer.addresses:type_name -> tari.rpc.Address
0, // 1: tari.rpc.NetworkStatusResponse.status:type_name -> tari.rpc.ConnectivityStatus
5, // 2: tari.rpc.Address.avg_latency:type_name -> tari.rpc.AverageLatency
2, // 3: tari.rpc.ListConnectedPeersResponse.connected_peers:type_name -> tari.rpc.Peer
4, // [4:4] is the sub-list for method output_type
4, // [4:4] is the sub-list for method input_type
4, // [4:4] is the sub-list for extension type_name
4, // [4:4] is the sub-list for extension extendee
0, // [0:4] is the sub-list for field type_name
}
func init() { file_network_proto_init() }
func file_network_proto_init() {
if File_network_proto != nil {
return
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_network_proto_rawDesc), len(file_network_proto_rawDesc)),
NumEnums: 1,
NumMessages: 9,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_network_proto_goTypes,
DependencyIndexes: file_network_proto_depIdxs,
EnumInfos: file_network_proto_enumTypes,
MessageInfos: file_network_proto_msgTypes,
}.Build()
File_network_proto = out.File
file_network_proto_goTypes = nil
file_network_proto_depIdxs = nil
}

View File

@@ -0,0 +1,97 @@
// Copyright 2020. The Tari Project
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
// following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
// disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
// following disclaimer in the documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
// products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto3";
package tari.rpc;
import "google/protobuf/timestamp.proto";
message NodeIdentity {
bytes public_key = 1;
repeated string public_addresses = 2;
bytes node_id = 3;
}
message Peer {
/// Public key of the peer
bytes public_key =1;
/// NodeId of the peer
bytes node_id =2;
/// Peer's addresses
repeated Address addresses = 3;
/// Last connection attempt to peer
uint64 last_connection = 4;
/// Flags for the peer.
uint32 flags = 5;
uint64 banned_until= 6;
string banned_reason= 7;
uint64 offline_at = 8;
/// Features supported by the peer
uint32 features = 9;
/// used as information for more efficient protocol negotiation.
repeated bytes supported_protocols = 11;
/// User agent advertised by the peer
string user_agent = 12;
}
enum ConnectivityStatus {
Initializing = 0;
Online = 1;
Degraded = 2;
Offline = 3;
}
message NetworkStatusResponse {
ConnectivityStatus status = 1;
uint32 avg_latency_ms = 2;
uint32 num_node_connections = 3;
}
message Address{
bytes address =1;
string last_seen = 2;
uint32 connection_attempts = 3;
AverageLatency avg_latency = 5;
}
message AverageLatency {
uint64 latency = 1;
}
message ListConnectedPeersResponse {
repeated Peer connected_peers = 1;
}
message SoftwareUpdate {
bool has_update = 1;
string version = 2;
string sha = 3;
string download_url = 4;
}
message GetIdentityRequest { }
message GetIdentityResponse {
bytes public_key = 1;
string public_address = 2;
bytes node_id = 3;
}

View File

@@ -0,0 +1,61 @@
// Copyright 2024. The Tari Project
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
// following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
// disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
// following disclaimer in the documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
// products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto3";
package tari.rpc;
import "base_node.proto";
import "block.proto";
service ShaP2Pool {
rpc GetTipInfo(GetTipInfoRequest) returns(GetTipInfoResponse);
rpc GetNewBlock(GetNewBlockRequest) returns(GetNewBlockResponse);
rpc SubmitBlock(SubmitBlockRequest) returns(tari.rpc.SubmitBlockResponse);
}
message GetTipInfoRequest {
}
message GetTipInfoResponse {
uint64 node_height = 1;
bytes node_tip_hash = 2;
uint64 p2pool_rx_height = 3;
bytes p2pool_rx_tip_hash = 4;
uint64 p2pool_sha_height = 5;
bytes p2pool_sha_tip_hash = 6;
}
message GetNewBlockRequest {
tari.rpc.PowAlgo pow = 1;
string coinbase_extra = 2;
string wallet_payment_address = 3;
}
message GetNewBlockResponse {
tari.rpc.GetNewBlockResult block = 1;
uint64 target_difficulty = 2;
}
message SubmitBlockRequest {
tari.rpc.Block block = 1;
string wallet_payment_address = 2;
}

View File

@@ -0,0 +1,77 @@
// Copyright 2020. The Tari Project
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
// following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
// disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
// following disclaimer in the documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
// products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto3";
package tari.rpc;
import "types.proto";
message SideChainFeature {
oneof side_chain_feature {
ValidatorNodeRegistration validator_node_registration = 1;
TemplateRegistration template_registration = 2;
ConfidentialOutputData confidential_output = 3;
}
}
message ValidatorNodeRegistration {
bytes public_key = 1;
Signature signature = 2;
}
message TemplateRegistration {
bytes author_public_key = 1;
Signature author_signature = 2;
string template_name = 3;
uint32 template_version = 4;
TemplateType template_type = 5;
BuildInfo build_info = 6;
bytes binary_sha = 7;
string binary_url = 8;
}
message ConfidentialOutputData {
bytes claim_public_key = 1;
}
message TemplateType {
oneof template_type {
WasmInfo wasm = 1;
FlowInfo flow = 2;
ManifestInfo manifest = 3;
}
}
message WasmInfo {
uint32 abi_version = 1;
}
message FlowInfo {
}
message ManifestInfo {
}
message BuildInfo {
string repo_url = 1;
bytes commit_hash = 2;
}

View File

@@ -0,0 +1,727 @@
// Copyright 2020. The Tari Project
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
// following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
// disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
// following disclaimer in the documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
// products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.6
// protoc v3.6.1
// source: sidechain_types.proto
package sidechain_types
import (
types "pool/internal/gbt/tari/proto/types"
reflect "reflect"
sync "sync"
unsafe "unsafe"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type SideChainFeature struct {
state protoimpl.MessageState `protogen:"open.v1"`
// Types that are valid to be assigned to SideChainFeature:
//
// *SideChainFeature_ValidatorNodeRegistration
// *SideChainFeature_TemplateRegistration
// *SideChainFeature_ConfidentialOutput
SideChainFeature isSideChainFeature_SideChainFeature `protobuf_oneof:"side_chain_feature"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *SideChainFeature) Reset() {
*x = SideChainFeature{}
mi := &file_sidechain_types_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *SideChainFeature) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SideChainFeature) ProtoMessage() {}
func (x *SideChainFeature) ProtoReflect() protoreflect.Message {
mi := &file_sidechain_types_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use SideChainFeature.ProtoReflect.Descriptor instead.
func (*SideChainFeature) Descriptor() ([]byte, []int) {
return file_sidechain_types_proto_rawDescGZIP(), []int{0}
}
func (x *SideChainFeature) GetSideChainFeature() isSideChainFeature_SideChainFeature {
if x != nil {
return x.SideChainFeature
}
return nil
}
func (x *SideChainFeature) GetValidatorNodeRegistration() *ValidatorNodeRegistration {
if x != nil {
if x, ok := x.SideChainFeature.(*SideChainFeature_ValidatorNodeRegistration); ok {
return x.ValidatorNodeRegistration
}
}
return nil
}
func (x *SideChainFeature) GetTemplateRegistration() *TemplateRegistration {
if x != nil {
if x, ok := x.SideChainFeature.(*SideChainFeature_TemplateRegistration); ok {
return x.TemplateRegistration
}
}
return nil
}
func (x *SideChainFeature) GetConfidentialOutput() *ConfidentialOutputData {
if x != nil {
if x, ok := x.SideChainFeature.(*SideChainFeature_ConfidentialOutput); ok {
return x.ConfidentialOutput
}
}
return nil
}
type isSideChainFeature_SideChainFeature interface {
isSideChainFeature_SideChainFeature()
}
type SideChainFeature_ValidatorNodeRegistration struct {
ValidatorNodeRegistration *ValidatorNodeRegistration `protobuf:"bytes,1,opt,name=validator_node_registration,json=validatorNodeRegistration,proto3,oneof"`
}
type SideChainFeature_TemplateRegistration struct {
TemplateRegistration *TemplateRegistration `protobuf:"bytes,2,opt,name=template_registration,json=templateRegistration,proto3,oneof"`
}
type SideChainFeature_ConfidentialOutput struct {
ConfidentialOutput *ConfidentialOutputData `protobuf:"bytes,3,opt,name=confidential_output,json=confidentialOutput,proto3,oneof"`
}
func (*SideChainFeature_ValidatorNodeRegistration) isSideChainFeature_SideChainFeature() {}
func (*SideChainFeature_TemplateRegistration) isSideChainFeature_SideChainFeature() {}
func (*SideChainFeature_ConfidentialOutput) isSideChainFeature_SideChainFeature() {}
type ValidatorNodeRegistration struct {
state protoimpl.MessageState `protogen:"open.v1"`
PublicKey []byte `protobuf:"bytes,1,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"`
Signature *types.Signature `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ValidatorNodeRegistration) Reset() {
*x = ValidatorNodeRegistration{}
mi := &file_sidechain_types_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ValidatorNodeRegistration) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ValidatorNodeRegistration) ProtoMessage() {}
func (x *ValidatorNodeRegistration) ProtoReflect() protoreflect.Message {
mi := &file_sidechain_types_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ValidatorNodeRegistration.ProtoReflect.Descriptor instead.
func (*ValidatorNodeRegistration) Descriptor() ([]byte, []int) {
return file_sidechain_types_proto_rawDescGZIP(), []int{1}
}
func (x *ValidatorNodeRegistration) GetPublicKey() []byte {
if x != nil {
return x.PublicKey
}
return nil
}
func (x *ValidatorNodeRegistration) GetSignature() *types.Signature {
if x != nil {
return x.Signature
}
return nil
}
type TemplateRegistration struct {
state protoimpl.MessageState `protogen:"open.v1"`
AuthorPublicKey []byte `protobuf:"bytes,1,opt,name=author_public_key,json=authorPublicKey,proto3" json:"author_public_key,omitempty"`
AuthorSignature *types.Signature `protobuf:"bytes,2,opt,name=author_signature,json=authorSignature,proto3" json:"author_signature,omitempty"`
TemplateName string `protobuf:"bytes,3,opt,name=template_name,json=templateName,proto3" json:"template_name,omitempty"`
TemplateVersion uint32 `protobuf:"varint,4,opt,name=template_version,json=templateVersion,proto3" json:"template_version,omitempty"`
TemplateType *TemplateType `protobuf:"bytes,5,opt,name=template_type,json=templateType,proto3" json:"template_type,omitempty"`
BuildInfo *BuildInfo `protobuf:"bytes,6,opt,name=build_info,json=buildInfo,proto3" json:"build_info,omitempty"`
BinarySha []byte `protobuf:"bytes,7,opt,name=binary_sha,json=binarySha,proto3" json:"binary_sha,omitempty"`
BinaryUrl string `protobuf:"bytes,8,opt,name=binary_url,json=binaryUrl,proto3" json:"binary_url,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *TemplateRegistration) Reset() {
*x = TemplateRegistration{}
mi := &file_sidechain_types_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *TemplateRegistration) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*TemplateRegistration) ProtoMessage() {}
func (x *TemplateRegistration) ProtoReflect() protoreflect.Message {
mi := &file_sidechain_types_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use TemplateRegistration.ProtoReflect.Descriptor instead.
func (*TemplateRegistration) Descriptor() ([]byte, []int) {
return file_sidechain_types_proto_rawDescGZIP(), []int{2}
}
func (x *TemplateRegistration) GetAuthorPublicKey() []byte {
if x != nil {
return x.AuthorPublicKey
}
return nil
}
func (x *TemplateRegistration) GetAuthorSignature() *types.Signature {
if x != nil {
return x.AuthorSignature
}
return nil
}
func (x *TemplateRegistration) GetTemplateName() string {
if x != nil {
return x.TemplateName
}
return ""
}
func (x *TemplateRegistration) GetTemplateVersion() uint32 {
if x != nil {
return x.TemplateVersion
}
return 0
}
func (x *TemplateRegistration) GetTemplateType() *TemplateType {
if x != nil {
return x.TemplateType
}
return nil
}
func (x *TemplateRegistration) GetBuildInfo() *BuildInfo {
if x != nil {
return x.BuildInfo
}
return nil
}
func (x *TemplateRegistration) GetBinarySha() []byte {
if x != nil {
return x.BinarySha
}
return nil
}
func (x *TemplateRegistration) GetBinaryUrl() string {
if x != nil {
return x.BinaryUrl
}
return ""
}
type ConfidentialOutputData struct {
state protoimpl.MessageState `protogen:"open.v1"`
ClaimPublicKey []byte `protobuf:"bytes,1,opt,name=claim_public_key,json=claimPublicKey,proto3" json:"claim_public_key,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ConfidentialOutputData) Reset() {
*x = ConfidentialOutputData{}
mi := &file_sidechain_types_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ConfidentialOutputData) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ConfidentialOutputData) ProtoMessage() {}
func (x *ConfidentialOutputData) ProtoReflect() protoreflect.Message {
mi := &file_sidechain_types_proto_msgTypes[3]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ConfidentialOutputData.ProtoReflect.Descriptor instead.
func (*ConfidentialOutputData) Descriptor() ([]byte, []int) {
return file_sidechain_types_proto_rawDescGZIP(), []int{3}
}
func (x *ConfidentialOutputData) GetClaimPublicKey() []byte {
if x != nil {
return x.ClaimPublicKey
}
return nil
}
type TemplateType struct {
state protoimpl.MessageState `protogen:"open.v1"`
// Types that are valid to be assigned to TemplateType:
//
// *TemplateType_Wasm
// *TemplateType_Flow
// *TemplateType_Manifest
TemplateType isTemplateType_TemplateType `protobuf_oneof:"template_type"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *TemplateType) Reset() {
*x = TemplateType{}
mi := &file_sidechain_types_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *TemplateType) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*TemplateType) ProtoMessage() {}
func (x *TemplateType) ProtoReflect() protoreflect.Message {
mi := &file_sidechain_types_proto_msgTypes[4]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use TemplateType.ProtoReflect.Descriptor instead.
func (*TemplateType) Descriptor() ([]byte, []int) {
return file_sidechain_types_proto_rawDescGZIP(), []int{4}
}
func (x *TemplateType) GetTemplateType() isTemplateType_TemplateType {
if x != nil {
return x.TemplateType
}
return nil
}
func (x *TemplateType) GetWasm() *WasmInfo {
if x != nil {
if x, ok := x.TemplateType.(*TemplateType_Wasm); ok {
return x.Wasm
}
}
return nil
}
func (x *TemplateType) GetFlow() *FlowInfo {
if x != nil {
if x, ok := x.TemplateType.(*TemplateType_Flow); ok {
return x.Flow
}
}
return nil
}
func (x *TemplateType) GetManifest() *ManifestInfo {
if x != nil {
if x, ok := x.TemplateType.(*TemplateType_Manifest); ok {
return x.Manifest
}
}
return nil
}
type isTemplateType_TemplateType interface {
isTemplateType_TemplateType()
}
type TemplateType_Wasm struct {
Wasm *WasmInfo `protobuf:"bytes,1,opt,name=wasm,proto3,oneof"`
}
type TemplateType_Flow struct {
Flow *FlowInfo `protobuf:"bytes,2,opt,name=flow,proto3,oneof"`
}
type TemplateType_Manifest struct {
Manifest *ManifestInfo `protobuf:"bytes,3,opt,name=manifest,proto3,oneof"`
}
func (*TemplateType_Wasm) isTemplateType_TemplateType() {}
func (*TemplateType_Flow) isTemplateType_TemplateType() {}
func (*TemplateType_Manifest) isTemplateType_TemplateType() {}
type WasmInfo struct {
state protoimpl.MessageState `protogen:"open.v1"`
AbiVersion uint32 `protobuf:"varint,1,opt,name=abi_version,json=abiVersion,proto3" json:"abi_version,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *WasmInfo) Reset() {
*x = WasmInfo{}
mi := &file_sidechain_types_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *WasmInfo) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*WasmInfo) ProtoMessage() {}
func (x *WasmInfo) ProtoReflect() protoreflect.Message {
mi := &file_sidechain_types_proto_msgTypes[5]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use WasmInfo.ProtoReflect.Descriptor instead.
func (*WasmInfo) Descriptor() ([]byte, []int) {
return file_sidechain_types_proto_rawDescGZIP(), []int{5}
}
func (x *WasmInfo) GetAbiVersion() uint32 {
if x != nil {
return x.AbiVersion
}
return 0
}
type FlowInfo struct {
state protoimpl.MessageState `protogen:"open.v1"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *FlowInfo) Reset() {
*x = FlowInfo{}
mi := &file_sidechain_types_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *FlowInfo) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*FlowInfo) ProtoMessage() {}
func (x *FlowInfo) ProtoReflect() protoreflect.Message {
mi := &file_sidechain_types_proto_msgTypes[6]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use FlowInfo.ProtoReflect.Descriptor instead.
func (*FlowInfo) Descriptor() ([]byte, []int) {
return file_sidechain_types_proto_rawDescGZIP(), []int{6}
}
type ManifestInfo struct {
state protoimpl.MessageState `protogen:"open.v1"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ManifestInfo) Reset() {
*x = ManifestInfo{}
mi := &file_sidechain_types_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ManifestInfo) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ManifestInfo) ProtoMessage() {}
func (x *ManifestInfo) ProtoReflect() protoreflect.Message {
mi := &file_sidechain_types_proto_msgTypes[7]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ManifestInfo.ProtoReflect.Descriptor instead.
func (*ManifestInfo) Descriptor() ([]byte, []int) {
return file_sidechain_types_proto_rawDescGZIP(), []int{7}
}
type BuildInfo struct {
state protoimpl.MessageState `protogen:"open.v1"`
RepoUrl string `protobuf:"bytes,1,opt,name=repo_url,json=repoUrl,proto3" json:"repo_url,omitempty"`
CommitHash []byte `protobuf:"bytes,2,opt,name=commit_hash,json=commitHash,proto3" json:"commit_hash,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *BuildInfo) Reset() {
*x = BuildInfo{}
mi := &file_sidechain_types_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *BuildInfo) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*BuildInfo) ProtoMessage() {}
func (x *BuildInfo) ProtoReflect() protoreflect.Message {
mi := &file_sidechain_types_proto_msgTypes[8]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use BuildInfo.ProtoReflect.Descriptor instead.
func (*BuildInfo) Descriptor() ([]byte, []int) {
return file_sidechain_types_proto_rawDescGZIP(), []int{8}
}
func (x *BuildInfo) GetRepoUrl() string {
if x != nil {
return x.RepoUrl
}
return ""
}
func (x *BuildInfo) GetCommitHash() []byte {
if x != nil {
return x.CommitHash
}
return nil
}
var File_sidechain_types_proto protoreflect.FileDescriptor
const file_sidechain_types_proto_rawDesc = "" +
"\n" +
"\x15sidechain_types.proto\x12\btari.rpc\x1a\vtypes.proto\"\xbb\x02\n" +
"\x10SideChainFeature\x12e\n" +
"\x1bvalidator_node_registration\x18\x01 \x01(\v2#.tari.rpc.ValidatorNodeRegistrationH\x00R\x19validatorNodeRegistration\x12U\n" +
"\x15template_registration\x18\x02 \x01(\v2\x1e.tari.rpc.TemplateRegistrationH\x00R\x14templateRegistration\x12S\n" +
"\x13confidential_output\x18\x03 \x01(\v2 .tari.rpc.ConfidentialOutputDataH\x00R\x12confidentialOutputB\x14\n" +
"\x12side_chain_feature\"m\n" +
"\x19ValidatorNodeRegistration\x12\x1d\n" +
"\n" +
"public_key\x18\x01 \x01(\fR\tpublicKey\x121\n" +
"\tsignature\x18\x02 \x01(\v2\x13.tari.rpc.SignatureR\tsignature\"\x81\x03\n" +
"\x14TemplateRegistration\x12*\n" +
"\x11author_public_key\x18\x01 \x01(\fR\x0fauthorPublicKey\x12>\n" +
"\x10author_signature\x18\x02 \x01(\v2\x13.tari.rpc.SignatureR\x0fauthorSignature\x12#\n" +
"\rtemplate_name\x18\x03 \x01(\tR\ftemplateName\x12)\n" +
"\x10template_version\x18\x04 \x01(\rR\x0ftemplateVersion\x12;\n" +
"\rtemplate_type\x18\x05 \x01(\v2\x16.tari.rpc.TemplateTypeR\ftemplateType\x122\n" +
"\n" +
"build_info\x18\x06 \x01(\v2\x13.tari.rpc.BuildInfoR\tbuildInfo\x12\x1d\n" +
"\n" +
"binary_sha\x18\a \x01(\fR\tbinarySha\x12\x1d\n" +
"\n" +
"binary_url\x18\b \x01(\tR\tbinaryUrl\"B\n" +
"\x16ConfidentialOutputData\x12(\n" +
"\x10claim_public_key\x18\x01 \x01(\fR\x0eclaimPublicKey\"\xa9\x01\n" +
"\fTemplateType\x12(\n" +
"\x04wasm\x18\x01 \x01(\v2\x12.tari.rpc.WasmInfoH\x00R\x04wasm\x12(\n" +
"\x04flow\x18\x02 \x01(\v2\x12.tari.rpc.FlowInfoH\x00R\x04flow\x124\n" +
"\bmanifest\x18\x03 \x01(\v2\x16.tari.rpc.ManifestInfoH\x00R\bmanifestB\x0f\n" +
"\rtemplate_type\"+\n" +
"\bWasmInfo\x12\x1f\n" +
"\vabi_version\x18\x01 \x01(\rR\n" +
"abiVersion\"\n" +
"\n" +
"\bFlowInfo\"\x0e\n" +
"\fManifestInfo\"G\n" +
"\tBuildInfo\x12\x19\n" +
"\brepo_url\x18\x01 \x01(\tR\arepoUrl\x12\x1f\n" +
"\vcommit_hash\x18\x02 \x01(\fR\n" +
"commitHashB8Z6pool/internal/gbt/tari/sidechain_types;sidechain_typesb\x06proto3"
var (
file_sidechain_types_proto_rawDescOnce sync.Once
file_sidechain_types_proto_rawDescData []byte
)
func file_sidechain_types_proto_rawDescGZIP() []byte {
file_sidechain_types_proto_rawDescOnce.Do(func() {
file_sidechain_types_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_sidechain_types_proto_rawDesc), len(file_sidechain_types_proto_rawDesc)))
})
return file_sidechain_types_proto_rawDescData
}
var file_sidechain_types_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
var file_sidechain_types_proto_goTypes = []any{
(*SideChainFeature)(nil), // 0: tari.rpc.SideChainFeature
(*ValidatorNodeRegistration)(nil), // 1: tari.rpc.ValidatorNodeRegistration
(*TemplateRegistration)(nil), // 2: tari.rpc.TemplateRegistration
(*ConfidentialOutputData)(nil), // 3: tari.rpc.ConfidentialOutputData
(*TemplateType)(nil), // 4: tari.rpc.TemplateType
(*WasmInfo)(nil), // 5: tari.rpc.WasmInfo
(*FlowInfo)(nil), // 6: tari.rpc.FlowInfo
(*ManifestInfo)(nil), // 7: tari.rpc.ManifestInfo
(*BuildInfo)(nil), // 8: tari.rpc.BuildInfo
(*types.Signature)(nil), // 9: tari.rpc.Signature
}
var file_sidechain_types_proto_depIdxs = []int32{
1, // 0: tari.rpc.SideChainFeature.validator_node_registration:type_name -> tari.rpc.ValidatorNodeRegistration
2, // 1: tari.rpc.SideChainFeature.template_registration:type_name -> tari.rpc.TemplateRegistration
3, // 2: tari.rpc.SideChainFeature.confidential_output:type_name -> tari.rpc.ConfidentialOutputData
9, // 3: tari.rpc.ValidatorNodeRegistration.signature:type_name -> tari.rpc.Signature
9, // 4: tari.rpc.TemplateRegistration.author_signature:type_name -> tari.rpc.Signature
4, // 5: tari.rpc.TemplateRegistration.template_type:type_name -> tari.rpc.TemplateType
8, // 6: tari.rpc.TemplateRegistration.build_info:type_name -> tari.rpc.BuildInfo
5, // 7: tari.rpc.TemplateType.wasm:type_name -> tari.rpc.WasmInfo
6, // 8: tari.rpc.TemplateType.flow:type_name -> tari.rpc.FlowInfo
7, // 9: tari.rpc.TemplateType.manifest:type_name -> tari.rpc.ManifestInfo
10, // [10:10] is the sub-list for method output_type
10, // [10:10] is the sub-list for method input_type
10, // [10:10] is the sub-list for extension type_name
10, // [10:10] is the sub-list for extension extendee
0, // [0:10] is the sub-list for field type_name
}
func init() { file_sidechain_types_proto_init() }
func file_sidechain_types_proto_init() {
if File_sidechain_types_proto != nil {
return
}
file_sidechain_types_proto_msgTypes[0].OneofWrappers = []any{
(*SideChainFeature_ValidatorNodeRegistration)(nil),
(*SideChainFeature_TemplateRegistration)(nil),
(*SideChainFeature_ConfidentialOutput)(nil),
}
file_sidechain_types_proto_msgTypes[4].OneofWrappers = []any{
(*TemplateType_Wasm)(nil),
(*TemplateType_Flow)(nil),
(*TemplateType_Manifest)(nil),
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_sidechain_types_proto_rawDesc), len(file_sidechain_types_proto_rawDesc)),
NumEnums: 0,
NumMessages: 9,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_sidechain_types_proto_goTypes,
DependencyIndexes: file_sidechain_types_proto_depIdxs,
MessageInfos: file_sidechain_types_proto_msgTypes,
}.Build()
File_sidechain_types_proto = out.File
file_sidechain_types_proto_goTypes = nil
file_sidechain_types_proto_depIdxs = nil
}

View File

@@ -0,0 +1,188 @@
// Copyright 2020. The Tari Project
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
// following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
// disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
// following disclaimer in the documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
// products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto3";
package tari.rpc;
import "types.proto";
import "sidechain_types.proto";
// The transaction kernel tracks the excess for a given transaction. For an explanation of what the excess is, and
// why it is necessary, refer to the
// [Mimblewimble TLU post](https://tlu.tarilabs.com/protocols/mimblewimble-1/sources/PITCHME.link.html?highlight=mimblewimble#mimblewimble).
// The kernel also tracks other transaction metadata, such as the lock height for the transaction (i.e. the earliest
// this transaction can be mined) and the transaction fee, in cleartext.
message TransactionKernel {
// Options for a kernel's structure or use
uint32 features = 1;
/// Fee originally included in the transaction this proof is for (in MicroMinotari)
uint64 fee = 2;
// This kernel is not valid earlier than lock_height blocks
// The max lock_height of all *inputs* to this transaction
uint64 lock_height = 3;
// Remainder of the sum of all transaction commitments. If the transaction
// is well formed, amounts components should sum to zero and the excess
// is hence a valid public key.
bytes excess = 6;
// The signature proving the excess is a valid public key, which signs
// the transaction fee.
Signature excess_sig = 7;
// The hash of the kernel, as it appears in the MMR
bytes hash = 8;
// Version
uint32 version = 9;
// Optional burned commitment
bytes burn_commitment = 10;
}
// A transaction input.
//
// Primarily a reference to an output being spent by the transaction.
message TransactionInput {
// The features of the output being spent. We will check maturity for all outputs.
OutputFeatures features = 1;
// The commitment referencing the output being spent.
bytes commitment = 2;
// Hash of the input, as it appears in the MMR
bytes hash = 3;
// The serialised script
bytes script = 4;
// The script input data, if any
bytes input_data = 5;
// A signature with k_s, signing the script, input data, and mined height
ComAndPubSignature script_signature = 7;
// The offset public key, K_O
bytes sender_offset_public_key = 8;
// The hash of the output this input is spending
bytes output_hash = 9;
// Covenant
bytes covenant = 10;
// Version
uint32 version = 11;
// The encrypted data
bytes encrypted_data = 12;
// The minimum value of the commitment that is proven by the range proof (in MicroMinotari)
uint64 minimum_value_promise = 13;
// The metadata signature for output this input is spending
ComAndPubSignature metadata_signature = 14;
// The rangeproof hash for output this input is spending
bytes rangeproof_hash = 15;
}
// Output for a transaction, defining the new ownership of coins that are being transferred. The commitment is a
// blinded value for the output while the range proof guarantees the commitment includes a positive value without
// overflow and the ownership of the private key.
message TransactionOutput {
// Options for an output's structure or use
OutputFeatures features = 1;
// The homomorphic commitment representing the output amount
bytes commitment = 2;
// A proof that the commitment is in the right range
RangeProof range_proof = 3;
// The hash of the output, as it appears in the MMR
bytes hash = 4;
// Tari script serialised script
bytes script = 5;
// Tari script offset public key, K_O
bytes sender_offset_public_key = 6;
// Metadata signature with the homomorphic commitment private values (amount and blinding factor) and the sender
// offset private key
ComAndPubSignature metadata_signature = 7;
// Covenant
bytes covenant = 8;
// Version
uint32 version = 9;
// Encrypted Pedersen commitment openings (value and mask) for the output
bytes encrypted_data = 10;
// The minimum value of the commitment that is proven by the range proof (in MicroMinotari)
uint64 minimum_value_promise = 11;
// Payment reference (PayRef) - 32-byte Blake2b hash of (block_hash || output_hash)
// This provides a unique, deterministic reference for the output that can be used
// for payment verification without revealing wallet ownership
bytes payment_reference = 12;
}
// Options for UTXOs
message OutputFeatures {
// Version
uint32 version = 1;
// The type of output, eg Coinbase, all of which have different consensus rules
uint32 output_type = 2;
// The maturity of the specific UTXO. This is the min lock height at which an UTXO can be spend. Coinbase UTXO
// require a min maturity of the Coinbase_lock_height, this should be checked on receiving new blocks.
uint64 maturity = 3;
// Additional arbitrary info in coinbase transactions supplied by miners
bytes coinbase_extra = 4;
// Features that are specific to a side chain
SideChainFeature sidechain_feature = 5;
// The type of range proof used in the output
uint32 range_proof_type = 6;
}
// The components of the block or transaction. The same struct can be used for either, since in Mimblewimble,
// cut-through means that blocks and transactions have the same structure. The inputs, outputs and kernels should
// be sorted by their Blake2b-256bit digest hash
message AggregateBody {
// List of inputs spent by the transaction.
repeated TransactionInput inputs = 1;
// List of outputs the transaction produces.
repeated TransactionOutput outputs = 2;
// Kernels contain the excesses and their signatures for transaction
repeated TransactionKernel kernels = 3;
}
// A transaction which consists of a kernel offset and an aggregate body made up of inputs, outputs and kernels.
message Transaction {
bytes offset = 1;
AggregateBody body = 2;
bytes script_offset = 3;
}
message UnblindedOutput {
// Value of the output
uint64 value = 1;
// Spending key of the output
bytes spending_key = 2;
// Options for an output's structure or use
OutputFeatures features = 3;
// Tari script serialised script
bytes script = 4;
// Tari script input data for spending
bytes input_data = 5;
// Tari script private key
bytes script_private_key = 7;
// Tari script offset pubkey, K_O
bytes sender_offset_public_key = 8;
// UTXO signature with the script offset private key, k_O
ComAndPubSignature metadata_signature = 9;
// The minimum height the script allows this output to be spent
uint64 script_lock_height = 10;
// Covenant
bytes covenant = 11;
// Encrypted data
bytes encrypted_data = 12;
// The minimum value of the commitment that is proven by the range proof (in MicroMinotari)
uint64 minimum_value_promise = 13;
// The range proof
RangeProof range_proof = 14;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,147 @@
// Copyright 2020. The Tari Project
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
// following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
// disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
// following disclaimer in the documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
// products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto3";
package tari.rpc;
/// An unsigned range interface to more accurately represent Rust native Range's
message Range {
uint64 min = 1;
uint64 max = 2;
}
/// An Empty placeholder for endpoints without request parameters
message Empty {}
/// Define an interface for block height
message BlockHeight {
uint64 block_height = 1;
}
// Define the explicit Signature implementation for the Minotari base layer. A different signature scheme can be
// employed by redefining this type.
message Signature {
bytes public_nonce = 1;
bytes signature = 2;
}
// Define the explicit ComAndPubSignature implementation for the Minotari base layer. A different signature scheme can be
// employed by redefining this type.
message ComAndPubSignature {
bytes ephemeral_commitment = 1;
bytes ephemeral_pubkey = 2;
bytes u_a = 3;
bytes u_x = 4;
bytes u_y = 5;
}
// Define the explicit CommitmentSignature implementation for the Minotari base layer. A different signature scheme can be
// employed by redefining this type
message CommitmentSignature {
bytes public_nonce = 1;
bytes u = 2;
bytes v = 3;
}
/// PoW Algorithm constants
message PowAlgorithmConstants {
uint64 min_difficulty = 2;
uint64 max_difficulty = 3;
uint64 target_time = 4;
}
/// Weight params
message WeightParams {
uint64 kernel_weight = 1;
uint64 input_weight = 2;
uint64 output_weight = 3;
uint64 features_and_scripts_bytes_per_gram = 4;
}
/// Output version
message OutputsVersion {
Range outputs = 1;
Range features = 2;
}
/// Output types
enum OutputType {
STANDARD = 0;
COINBASE = 1;
BURN = 2;
VALIDATOR_NODE_REGISTRATION = 3;
CODE_TEMPLATE_REGISTRATION = 4;
}
/// Range proof types
enum RangeProofType {
BULLETPROOF_PLUS = 0;
REVEALED_VALUE = 1;
}
message PermittedRangeProofs {
OutputType output_type = 1;
repeated RangeProofType range_proof_types = 2;
}
/// Range proof
message RangeProof {
bytes proof_bytes = 1;
}
/// Consensus Constants response
message ConsensusConstants {
uint64 coinbase_min_maturity = 1;
uint32 blockchain_version = 2;
uint64 future_time_limit = 3;
uint64 difficulty_block_window = 5;
uint64 max_block_transaction_weight = 7;
uint64 pow_algo_count = 8;
uint64 median_timestamp_count = 9;
uint64 emission_initial = 10;
repeated uint64 emission_decay = 11;
uint64 emission_tail = 12 [deprecated=true];
uint64 min_sha3x_pow_difficulty = 13;
uint64 block_weight_inputs = 14;
uint64 block_weight_outputs = 15;
uint64 block_weight_kernels = 16;
uint64 pre_mine_value = 17;
uint64 max_script_byte_size = 18;
uint64 validator_node_validity_period = 19;
uint64 effective_from_height = 20;
Range valid_blockchain_version_range = 21;
uint64 max_randomx_seed_height = 22;
map<uint32, PowAlgorithmConstants> proof_of_work = 23;
WeightParams transaction_weight = 24;
Range input_version_range = 26;
OutputsVersion output_version_range = 27;
Range kernel_version_range = 28;
repeated OutputType permitted_output_types = 29;
uint64 epoch_length = 30;
uint64 validator_node_registration_min_deposit_amount = 31;
uint64 validator_node_registration_min_lock_height = 32;
uint64 validator_node_registration_shuffle_interval_epoch = 33;
repeated PermittedRangeProofs permitted_range_proof_types = 34;
uint64 inflation_bips = 35;
uint64 tail_epoch_length = 36;
uint64 max_block_coinbase_count = 37;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,132 @@
// Copyright 2021. The Tari Project
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
// following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
// disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
// following disclaimer in the documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
// products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto3";
import "types.proto";
import "network.proto";
import "transaction.proto";
package tari.rpc;
service ValidatorNode {
rpc GetIdentity(GetIdentityRequest) returns (GetIdentityResponse);
rpc GetMetadata(GetMetadataRequest) returns (GetMetadataResponse);
rpc GetTokenData(GetTokenDataRequest) returns (GetTokenDataResponse);
// rpc ExecuteInstruction(ExecuteInstructionRequest) returns (ExecuteInstructionResponse);
rpc InvokeReadMethod(InvokeReadMethodRequest) returns (InvokeReadMethodResponse);
rpc InvokeMethod(InvokeMethodRequest) returns (InvokeMethodResponse);
rpc GetConstitutionRequests(GetConstitutionRequestsRequest) returns (stream TransactionOutput);
rpc PublishContractAcceptance(PublishContractAcceptanceRequest) returns (PublishContractAcceptanceResponse);
rpc PublishContractUpdateProposalAcceptance(PublishContractUpdateProposalAcceptanceRequest) returns (PublishContractUpdateProposalAcceptanceResponse);
}
message GetConstitutionRequestsRequest {
// empty
}
message GetMetadataRequest {
// empty
}
message PublishContractAcceptanceRequest {
bytes contract_id = 1;
}
message PublishContractAcceptanceResponse {
string status = 1;
uint64 tx_id = 2;
}
message PublishContractUpdateProposalAcceptanceRequest {
bytes contract_id = 1;
uint64 proposal_id = 2;
}
message PublishContractUpdateProposalAcceptanceResponse {
string status = 1;
uint64 tx_id = 2;
}
message GetMetadataResponse {
repeated SidechainMetadata sidechains = 1;
}
message SidechainMetadata {
bytes asset_public_key =1;
uint64 committed_height = 2;
bytes committed_hash = 3;
}
message GetTokenDataRequest {
bytes asset_pub_key = 1;
bytes unique_id = 2;
}
message GetTokenDataResponse {
}
//message ExecuteInstructionRequest{
// bytes asset_public_key = 1;
// uint32 template_id = 2;
// string method = 3;
// bytes args = 4;
//// bytes token_id = 5;
//// bytes signature = 6;
//}
//
//message ExecuteInstructionResponse {
// string status = 1;
// optional bytes result = 2;
//}
message InvokeReadMethodRequest{
bytes contract_id = 1;
uint32 template_id = 2;
string method = 3;
bytes args = 4;
bytes sender = 5;
}
message InvokeReadMethodResponse {
bytes result = 1;
Authority authority = 2;
}
message Authority {
bytes node_public_key =1;
bytes signature = 2;
bytes proxied_by = 3;
}
message InvokeMethodRequest {
bytes contract_id = 1;
uint32 template_id = 2;
string method = 3;
bytes args = 4;
bytes sender = 5;
}
message InvokeMethodResponse {
string status = 1;
bytes result = 2;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,385 @@
package sha3x
import (
"context"
"crypto/rand"
"database/sql"
"encoding/binary"
"encoding/hex"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"pool/internal/db"
"pool/internal/gbt/coin"
"pool/internal/gbt/dbif"
"pool/internal/gbt/tari"
"pool/internal/msg"
"pool/internal/utility"
"sync"
"sync/atomic"
"time"
"go.uber.org/zap"
)
const GBT_SHA3X_VERSION string = "sha3x v1.0"
type Sha3xAddrConfig struct {
Addr string `json:"addr"`
}
type Sha3xConfig struct {
Monero Sha3xAddrConfig `json:"sha3x"`
}
type GbtSha3xContext struct {
Config Sha3xConfig
GbtCtx *coin.GbtContext
Ctx context.Context
last_time time.Time
last_gbt tari.TariBlockTemplate
last_blockhash string
last_height uint64
Submits float64
addressIndex int
Target []byte
Header []byte
last_body string
Jobs sync.Map
JobIds []string
JobGenCount int
new_block_chan chan int
new_block_index int
}
var logg *zap.Logger
var GbtSha3xCtx GbtSha3xContext
func configInit(config *Sha3xConfig) {
data, err := ioutil.ReadFile("gbt.conf")
if err != nil {
panic(err.Error())
}
if err = json.Unmarshal(data, &config); err != nil {
panic(err.Error())
}
}
func Init(GbtCtx *coin.GbtContext, DbCtx *db.DbContext) {
GbtSha3xCtx.GbtCtx = GbtCtx
GbtSha3xCtx.last_height = 0
configInit(&GbtSha3xCtx.Config)
GbtSha3xCtx.JobGenCount = 0
GbtSha3xCtx.Target = make([]byte, 32)
GbtSha3xCtx.Header = make([]byte, 49)
GbtSha3xCtx.last_time = time.Now()
GbtSha3xCtx.Ctx = context.Background()
logg = GbtCtx.Log
GbtSha3xCtx.new_block_chan = make(chan int, 256)
GbtSha3xCtx.new_block_index = 0
logg.Info("[gbt]", zap.String("gbt_sha3x_version", GBT_SHA3X_VERSION))
}
func Start() {
go gbt_running(&GbtSha3xCtx)
go gbt_notify_running(&GbtSha3xCtx)
go submit_block_running(&GbtSha3xCtx)
}
func Stop() {
defer close(GbtSha3xCtx.new_block_chan)
}
func update_block_confirm(gbt *GbtSha3xContext) {
}
func randomxJobId() string {
// 生成4个字节
bytes := make([]byte, 4)
_, err := rand.Read(bytes)
if err != nil {
panic(err)
}
// 转成 hex 字符串
hexStr := hex.EncodeToString(bytes)
return hexStr
}
func removeJobs(gbt *GbtSha3xContext, clean bool) {
if !clean {
if len(gbt.JobIds) > 10 {
end := len(gbt.JobIds) - 10
for i := 0; i < end; i++ {
gbt.Jobs.Delete(gbt.JobIds[i])
}
gbt.JobIds = gbt.JobIds[end:]
}
} else {
gbt.Jobs.Range(func(key, value interface{}) bool {
gbt.Jobs.Delete(key)
return true
})
gbt.JobIds = nil
gbt.JobGenCount = 0
}
}
func gbt_running(gbt *GbtSha3xContext) {
ticker := time.NewTicker(1000 * time.Millisecond)
defer ticker.Stop()
for gbt.GbtCtx.Started {
select {
case <-ticker.C:
// 获取区块模板
blockTemplate, err := gbt.GbtCtx.TariClient.GetBlockTemplate(gbt.Ctx, 1)
if err != nil || len(blockTemplate.Header) != 638 {
fmt.Println("任务模板中的区块头长度:", len(blockTemplate.Header))
return
}
// 初始化 ZMQ 发布通道
if gbt.GbtCtx.PubCh == nil {
gbt.GbtCtx.PubCh = utility.InitZmqPub(gbt.GbtCtx.Config.Zmq.Pub)
continue
}
height := blockTemplate.Height
if height == gbt.last_height {
removeJobs(gbt, false)
if gbt.JobGenCount >= 10 {
generateJob(gbt, &blockTemplate)
gbt.JobGenCount = 0 // 成功生成 Job 后重置计数器
}
} else {
removeJobs(gbt, true)
generateJob(gbt, &blockTemplate)
gbt.last_height = height
gbt.JobGenCount = 0 // 高度变化也重置计数器
}
// 标记存活
atomic.StoreInt32(&(gbt.GbtCtx.FlagAliving), 1)
// 无论是否需要发布新任务,计数均+1保持至少10秒更新一次任务
gbt.JobGenCount += 1
case blkIdx := <-gbt.new_block_chan:
log.Println("new block chan", blkIdx)
update_block_confirm(gbt)
case <-gbt.GbtCtx.ExitGbtChan:
logg.Error("[gbt]", zap.String("gbt", "exit"))
return
}
}
}
func generateJob(gbt *GbtSha3xContext, blockTemplate *tari.TariBlockTemplate) {
for trycnt := 0; trycnt < 3; trycnt++ {
job := msg.Sha3xJob{
JobId: randomxJobId(),
MiningHash: blockTemplate.MiningHash,
Header: blockTemplate.Header,
Body: blockTemplate.Body,
TargetDifficulty: blockTemplate.TargetDifficulty,
Height: blockTemplate.Height,
}
sendMsg := msg.Sha3xStratumJob{
JobId: job.JobId,
Header: job.MiningHash,
U64target: job.TargetDifficulty,
Height: uint32(job.Height),
}
bt, err := json.Marshal(sendMsg)
if err != nil {
fmt.Println(err)
continue
}
// 保存 Job
gbt.Jobs.LoadOrStore(job.JobId, job)
gbt.JobIds = append(gbt.JobIds, job.JobId)
// 发布 Job
if err := gbt.GbtCtx.PubCh.SendMessage([][]byte{[]byte("jobsha3x"), bt}); err != nil {
logg.Warn("[gbt]", zap.String("job", err.Error()))
continue
}
logg.Warn("[gbt]", zap.String("job", "sent"))
gbt.JobGenCount++
break
}
}
func gbt_notify_running(gbt *GbtSha3xContext) {
for {
if !gbt.GbtCtx.Started {
break
}
if gbt.GbtCtx.MoneroNewBlockSubCh == nil {
gbt.GbtCtx.MoneroNewBlockSubCh = utility.InitZmqSub(gbt.GbtCtx.Config.Rpc.ZmqSub, utility.BITCOIND_ZMQ_HASHBLOCK)
}
if gbt.GbtCtx.MoneroNewBlockSubCh != nil {
cmsg_sub, err := gbt.GbtCtx.MoneroNewBlockSubCh.RecvMessage()
if err != nil {
if !gbt.GbtCtx.Started {
break
}
gbt.GbtCtx.MoneroNewBlockSubCh.SetSubscribe(utility.BITCOIND_ZMQ_HASHBLOCK)
gbt.GbtCtx.MoneroNewBlockSubCh.Connect(gbt.GbtCtx.Config.Rpc.ZmqSub)
continue
}
if len(cmsg_sub) >= 2 {
if string(cmsg_sub[0]) == "hashblock" {
GbtSha3xCtx.new_block_index = GbtSha3xCtx.new_block_index + 1
//log.Println("gbt_notify_running", hex.EncodeToString(cmsg_sub[1]), GbtNexaCtx.new_block_index)
gbt.new_block_chan <- GbtSha3xCtx.new_block_index
}
}
} else {
logg.Error("[gbt]", zap.String("notify", "NodeSubCh fail!"))
time.Sleep(time.Duration(1) * time.Second)
}
}
}
type ServerSubmitBlock struct {
JobId string
Header []byte
Body []byte
Nonce string
}
func submit_block_running(block *GbtSha3xContext) {
logg.Info("[block]", zap.String("submit_block_running", "Start."))
for {
if !block.GbtCtx.Started {
break
}
if block.GbtCtx.SubCh == nil {
block.GbtCtx.SubCh = utility.InitZmqSub(block.GbtCtx.Config.Zmq.Sub, "blk"+block.GbtCtx.Coin)
}
if block.GbtCtx.SubCh != nil {
cmsg_sub, err := block.GbtCtx.SubCh.RecvMessage()
if err != nil {
if !block.GbtCtx.Started {
break
}
time.Sleep(time.Duration(1) * time.Second)
block.GbtCtx.SubCh.SetSubscribe("blk" + block.GbtCtx.Coin)
block.GbtCtx.SubCh.Connect(block.GbtCtx.Config.Zmq.Sub)
continue
}
if len(cmsg_sub) >= 2 {
if string(cmsg_sub[0]) == "blksha3x" {
cmsg := cmsg_sub[1]
//block data
msgb := make([]byte, len(cmsg)-16)
copy(msgb, cmsg)
var submitMsg msg.BlockSha3xMsg
if err := json.Unmarshal(msgb, &submitMsg); err != nil {
//block.Consumer.MarkOffset(cmsg, "")
logg.Error("[block]", zap.String("failed to Unmarshal job", err.Error()))
continue
}
var height = submitMsg.Height
logg.Warn("[block]", zap.Uint64("height", height))
if height <= block.last_height {
continue
}
block.last_height = height
indexb, err1 := hex.DecodeString(string(cmsg[len(msgb)+8:]))
if err1 != nil {
logg.Error("[block]", zap.String("failed to decode index", err1.Error()))
continue
}
var index uint32 = utility.ByteToUint32(indexb)
logg.Warn("[block]", zap.Uint32("index", index))
logg.Debug("[block]", zap.String("msg", string(cmsg)), zap.String("blk", string(msgb)))
if v, ok := block.Jobs.Load(submitMsg.Id); ok {
job := v.(*msg.Sha3xJob) // 类型断言
headerStr, bodyStr := job.Header, job.Body
header, err := hex.DecodeString(headerStr)
if err != nil {
fmt.Println(err)
return
}
body, err := hex.DecodeString(bodyStr)
if err != nil {
fmt.Println(err)
return
}
nonceByte := make([]byte, 8)
binary.LittleEndian.PutUint64(nonceByte, submitMsg.Nonce)
copy(header[311:319], nonceByte)
blockHash_byte, _ := block.GbtCtx.TariClient.SubmitBlock(block.Ctx, header, body)
nonceStr := fmt.Sprintf("%x", submitMsg.Nonce)
blockHash := hex.EncodeToString(blockHash_byte)
dbif.NotifyPoolBlkStatsSubmitResult(block.GbtCtx, int64(height), blockHash, "OK", nonceStr, submitMsg.SubIdx)
block.Submits += 1
logg.Warn("[block]", zap.Float64("total submits", block.Submits), zap.Int64("SubIdx", submitMsg.SubIdx))
new_block_into_db(block, submitMsg.User, submitMsg.Miner, submitMsg.Index, int64(height), nonceStr, blockHash, submitMsg.SubIdx)
}
}
}
} else {
logg.Error("[block]", zap.String("block", "SubCh failed! retry"))
time.Sleep(time.Duration(1) * time.Second)
}
}
}
func new_block_into_db(block *GbtSha3xContext, user string, miner string, minerid string, height int64, nonce string, hash string, subidx int64) bool {
db, err := sql.Open("sqlite3", "./blocks.db")
if err != nil {
log.Printf("Error opening database: %v", err)
return false
}
defer db.Close()
createTableSQL := `
CREATE TABLE IF NOT EXISTS blocks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user TEXT NOT NULL,
miner TEXT NOT NULL,
minerid TEXT NOT NULL,
height INTEGER,
nonce TEXT NOT NULL,
hash TEXT NOT NULL,
subidx INTEGER,
checked INTEGER,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);`
_, err = db.Exec(createTableSQL)
if err != nil {
log.Printf("Error creating table: %v", err)
return false
}
insertSQL := `INSERT INTO blocks (user, miner, minerid, height, nonce, checked, hash, subidx) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`
_, err = db.Exec(insertSQL, user, miner, minerid, height, nonce, 0, hash, subidx)
if err != nil {
log.Printf("Error inserting data from blocks %s: %v", fmt.Sprint(height), err)
return false
}
return true
}

120
internal/gbt/tari/tari.go Normal file
View File

@@ -0,0 +1,120 @@
package tari
import (
"context"
"encoding/base64"
"encoding/hex"
"fmt"
base_node "pool/internal/gbt/tari/proto"
block "pool/internal/gbt/tari/proto/block"
"google.golang.org/grpc"
)
// var PowAlgoMap = []string{"randomxM", "sha3x", "randomxT"}
type BaseNodeClient struct {
Conn *grpc.ClientConn
Client base_node.BaseNodeClient
}
// 创建BaseNode客户端
func NewBaseNodeClient(address string) (*BaseNodeClient, error) {
conn, err := grpc.Dial(address, grpc.WithInsecure())
if err != nil {
return nil, fmt.Errorf("failed to connect to base node: %v", err)
}
// 移除 defer conn.Close(),让连接保持打开状态
client := base_node.NewBaseNodeClient(conn)
return &BaseNodeClient{
Conn: conn,
Client: client,
}, nil
}
// Close 关闭GRPC连接
func (c *BaseNodeClient) Close() error {
if c.Conn != nil {
return c.Conn.Close()
}
return nil
}
type TariBlockTemplate struct {
MiningHash string
Header string
Body string
Height uint64
TargetDifficulty uint64
}
func base64ToHex(data string) (string, error) {
result, err := base64.StdEncoding.DecodeString(data)
if err != nil {
return "", err
}
return hex.EncodeToString(result), nil
}
func (nc *BaseNodeClient) GetBlockTemplate(ctx context.Context, powIndex uint32) (TariBlockTemplate, error) {
var pow_algo block.PowAlgo_PowAlgos
switch powIndex {
case 0:
pow_algo = block.PowAlgo_POW_ALGOS_RANDOMXM
case 1:
pow_algo = block.PowAlgo_POW_ALGOS_SHA3X
case 2:
pow_algo = block.PowAlgo_POW_ALGOS_RANDOMXT
default:
fmt.Println("不支持", powIndex, "算法")
}
templateReq := &base_node.NewBlockTemplateRequest{
Algo: &block.PowAlgo{
PowAlgo: pow_algo,
},
MaxWeight: 0x00,
}
templateResp, err := nc.Client.GetNewBlockTemplate(ctx, templateReq)
if err != nil {
fmt.Println(pow_algo, "获取区块模板失败:", err)
return TariBlockTemplate{}, err
}
// 节点未同步完成
if !templateResp.InitialSyncAchieved {
fmt.Println("节点还未完成同步")
return TariBlockTemplate{}, err
}
blk_template, miner_data := templateResp.NewBlockTemplate, templateResp.MinerData
targetDifficulty := miner_data.TargetDifficulty
height := blk_template.Header.Height
blockBlob, err := nc.Client.GetNewBlockBlob(ctx, blk_template)
if err != nil {
fmt.Println("获得block blob失败", err)
return TariBlockTemplate{}, err
}
mining_hash, header, body := blockBlob.BlockHash, blockBlob.Header, blockBlob.BlockBody
var t_bt = TariBlockTemplate{
MiningHash: hex.EncodeToString(mining_hash),
Header: hex.EncodeToString(header),
Body: hex.EncodeToString(body),
TargetDifficulty: targetDifficulty,
Height: height,
}
return t_bt, nil
}
func (nc *BaseNodeClient) SubmitBlock(ctx context.Context, header, body []byte) ([]byte, error) {
submitReq := &base_node.BlockBlobRequest{
HeaderBlob: header,
BodyBlob: body,
}
submitResp, err := nc.Client.SubmitBlockBlob(ctx, submitReq)
if err != nil {
fmt.Println("提交区块失败:", err)
return nil, err
}
blockHash := submitResp.BlockHash
return blockHash, nil
}