Commit 52686069 authored by BRC985's avatar BRC985

init grid validator

parent 3947d56e
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <cuda.h>
#include "sha256.cuh"
#include <dirent.h>
#include <ctype.h>
#include <sys/time.h>
// #include <openssl/sha.h>
#include <time.h>
__global__ void sha256_cuda(int diffcult, int index, BYTE *data, size_t len, long long *result, long long n)
{
long long i = blockIdx.x * blockDim.x + threadIdx.x;
long long start = index * n;
// perform sha256 calculation here
if (i < n)
{
long long offset = start + i;
BYTE idx[8];
idx[0] = (BYTE)(offset & 0xff);
idx[1] = (BYTE)((offset >> 8) & 0xff);
idx[2] = (BYTE)((offset >> 16) & 0xff);
idx[3] = (BYTE)((offset >> 24) & 0xff);
idx[4] = (BYTE)((offset >> 32) & 0xff);
idx[5] = (BYTE)((offset >> 40) & 0xff);
idx[6] = (BYTE)((offset >> 48) & 0xff);
idx[7] = (BYTE)((offset >> 56) & 0xff);
SHA256_CTX ctx;
BYTE hash[32];
sha256_init(&ctx);
sha256_update(&ctx, data, len);
sha256_update(&ctx, idx, 8);
sha256_final(&ctx, hash);
if (checkOutput(hash, diffcult) == 0)
{
*result = offset;
}
}
}
void pre_sha256()
{
// compy symbols
checkCudaErrors(cudaMemcpyToSymbol(dev_k, host_k, sizeof(host_k), 0, cudaMemcpyHostToDevice));
}
void runSha256(int diffcult, int index, BYTE *data, size_t len, long long *result, long long n)
{
int blockSize = 16;
int numBlocks = (n + blockSize - 1) / blockSize;
sha256_cuda<<<numBlocks, blockSize>>>(diffcult, index, data, len, result, n);
}
void byteToHexStr(const unsigned char *source, char *dest, int sourceLen)
{
short i;
unsigned char highByte, lowByte;
for (i = 0; i < sourceLen; i++)
{
highByte = source[i] >> 4;
lowByte = source[i] & 0x0f;
highByte += 0x30;
if (highByte > 0x39)
dest[i * 2] = highByte + 0x07;
else
dest[i * 2] = highByte;
lowByte += 0x30;
if (lowByte > 0x39)
dest[i * 2 + 1] = lowByte + 0x07;
else
dest[i * 2 + 1] = lowByte;
}
return;
}
void printOutput(const unsigned char *output, int len)
{
char *outputHex = (char *)malloc((2 * len + 1) * sizeof(char));
byteToHexStr(output, outputHex, len);
outputHex[2 * len] = '\0';
printf("%s\n", outputHex);
free(outputHex);
return;
}
// long long stringToLong(const char *arr)
// {
// long long res = 0;
// char sign;
// int index = 0;
// if (arr[index] == '-' || arr[index] == '+')
// {
// sign = arr[index++];
// }
// char c = arr[index++];
// while (isdigit(c))
// {
// res = res * 10 + (c - '0');
// c = arr[index++];
// }
// if (sign == '-')
// {
// return -res;
// }
// return res;
// }
extern "C"
{
int generatePOW(char *rand, int len, int diffcult, long long *index)
{
BYTE **inputs;
// BYTE **outputs;
long long **indexes;
long long count = 2 << (diffcult + 1);
int deviceCount;
cudaGetDeviceCount(&deviceCount);
inputs = (BYTE **)malloc(deviceCount * sizeof(BYTE *));
// outputs = (BYTE **)malloc(deviceCount * sizeof(BYTE *));
indexes = (long long **)malloc(deviceCount * sizeof(long long *));
for (int i = 0; i < deviceCount; i++)
{
checkCudaErrors(cudaSetDevice(i));
checkCudaErrors(cudaMallocManaged(&inputs[i], len * sizeof(BYTE)));
// checkCudaErrors(cudaMallocManaged(&outputs[i], 32 * sizeof(BYTE)));
checkCudaErrors(cudaMallocManaged(&indexes[i], sizeof(long long)));
checkCudaErrors(cudaMemcpy(inputs[i], rand, len, cudaMemcpyHostToDevice));
}
for (int i = 0; i < deviceCount; i++)
{
checkCudaErrors(cudaSetDevice(i));
*indexes[i] = -1;
pre_sha256();
runSha256(diffcult, i, inputs[i], len, indexes[i], count / deviceCount);
}
for (int i = 0; i < deviceCount; i++)
{
checkCudaErrors(cudaSetDevice(i));
cudaDeviceSynchronize();
}
// long long proof;
for (int i = 0; i < deviceCount; i++)
if (*indexes[i] != -1)
{
*index = *indexes[i];
break;
}
for (int i = 0; i < deviceCount; i++)
{
checkCudaErrors(cudaSetDevice(i));
cudaFree(inputs[i]);
// cudaFree(outputs[i]);
cudaFree(indexes[i]);
}
free(inputs);
// free(outputs);
free(indexes);
return 0;
}
}
\ No newline at end of file
#ifndef SHA256_H
#define SHA256_H
/****************************** MACROS ******************************/
#define SHA256_BLOCK_SIZE 32 // SHA256 outputs a 32 byte digest
#define ROTLEFT(a, b) (((a) << (b)) | ((a) >> (32 - (b))))
#define ROTRIGHT(a, b) (((a) >> (b)) | ((a) << (32 - (b))))
#define CH(x, y, z) (((x) & (y)) ^ (~(x) & (z)))
#define MAJ(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
#define EP0(x) (ROTRIGHT(x, 2) ^ ROTRIGHT(x, 13) ^ ROTRIGHT(x, 22))
#define EP1(x) (ROTRIGHT(x, 6) ^ ROTRIGHT(x, 11) ^ ROTRIGHT(x, 25))
#define SIG0(x) (ROTRIGHT(x, 7) ^ ROTRIGHT(x, 18) ^ ((x) >> 3))
#define SIG1(x) (ROTRIGHT(x, 17) ^ ROTRIGHT(x, 19) ^ ((x) >> 10))
#define checkCudaErrors(x) \
{ \
cudaGetLastError(); \
x; \
cudaError_t err = cudaGetLastError(); \
if (err != cudaSuccess) \
printf("GPU: cudaError %d (%s)\n", err, cudaGetErrorString(err)); \
}
/**************************** DATA TYPES ****************************/
typedef unsigned char BYTE; // 8-bit byte
typedef uint32_t WORD; // 32-bit word, change to "long" for 16-bit machines
typedef struct JOB
{
BYTE *data;
unsigned long long size;
BYTE digest[64];
char fname[128];
} JOB;
typedef struct
{
BYTE data[64];
WORD datalen;
unsigned long long bitlen;
WORD state[8];
} SHA256_CTX;
__constant__ WORD dev_k[64] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};
static const WORD host_k[64] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};
/*********************** FUNCTION DECLARATIONS **********************/
char *print_sha(BYTE *buff);
__device__ void sha256_init(SHA256_CTX *ctx);
__device__ void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len);
__device__ void sha256_final(SHA256_CTX *ctx, BYTE hash[]);
char *hash_to_string(BYTE *buff)
{
char *string = (char *)malloc(70);
int k, i;
for (i = 0, k = 0; i < 32; i++, k += 2)
{
sprintf(string + k, "%.2x", buff[i]);
// printf("%02x", buff[i]);
}
string[64] = 0;
return string;
}
void print_job(JOB *j)
{
printf("%s %s\n", hash_to_string(j->digest), j->fname);
}
void print_jobs(JOB **jobs, int n)
{
for (int i = 0; i < n; i++)
{
print_job(jobs[i]);
// printf("@ %p JOB[%i] \n", jobs[i], i);
// printf("\t @ 0x%p data = %x \n", jobs[i]->data, (jobs[i]->data == 0)? 0 : jobs[i]->data[0]);
// printf("\t @ 0x%p size = %llu \n", &(jobs[i]->size), jobs[i]->size);
// printf("\t @ 0x%p fname = %s \n", &(jobs[i]->fname), jobs[i]->fname);
// printf("\t @ 0x%p digest = %s \n------\n", jobs[i]->digest, hash_to_string(jobs[i]->digest));
}
}
__device__ int checkOutput(BYTE hash[32], int diffcult)
{
if (diffcult > 256)
return -1;
int n = diffcult / 8;
BYTE remain = ~(0xff >> (diffcult % 8));
for (int i = 0; i < n; i++)
if (hash[i] != 0)
return -1;
if ((hash[n] & remain) != 0)
return -1;
return 0;
}
__device__ void
mycpy12(uint32_t *d, const uint32_t *s)
{
#pragma unroll 3
for (int k = 0; k < 3; k++)
d[k] = s[k];
}
__device__ void mycpy16(uint32_t *d, const uint32_t *s)
{
#pragma unroll 4
for (int k = 0; k < 4; k++)
d[k] = s[k];
}
__device__ void mycpy32(uint32_t *d, const uint32_t *s)
{
#pragma unroll 8
for (int k = 0; k < 8; k++)
d[k] = s[k];
}
__device__ void mycpy44(uint32_t *d, const uint32_t *s)
{
#pragma unroll 11
for (int k = 0; k < 11; k++)
d[k] = s[k];
}
__device__ void mycpy48(uint32_t *d, const uint32_t *s)
{
#pragma unroll 12
for (int k = 0; k < 12; k++)
d[k] = s[k];
}
__device__ void mycpy64(uint32_t *d, const uint32_t *s)
{
#pragma unroll 16
for (int k = 0; k < 16; k++)
d[k] = s[k];
}
__device__ void sha256_transform(SHA256_CTX *ctx, const BYTE data[])
{
WORD a, b, c, d, e, f, g, h, i, j, t1, t2, m[64];
WORD S[8];
// mycpy32(S, ctx->state);
#pragma unroll 16
for (i = 0, j = 0; i < 16; ++i, j += 4)
m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]);
#pragma unroll 64
for (; i < 64; ++i)
m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16];
a = ctx->state[0];
b = ctx->state[1];
c = ctx->state[2];
d = ctx->state[3];
e = ctx->state[4];
f = ctx->state[5];
g = ctx->state[6];
h = ctx->state[7];
#pragma unroll 64
for (i = 0; i < 64; ++i)
{
t1 = h + EP1(e) + CH(e, f, g) + dev_k[i] + m[i];
t2 = EP0(a) + MAJ(a, b, c);
h = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
}
ctx->state[0] += a;
ctx->state[1] += b;
ctx->state[2] += c;
ctx->state[3] += d;
ctx->state[4] += e;
ctx->state[5] += f;
ctx->state[6] += g;
ctx->state[7] += h;
}
__device__ void sha256_init(SHA256_CTX *ctx)
{
ctx->datalen = 0;
ctx->bitlen = 0;
ctx->state[0] = 0x6a09e667;
ctx->state[1] = 0xbb67ae85;
ctx->state[2] = 0x3c6ef372;
ctx->state[3] = 0xa54ff53a;
ctx->state[4] = 0x510e527f;
ctx->state[5] = 0x9b05688c;
ctx->state[6] = 0x1f83d9ab;
ctx->state[7] = 0x5be0cd19;
}
__device__ void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len)
{
WORD i;
// for each byte in message
for (i = 0; i < len; ++i)
{
// ctx->data == message 512 bit chunk
ctx->data[ctx->datalen] = data[i];
ctx->datalen++;
if (ctx->datalen == 64)
{
sha256_transform(ctx, ctx->data);
ctx->bitlen += 512;
ctx->datalen = 0;
}
}
}
__device__ void sha256_final(SHA256_CTX *ctx, BYTE hash[])
{
WORD i;
i = ctx->datalen;
// Pad whatever data is left in the buffer.
if (ctx->datalen < 56)
{
ctx->data[i++] = 0x80;
while (i < 56)
ctx->data[i++] = 0x00;
}
else
{
ctx->data[i++] = 0x80;
while (i < 64)
ctx->data[i++] = 0x00;
sha256_transform(ctx, ctx->data);
memset(ctx->data, 0, 56);
}
// Append to the padding the total message's length in bits and transform.
ctx->bitlen += ctx->datalen * 8;
ctx->data[63] = ctx->bitlen;
ctx->data[62] = ctx->bitlen >> 8;
ctx->data[61] = ctx->bitlen >> 16;
ctx->data[60] = ctx->bitlen >> 24;
ctx->data[59] = ctx->bitlen >> 32;
ctx->data[58] = ctx->bitlen >> 40;
ctx->data[57] = ctx->bitlen >> 48;
ctx->data[56] = ctx->bitlen >> 56;
sha256_transform(ctx, ctx->data);
// Since this implementation uses little endian byte ordering and SHA uses big endian,
// reverse all the bytes when copying the final state to the output hash.
for (i = 0; i < 4; ++i)
{
hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff;
hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff;
hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff;
hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff;
hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff;
hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff;
hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff;
hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff;
}
}
#endif // SHA256_H
package cmd
import (
"context"
"grid-prover/core/validator"
"grid-prover/database"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"github.com/ethereum/go-ethereum/crypto"
"github.com/gin-gonic/gin"
"github.com/urfave/cli/v2"
)
var provider1 = "0x867F691B053B61490F8eB74c2df63745CfC0A973"
var ValidatorCmd = &cli.Command{
Name: "validator",
Usage: "grid validator node",
Subcommands: []*cli.Command{
// validatorNodeRunCmd,
validatorNodeTestCmd,
},
}
var validatorNodeTestCmd = &cli.Command{
Name: "run",
Usage: "run meeda store node",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "endpoint",
Aliases: []string{"e"},
Usage: "input your endpoint",
Value: ":8081",
},
&cli.StringFlag{
Name: "sk",
Usage: "input your private key",
Value: "",
},
&cli.StringFlag{
Name: "chain",
Usage: "input chain name, e.g.(dev)",
Value: "product",
},
},
Action: func(ctx *cli.Context) error {
endPoint := ctx.String("endpoint")
sk := ctx.String("sk")
chain := ctx.String("chain")
privateKey, err := crypto.HexToECDSA(sk)
if err != nil {
privateKey, err = crypto.GenerateKey()
if err != nil {
return err
}
}
err = InitTestDataBase("~/grid")
if err != nil {
return err
}
validator, err := validator.NewGRIDValidator(chain, privateKey)
if err != nil {
return err
}
go validator.Start(context.TODO())
server, err := NewValidatorServer(validator, endPoint)
if err != nil {
return err
}
go func() {
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("listen: %s\n", err)
}
}()
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
log.Println("Shutting down server...")
if err := server.Shutdown(context.TODO()); err != nil {
log.Fatal("Server forced to shutdown: ", err)
}
validator.Stop()
log.Println("Server exiting")
return nil
},
}
func NewValidatorServer(validator *validator.GRIDValidator, endpoint string) (*http.Server, error) {
gin.SetMode(gin.ReleaseMode)
router := gin.Default()
router.MaxMultipartMemory = 8 << 20 // 8 MiB
router.GET("/", func(c *gin.Context) {
c.String(http.StatusOK, "Welcome GRID Validator Node")
})
validator.LoadValidatorModule(router.Group("/v1"))
return &http.Server{
Addr: endpoint,
Handler: router,
}, nil
}
func InitTestDataBase(path string) error {
err := database.RemoveDataBase(path)
if err != nil {
return err
}
err = database.InitDatabase(path)
if err != nil {
return err
}
provider := database.Provider{
Address: provider1,
Name: "test",
IP: "127.0.0.1",
Port: "40",
}
err = provider.CreateProvider()
if err != nil {
return err
}
node := database.Node{
Address: provider1,
Id: 1,
CPUPrice: 10,
CPUModel: "AMD 7309",
GPUPrice: 20,
GPUModel: "NIVIDA 3060",
MemPrice: 5,
MemCapacity: 20,
DiskPrice: 1,
DiskCapacity: 1000,
}
err = node.CreateNode()
if err != nil {
return err
}
order := database.Order{
Address: provider1,
Id: 1,
ActivateTime: time.Now(),
StartTime: time.Now().Add(30 * time.Second),
EndTime: time.Now().Add(2 * time.Hour),
Probation: 30,
Duration: 7170,
}
err = order.CreateOrder()
if err != nil {
return err
}
profit := database.Profit{
Address: provider1,
Balance: 0,
Profit: 10000000,
Penalty: 0,
LastTime: time.Now(),
EndTime: time.Now().Add(10 * time.Hour),
}
return profit.CreateProfit()
}
package cmd
import (
"fmt"
"github.com/urfave/cli/v2"
)
var Version = "0.0.1"
var BuildFlag string
var VersionCmd = &cli.Command{
Name: "version",
Usage: "print version",
Aliases: []string{"V"},
Action: func(_ *cli.Context) error {
fmt.Println(Version + "+" + BuildFlag)
return nil
},
}
package core
const GRIDABI = "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32[4]\",\"name\":\"etag\",\"type\":\"bytes32[4]\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"start\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"end\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"size\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"price\",\"type\":\"uint64\"}],\"name\":\"AddFile\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"interval\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"period\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"chalSum\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"respondTime\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"price\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"submitter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"foundation\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"chalRewardRatio\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"chalPledge\",\"type\":\"uint256\"},{\"internalType\":\"bytes32[8]\",\"name\":\"vk\",\"type\":\"bytes32[8]\"}],\"indexed\":false,\"internalType\":\"structIFileProof.SettingInfo\",\"name\":\"si\",\"type\":\"tuple\"}],\"name\":\"AlterSetting\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"rnd\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32[4]\",\"name\":\"cn\",\"type\":\"bytes32[4]\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"chalPledge\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"challenger\",\"type\":\"address\"}],\"name\":\"CreateChal\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"rnd\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"submitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"challenger\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fine\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"reward\",\"type\":\"uint256\"}],\"name\":\"Fraud\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"rnd\",\"type\":\"bytes32\"}],\"name\":\"GenRnd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"rnd\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"submitter\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"challenger\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"compensation\",\"type\":\"uint256\"}],\"name\":\"NoFraud\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldLast\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newLast\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"misProfit\",\"type\":\"uint256\"}],\"name\":\"NoProofs\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"relProfit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"locProfit\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"misProfit\",\"type\":\"uint256\"}],\"name\":\"ProfitRelease\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"rnd\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32[4]\",\"name\":\"cn\",\"type\":\"bytes32[4]\"},{\"components\":[{\"internalType\":\"bytes32[4]\",\"name\":\"npsi\",\"type\":\"bytes32[4]\"},{\"internalType\":\"bytes32\",\"name\":\"y\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structIFileProof.ProofInfo\",\"name\":\"pn\",\"type\":\"tuple\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"res\",\"type\":\"bool\"}],\"name\":\"SubmitProof\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32[4]\",\"name\":\"etag\",\"type\":\"bytes32[4]\"},{\"internalType\":\"uint64\",\"name\":\"sizeByte\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"start\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"end\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"credential\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"addFile\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"interval\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"period\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"chalSum\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"respondTime\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"price\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"submitter\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"foundation\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"chalRewardRatio\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"chalPledge\",\"type\":\"uint256\"},{\"internalType\":\"bytes32[8]\",\"name\":\"vk\",\"type\":\"bytes32[8]\"}],\"internalType\":\"structIFileProof.SettingInfo\",\"name\":\"si\",\"type\":\"tuple\"}],\"name\":\"alterSetting\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"challenge\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"_chalIndex\",\"type\":\"uint8\"}],\"name\":\"doChallenge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"endChallenge\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"commit\",\"type\":\"bytes\"}],\"name\":\"files\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"genRnd\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"i\",\"type\":\"uint256\"}],\"name\":\"getCommit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes32[4]\",\"name\":\"\",\"type\":\"bytes32[4]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getVK\",\"outputs\":[{\"internalType\":\"bytes32[8]\",\"name\":\"\",\"type\":\"bytes32[8]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[4][]\",\"name\":\"_commitments\",\"type\":\"bytes32[4][]\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"oneStepProve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"profit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"proof\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[4][10]\",\"name\":\"_cns\",\"type\":\"bytes32[4][10]\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"responseChal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"i\",\"type\":\"uint256\"}],\"name\":\"selectFiles\",\"outputs\":[{\"internalType\":\"bytes32[4]\",\"name\":\"\",\"type\":\"bytes32[4]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"setting\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_rnd\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[4]\",\"name\":\"_Cn\",\"type\":\"bytes32[4]\"},{\"components\":[{\"internalType\":\"bytes32[4]\",\"name\":\"npsi\",\"type\":\"bytes32[4]\"},{\"internalType\":\"bytes32\",\"name\":\"y\",\"type\":\"bytes32\"}],\"internalType\":\"structIFileProof.ProofInfo\",\"name\":\"_Pn\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"submitProof\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"withdrawMissedProfit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"
package client
import (
"bytes"
"context"
"encoding/hex"
"encoding/json"
"grid-prover/core/types"
"io"
"net/http"
"golang.org/x/xerrors"
)
type GRIDClient struct {
baseUrl string
}
func NewGRIDClient(url string) *GRIDClient {
return &GRIDClient{
baseUrl: url,
}
}
type rndResult struct {
Rnd string
}
func (c *GRIDClient) GetRND(ctx context.Context) ([32]byte, error) {
var url = c.baseUrl + "/rnd"
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
if err != nil {
return [32]byte{}, err
}
res, err := http.DefaultClient.Do(req)
if err != nil {
return [32]byte{}, err
}
if res.StatusCode != http.StatusOK {
return [32]byte{}, xerrors.Errorf("Failed to get rnd, status [%d]", res.StatusCode)
}
body, err := io.ReadAll(res.Body)
defer res.Body.Close()
if err != nil {
return [32]byte{}, err
}
var rndRes rndResult
err = json.Unmarshal(body, &rndRes)
if err != nil {
return [32]byte{}, err
}
rndBytes, err := hex.DecodeString(rndRes.Rnd)
if err != nil {
return [32]byte{}, err
}
var rnd [32]byte
copy(rnd[:], rndBytes)
return rnd, nil
}
func (c *GRIDClient) SubmitProof(ctx context.Context, proof types.Proof) error {
var url = c.baseUrl + "/proof"
payload := make(map[string]interface{})
payload["address"] = proof.Address
payload["id"] = proof.ID
payload["nonce"] = proof.Nonce
b, err := json.Marshal(payload)
if err != nil {
return err
}
req, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewReader(b))
if err != nil {
return err
}
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
if res.StatusCode != http.StatusOK {
return xerrors.Errorf("Failed to submit proof, status [%d]", res.StatusCode)
}
return nil
}
package core
import (
"grid-prover/database"
"grid-prover/logs"
"math/big"
"strings"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
)
var (
// blockNumber = big.NewInt(0)
logger = logs.Logger("dumper")
)
type Dumper struct {
endpoint string
contractABI []abi.ABI
contractAddress []common.Address
// store MapStore
blockNumber *big.Int
eventNameMap map[common.Hash]string
indexedMap map[common.Hash]abi.Arguments
}
func NewGRIDDumper(chain string, contractAddress common.Address) (dumper *Dumper, err error) {
dumper = &Dumper{
// store: store,
eventNameMap: make(map[common.Hash]string),
indexedMap: make(map[common.Hash]abi.Arguments),
}
dumper.contractAddress = []common.Address{contractAddress}
fpContractABI, err := abi.JSON(strings.NewReader(GRIDABI))
if err != nil {
return dumper, err
}
dumper.contractABI = []abi.ABI{fpContractABI}
for _, ABI := range dumper.contractABI {
for name, event := range ABI.Events {
dumper.eventNameMap[event.ID] = name
var indexed abi.Arguments
for _, arg := range ABI.Events[name].Inputs {
if arg.Indexed {
indexed = append(indexed, arg)
}
}
dumper.indexedMap[event.ID] = indexed
}
}
blockNumber, err := database.GetBlockNumber()
if err != nil {
blockNumber = 0
}
dumper.blockNumber = big.NewInt(blockNumber)
return dumper, nil
}
package types
import (
"encoding/binary"
"github.com/ethereum/go-ethereum/common"
)
type NodeID struct {
Address string `json:"address"`
ID int64 `json:"id"`
}
func (n *NodeID) ToBytes() []byte {
var buf = make([]byte, 8)
binary.LittleEndian.PutUint64(buf, uint64(n.ID))
return append(common.Hex2Bytes(n.Address), buf...)
}
type Proof struct {
NodeID
Nonce int64 `json:"nonce"`
}
func (p *Proof) ToBytes() []byte {
var nonceBuf = make([]byte, 8)
binary.LittleEndian.PutUint64(nonceBuf, uint64(p.Nonce))
buf := p.NodeID.ToBytes()
return append(buf, nonceBuf...)
}
type Result struct {
NodeID
Success bool
}
package validator
import (
"crypto/sha256"
"encoding/hex"
"fmt"
"grid-prover/core/types"
"net/http"
"github.com/gin-gonic/gin"
)
func (v *GRIDValidator) LoadValidatorModule(g *gin.RouterGroup) {
g.GET("/rnd", v.GetRNDHandler)
g.GET("/withdraw/signature", v.GetWithdrawSignatureHandler)
g.POST("/proof", v.SubmitProofHandler)
fmt.Println("load light node moudle success!")
}
func (v *GRIDValidator) GetRNDHandler(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"rnd": hex.EncodeToString(RND[:]),
})
}
// func GetSettingInfo(c *gin.Context) {
// }
func (v *GRIDValidator) SubmitProofHandler(c *gin.Context) {
var proof types.Proof
err := c.BindJSON(&proof)
if err != nil {
logger.Error(err)
c.AbortWithStatusJSON(500, err.Error())
return
}
if !v.IsProveTime() {
logger.Error("Failure to submit proof within the proof time")
c.AbortWithStatusJSON(400, "Failure to submit proof within the proof time")
return
}
hash := sha256.New()
hash.Write(RND[:])
hash.Write(proof.ToBytes())
result := hash.Sum(nil)
diffcult, err := getDiffcultByProviderId(proof.NodeID)
if err != nil {
logger.Error(err)
c.AbortWithStatusJSON(500, err.Error())
return
}
if !checkPOWResult(result, diffcult) {
logger.Error("Verify Proof Failed:", hex.EncodeToString(result))
c.AbortWithStatusJSON(400, "Verify Proof Failed")
return
}
resultChan <- types.Result{
NodeID: proof.NodeID,
Success: true,
}
c.JSON(http.StatusOK, "Verify Proof Success")
}
func (v *GRIDValidator) GetProfitInfo(c *gin.Context) {
}
func (v *GRIDValidator) GetWithdrawSignatureHandler(c *gin.Context) {
address := c.Query("address")
amount := c.Query("amount")
if len(address) == 0 || len(amount) == 0 {
logger.Error("field address or amount is not set")
c.AbortWithStatusJSON(400, "field address or amount is not set")
return
}
}
func getDiffcultByProviderId(nodeID types.NodeID) (int, error) {
return 8, nil
}
func checkPOWResult(hash []byte, diffcult int) bool {
if diffcult >= 256 {
return false
}
n := diffcult / 8
var remain byte = 0xff ^ (0xff >> (diffcult % 8))
for i := 0; i < n; i++ {
if hash[i] != 0 {
return false
}
}
if hash[n]&remain != 0 {
return false
}
return true
}
package validator
import (
"context"
"crypto/ecdsa"
"grid-prover/database"
"grid-prover/logs"
"math/rand"
"time"
"grid-prover/core/types"
)
var logger = logs.Logger("grid validator")
// var proofChan = make(chan Proof, 100)
var resultChan = make(chan types.Result, 100)
var RND [32]byte
type GRIDValidator struct {
last int64
prepareInterval time.Duration
proveInterval time.Duration
waitInterval time.Duration
sk *ecdsa.PrivateKey
done chan struct{}
doned bool
}
func NewGRIDValidator(chain string, sk *ecdsa.PrivateKey) (*GRIDValidator, error) {
// get time information from contract
prepareInterval := 10 * time.Second
proveInterval := 10 * time.Second
waitInterval := 2*time.Minute - prepareInterval - proveInterval
return &GRIDValidator{
last: 0,
prepareInterval: prepareInterval,
proveInterval: proveInterval,
waitInterval: waitInterval,
sk: sk,
done: make(chan struct{}),
doned: false,
}, nil
}
func (v *GRIDValidator) Start(ctx context.Context) {
for {
// 等待下一个prepare时期
wait, nextTime := v.CalculateWatingToPrepare()
select {
case <-ctx.Done():
v.doned = true
return
case <-v.done:
v.doned = true
return
case <-time.After(wait):
}
err := v.GenerateRND(ctx)
if err != nil {
logger.Error(err.Error())
continue
}
// 等待下一个prove时期
wait, _ = v.CalculateWatingToProve()
select {
case <-ctx.Done():
return
case <-v.done:
v.doned = true
return
case <-time.After(wait):
}
resultMap, err := v.GetChallengeNode(ctx)
if err != nil {
logger.Error(err.Error())
continue
}
res, err := v.HandleResult(ctx, resultMap)
if err != nil {
logger.Error(err.Error())
continue
}
logger.Info("Start update profits")
err = v.AddPenalty(ctx, res)
if err != nil {
logger.Error(err.Error())
continue
}
v.last = nextTime
}
}
func (v *GRIDValidator) Stop() {
close(v.done)
for !v.doned {
time.Sleep(200 * time.Millisecond)
}
}
func (v *GRIDValidator) IsProveTime() bool {
challengeCycleSeconds := int64((v.prepareInterval + v.proveInterval + v.waitInterval).Seconds())
now := time.Now().Unix()
duration := now - v.last
over := duration % challengeCycleSeconds
if over >= int64(v.prepareInterval.Seconds()) && over <= int64((v.prepareInterval+v.proveInterval).Seconds()) {
return true
}
return false
}
func (v *GRIDValidator) CalculateWatingToPrepare() (time.Duration, int64) {
challengeCycleSeconds := int64((v.prepareInterval + v.proveInterval + v.waitInterval).Seconds())
now := time.Now().Unix()
duration := now - v.last
over := duration % challengeCycleSeconds
var waitingSeconds int64 = 0
if over >= int64(v.prepareInterval.Seconds()) {
waitingSeconds = challengeCycleSeconds - over
}
v.last = now - over
next := v.last + challengeCycleSeconds
return time.Duration(waitingSeconds) * time.Second, next
}
func (v *GRIDValidator) CalculateWatingToProve() (time.Duration, int64) {
challengeCycleSeconds := int64((v.prepareInterval + v.proveInterval + v.waitInterval).Seconds())
now := time.Now().Unix()
duration := now - v.last
over := duration % challengeCycleSeconds
var waitingSeconds int64 = 0
if over < int64(v.prepareInterval.Seconds()) {
waitingSeconds = int64(v.prepareInterval.Seconds()) - over
v.last = now - over
} else if over > int64((v.prepareInterval + v.proveInterval).Seconds()) {
waitingSeconds = challengeCycleSeconds + int64(v.prepareInterval.Seconds()) - over
v.last = now - over + challengeCycleSeconds
}
next := v.last + challengeCycleSeconds
return time.Duration(waitingSeconds) * time.Second, next
}
func (v *GRIDValidator) GenerateRND(ctx context.Context) error {
// TODO: call the contract
for index := range RND {
RND[index] = byte(rand.Int())
}
return nil
}
func (v *GRIDValidator) GetChallengeNode(ctx context.Context) (map[types.NodeID]bool, error) {
orders, err := database.ListAllActivedOrder()
if err != nil {
return nil, err
}
var resultMap = make(map[types.NodeID]bool)
for _, order := range orders {
resultMap[types.NodeID{
Address: order.Address,
ID: order.Id,
}] = false
}
return resultMap, nil
}
func (v *GRIDValidator) HandleResult(ctx context.Context, resultMap map[types.NodeID]bool) (map[types.NodeID]bool, error) {
var channel = make(chan struct{})
logger.Info("start handle result")
go func() {
select {
case <-ctx.Done():
channel <- struct{}{}
return
case <-v.done:
channel <- struct{}{}
return
case <-time.After(v.proveInterval):
channel <- struct{}{}
return
}
}()
for {
select {
case <-channel:
logger.Info("end handle result")
return resultMap, nil
case result := <-resultChan:
resultMap[result.NodeID] = true
}
}
// return resultMap, nil
}
func (v *GRIDValidator) AddPenalty(ctx context.Context, res map[types.NodeID]bool) error {
for nodeID, result := range res {
profitInfo, err := database.GetProfitByAddress(nodeID.Address)
if err != nil {
return err
}
reward := profitInfo.Profit * (v.last - profitInfo.LastTime.Unix()) / (profitInfo.EndTime.Unix() - profitInfo.LastTime.Unix())
remain := profitInfo.Profit - reward
var penalty int64 = 0
if !result {
penalty = remain / 100
}
profitInfo.LastTime = time.Unix(v.last, 0)
profitInfo.Balance += reward
profitInfo.Profit = remain - penalty
profitInfo.Penalty += penalty
logger.Infof("Balance: %d, Profit: %d, penalty: %d", profitInfo.Balance, profitInfo.Profit, profitInfo.Penalty)
err = profitInfo.UpdateProfit()
if err != nil {
return err
}
}
return nil
}
package database
import (
// "database/sql"
"grid-prover/logs"
"os"
"path/filepath"
"time"
// "gorm.io/driver/mysql"
// _ "github.com/go-sql-driver/mysql"
"github.com/mitchellh/go-homedir"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
var GlobalDataBase *gorm.DB
var logger = logs.Logger("database")
func InitDatabase(path string) error {
dir, err := homedir.Expand(path)
if err != nil {
return err
}
if _, err := os.Stat(dir); os.IsNotExist(err) {
err := os.MkdirAll(dir, 0666)
if err != nil {
return err
}
}
// dsn := "root@tcp(127.0.0.1:3306)/grid?charset=utf8mb4&parseTime=True&loc=Local"
// mysqlDB, err := sql.Open("mysql", dsn)
// if err != nil {
// return err
// }
db, err := gorm.Open(sqlite.Open(filepath.Join(dir, "grid.db")), &gorm.Config{})
if err != nil {
return err
}
sqlDB, err := db.DB()
if err != nil {
return err
}
// 设置连接池中空闲连接的最大数量。
sqlDB.SetMaxIdleConns(10)
// 设置打开数据库连接的最大数量。
sqlDB.SetMaxOpenConns(100)
// 设置超时时间
sqlDB.SetConnMaxLifetime(time.Second * 30)
err = sqlDB.Ping()
if err != nil {
return err
}
db.AutoMigrate(&Order{}, &Profit{}, &BlockNumber{}, &Provider{}, &Node{})
GlobalDataBase = db
logger.Info("init database success")
return nil
}
func RemoveDataBase(path string) error {
dir, err := homedir.Expand(path)
if err != nil {
return err
}
databasePath := filepath.Join(dir, "grid.db")
if _, err := os.Stat(databasePath); os.IsExist(err) {
if err := os.Remove(databasePath); err != nil {
return err
}
}
return nil
}
package database
import "time"
type Order struct {
Address string
Id int64
ActivateTime time.Time `gorm:"column:activate"`
StartTime time.Time `gorm:"column:start"`
EndTime time.Time `gorm:"column:end"`
Probation int64
Duration int64
}
func InitOrder() error {
return GlobalDataBase.AutoMigrate(&Order{})
}
func (o *Order) CreateOrder() error {
o.StartTime = o.ActivateTime.Add(time.Duration(o.Probation) * time.Second)
o.EndTime = o.StartTime.Add(time.Duration(o.Duration) * time.Second)
return GlobalDataBase.Create(o).Error
}
func GetOrderByAddressAndId(address string, id int64) (Order, error) {
var order Order
err := GlobalDataBase.Model(&Order{}).Where("address = ? AND id = ?", address, id).Last(&order).Error
if err != nil {
return Order{}, err
}
return order, nil
}
func ListAllActivedOrder() ([]Order, error) {
var now = time.Now()
var orders []Order
err := GlobalDataBase.Model(&Order{}).Where("start < ? AND end > ?", now, now).Find(&orders).Error
if err != nil {
return nil, err
}
return orders, nil
}
package database
import "time"
type Profit struct {
Address string `gorm:"primarykey"` // CPU/GPU供应商ID
// ID int64
Balance int64 // 余额
Profit int64 // 分润值
Penalty int64 // 惩罚值
LastTime time.Time // 上次更新时间
EndTime time.Time // 可以取出全部分润值时间
}
func InitProfit() error {
return GlobalDataBase.AutoMigrate(&Profit{})
}
func (p *Profit) CreateProfit() error {
return GlobalDataBase.Create(p).Error
}
func (p *Profit) UpdateProfit() error {
return GlobalDataBase.Model(&Profit{}).Where("address = ?", p.Address).Save(p).Error
}
func GetProfitByAddress(address string) (Profit, error) {
var profit Profit
err := GlobalDataBase.Model(&Profit{}).Where("address = ?", address).First(&profit).Error
if err != nil {
return Profit{}, err
}
return profit, nil
}
var blockNumberKey = "block_number_key"
type BlockNumber struct {
BlockNumberKey string `gorm:"primarykey;column:key"`
BlockNumber int64
}
func SetBlockNumber(blockNumber int64) error {
var daBlockNumber = BlockNumber{
BlockNumberKey: blockNumberKey,
BlockNumber: blockNumber,
}
return GlobalDataBase.Save(&daBlockNumber).Error
}
func GetBlockNumber() (int64, error) {
var blockNumber BlockNumber
err := GlobalDataBase.Model(&BlockNumber{}).First(&blockNumber).Error
return blockNumber.BlockNumber, err
}
package database
type Provider struct {
Address string `gorm:"primarykey"`
Name string
IP string
Port string
}
type Node struct {
Address string `gorm:"primaryKey"`
Id int `gorm:"primaryKey"`
CPUPrice int64
CPUModel string
GPUPrice int64
GPUModel string
MemPrice int64
MemCapacity int64
DiskPrice int64
DiskCapacity int64
}
func InitProvider() error {
return GlobalDataBase.AutoMigrate(&Provider{})
}
func (p *Provider) CreateProvider() error {
return GlobalDataBase.Create(p).Error
}
func (p *Provider) GetProviderByAddress(address string) (Provider, error) {
var provider Provider
err := GlobalDataBase.Model(&Provider{}).Where("address = ?", address).First(&provider).Error
if err != nil {
return Provider{}, err
}
return provider, nil
}
func InitNode() error {
return GlobalDataBase.AutoMigrate(&Node{})
}
func (n *Node) CreateNode() error {
return GlobalDataBase.Create(n).Error
}
func (n *Node) GetNodeByAddressAndId(address string, id int64) (Node, error) {
var node Node
err := GlobalDataBase.Model(&Node{}).Where("address = ? AND id = ?", address, id).First(&node).Error
if err != nil {
return node, err
}
return node, nil
}
module grid-prover
go 1.22.3
require (
github.com/ethereum/go-ethereum v1.14.11
github.com/gin-gonic/gin v1.10.0
github.com/mitchellh/go-homedir v1.1.0
github.com/urfave/cli/v2 v2.25.7
go.uber.org/zap v1.27.0
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da
gopkg.in/natefinch/lumberjack.v2 v2.2.1
gorm.io/driver/sqlite v1.5.6
gorm.io/gorm v1.25.12
)
require (
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
github.com/bytedance/sonic v1.11.6 // indirect
github.com/bytedance/sonic/loader v0.1.1 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gin-contrib/sse v0.1.0 // 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/goccy/go-json v0.10.2 // indirect
github.com/holiman/uint256 v1.3.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/cpuid/v2 v2.2.7 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-sqlite3 v1.14.22 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // 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-20201216005158-039620a65673 // indirect
go.uber.org/multierr v1.10.0 // indirect
golang.org/x/arch v0.8.0 // indirect
golang.org/x/crypto v0.23.0 // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/text v0.15.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0=
github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs=
github.com/ethereum/go-ethereum v1.14.11 h1:8nFDCUUE67rPc6AKxFj7JKaOa2W/W1Rse3oS6LvvxEY=
github.com/ethereum/go-ethereum v1.14.11/go.mod h1:+l/fr42Mma+xBnhefL/+z11/hcmJ2egl+ScIVPjhc7E=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8=
github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/holiman/uint256 v1.3.1 h1:JfTzmih28bittyHM8z360dCjIA9dbPIBlcTI6lmctQs=
github.com/holiman/uint256 v1.3.1/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs=
github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY=
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/sqlite v1.5.6 h1:fO/X46qn5NUEEOZtnjJRWRzZMe8nqJiQ9E+0hi+hKQE=
gorm.io/driver/sqlite v1.5.6/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4=
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
package logs
import (
"fmt"
"net/http"
)
type StorageError struct {
Storage string
Message string
}
func (e StorageError) Error() string {
return e.Storage + ":" + e.Message
}
type NotImplemented struct {
Message string
}
func (e NotImplemented) Error() string {
return e.Message
}
type StorageNotSupport struct{}
func (e StorageNotSupport) Error() string {
return "storage not support"
}
type AddressError struct {
Message string
}
func (e AddressError) Error() string {
return e.Message
}
type AuthenticationFailed struct {
Message string
}
func (e AuthenticationFailed) Error() string {
return e.Message
}
type EthError struct {
Message string
}
func (e EthError) Error() string {
return e.Message
}
type ContractError struct {
Message string
}
func (e ContractError) Error() string {
return e.Message
}
type ServerError struct {
Message string
}
func (e ServerError) Error() string {
return e.Message
}
type GatewayError struct {
Message string
}
func (e GatewayError) Error() string {
return e.Message
}
type ConfigError struct {
Message string
}
func (e ConfigError) Error() string {
return e.Message
}
type DataBaseError struct {
Message string
}
func (e DataBaseError) Error() string {
return e.Message
}
type DataStoreError struct {
Message string
}
func (e DataStoreError) Error() string {
return e.Message
}
type ControllerError struct {
Message string
}
func (e ControllerError) Error() string {
return e.Message
}
type NoPermission struct {
Message string
}
func (e NoPermission) Error() string {
return e.Message
}
type WalletError struct {
Message string
}
func (e WalletError) Error() string {
return e.Message
}
type APIError struct {
Code string
Description string
HTTPStatusCode int
}
type APIErrorCode int
type errorCodeMap map[APIErrorCode]APIError
const (
ErrNone APIErrorCode = iota
ErrInternal
ErrNotImplemented
ErrStorage
ErrAddress
ErrStorageNotSupport
ErrAuthenticationFailed
ErrContract
ErrEth
ErrServer
ErrGateway
ErrConfig
ErrDataBase
ErrDataStore
ErrController
ErrNoPermission
ErrWallet
)
func (e errorCodeMap) ToAPIErrWithErr(errCode APIErrorCode, err error) APIError {
apiErr, ok := e[errCode]
if !ok {
apiErr = e[ErrAddress]
}
if err != nil {
apiErr.Description = fmt.Sprintf("%s (%s)", apiErr.Description, err.Error())
}
return apiErr
}
func (e errorCodeMap) ToAPIErr(errCode APIErrorCode) APIError {
return e.ToAPIErrWithErr(errCode, nil)
}
var ErrorCodes = errorCodeMap{
ErrInternal: {
Code: "InternalError",
Description: "We encountered an internal error, please try again.",
HTTPStatusCode: http.StatusInternalServerError,
},
ErrNotImplemented: {
Code: "NotImplemented",
Description: "A header you provided implies functionality that is not implemented",
HTTPStatusCode: http.StatusNotImplemented,
},
ErrStorage: {
Code: "Storage",
Description: "Error storing file",
HTTPStatusCode: 516,
},
ErrAddress: {
Code: "Address",
Description: "Address Error",
HTTPStatusCode: 517,
},
ErrStorageNotSupport: {
Code: "Storage",
Description: "Storage Error",
HTTPStatusCode: 518,
},
ErrAuthenticationFailed: {
Code: "Authentication",
Description: "Authentication Failed",
HTTPStatusCode: 401,
},
ErrContract: {
Code: "contract",
Description: "contract Error",
HTTPStatusCode: 519,
},
ErrEth: {
Code: "Eth",
Description: "Eth Error",
HTTPStatusCode: 520,
},
ErrServer: {
Code: "ServerError",
Description: "Server Error",
HTTPStatusCode: 521,
},
ErrGateway: {
Code: "GatewayError",
Description: "Gateway Error",
HTTPStatusCode: 522,
},
ErrConfig: {
Code: "ConfigError",
Description: "Config Error",
HTTPStatusCode: 523,
},
ErrDataBase: {
Code: "DataBaseError",
Description: "DataBase Error",
HTTPStatusCode: 524,
},
ErrController: {
Code: "ControllerError",
Description: "Controller Error",
HTTPStatusCode: 525,
},
ErrNoPermission: {
Code: "Permission",
Description: "You don't have access to the resource",
HTTPStatusCode: 526,
},
ErrWallet: {
Code: "Wallet",
Description: "Wallet error",
HTTPStatusCode: 527,
},
ErrDataStore: {
Code: "datastore",
Description: "datastore error",
HTTPStatusCode: 528,
},
}
func ToAPIErrorCode(err error) APIError {
if err == nil {
return ErrorCodes.ToAPIErr(ErrNone)
}
var apiErr APIErrorCode
switch err.(type) {
case NotImplemented:
apiErr = ErrNotImplemented
case StorageError:
apiErr = ErrStorage
case AddressError:
apiErr = ErrAddress
case StorageNotSupport:
apiErr = ErrStorageNotSupport
case AuthenticationFailed:
apiErr = ErrAuthenticationFailed
case ContractError:
apiErr = ErrContract
case EthError:
apiErr = ErrEth
case ServerError:
apiErr = ErrServer
case GatewayError:
apiErr = ErrGateway
case ConfigError:
apiErr = ErrConfig
case DataBaseError:
apiErr = ErrDataBase
case ControllerError:
apiErr = ErrController
case NoPermission:
apiErr = ErrNoPermission
case WalletError:
apiErr = ErrWallet
case *DataStoreError:
apiErr = ErrDataStore
default:
apiErr = ErrInternal
}
return ErrorCodes.ToAPIErrWithErr(apiErr, err)
}
var (
ErrAlreadyExist = fmt.Errorf("already exist")
ErrNotExist = fmt.Errorf("not exist")
)
type ErrResponse struct {
Package string
Err error
}
package logs
import (
"fmt"
"os"
"sync"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"gopkg.in/natefinch/lumberjack.v2"
)
var mLogger *zap.SugaredLogger
var mLoglevel zap.AtomicLevel
var lk sync.Mutex
func Logger(name string) *zap.SugaredLogger {
lk.Lock()
defer lk.Unlock()
return mLogger.Named(name)
}
// StartLogger starts
func init() {
mLoglevel = zap.NewAtomicLevel()
outputs := []string{"stdout"}
debugWriter, _, err := zap.Open(outputs...)
if err != nil {
panic(fmt.Sprintf("unable to open logging output: %v", err))
}
lf := os.Getenv("MEFS_LOG_FILE")
if lf != "" {
debugWriter = getLogWriter(lf)
}
encoder := getEncoder()
core := zapcore.NewCore(encoder, debugWriter, mLoglevel)
// NewProduction
logger := zap.New(core, zap.AddCaller())
mLogger = logger.Sugar()
l := getLogLevel(os.Getenv("MEFS_LOG_LEVEL"))
mLoglevel.SetLevel(l)
}
func getEncoder() zapcore.Encoder {
encoderConfig := zapcore.EncoderConfig{
TimeKey: "time",
LevelKey: "level",
NameKey: "sub",
CallerKey: "caller",
MessageKey: "msg",
StacktraceKey: "stacktrace",
LineEnding: zapcore.DefaultLineEnding,
EncodeLevel: zapcore.CapitalLevelEncoder,
EncodeTime: zapcore.RFC3339TimeEncoder,
EncodeDuration: zapcore.SecondsDurationEncoder,
EncodeCaller: zapcore.ShortCallerEncoder,
}
return zapcore.NewJSONEncoder(encoderConfig)
}
func getLogWriter(filename string) zapcore.WriteSyncer {
lumberJackLogger := &lumberjack.Logger{
Filename: filename + ".log",
MaxSize: 100, //MB
MaxBackups: 3,
MaxAge: 30, //days
Compress: false,
}
return zapcore.AddSync(lumberJackLogger)
}
func getLogLevel(level string) zapcore.Level {
l := zapcore.InfoLevel
switch level {
case "debug", "DEBUG":
l = zapcore.DebugLevel
case "info", "INFO", "": // make the zero value useful
l = zapcore.InfoLevel
case "warn", "WARN":
l = zapcore.WarnLevel
case "error", "ERROR":
l = zapcore.ErrorLevel
case "dpanic", "DPANIC":
l = zapcore.DPanicLevel
case "panic", "PANIC":
l = zapcore.PanicLevel
case "fatal", "FATAL":
l = zapcore.FatalLevel
}
return l
}
func SetLogLevel(level string) error {
l := getLogLevel(level)
lk.Lock()
defer lk.Unlock()
mLoglevel.SetLevel(l)
return nil
}
package main
import (
"fmt"
"grid-prover/cmd"
"os"
"github.com/urfave/cli/v2"
)
func main() {
local := make([]*cli.Command, 0, 1)
local = append(local, cmd.ValidatorCmd, cmd.VersionCmd)
app := cli.App{
Commands: local,
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "version",
Aliases: []string{"v"},
Usage: "Show application version",
},
},
Action: func(ctx *cli.Context) error {
if ctx.Bool("version") {
fmt.Println(cmd.Version + "+" + cmd.BuildFlag)
}
return nil
},
}
app.Setup()
err := app.Run(os.Args)
if err != nil {
fmt.Fprintf(os.Stderr, "ERROR: %s\n\n", err) // nolint:errcheck
os.Exit(1)
}
}
APP_NAME=meeda
LIB_NAME=libpow.so
# GIT_COMMIT=$(shell git rev-parse --short HEAD)
BUILD_TIME=$(shell TZ=Asia/Shanghai date +'%Y-%m-%d.%H:%M:%S%Z')
BUILD_FLAGS=-ldflags "-X 'github.com/memoio/meeda-node/cmd.BuildFlag=$(BUILD_TIME)'"
all: clean cuda build
clean:
rm -f ${APP_NAME} ${LIB_NAME}
cuda:
nvcc --ptxas-options=-v --compiler-options '-fPIC' -o ${LIB_NAME} --shared CudaSha256/pow.cu
build:
go build $(BUILD_FLAGS) -o ${APP_NAME}
install:
mv ${APP_NAME} /usr/local/bin
.PHONY: all clean cuda build
\ No newline at end of file
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