create git
This commit is contained in:
367
internal/utility/utility.go
Normal file
367
internal/utility/utility.go
Normal file
@@ -0,0 +1,367 @@
|
||||
// utility.go
|
||||
package utility
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
"bytes"
|
||||
"log"
|
||||
"math"
|
||||
"math/big"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"time"
|
||||
|
||||
"github.com/zeromq/goczmq"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
"gopkg.in/natefinch/lumberjack.v2"
|
||||
)
|
||||
|
||||
const BITCOIND_ZMQ_HASHBLOCK string = "hashblock"
|
||||
|
||||
type CoinConfig struct {
|
||||
Coin string `json:"coin"`
|
||||
Pprof string `json:"pprof,omitempty"`
|
||||
}
|
||||
|
||||
type ZmqConfig struct {
|
||||
Pub string `json:"pub"`
|
||||
Sub string `json:"sub"`
|
||||
}
|
||||
|
||||
type RedisConfig struct {
|
||||
Addr string `json:"addr"`
|
||||
Password string `json:"password"`
|
||||
DB int `json:"db"`
|
||||
}
|
||||
|
||||
type LogRotateConfig struct {
|
||||
MaxSize int `json:"maxsize"`
|
||||
MaxBackups int `json:"maxbackups"`
|
||||
MaxAge int `json:"maxage"`
|
||||
Compress bool `json:"compress"`
|
||||
}
|
||||
|
||||
func InitLogg(zaplog *zap.Config, rotate *LogRotateConfig, coinname string, modulename string) (*zap.Logger, *lumberjack.Logger, error) {
|
||||
os.MkdirAll("logs/"+coinname, os.ModePerm)
|
||||
logfile := "./logs/" + coinname + "/" + modulename + ".log"
|
||||
|
||||
logRotate := &lumberjack.Logger{
|
||||
Filename: logfile,
|
||||
MaxSize: rotate.MaxSize,
|
||||
MaxBackups: rotate.MaxBackups,
|
||||
MaxAge: rotate.MaxAge,
|
||||
Compress: rotate.Compress,
|
||||
}
|
||||
|
||||
zaplog.EncoderConfig = zap.NewProductionEncoderConfig()
|
||||
zaplog.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
|
||||
|
||||
opath := []string{"", ""}
|
||||
opath[0] = zaplog.OutputPaths[0]
|
||||
opath[1] = logfile
|
||||
zaplog.OutputPaths = opath
|
||||
|
||||
l, err := zaplog.Build(
|
||||
zap.WrapCore(func(core zapcore.Core) zapcore.Core {
|
||||
return zapcore.NewCore(
|
||||
zapcore.NewJSONEncoder(zaplog.EncoderConfig),
|
||||
zapcore.AddSync(logRotate),
|
||||
zaplog.Level,
|
||||
)
|
||||
}),
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatal("[gbt]", err.Error())
|
||||
return nil, nil, err
|
||||
}
|
||||
return l, logRotate, nil
|
||||
}
|
||||
|
||||
func GetCoin(config_file string) (string, string) {
|
||||
var config CoinConfig
|
||||
data, err := ioutil.ReadFile(config_file)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
if err = json.Unmarshal(data, &config); err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
return config.Coin, config.Pprof
|
||||
}
|
||||
|
||||
func confirmXPubSubscriptions(pub *goczmq.Channeler, count int) {
|
||||
for i := 0; i < count; i++ {
|
||||
select {
|
||||
case <-pub.RecvChan:
|
||||
case <-time.After(time.Second * 2):
|
||||
log.Println("confirmXPubSubscriptions, timeout")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func InitZmqPub(pub_host string) *goczmq.Sock {
|
||||
pub_ch, err := goczmq.NewXPub(pub_host)
|
||||
if err != nil {
|
||||
log.Fatal("[server]", zap.String("NewXPub", "zmq pub create failed!"))
|
||||
}
|
||||
return pub_ch
|
||||
}
|
||||
|
||||
func InitZmqSub(sub_to string, topic string) *goczmq.Sock {
|
||||
|
||||
sub_ch, err := goczmq.NewSub(sub_to, topic)
|
||||
if err != nil {
|
||||
log.Fatal("[server]", zap.String("NewSub", "zmq sub connect failed!"))
|
||||
}
|
||||
return sub_ch
|
||||
|
||||
}
|
||||
|
||||
func InitZmqPush(sub_to string) *goczmq.Sock {
|
||||
push_ch, err := goczmq.NewPush(sub_to)
|
||||
if err != nil {
|
||||
log.Fatal("[server]", zap.String("NewPushChanneler", "zmq push connect failed!"))
|
||||
}
|
||||
//push_ch.Bind(sub_to)
|
||||
|
||||
return push_ch
|
||||
}
|
||||
|
||||
func InitZmqPull(sub_to string) *goczmq.Sock {
|
||||
pull_ch, err := goczmq.NewPull(sub_to)
|
||||
if err != nil {
|
||||
log.Fatal("[server]", zap.String("InitZmqPull", "zmq pull connect failed! "+err.Error()))
|
||||
}
|
||||
|
||||
return pull_ch
|
||||
}
|
||||
|
||||
func Int32ToString(n uint32) string {
|
||||
buf := [11]byte{}
|
||||
pos := len(buf)
|
||||
i := int64(n)
|
||||
signed := i < 0
|
||||
if signed {
|
||||
i = -i
|
||||
}
|
||||
for {
|
||||
pos--
|
||||
buf[pos], i = '0'+byte(i%10), i/10
|
||||
if i == 0 {
|
||||
if signed {
|
||||
pos--
|
||||
buf[pos] = '-'
|
||||
}
|
||||
return string(buf[pos:])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ByteToUint32(bytes []byte) uint32 {
|
||||
return binary.LittleEndian.Uint32(bytes)
|
||||
}
|
||||
|
||||
func Reverse_string(instr string) string {
|
||||
var outstr string = ""
|
||||
for i := 0; i < len(instr)/2; i++ {
|
||||
outstr = outstr + instr[len(instr)-i*2-2:len(instr)-i*2]
|
||||
}
|
||||
return outstr
|
||||
}
|
||||
|
||||
// CompactToBig converts a compact representation of a whole number N to an
|
||||
// unsigned 32-bit number. The representation is similar to IEEE754 floating
|
||||
// point numbers.
|
||||
//
|
||||
// Like IEEE754 floating point, there are three basic components: the sign,
|
||||
// the exponent, and the mantissa. They are broken out as follows:
|
||||
//
|
||||
// - the most significant 8 bits represent the unsigned base 256 exponent
|
||||
// - bit 23 (the 24th bit) represents the sign bit
|
||||
// - the least significant 23 bits represent the mantissa
|
||||
//
|
||||
// -------------------------------------------------
|
||||
// | Exponent | Sign | Mantissa |
|
||||
// -------------------------------------------------
|
||||
// | 8 bits [31-24] | 1 bit [23] | 23 bits [22-00] |
|
||||
// -------------------------------------------------
|
||||
//
|
||||
// The formula to calculate N is:
|
||||
//
|
||||
// N = (-1^sign) * mantissa * 256^(exponent-3)
|
||||
//
|
||||
// This compact form is only used in bitcoin to encode unsigned 256-bit numbers
|
||||
// which represent difficulty targets, thus there really is not a need for a
|
||||
// sign bit, but it is implemented here to stay consistent with bitcoind.
|
||||
func CompactToBig(compact uint32) *big.Int {
|
||||
// Extract the mantissa, sign bit, and exponent.
|
||||
mantissa := compact & 0x007fffff
|
||||
isNegative := compact&0x00800000 != 0
|
||||
exponent := uint(compact >> 24)
|
||||
|
||||
// Since the base for the exponent is 256, the exponent can be treated
|
||||
// as the number of bytes to represent the full 256-bit number. So,
|
||||
// treat the exponent as the number of bytes and shift the mantissa
|
||||
// right or left accordingly. This is equivalent to:
|
||||
// N = mantissa * 256^(exponent-3)
|
||||
var bn *big.Int
|
||||
if exponent <= 3 {
|
||||
mantissa >>= 8 * (3 - exponent)
|
||||
bn = big.NewInt(int64(mantissa))
|
||||
} else {
|
||||
bn = big.NewInt(int64(mantissa))
|
||||
bn.Lsh(bn, 8*(exponent-3))
|
||||
}
|
||||
|
||||
// Make it negative if the sign bit is set.
|
||||
if isNegative {
|
||||
bn = bn.Neg(bn)
|
||||
}
|
||||
|
||||
return bn
|
||||
}
|
||||
|
||||
const truediffone float64 = 26959535291011309493156476344723991336010898738574164086137773096960.0
|
||||
const bits192 float64 = 6277101735386680763835789423207666416102355444464034512896.0
|
||||
const bits128 float64 = 340282366920938463463374607431768211456.0
|
||||
const bits64 float64 = 18446744073709551616.0
|
||||
|
||||
func target2float(target []byte) float64 {
|
||||
var b64 float64 = float64(binary.LittleEndian.Uint64(target[24:32])) * bits192
|
||||
b64 += (float64(binary.LittleEndian.Uint64(target[16:24])) * bits128)
|
||||
b64 += (float64(binary.LittleEndian.Uint64(target[8:16])) * bits64)
|
||||
b64 += (float64(binary.LittleEndian.Uint64(target[0:8])))
|
||||
return b64
|
||||
}
|
||||
|
||||
func Target2Diff(target []byte) float64 {
|
||||
//var f64 float64 = truediffone
|
||||
//max, _ := new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 16)
|
||||
max, _ := new(big.Int).SetString("00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 16)
|
||||
maxf, _ := new(big.Float).SetString(max.String())
|
||||
f64, _ := maxf.Float64()
|
||||
var fcut64 float64 = target2float(target)
|
||||
//log.Println("diff", f64, fcut64, f64/fcut64)
|
||||
return f64 / fcut64
|
||||
}
|
||||
|
||||
func MoneroTarget2Diff(target []byte) float64 {
|
||||
//var f64 float64 = truediffone
|
||||
// max, _ := new(big.Int).SetString("00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 16)
|
||||
max, _ := new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 16)
|
||||
maxf, _ := new(big.Float).SetString(max.String())
|
||||
f64, _ := maxf.Float64()
|
||||
var fcut64 float64 = target2float(target)
|
||||
//log.Println("diff", f64, fcut64, f64/fcut64)
|
||||
return f64 / fcut64
|
||||
}
|
||||
|
||||
func DiffToTarget(diff float64 /*, powLimit *big.Int*/) (*big.Int, error) {
|
||||
if diff <= 0 {
|
||||
return nil, fmt.Errorf("invalid pool difficulty %v (0 or less than "+
|
||||
"zero passed)", diff)
|
||||
}
|
||||
|
||||
// Round down in the case of a non-integer diff since we only support
|
||||
// ints (unless diff < 1 since we don't allow 0)..
|
||||
if diff <= 1 {
|
||||
diff = 1
|
||||
} else {
|
||||
diff = math.Floor(diff)
|
||||
}
|
||||
divisor := new(big.Int).SetInt64(int64(diff))
|
||||
//max, _ := new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 16)
|
||||
max, _ := new(big.Int).SetString("00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 16)
|
||||
target := new(big.Int)
|
||||
//log.Println("target calc", hex.EncodeToString(max.Bytes()), hex.EncodeToString(divisor.Bytes()))
|
||||
target.Div(max, divisor)
|
||||
|
||||
return target, nil
|
||||
}
|
||||
|
||||
func MoneroDiffToTarget(diff float64 /*, powLimit *big.Int*/) (*big.Int, error) {
|
||||
if diff <= 0 {
|
||||
return nil, fmt.Errorf("invalid pool difficulty %v (0 or less than "+
|
||||
"zero passed)", diff)
|
||||
}
|
||||
|
||||
// Round down in the case of a non-integer diff since we only support
|
||||
// ints (unless diff < 1 since we don't allow 0)..
|
||||
if diff <= 1 {
|
||||
diff = 1
|
||||
} else {
|
||||
diff = math.Floor(diff)
|
||||
}
|
||||
divisor := new(big.Int).SetInt64(int64(diff))
|
||||
// max, _ := new(big.Int).SetString("00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 16)
|
||||
max, _ := new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 16)
|
||||
target := new(big.Int)
|
||||
//log.Println("target calc", hex.EncodeToString(max.Bytes()), hex.EncodeToString(divisor.Bytes()))
|
||||
target.Div(max, divisor)
|
||||
|
||||
return target, nil
|
||||
}
|
||||
|
||||
func Convert_big_endian(src []byte) []byte {
|
||||
var dst []byte = make([]byte, 32)
|
||||
for i := 0; i < 8; i++ {
|
||||
dst[0+4*i] = src[3+4*i]
|
||||
dst[1+4*i] = src[2+4*i]
|
||||
dst[2+4*i] = src[1+4*i]
|
||||
dst[3+4*i] = src[0+4*i]
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
func ReverseS(s string) (string, error) {
|
||||
a := strings.Split(s, "")
|
||||
sRev := ""
|
||||
if len(a)%2 != 0 {
|
||||
return "", fmt.Errorf("Incorrect input length")
|
||||
}
|
||||
for i := 0; i < len(a); i += 2 {
|
||||
tmp := []string{a[i], a[i+1], sRev}
|
||||
sRev = strings.Join(tmp, "")
|
||||
}
|
||||
return sRev, nil
|
||||
}
|
||||
|
||||
func Reverse(src []byte) []byte {
|
||||
dst := make([]byte, len(src))
|
||||
for i := len(src); i > 0; i-- {
|
||||
dst[len(src)-i] = src[i-1]
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
func Uint32ToByte(targetu uint32) []byte {
|
||||
bytes := make([]byte, 4)
|
||||
binary.LittleEndian.PutUint32(bytes, targetu)
|
||||
return bytes
|
||||
}
|
||||
|
||||
func Uint32ToByteBig(targetu uint32) []byte {
|
||||
bytes := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(bytes, targetu)
|
||||
return bytes
|
||||
}
|
||||
|
||||
func ExecShellCmd(s string) (string, error) {
|
||||
cmd := exec.Command("/bin/bash", "-c", s)
|
||||
var out bytes.Buffer
|
||||
cmd.Stdout = &out
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
//fmt.Println(out.String(), s)
|
||||
return out.String(), err
|
||||
}
|
||||
Reference in New Issue
Block a user