Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update #506

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
.DS_Store
config.json
testnet.json
payouts.json


.idea
/build/_workspace/
/build/bin/
37 changes: 37 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
module github.com/sammy007/open-ethereum-pool

go 1.19

require (
github.com/FranckStone/ethash v0.0.2
github.com/ethereumfair/go-ethereum v1.0.5
github.com/gorilla/mux v1.8.0
github.com/yvasiyarov/gorelic v0.0.7
gopkg.in/redis.v3 v3.6.4
)

require (
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect
github.com/deckarep/golang-set v1.8.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
github.com/garyburd/redigo v1.6.4 // indirect
github.com/go-ole/go-ole v1.2.1 // indirect
github.com/go-stack/stack v1.8.0 // indirect
github.com/google/uuid v1.2.0 // indirect
github.com/gorilla/websocket v1.4.2 // indirect
github.com/mattn/go-runewidth v0.0.9 // indirect
github.com/onsi/ginkgo v1.16.5 // indirect
github.com/onsi/gomega v1.22.1 // indirect
github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 // indirect
github.com/rjeczalik/notify v0.9.1 // indirect
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect
github.com/tklauser/go-sysconf v0.3.5 // indirect
github.com/tklauser/numcpus v0.2.2 // indirect
github.com/yvasiyarov/go-metrics v0.0.0-20150112132944-c25f46c4b940 // indirect
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20160601141957-9c099fbc30e9 // indirect
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
gopkg.in/bsm/ratelimit.v1 v1.0.0-20160220154919-db14e161995a // indirect
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
)
170 changes: 170 additions & 0 deletions go.sum

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build go1.9
// +build go1.9

package main
Expand Down
145 changes: 105 additions & 40 deletions payouts/payer.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
package payouts

import (
"context"
"crypto/ecdsa"
"fmt"
"github.com/ethereumfair/go-ethereum/accounts/keystore"
"github.com/ethereumfair/go-ethereum/common"
"github.com/ethereumfair/go-ethereum/common/hexutil"
"github.com/ethereumfair/go-ethereum/console/prompt"
"github.com/ethereumfair/go-ethereum/core/types"
"github.com/ethereumfair/go-ethereum/crypto"
"github.com/ethereumfair/go-ethereum/ethclient"
"io/ioutil"
"log"
"math/big"
"os"
"strconv"
"time"

"github.com/ethereum/go-ethereum/common/hexutil"

"github.com/sammy007/open-ethereum-pool/rpc"
"github.com/sammy007/open-ethereum-pool/storage"
"github.com/sammy007/open-ethereum-pool/util"
)
Expand All @@ -27,6 +34,8 @@ type PayoutsConfig struct {
Gas string `json:"gas"`
GasPrice string `json:"gasPrice"`
AutoGas bool `json:"autoGas"`
KeyPath string `json:"keyPath"`

// In Shannon
Threshold int64 `json:"threshold"`
BgSave bool `json:"bgsave"`
Expand All @@ -43,29 +52,45 @@ func (self PayoutsConfig) GasPriceHex() string {
}

type PayoutsProcessor struct {
config *PayoutsConfig
backend *storage.RedisClient
rpc *rpc.RPCClient
halt bool
lastFail error
config *PayoutsConfig
backend *storage.RedisClient
privateKey *ecdsa.PrivateKey
rpc *ethclient.Client
halt bool
lastFail error
}

func NewPayoutsProcessor(cfg *PayoutsConfig, backend *storage.RedisClient) *PayoutsProcessor {
u := &PayoutsProcessor{config: cfg, backend: backend}
u.rpc = rpc.NewRPCClient("PayoutsProcessor", cfg.Daemon, cfg.Timeout)
u.rpc, _ = ethclient.Dial(cfg.Daemon)
return u
}

func (u *PayoutsProcessor) Start() {
log.Println("Starting payouts")

if u.mustResolvePayout() {
log.Println("Running with env RESOLVE_PAYOUT=1, now trying to resolve locked payouts")
u.resolvePayouts()
log.Println("Now you have to restart payouts module with RESOLVE_PAYOUT=0 for normal run")
//if u.mustResolvePayout() {
// log.Println("Running with env RESOLVE_PAYOUT=1, now trying to resolve locked payouts")
// u.resolvePayouts()
// log.Println("Now you have to restart payouts module with RESOLVE_PAYOUT=0 for normal run")
// return
//}

password, _ := prompt.Stdin.PromptPassword("Please enter the password :")
keyjson, err := ioutil.ReadFile(u.config.KeyPath)
if err != nil {
log.Println("failed to read the keyfile at", "keyfile", u.config.KeyPath, "err", err)
return
}

key, err := keystore.DecryptKey(keyjson, password)
if err != nil {
log.Println("error decrypting ", "err", err)
return
}

u.privateKey = key.PrivateKey

intv := util.MustParseDuration(u.config.Interval)
timer := time.NewTimer(intv)
log.Printf("Set payouts interval to %v", intv)
Expand Down Expand Up @@ -132,13 +157,9 @@ func (u *PayoutsProcessor) process() {
if !u.checkPeers() {
break
}
// Require unlocked account
if !u.isUnlockedAccount() {
break
}

// Check if we have enough funds
poolBalance, err := u.rpc.GetBalance(u.config.Address)
poolBalance, err := u.rpc.BalanceAt(context.TODO(), common.HexToAddress(u.config.Address), nil)
if err != nil {
u.halt = true
u.lastFail = err
Expand Down Expand Up @@ -171,8 +192,52 @@ func (u *PayoutsProcessor) process() {
break
}

value := hexutil.EncodeBig(amountInWei)
txHash, err := u.rpc.SendTransaction(u.config.Address, login, u.config.GasHex(), u.config.GasPriceHex(), value, u.config.AutoGas)
publicKey := u.privateKey.Public()
publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
if !ok {
log.Printf("publicKey")
u.halt = true
u.lastFail = err
break
}

fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
nonce, err := u.rpc.NonceAt(context.TODO(), fromAddress, nil)
if err != nil {
log.Printf("NonceAt")
u.halt = true
u.lastFail = err
break
}

gasLimit := uint64(21000) // in units
gasPrice, err := u.rpc.SuggestGasPrice(context.Background())
if err != nil {
log.Printf("SuggestGasPrice")
u.halt = true
u.lastFail = err
break
}

var data []byte
tx := types.NewTransaction(nonce, common.HexToAddress(login), amountInWei, gasLimit, gasPrice, data)
signedTx, err := types.SignTx(tx, types.NewEIP155Signer(big.NewInt(1337)), u.privateKey)
if err != nil {
log.Printf("SignTx")
u.halt = true
u.lastFail = err
break
}

err = u.rpc.SendTransaction(context.Background(), signedTx)
if err != nil {
log.Println("SendTransaction", err)
u.halt = true
u.lastFail = err
break
}

//txHash, err := u.rpc.SendTransaction(privateKey, u.config.Address, login, u.config.GasHex(), u.config.GasPriceHex(), value, u.config.AutoGas)
if err != nil {
log.Printf("Failed to send payment to %s, %v Shannon: %v. Check outgoing tx for %s in block explorer and docs/PAYOUTS.md",
login, amount, err, login)
Expand All @@ -182,33 +247,33 @@ func (u *PayoutsProcessor) process() {
}

// Log transaction hash
err = u.backend.WritePayment(login, txHash, amount)
err = u.backend.WritePayment(login, signedTx.Hash().String(), amount)
if err != nil {
log.Printf("Failed to log payment data for %s, %v Shannon, tx: %s: %v", login, amount, txHash, err)
log.Printf("Failed to log payment data for %s, %v Shannon, tx: %s: %v", login, amount, signedTx.Hash().String(), err)
u.halt = true
u.lastFail = err
break
}

minersPaid++
totalAmount.Add(totalAmount, big.NewInt(amount))
log.Printf("Paid %v Shannon to %v, TxHash: %v", amount, login, txHash)
log.Printf("Paid %v Shannon to %v, TxHash: %v", amount, login, signedTx.Hash().String())

// Wait for TX confirmation before further payouts
for {
log.Printf("Waiting for tx confirmation: %v", txHash)
log.Printf("Waiting for tx confirmation: %v", signedTx.Hash().String())
time.Sleep(txCheckInterval)
receipt, err := u.rpc.GetTxReceipt(txHash)
receipt, err := u.rpc.TransactionReceipt(context.TODO(), common.HexToHash(signedTx.Hash().String()))
if err != nil {
log.Printf("Failed to get tx receipt for %v: %v", txHash, err)
log.Printf("Failed to get tx receipt for %v: %v", signedTx.Hash().String(), err)
continue
}
// Tx has been mined
if receipt != nil && receipt.Confirmed() {
if receipt.Successful() {
log.Printf("Payout tx successful for %s: %s", login, txHash)
if receipt != nil && receipt.Status == 1 {
if receipt.Status == 1 {
log.Printf("Payout tx successful for %s: %s", login, signedTx.Hash().String())
} else {
log.Printf("Payout tx failed for %s: %s. Address contract throws on incoming tx.", login, txHash)
log.Printf("Payout tx failed for %s: %s. Address contract throws on incoming tx.", login, signedTx.Hash().String())
}
break
}
Expand All @@ -227,22 +292,22 @@ func (u *PayoutsProcessor) process() {
}
}

func (self PayoutsProcessor) isUnlockedAccount() bool {
_, err := self.rpc.Sign(self.config.Address, "0x0")
if err != nil {
log.Println("Unable to process payouts:", err)
return false
}
return true
}
//func (self PayoutsProcessor) isUnlockedAccount() bool {
// _, err := self.rpc.Sign(self.config.Address, "0x0")
// if err != nil {
// log.Println("Unable to process payouts:", err)
// return false
// }
// return true
//}

func (self PayoutsProcessor) checkPeers() bool {
n, err := self.rpc.GetPeerCount()
n, err := self.rpc.PeerCount(context.TODO())
if err != nil {
log.Println("Unable to start payouts, failed to retrieve number of peers from node:", err)
return false
}
if n < self.config.RequirePeers {
if int64(n) < self.config.RequirePeers {
log.Println("Unable to start payouts, number of peers on a node is less than required", self.config.RequirePeers)
return false
}
Expand Down
18 changes: 7 additions & 11 deletions payouts/unlocker.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"strings"
"time"

"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereumfair/go-ethereum/common/math"

"github.com/sammy007/open-ethereum-pool/rpc"
"github.com/sammy007/open-ethereum-pool/storage"
Expand All @@ -31,8 +31,7 @@ type UnlockerConfig struct {
const minDepth = 16
const byzantiumHardForkHeight = 4370000

var homesteadReward = math.MustParseBig256("5000000000000000000")
var byzantiumReward = math.MustParseBig256("3000000000000000000")
var reward = math.MustParseBig256("2000000000000000000")

// Donate 10% from pool fees to developers
const donationFee = 10.0
Expand Down Expand Up @@ -209,7 +208,7 @@ func (u *BlockUnlocker) handleBlock(block *rpc.GetBlockReply, candidate *storage
return err
}
candidate.Height = correctHeight
reward := getConstReward(candidate.Height)
reward := getConstReward()

// Add TX fees
extraTxReward, err := u.getExtraRewardForTx(block)
Expand Down Expand Up @@ -501,20 +500,17 @@ func weiToShannonInt64(wei *big.Rat) int64 {
return value
}

func getConstReward(height int64) *big.Int {
if height >= byzantiumHardForkHeight {
return new(big.Int).Set(byzantiumReward)
}
return new(big.Int).Set(homesteadReward)
func getConstReward() *big.Int {
return new(big.Int).Set(reward)
}

func getRewardForUncle(height int64) *big.Int {
reward := getConstReward(height)
reward := getConstReward()
return new(big.Int).Div(reward, new(big.Int).SetInt64(32))
}

func getUncleReward(uHeight, height int64) *big.Int {
reward := getConstReward(height)
reward := getConstReward()
k := height - uHeight
reward.Mul(big.NewInt(8-k), reward)
reward.Div(reward, big.NewInt(8))
Expand Down
2 changes: 1 addition & 1 deletion proxy/blocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"strings"
"sync"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereumfair/go-ethereum/common"

"github.com/sammy007/open-ethereum-pool/rpc"
"github.com/sammy007/open-ethereum-pool/util"
Expand Down
4 changes: 2 additions & 2 deletions proxy/miner.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"strconv"
"strings"

"github.com/ethereum/ethash"
"github.com/ethereum/go-ethereum/common"
"github.com/FranckStone/ethash"
"github.com/ethereumfair/go-ethereum/common"
)

var hasher = ethash.New()
Expand Down
5 changes: 2 additions & 3 deletions rpc/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ import (
"strings"
"sync"

"github.com/ethereum/go-ethereum/common"

"github.com/ethereumfair/go-ethereum/common"
"github.com/sammy007/open-ethereum-pool/util"
)

Expand Down Expand Up @@ -177,7 +176,7 @@ func (r *RPCClient) GetBalance(address string) (*big.Int, error) {

func (r *RPCClient) Sign(from string, s string) (string, error) {
hash := sha256.Sum256([]byte(s))
rpcResp, err := r.doPost(r.Url, "eth_sign", []string{from, common.ToHex(hash[:])})
rpcResp, err := r.doPost(r.Url, "eth_sign", []string{from, common.Bytes2Hex(hash[:])})
var reply string
if err != nil {
return reply, err
Expand Down
Loading