migration of open-etc-friends-pool for use with Etica/EGAZ
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

591 lines
14 KiB

package storage
import (
"os"
"reflect"
"strconv"
"testing"
"gopkg.in/redis.v3"
"log"
)
var r *RedisClient
const prefix = "test"
func TestMain(m *testing.M) {
r = NewRedisClient(&Config{Endpoint: "35.187.240.179:6379", Database: 10}, prefix, 1000000, "UBIQ")
reset()
c := m.Run()
reset()
os.Exit(c)
}
func TestWriteShareCheckExist(t *testing.T) {
reset()
exist, _ := r.WriteShare("x", "x", []string{"0x0", "0x0", "0x0"}, 10, 1008, 0)
if exist {
t.Error("PoW must not exist")
}
exist, _ = r.WriteShare("x", "x", []string{"0x0", "0x1", "0x0"}, 10, 1008, 0)
if exist {
t.Error("PoW must not exist")
}
exist, _ = r.WriteShare("x", "x", []string{"0x0", "0x0", "0x1"}, 100, 1010, 0)
if exist {
t.Error("PoW must not exist")
}
exist, _ = r.WriteShare("z", "x", []string{"0x0", "0x0", "0x1"}, 100, 1016, 0)
if !exist {
t.Error("PoW must exist")
}
exist, _ = r.WriteShare("x", "x", []string{"0x0", "0x0", "0x1"}, 100, 1025, 0)
if exist {
t.Error("PoW must not exist")
}
}
func TestGetPayees(t *testing.T) {
reset()
n := 256
for i := 0; i < n; i++ {
r.client.HSet(r.formatKey("miners", strconv.Itoa(i)), "balance", strconv.Itoa(i))
}
var payees []string
payees, _ = r.GetPayees()
if len(payees) != n {
t.Error("Must return all payees")
}
m := make(map[string]struct{})
for _, v := range payees {
m[v] = struct{}{}
}
if len(m) != n {
t.Error("Must be unique list")
}
}
func TestGetBalance(t *testing.T) {
reset()
r.client.HSet(r.formatKey("miners:x"), "balance", "750")
v, _ := r.GetBalance("x")
if v != 750 {
t.Error("Must return balance")
}
v, err := r.GetBalance("z")
if v != 0 {
t.Error("Must return 0 if account does not exist")
}
if err != nil {
t.Error("Must not return error if account does not exist")
}
}
func TestLockPayouts(t *testing.T) {
reset()
r.LockPayouts("x", 1000)
v := r.client.Get("test:payments:lock").Val()
if v != "x:1000" {
t.Errorf("Invalid lock amount: %v", v)
}
err := r.LockPayouts("x", 100)
if err == nil {
t.Errorf("Must not overwrite lock")
}
}
func TestUnlockPayouts(t *testing.T) {
reset()
r.client.Set(r.formatKey("payments:lock"), "x:1000", 0)
r.UnlockPayouts()
err := r.client.Get(r.formatKey("payments:lock")).Err()
if err != redis.Nil {
t.Errorf("Must release lock")
}
}
func TestIsPayoutsLocked(t *testing.T) {
reset()
r.LockPayouts("x", 1000)
if locked, _ := r.IsPayoutsLocked(); !locked {
t.Errorf("Payouts must be locked")
}
}
func TestUpdateBalance(t *testing.T) {
reset()
r.client.HMSetMap(
r.formatKey("miners:x"),
map[string]string{"paid": "50", "balance": "1000"},
)
r.client.HMSetMap(
r.formatKey("finances"),
map[string]string{"paid": "500", "balance": "10000"},
)
amount := int64(250)
r.UpdateBalance("x", amount)
result := r.client.HGetAllMap(r.formatKey("miners:x")).Val()
if result["pending"] != "250" {
t.Error("Must set pending amount")
}
if result["balance"] != "750" {
t.Error("Must deduct balance")
}
if result["paid"] != "50" {
t.Error("Must not touch paid")
}
result = r.client.HGetAllMap(r.formatKey("finances")).Val()
if result["pending"] != "250" {
t.Error("Must set pool pending amount")
}
if result["balance"] != "9750" {
t.Error("Must deduct pool balance")
}
if result["paid"] != "500" {
t.Error("Must not touch pool paid")
}
rank := r.client.ZRank(r.formatKey("payments:pending"), join("x", amount)).Val()
if rank != 0 {
t.Error("Must add pending payment")
}
}
func TestRollbackBalance(t *testing.T) {
reset()
r.client.HMSetMap(
r.formatKey("miners:x"),
map[string]string{"paid": "100", "balance": "750", "pending": "250"},
)
r.client.HMSetMap(
r.formatKey("finances"),
map[string]string{"paid": "500", "balance": "10000", "pending": "250"},
)
r.client.ZAdd(r.formatKey("payments:pending"), redis.Z{Score: 1, Member: "xx"})
amount := int64(250)
r.RollbackBalance("x", amount)
result := r.client.HGetAllMap(r.formatKey("miners:x")).Val()
if result["paid"] != "100" {
t.Error("Must not touch paid")
}
if result["balance"] != "1000" {
t.Error("Must increase balance")
}
if result["pending"] != "0" {
t.Error("Must deduct pending")
}
result = r.client.HGetAllMap(r.formatKey("finances")).Val()
if result["paid"] != "500" {
t.Error("Must not touch pool paid")
}
if result["balance"] != "10250" {
t.Error("Must increase pool balance")
}
if result["pending"] != "0" {
t.Error("Must deduct pool pending")
}
err := r.client.ZRank(r.formatKey("payments:pending"), join("x", amount)).Err()
if err != redis.Nil {
t.Errorf("Must remove pending payment")
}
}
func TestWritePayment(t *testing.T) {
reset()
r.client.HMSetMap(
r.formatKey("miners:x"),
map[string]string{"paid": "50", "balance": "1000", "pending": "250"},
)
r.client.HMSetMap(
r.formatKey("finances"),
map[string]string{"paid": "500", "balance": "10000", "pending": "250"},
)
amount := int64(250)
tx := int64(2)
r.WritePayment("x", "0x0", amount, tx)
result := r.client.HGetAllMap(r.formatKey("miners:x")).Val()
if result["pending"] != "0" {
t.Error("Must unset pending amount")
}
if result["balance"] != "1000" {
t.Error("Must not touch balance")
}
if result["paid"] != "300" {
t.Error("Must increase paid")
}
result = r.client.HGetAllMap(r.formatKey("finances")).Val()
if result["pending"] != "0" {
t.Error("Must deduct pool pending amount")
}
if result["balance"] != "10000" {
t.Error("Must not touch pool balance")
}
if result["paid"] != "750" {
t.Error("Must increase pool paid")
}
err := r.client.Get(r.formatKey("payments:lock")).Err()
if err != redis.Nil {
t.Errorf("Must release lock")
}
err = r.client.ZRank(r.formatKey("payments:pending"), join("x", amount)).Err()
if err != redis.Nil {
t.Error("Must remove pending payment")
}
err = r.client.ZRank(r.formatKey("payments:all"), join("0x0", "x", amount)).Err()
if err == redis.Nil {
t.Error("Must add payment to set")
}
err = r.client.ZRank(r.formatKey("payments:x"), join("0x0", amount)).Err()
if err == redis.Nil {
t.Error("Must add payment to set")
}
}
func TestGetPendingPayments(t *testing.T) {
reset()
r.client.HMSetMap(
r.formatKey("miners:x"),
map[string]string{"paid": "100", "balance": "750", "pending": "250"},
)
amount := int64(1000)
r.UpdateBalance("x", amount)
pending := r.GetPendingPayments()
if len(pending) != 1 {
t.Error("Must return pending payment")
}
if pending[0].Amount != amount {
t.Error("Must have corrent amount")
}
if pending[0].Address != "x" {
t.Error("Must have corrent account")
}
if pending[0].Timestamp <= 0 {
t.Error("Must have timestamp")
}
}
func TestCollectLuckStats(t *testing.T) {
reset()
members := []redis.Z{
redis.Z{Score: 0, Member: "1:0:0x0:0x0:0:100:100:0"},
}
r.client.ZAdd(r.formatKey("blocks:immature"), members...)
members = []redis.Z{
redis.Z{Score: 1, Member: "1:0:0x2:0x0:0:50:100:0"},
redis.Z{Score: 2, Member: "0:1:0x1:0x0:0:100:100:0"},
redis.Z{Score: 3, Member: "0:0:0x3:0x0:0:200:100:0"},
}
r.client.ZAdd(r.formatKey("blocks:matured"), members...)
stats, _ := r.CollectLuckStats([]int{1, 2, 5, 10})
expectedStats := map[string]interface{}{
"1": map[string]float64{
"luck": 1, "uncleRate": 1, "orphanRate": 0,
},
"2": map[string]float64{
"luck": 0.75, "uncleRate": 0.5, "orphanRate": 0,
},
"4": map[string]float64{
"luck": 1.125, "uncleRate": 0.5, "orphanRate": 0.25,
},
}
if !reflect.DeepEqual(stats, expectedStats) {
t.Error("Stats != expected stats")
}
}
func TestCollectStats(t *testing.T) {
stat, err := r.CollectStats(500000, 100, 100)
if err != nil {
t.Errorf("Result : %v, Err : %v", stat, err)
}
t.Logf("Result : %v", stat)
}
func TestGetMinerStats(t *testing.T) {
stats := make(map[string]interface{})
login := "0x5ca87a9e8e132be404a1efb6516665252a74a4e2"
tx := r.client.Multi()
defer tx.Close()
cmds, err := tx.Exec(func() error {
tx.HGetAllMap(r.formatKey("miners", login))
tx.ZRevRangeWithScores(r.formatKey("payments", login), 0, 100)
tx.ZCard(r.formatKey("payments", login))
tx.HGet(r.formatKey("shares", "roundCurrent"), login)
return nil
})
if err != nil && err != redis.Nil {
t.Errorf("Error :", err)
} else {
result, _ := cmds[0].(*redis.StringStringMapCmd).Result()
stats["stats"] = convertStringMap(result)
payments := convertPaymentsResults(cmds[1].(*redis.ZSliceCmd))
stats["payments"] = payments
stats["paymentsTotal"] = cmds[2].(*redis.IntCmd).Val()
roundShares, _ := cmds[3].(*redis.StringCmd).Int64()
if roundShares < 0 {
roundShares = 0
}
stats["roundShares"] = roundShares
log.Printf("Inner Result : %v ", result)
}
log.Printf("Result : %v ", stats)
if err != nil {
t.Errorf("Error :", err)
}
}
func TestStoreExchangeData(t *testing.T) {
m := map[string]string{
"id": "ethereum",
"name": "Ethereum",
"symbol": "ETH",
"rank": "2",
"price_usd": "311.984",
"price_btc": "0.0823755",
"24h_volume_usd": "1161280000.0",
"market_cap_usd": "29309660622.0",
"available_supply": "93946038.0",
"total_supply": "93946038.0",
"percent_change_1h": "0.47",
"percent_change_24h": "4.12",
"percent_change_7d": "30.36",
"last_updated": "1502540048",
"price_inr": "19995.366544",
"24h_volume_inr": "74427596480.0",
"market_cap_inr": "1878485458898",
}
m1 := map[string]string{
"id": "bitcoin",
"name": "Bitcoin",
"symbol": "BTC",
"rank": "1",
"price_usd": "3836.67",
"price_btc": "1.0",
"24h_volume_usd": "2080280000.0",
"market_cap_usd": "63315651883.0",
"available_supply": "16502762.0",
"total_supply": "16502762.0",
"percent_change_1h": "1.26",
"percent_change_24h": "8.93",
"percent_change_7d": "19.58",
"last_updated": "1502551754",
"price_inr": "245896.01697",
"24h_volume_inr": "133327225479.9999847412",
"market_cap_inr": "4057963444804",
}
data := []map[string]string{
m1,
m,
}
tx := r.client.Multi()
defer tx.Close()
for _, v := range data {
for k1, v1 := range v {
tx.HSet(r.formatKey("exchange", v["symbol"]), k1, v1)
}
}
log.Print("Writing Exchange Data : %v", data)
}
func TestGetExchangeData(t *testing.T) {
cmd := r.client.HGetAllMap(r.formatKey("exchange", "ETH"))
result, err := cmd.Result()
log.Printf("Writing Exchange Data : %v ", result)
if err != nil {
t.Errorf("Error at GetExchangeData:", err)
}
}
func TestCreateNewNValue(t *testing.T) {
result, err := r.CreateNewNValue(4000000000)
if err != nil {
t.Errorf("Result : %v, Err : %v", result, err)
}
t.Logf("Result : %v", result)
}
func TestGetNetworkDifficultyForCurrentShareDifficulty(t *testing.T) {
//m ,err := r.GetNodeStates()
result, err := r.GetNetworkDifficultyForCurrentShareDifficulty(4000000000)
if err != nil {
t.Errorf("Result : %v, Err : %v", result, err)
}
t.Logf("Result : %v", result)
}
func TestGetNetworkDifficulty(t *testing.T) {
result, err := r.GetNetworkDifficulty()
if err != nil {
t.Errorf("Result : %v, Err :%v", result, err)
}
t.Logf("Result : %v", result)
}
func TestGetThreshold(t *testing.T) {
result, err := r.SetThreshold("0xfacb288273969c68e9ad1eeeb81f08ab92cf57ad", 5000000)
t.Logf("Result : %v", result)
if err != nil {
t.Errorf("Error , %v", err)
}
}
func TestSetThreshold(t *testing.T) {
r.SetThreshold("0xfacb288273969c68e9ad1eeeb81f08ab92cf57ad", 5000000)
result, err := r.GetThreshold("0xfacb288273969c68e9ad1eeeb81f08ab92cf57ad")
t.Logf("Result : %v", result)
if err != nil {
t.Errorf("Error , %v", err)
}
}
func TestLogIP(t *testing.T) {
r.LogIP("0xb9cf2da90bdff1bc014720cc84f5ab99d7974eba", "192.168.00.100")
}
func TestAdjustCurrentNShares(t *testing.T) {
result, err := r.AdjustCurrentNShares(4000000000)
t.Logf("Result : %v", result)
if err != nil {
t.Errorf("Error , %v", err)
}
/*currentNShare := 1010
lastN := 1000
tx := r.client.Multi()
defer tx.Close()
if currentNShare > lastN{
shareHash := make([]string, currentNShare-lastN)
cmd, err := tx.Exec(func() error {
//Keep removing the shares from the List by RPOP and while removing adjust the correcponding miner share value and the stat:roundCurrent Share value
//count :=0
for loopIndex := currentNShare; loopIndex > lastN; loopIndex--{
//Generate all the poped value of the ShareHash on the Array
//tx.LIndex(r.formatKey("lastshares"),-1)
tx.RPop(r.formatKey("lastshares"))
//tx.HIncrBy(r.formatKey("shares", "roundCurrent"), str, -1)
//t.Logf("List index value : %v", str)
//count++
}
return nil
})
if err != nil {
t.Logf("Error while Reducing the share count , %v", err)
} else {
tx2 := r.client.Multi()
defer tx2.Close()
//Decrement the corresponding share value
_, err := tx2.Exec(func() error {
for key , _ := range shareHash {
poppedValue, err := cmd[key].(*redis.StringCmd).Result()
//poppedValue1, err := cmd[1].(*redis.StringCmd).Result()
if err==nil{
tx2.HIncrBy(r.formatKey("stats"), "roundShares", -1)
tx2.HIncrBy(r.formatKey("shares", "roundCurrent"),poppedValue, -1)
return errors.New("TEST RETURN")
}
log.Print(poppedValue)
log.Print(key)
//log.Print(poppedValue1)
}
return nil
})
if err!=nil{
t.Errorf("Error while adjusting the last share window count , %v", err)
}
}
} else {
//No adjustment is required for the Window
t.Logf("No formatting required")
}
*/
}
func TestWriteBlock(t *testing.T) {
}
func TestWriteShare(t *testing.T) {
}
func reset() {
keys := r.client.Keys(r.prefix + ":*").Val()
for _, k := range keys {
r.client.Del(k)
}
}