Commit 5ebc93d3 authored by 贾浩@五瓣科技's avatar 贾浩@五瓣科技

update api

parent c09f8572
package api
const (
InvalidParams = "invalid params"
DateOutOfRange = "date out of range"
InternalError = "internal error"
)
package api
import (
"encoding/json"
"net/http"
"time"
"github.com/ethereum/go-ethereum/common"
)
func rpcHandle(w http.ResponseWriter, r *http.Request) {
req := &jsonrpcMessage{}
resp := &jsonrpcMessage{}
if r.Method != "POST" {
w.Write([]byte("method not allowed"))
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
w.Header().Set("Content-Type", "application/json")
contentType := r.Header.Get("Content-Type")
if contentType != "application/json" {
resp.Error = &jsonError{
Code: -32600,
Message: "invalid Content-Type header",
}
resp.Version = "2.0"
_ = json.NewEncoder(w).Encode(resp)
return
}
err := json.NewDecoder(r.Body).Decode(req)
if err != nil {
resp.Error = &jsonError{
Code: -32603,
Message: err.Error(),
}
resp.Version = "2.0"
_ = json.NewEncoder(w).Encode(resp)
return
}
if req.Version != "2.0" {
resp.Error = &jsonError{
Code: -32600,
Message: "invalid jsonrpc version",
}
resp.Version = "2.0"
_ = json.NewEncoder(w).Encode(resp)
return
}
resp.Version = req.Version
resp.ID = req.ID
switch req.Method {
case "getWithdrawProofs":
getWithdrawProofs(req.Params, resp)
_ = json.NewEncoder(w).Encode(resp)
return
case "getPendingWorkload":
getPendingWorkload(req.Params, resp)
_ = json.NewEncoder(w).Encode(resp)
return
case "getDailyMerkleNodes":
getDailyMerkleNodes(req.Params, resp)
_ = json.NewEncoder(w).Encode(resp)
case "getDailyMerkleSumNodes":
getDailyMerkleSumNodes(req.Params, resp)
_ = json.NewEncoder(w).Encode(resp)
default:
resp.Error = &jsonError{
Code: -32601,
Message: "method not found",
}
_ = json.NewEncoder(w).Encode(resp)
return
}
}
func getWithdrawProofs(params []byte, resp *jsonrpcMessage) {
paramList := make([]string, 0)
err := json.Unmarshal(params, &paramList)
if err != nil || len(paramList) < 1 || len(paramList) > 2 {
resp.Error = &jsonError{
Code: -32602,
Message: "invalid params",
}
return
}
if !common.IsHexAddress(paramList[0]) {
resp.Error = &jsonError{
Code: -32602,
Message: "invalid params",
}
return
}
var date string
if len(paramList) > 1 {
_, err = time.Parse("2006-01-02", paramList[1])
if err != nil {
resp.Error = &jsonError{
Code: -32602,
Message: "invalid params",
}
return
}
date = paramList[1]
}
amount, proofs := validator.GetMerkleProof(common.HexToAddress(paramList[0]), date)
temp := map[string]interface{}{
"amount": amount,
"proofs": proofs,
}
resp.Result, _ = json.Marshal(temp)
return
}
func getPendingWorkload(params []byte, resp *jsonrpcMessage) {
addressList := make([]string, 0)
err := json.Unmarshal(params, &addressList)
if err != nil || len(addressList) != 1 {
resp.Error = &jsonError{
Code: -32602,
Message: "invalid params",
}
return
}
if !common.IsHexAddress(addressList[0]) {
resp.Error = &jsonError{
Code: -32602,
Message: "invalid params",
}
return
}
workload, globalWorkload := validator.GetPendingWorkload(common.HexToAddress(addressList[0]))
temp := map[string]interface{}{
"workload": workload,
"global_workload": globalWorkload,
}
resp.Result, _ = json.Marshal(temp)
return
}
func getDailyMerkleNodes(params []byte, resp *jsonrpcMessage) {
// date string, depth int, rootHash common.Hash
paramList := make([]interface{}, 0)
err := json.Unmarshal(params, &paramList)
if err != nil || len(paramList) < 1 || len(paramList) > 3 {
resp.Error = &jsonError{
Code: -32602,
Message: "invalid params",
}
return
}
var date string
var depth = 1
var rootHash common.Hash
_, err = time.Parse("2006-01-02", paramList[0].(string))
if err != nil {
resp.Error = &jsonError{
Code: -32602,
Message: "invalid params",
}
return
}
date = paramList[0].(string)
if len(paramList) >= 2 {
_depth, ok := paramList[1].(float64)
if !ok {
resp.Error = &jsonError{
Code: -32602,
Message: "invalid params",
}
return
}
depth = int(uint(_depth))
}
if len(paramList) >= 3 {
rootHash = common.HexToHash(paramList[2].(string))
}
nodes := validator.GetDailyMerkleNodes(date, depth, rootHash)
resp.Result, _ = json.Marshal(nodes)
}
func getDailyMerkleSumNodes(params []byte, resp *jsonrpcMessage) {
// date string, depth int, rootHash common.Hash
paramList := make([]interface{}, 0)
err := json.Unmarshal(params, &paramList)
if err != nil || len(paramList) < 1 || len(paramList) > 3 {
resp.Error = &jsonError{
Code: -32602,
Message: "invalid params",
}
return
}
var date string
var depth = 1
var rootHash common.Hash
_, err = time.Parse("2006-01-02", paramList[0].(string))
if err != nil {
resp.Error = &jsonError{
Code: -32602,
Message: "invalid params",
}
return
}
date = paramList[0].(string)
if len(paramList) >= 2 {
_depth, ok := paramList[1].(float64)
if !ok {
resp.Error = &jsonError{
Code: -32602,
Message: "invalid params",
}
return
}
depth = int(uint(_depth))
}
if len(paramList) >= 3 {
rootHash = common.HexToHash(paramList[2].(string))
}
nodes, vals := validator.GetDailyMerkleSumNodes(date, depth, rootHash)
resp.Result, _ = json.Marshal(map[string]interface{}{
"nodes": nodes,
"values": vals,
})
}
package api
import (
"github.com/gin-gonic/gin"
)
func initRouter(engine *gin.Engine) {
g := engine.Group("/api/v1")
g.POST("/workload", getWorkload)
g.POST("/reward", getReward)
g.POST("/record", getRecord)
}
\ No newline at end of file
package api
import (
"encoding/json"
"net/http"
"fmt"
"math/big"
"strconv"
"time"
"validator/claim_monitor"
"validator/core"
"github.com/ethereum/go-ethereum/common"
log "github.com/sirupsen/logrus"
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
)
var validator *core.Validator
func rpcHandle(w http.ResponseWriter, r *http.Request) {
req := &jsonrpcMessage{}
resp := &jsonrpcMessage{}
if r.Method != "POST" {
w.Write([]byte("method not allowed"))
w.WriteHeader(http.StatusMethodNotAllowed)
var claimMonitorCli *claim_monitor.Client
var log = logrus.WithField("module", "api")
func getWorkload(c *gin.Context) {
// 每天的workload获取
dateList := make([]string, 0)
if err := c.ShouldBindJSON(&dateList); err != nil {
c.JSON(200, withError(InvalidParams))
return
}
w.Header().Set("Content-Type", "application/json")
contentType := r.Header.Get("Content-Type")
if contentType != "application/json" {
resp.Error = &jsonError{
Code: -32600,
Message: "invalid Content-Type header",
timestampList := make([]uint64, 0)
for _, date := range dateList {
t, err := time.Parse("2006-01-02", date)
if err != nil {
c.JSON(200, withError(DateOutOfRange))
return
}
resp.Version = "2.0"
_ = json.NewEncoder(w).Encode(resp)
return
}
err := json.NewDecoder(r.Body).Decode(req)
if err != nil {
resp.Error = &jsonError{
Code: -32603,
Message: err.Error(),
utcNow := time.Now().UTC()
if t.After(time.Date(utcNow.Year(), utcNow.Month(), utcNow.Day(), 0, 0, 0, 0, time.UTC)) {
c.JSON(200, withError(DateOutOfRange))
return
}
resp.Version = "2.0"
_ = json.NewEncoder(w).Encode(resp)
return
}
if req.Version != "2.0" {
resp.Error = &jsonError{
Code: -32600,
Message: "invalid jsonrpc version",
}
resp.Version = "2.0"
_ = json.NewEncoder(w).Encode(resp)
return
timestampList = append(timestampList, uint64(t.Unix()))
}
resp.Version = req.Version
resp.ID = req.ID
switch req.Method {
case "getWithdrawProofs":
getWithdrawProofs(req.Params, resp)
_ = json.NewEncoder(w).Encode(resp)
return
case "getPendingWorkload":
getPendingWorkload(req.Params, resp)
_ = json.NewEncoder(w).Encode(resp)
return
case "getDailyMerkleNodes":
getDailyMerkleNodes(req.Params, resp)
_ = json.NewEncoder(w).Encode(resp)
case "getDailyMerkleSumNodes":
getDailyMerkleSumNodes(req.Params, resp)
_ = json.NewEncoder(w).Encode(resp)
default:
resp.Error = &jsonError{
Code: -32601,
Message: "method not found",
}
_ = json.NewEncoder(w).Encode(resp)
return
ret, err := validator.GetWorkload(timestampList)
if err != nil {
log.WithError(err).Error("failed to get workload")
c.JSON(200, withError(InternalError))
}
c.JSON(200, withSuccess(ret))
}
func getWithdrawProofs(params []byte, resp *jsonrpcMessage) {
paramList := make([]string, 0)
err := json.Unmarshal(params, &paramList)
if err != nil || len(paramList) < 1 || len(paramList) > 2 {
resp.Error = &jsonError{
Code: -32602,
Message: "invalid params",
}
func getReward(c *gin.Context) {
// 在这里获取全部,再通过api获取已领取的
tmp := struct {
Address string `json:"address"`
}{}
if err := c.ShouldBindJSON(&tmp); err != nil {
c.JSON(200, withError(InvalidParams))
return
}
if !common.IsHexAddress(paramList[0]) {
resp.Error = &jsonError{
Code: -32602,
Message: "invalid params",
}
if !common.IsHexAddress(tmp.Address) {
c.JSON(200, withError(InvalidParams))
return
}
reward := validator.GetReward(common.HexToAddress(tmp.Address))
ether := big.NewInt(1000000000000000000)
var date string
if len(paramList) > 1 {
_, err = time.Parse("2006-01-02", paramList[1])
if err != nil {
resp.Error = &jsonError{
Code: -32602,
Message: "invalid params",
}
return
}
date = paramList[1]
}
amount, proofs := validator.GetMerkleProof(common.HexToAddress(paramList[0]), date)
floatReward, _ := new(big.Float).Quo(new(big.Float).SetInt(reward), new(big.Float).SetInt(ether)).Float64()
temp := map[string]interface{}{
"amount": amount,
"proofs": proofs,
claimedReward, err := claimMonitorCli.GetClaimedAmount(tmp.Address)
if err != nil {
log.WithError(err).Error("failed to get claimed reward")
c.JSON(200, withError(InternalError))
return
}
floatClaimedReward, _ := strconv.ParseFloat(claimedReward, 64)
resp.Result, _ = json.Marshal(temp)
return
c.JSON(200, withSuccess(gin.H{
"total": fmt.Sprintf("%.6f", floatReward),
"claimed": claimedReward,
"unclaimed": fmt.Sprintf("%.6f", floatReward-floatClaimedReward),
}))
}
func getPendingWorkload(params []byte, resp *jsonrpcMessage) {
addressList := make([]string, 0)
err := json.Unmarshal(params, &addressList)
if err != nil || len(addressList) != 1 {
resp.Error = &jsonError{
Code: -32602,
Message: "invalid params",
}
return
}
func getRecord(c *gin.Context) {
// 通过api获取
tmp := struct {
Address string `json:"address"`
Page int `json:"page"`
PageSize int `json:"pageSize"`
}{}
if !common.IsHexAddress(addressList[0]) {
resp.Error = &jsonError{
Code: -32602,
Message: "invalid params",
}
if err := c.ShouldBindJSON(&tmp); err != nil {
c.JSON(200, withError(InvalidParams))
return
}
workload, globalWorkload := validator.GetPendingWorkload(common.HexToAddress(addressList[0]))
temp := map[string]interface{}{
"workload": workload,
"global_workload": globalWorkload,
}
resp.Result, _ = json.Marshal(temp)
return
}
func getDailyMerkleNodes(params []byte, resp *jsonrpcMessage) {
// date string, depth int, rootHash common.Hash
paramList := make([]interface{}, 0)
err := json.Unmarshal(params, &paramList)
if err != nil || len(paramList) < 1 || len(paramList) > 3 {
resp.Error = &jsonError{
Code: -32602,
Message: "invalid params",
}
if !common.IsHexAddress(tmp.Address) {
c.JSON(200, withError(InvalidParams))
return
}
var date string
var depth = 1
var rootHash common.Hash
_, err = time.Parse("2006-01-02", paramList[0].(string))
data, err := claimMonitorCli.GetClaimRecord(tmp.Address, tmp.Page, tmp.PageSize)
if err != nil {
resp.Error = &jsonError{
Code: -32602,
Message: "invalid params",
}
log.WithError(err).Error("failed to get claim record")
c.JSON(200, withError(InternalError))
return
}
date = paramList[0].(string)
if len(paramList) >= 2 {
_depth, ok := paramList[1].(float64)
if !ok {
resp.Error = &jsonError{
Code: -32602,
Message: "invalid params",
}
return
}
depth = int(uint(_depth))
}
if len(paramList) >= 3 {
rootHash = common.HexToHash(paramList[2].(string))
}
nodes := validator.GetDailyMerkleNodes(date, depth, rootHash)
resp.Result, _ = json.Marshal(nodes)
c.Data(200, "application/json", data)
}
func getDailyMerkleSumNodes(params []byte, resp *jsonrpcMessage) {
// date string, depth int, rootHash common.Hash
paramList := make([]interface{}, 0)
err := json.Unmarshal(params, &paramList)
if err != nil || len(paramList) < 1 || len(paramList) > 3 {
resp.Error = &jsonError{
Code: -32602,
Message: "invalid params",
}
return
func withSuccess(data interface{}) interface{} {
return map[string]interface{}{
"code": 0,
"msg": "ok",
"data": data,
}
}
var date string
var depth = 1
var rootHash common.Hash
_, err = time.Parse("2006-01-02", paramList[0].(string))
if err != nil {
resp.Error = &jsonError{
Code: -32602,
Message: "invalid params",
}
return
func withError(msg string) interface{} {
return map[string]interface{}{
"code": 1,
"msg": "",
"error": msg,
}
date = paramList[0].(string)
}
if len(paramList) >= 2 {
_depth, ok := paramList[1].(float64)
if !ok {
resp.Error = &jsonError{
Code: -32602,
Message: "invalid params",
}
return
}
depth = int(uint(_depth))
}
func StartServer(listenAddress string, v *core.Validator, c *claim_monitor.Client) {
validator = v
claimMonitorCli = c
if len(paramList) >= 3 {
rootHash = common.HexToHash(paramList[2].(string))
}
engine := gin.Default()
engine.Use(cors.Default())
initRouter(engine)
nodes, vals := validator.GetDailyMerkleSumNodes(date, depth, rootHash)
resp.Result, _ = json.Marshal(map[string]interface{}{
"nodes": nodes,
"values": vals,
})
}
log.WithField("listen", listenAddress).Info("start api server")
func StartJSONRPC(listenAddress string, w *core.Validator) {
validator = w
http.HandleFunc("/", rpcHandle)
log.WithField("listen", listenAddress).Info("start JSON-RPC server")
err := http.ListenAndServe(listenAddress, nil)
err := engine.Run(listenAddress)
if err != nil {
log.WithError(err).Fatal("failed to start JSON-RPC server")
log.WithError(err).Fatal("failed to start api server")
}
}
package claim_monitor
import (
"fmt"
"io"
"net/http"
"github.com/tidwall/gjson"
)
type Client struct {
Server string
}
func NewClient(server string) *Client {
return &Client{
Server: server,
}
}
func (cli *Client) GetClaimedAmount(address string) (string, error) {
resp, err := http.DefaultClient.Get(fmt.Sprintf("%s/api/v1/claimed?address=%s", cli.Server, address))
if err != nil {
return "0", err
}
defer resp.Body.Close()
data, err := io.ReadAll(resp.Body)
if err != nil {
return "0", err
}
if gjson.Get(string(data), "code").Int() != 0 {
return "0", fmt.Errorf(string(data))
}
return gjson.Get(string(data), "data.claimed").String(), nil
}
func (cli *Client) GetClaimRecord(address string, page, pageSize int) ([]byte, error) {
resp, err := http.DefaultClient.Get(fmt.Sprintf("%s/api/v1/record?address=%s&page=%d&pageSize=%d", cli.Server, address, page, pageSize))
if err != nil {
return nil, err
}
defer resp.Body.Close()
return io.ReadAll(resp.Body)
}
......@@ -34,12 +34,17 @@ var (
Value: "0.0.0.0:20010",
}
rpcListenAddrFlag = &cli.StringFlag{
Name: "rpc-listen",
Usage: "The listen address of the jsonrpc server",
apiListenAddrFlag = &cli.StringFlag{
Name: "api-listen",
Usage: "The listen address of the api server",
Value: "0.0.0.0:20012",
}
claimMonitorServerFlag = &cli.StringFlag{
Name: "claim-monitor-server",
Usage: "The host of the claim monitor server",
}
privateKeyFlag = &cli.StringFlag{
Name: "private-key",
Usage: "The private key of the account",
......
......@@ -4,6 +4,7 @@ import (
"net/http"
"os"
"validator/api"
"validator/claim_monitor"
"validator/conf"
"validator/core"
"validator/quest"
......@@ -20,7 +21,8 @@ var (
dataDirFlag,
metricsListenAddrFlag,
debugFlag,
rpcListenAddrFlag,
apiListenAddrFlag,
claimMonitorServerFlag,
privateKeyFlag,
chainRPCFlag,
storeContractFlag,
......@@ -54,15 +56,16 @@ func main() {
func run(ctx *cli.Context) {
cfg := &conf.Config{
MetricsListenAddr: ctx.String(metricsListenAddrFlag.Name),
Debug: ctx.Bool(debugFlag.Name),
RPCListenAddr: ctx.String(rpcListenAddrFlag.Name),
PrivateKey: ctx.String(privateKeyFlag.Name),
ChainRPC: ctx.String(chainRPCFlag.Name),
StoreContract: ctx.String(storeContractFlag.Name),
ValidatorContract: ctx.String(validatorContractFlag.Name),
DataDir: ctx.String(dataDirFlag.Name),
CommitOffset: ctx.Int(commitOffsetFlag.Name),
MetricsListenAddr: ctx.String(metricsListenAddrFlag.Name),
Debug: ctx.Bool(debugFlag.Name),
APIListenAddr: ctx.String(apiListenAddrFlag.Name),
ClaimMonitorServer: ctx.String(claimMonitorServerFlag.Name),
PrivateKey: ctx.String(privateKeyFlag.Name),
ChainRPC: ctx.String(chainRPCFlag.Name),
StoreContract: ctx.String(storeContractFlag.Name),
ValidatorContract: ctx.String(validatorContractFlag.Name),
DataDir: ctx.String(dataDirFlag.Name),
CommitOffset: ctx.Int(commitOffsetFlag.Name),
}
if cfg.Debug {
......@@ -83,7 +86,8 @@ func run(ctx *cli.Context) {
w := core.RunValidator(q, cfg)
// runGrpcServer(cfg.GRPCListenAddr, w)
runJSONRPCServer(cfg.RPCListenAddr, w)
monitorCli := claim_monitor.NewClient(cfg.ClaimMonitorServer)
runAPIServer(cfg.APIListenAddr, w, monitorCli)
select {}
}
......@@ -97,6 +101,6 @@ func runMetrics(listen string) {
}()
}
func runJSONRPCServer(listen string, w *core.Validator) {
go api.StartJSONRPC(listen, w)
func runAPIServer(listen string, w *core.Validator, c *claim_monitor.Client) {
go api.StartServer(listen, w, c)
}
package conf
type Config struct {
MetricsListenAddr string
Debug bool
RPCListenAddr string
ChainRPC string
PrivateKey string
StoreContract string
ValidatorContract string
RewardContract string
DataDir string
CommitOffset int
MetricsListenAddr string
Debug bool
APIListenAddr string
ChainRPC string
PrivateKey string
StoreContract string
ValidatorContract string
RewardContract string
DataDir string
CommitOffset int
ClaimMonitorServer string
}
type QuestConfig struct {
......
......@@ -4,15 +4,17 @@ data-dir = "./data"
metrics-listen = "0.0.0.0:20010"
rpc-listen = "0.0.0.0:20012"
api-listen = "0.0.0.0:20012"
private-key = "529f4efb80ac534f17d873104c71881c0970dbd5a886f183f63c5c6bb7a1fcd9"
chain-rpc = "https://dev.rpc.agicoin.ai"
store-contract = "0xfFb096e2B90324FFcCbaf987BdD724462c0aE18c"
store-contract = "0xA0ec84eCa14CD23afD5D7ba973390E83F0Cbe89A"
validator-contract = "0x2A03bA42139860aF46263755f6e5CBAe8195bB92" # 测试版本 不会revert
validator-contract = "0x7CBD03ecfA9093F83150E9625A25B00F555c81F7" # 测试版本 不会revert
claim-monitor-server = ""
commit-offset = 3600 # utc + n seconds
......
This diff is collapsed.
......@@ -77,11 +77,29 @@ func (r *ChainRPC) GetNMAddresses() (addrs []common.Address, err error) {
}
func (r *ChainRPC) GetWorkloadThreshold(totalWorkload uint64) (threshold *big.Int, err error) {
return r.validatorContract.GetWorkloadDistribution(nil, big.NewInt(int64(totalWorkload)))
return r.validatorContract.GetWorkloadReward(nil, big.NewInt(int64(totalWorkload)))
}
// GetWeiPerWorkload 给定日期,获取当天的总奖励,总工作量,每工作量奖励
func (r *ChainRPC) GetWeiPerWorkload(timestamp uint64) (reward, workload, weiPerWorkload *big.Int, err error) {
rewardDay, err := r.validatorContract.GetRewardByDate(nil, big.NewInt(int64(timestamp)))
if err != nil {
return
}
workloadDay, err := r.validatorContract.GetWorkloadByDate(nil, big.NewInt(int64(timestamp)))
if err != nil {
return
}
if big.NewInt(0).Cmp(workloadDay) == 0 || big.NewInt(0).Cmp(rewardDay) == 0 {
err = errors.New("workload or reward is zero")
return
}
return rewardDay, workloadDay, big.NewInt(0).Quo(rewardDay, workloadDay), nil
}
// SubmitProofs 调用合约提交root
func (r *ChainRPC) SubmitProofs(dateTimestamp int64, merkleSumTreeRoot, merkleTreeRoot common.Hash) (txHash common.Hash, err error) {
func (r *ChainRPC) SubmitProofs(dateTimestamp int64, merkleSumTreeRoot, merkleTreeRoot common.Hash, totalWorkload uint64) (txHash common.Hash, err error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()
opts, err := bind.NewKeyedTransactorWithChainID(r.privateKey, r.chainID)
......@@ -91,7 +109,7 @@ func (r *ChainRPC) SubmitProofs(dateTimestamp int64, merkleSumTreeRoot, merkleTr
opts.GasLimit = 500000
opts.Context = ctx
for i := 0; i < 10; i++ {
signedTx, err := r.validatorContract.SubmitMerkleRoot(opts, big.NewInt(dateTimestamp), merkleSumTreeRoot, merkleTreeRoot)
signedTx, err := r.validatorContract.SubmitMerkleRoot(opts, big.NewInt(dateTimestamp), merkleSumTreeRoot, merkleTreeRoot, big.NewInt(0).SetUint64(totalWorkload))
if err != nil {
log.WithError(err).Error("submit root, call contract failed, retry after 3 seconds")
time.Sleep(time.Second * 3)
......
......@@ -138,3 +138,31 @@ func (v *Validator) GetDailyMerkleSumNodes(date string, depth int, rootHash comm
}
return nodesHash, nodesVal
}
// GetWorkload /api/v1/workload
func (v *Validator) GetWorkload(timestampList []uint64) (ret []map[string]string, err error) {
for _, timestamp := range timestampList {
r, w, wei, err := v.rpc.GetWeiPerWorkload(timestamp)
if err != nil {
return nil, err
}
ret = append(ret, map[string]string{
"date": v.timestampToDate(int64(timestamp)),
"weiPerWorkload": wei.String(),
"reward": w.String(),
"workload": r.String(),
})
}
return ret, nil
}
// GetReward /api/v1/reward
func (v *Validator) GetReward(address common.Address) (reward *big.Int) {
object := v.state.GetMinerObject(address)
if object == nil {
return big.NewInt(0)
}
b, _ := big.NewInt(0).SetString(object.Balance, 10)
return b
}
......@@ -75,7 +75,7 @@ func RunValidator(q *quest.Quest, cfg *conf.Config) *Validator {
}
// v.date = 3, 如果当前时间超过提交昨天的时间,需要提交昨天的
if v.dateToTimestamp(v.date) < v.yesterdayTimestamp() &&
time.Now().After(time.Unix(v.todayTimestamp()+int64(cfg.CommitOffset), 0)) {
time.Now().UTC().After(time.Unix(v.todayTimestamp()+int64(cfg.CommitOffset), 0)) {
if err = v.SyncDayJob(v.dateToTimestamp(v.date)+86400, true); err != nil {
return nil
}
......@@ -146,7 +146,7 @@ func (v *Validator) ProcessDayJob() {
}).Debug("process day job")
v.LoadPendingProofs(v.yesterdayTimestamp(), v.todayTimestamp())
v.date = v.yesterdayString()
dayProof := v.Commit()
dayProof, totalWorkload := v.Commit()
mstRoot, _, err := v.CommitMST(dayProof)
if err != nil {
log.WithError(err).Error("failed to commit merkle sum tree")
......@@ -158,7 +158,7 @@ func (v *Validator) ProcessDayJob() {
log.WithError(err).Error("failed to commit merkle tree")
return
}
txHash, err := v.rpc.SubmitProofs(v.dateToTimestamp(v.date), mstRoot, mtRoot)
txHash, err := v.rpc.SubmitProofs(v.dateToTimestamp(v.date), mstRoot, mtRoot, totalWorkload)
if err != nil {
log.WithError(err).Error("submit proofs")
return
......@@ -190,7 +190,7 @@ func (v *Validator) SyncDayJob(dateTimestamp int64, commitToChain bool) (err err
}).Debug("sync day job")
v.LoadPendingProofs(dateTimestamp, dateTimestamp+86400)
v.date = v.timestampToDate(dateTimestamp)
dayProof := v.Commit()
dayProof, totalWorkload := v.Commit()
mstRoot, _, err := v.CommitMST(dayProof)
if err != nil {
log.WithError(err).Error("failed to commit merkle sum tree")
......@@ -204,7 +204,7 @@ func (v *Validator) SyncDayJob(dateTimestamp int64, commitToChain bool) (err err
}
var txHash common.Hash
if commitToChain {
txHash, err = v.rpc.SubmitProofs(dateTimestamp, mstRoot, mtRoot)
txHash, err = v.rpc.SubmitProofs(dateTimestamp, mstRoot, mtRoot, totalWorkload)
if err != nil {
log.WithError(err).Error("submit proofs")
return
......@@ -226,7 +226,7 @@ func (v *Validator) SyncDayJob(dateTimestamp int64, commitToChain bool) (err err
}
// Commit statedb提交
func (v *Validator) Commit() (dayProofs map[common.Address]*validatorv1.ValidatedProof) {
func (v *Validator) Commit() (dayProofs map[common.Address]*validatorv1.ValidatedProof, totalWorkload uint64) {
st := time.Now()
proof, totalWorkload := v.RefreshPendingProof()
balancePerWorkload, err := v.rpc.GetWorkloadThreshold(totalWorkload)
......@@ -259,7 +259,7 @@ func (v *Validator) Commit() (dayProofs map[common.Address]*validatorv1.Validate
return
}
v.state, _ = NewStateDB(v.lvdb, root)
return proof
return proof, totalWorkload
}
func (v *Validator) SealProof(miner common.Address, proof *validatorv1.ValidatedProof) (err error) {
......@@ -298,7 +298,7 @@ func (v *Validator) RefreshPendingProof() (proof map[common.Address]*validatorv1
func (v *Validator) Ticker() {
executionTime := time.Unix(v.todayTimestamp()+86400+int64(v.cfg.CommitOffset), 0)
// executionTime := time.Now().Add(time.Second * 3) for test
waitTime := executionTime.Sub(time.Now())
waitTime := executionTime.Sub(time.Now().UTC())
timer := time.NewTimer(waitTime)
log.WithFields(log.Fields{
"execution_time": executionTime.UTC().String(),
......@@ -308,7 +308,7 @@ func (v *Validator) Ticker() {
<-timer.C
v.ProcessDayJob()
executionTime = executionTime.Add(v.duration())
waitTime = executionTime.Sub(time.Now())
waitTime = executionTime.Sub(time.Now().UTC())
timer.Reset(waitTime)
log.WithFields(log.Fields{
"execution_time": executionTime.UTC().String(),
......@@ -373,7 +373,10 @@ func (v *Validator) yesterdayTimestamp() int64 {
}
func (v *Validator) dateToTimestamp(date string) int64 {
t, _ := time.ParseInLocation("2006-01-02", date, time.UTC)
t, err := time.ParseInLocation("2006-01-02", date, time.UTC)
if err != nil {
return 0
}
return t.Unix()
}
......
......@@ -5,11 +5,14 @@ go 1.21
require (
github.com/btcsuite/btcd/btcec/v2 v2.3.2
github.com/ethereum/go-ethereum v1.13.5-0.20231027145059-2d7dba024d76
github.com/gin-contrib/cors v1.7.2
github.com/gin-gonic/gin v1.9.1
github.com/gogo/protobuf v1.3.2
github.com/odysseus/odysseus-protocol v0.0.0-00010101000000-000000000000
github.com/prometheus/client_golang v1.18.0
github.com/sirupsen/logrus v1.9.3
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d
github.com/tidwall/gjson v1.17.1
github.com/urfave/cli/v2 v2.27.1
gorm.io/driver/postgres v1.5.6
gorm.io/gorm v1.25.7
......@@ -22,8 +25,12 @@ require (
github.com/VictoriaMetrics/fastcache v1.12.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bits-and-blooms/bitset v1.7.0 // indirect
github.com/bytedance/sonic v1.11.6 // indirect
github.com/bytedance/sonic/loader v0.1.1 // indirect
github.com/cespare/cp v1.1.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect
github.com/cockroachdb/errors v1.9.1 // indirect
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 // indirect
......@@ -37,10 +44,16 @@ require (
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
github.com/ethereum/c-kzg-4844 v0.4.0 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect
github.com/getsentry/sentry-go v0.18.0 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.20.0 // indirect
github.com/go-stack/stack v1.8.1 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/gofrs/flock v0.8.1 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
......@@ -53,14 +66,20 @@ require (
github.com/jackc/puddle/v2 v2.2.1 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.17.6 // indirect
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/mmcloughlin/addchain v0.4.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/onsi/gomega v1.30.0 // indirect
github.com/pelletier/go-toml/v2 v2.2.1 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_model v0.6.0 // indirect
github.com/prometheus/common v0.47.0 // indirect
......@@ -70,21 +89,26 @@ require (
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
github.com/supranational/blst v0.3.11 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect
github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
golang.org/x/crypto v0.20.0 // indirect
golang.org/x/arch v0.7.0 // indirect
golang.org/x/crypto v0.22.0 // indirect
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect
golang.org/x/mod v0.15.0 // indirect
golang.org/x/net v0.21.0 // indirect
golang.org/x/net v0.24.0 // indirect
golang.org/x/sync v0.6.0 // indirect
golang.org/x/sys v0.17.0 // indirect
golang.org/x/sys v0.19.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/tools v0.18.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 // indirect
google.golang.org/grpc v1.60.1 // indirect
google.golang.org/protobuf v1.32.0 // indirect
google.golang.org/protobuf v1.34.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
rsc.io/tmplfunc v0.0.3 // indirect
)
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment