From 7ff3eaa37664e0fe319d20ecb9aaccbabde2d0bc Mon Sep 17 00:00:00 2001 From: yuriy0803 <68668177+yuriy0803@users.noreply.github.com> Date: Thu, 9 Sep 2021 23:32:25 +0200 Subject: [PATCH] update unlocker mordor, classic, ethereum, ropsten or ubiq --- README.md | 25 +++--- payouts/unlocker.go | 192 ++++++++++++++++++++++++++++++++++++++------ proxy/miner.go | 5 ++ 3 files changed, 185 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index e28b30a..1439eb4 100644 --- a/README.md +++ b/README.md @@ -115,8 +115,8 @@ otherwise you will get errors on start because of JSON comments.** "coin": "etc", // Give unique name to each instance "name": "main", - // mordor OR classic - //"network": "classic", + // mordor, classic, ethereum, ropsten or ubiq + "network": "classic", "proxy": { "enabled": true, @@ -139,10 +139,13 @@ otherwise you will get errors on start because of JSON comments.** // Bind stratum mining socket to this IP:PORT "listen": "0.0.0.0:8008", "timeout": "120s", - "maxConn": 8192 + "maxConn": 8192, + "tls": false, + "certFile": "/path/to/cert.pem", + "keyFile": "/path/to/key.pem" }, - // Try to get new job from geth in this interval + // Try to get new job from node in this interval "blockRefreshInterval": "120ms", "stateUpdateInterval": "3s", // Require this share difficulty from miners @@ -216,10 +219,10 @@ otherwise you will get errors on start because of JSON comments.** "purgeOnly": false }, - // Check health of each geth node in this interval + // Check health of each node in this interval "upstreamCheckInterval": "5s", - /* List of geth nodes to poll for new jobs. Pool will try to get work from + /* List of parity nodes to poll for new jobs. Pool will try to get work from first alive one and check in background for failed to back up. Current block template of the pool is always cached in RAM indeed. */ @@ -262,9 +265,9 @@ otherwise you will get errors on start because of JSON comments.** "keepTxFees": false, // Run unlocker in this interval "interval": "10m", - // Geth instance node rpc endpoint for unlocking blocks + // Parity node rpc endpoint for unlocking blocks "daemon": "http://127.0.0.1:8545", - // Rise error if can't reach geth in this amount of time + // Rise error if can't reach parity "timeout": "10s" }, @@ -275,13 +278,13 @@ otherwise you will get errors on start because of JSON comments.** "requirePeers": 25, // Run payouts in this interval "interval": "12h", - // Geth instance node rpc endpoint for payouts processing + // Parity node rpc endpoint for payouts processing "daemon": "http://127.0.0.1:8545", - // Rise error if can't reach geth in this amount of time + // Rise error if can't reach parity "timeout": "10s", // Address with pool balance "address": "0x0", - // Let geth to determine gas and gasPrice + // Let parity to determine gas and gasPrice "autoGas": true, // Gas amount and price for payout tx (advanced users only) "gas": "21000", diff --git a/payouts/unlocker.go b/payouts/unlocker.go index d4d02f7..6e190f7 100644 --- a/payouts/unlocker.go +++ b/payouts/unlocker.go @@ -17,28 +17,41 @@ import ( ) type UnlockerConfig struct { - Enabled bool `json:"enabled"` - PoolFee float64 `json:"poolFee"` - PoolFeeAddress string `json:"poolFeeAddress"` - Donate bool `json:"donate"` - Depth int64 `json:"depth"` - ImmatureDepth int64 `json:"immatureDepth"` - KeepTxFees bool `json:"keepTxFees"` - Interval string `json:"interval"` - Daemon string `json:"daemon"` - Timeout string `json:"timeout"` - Ecip1017FBlock int64 `json:"ecip1017FBlock"` - Ecip1017EraRounds *big.Int `json:"ecip1017EraRounds"` + Enabled bool `json:"enabled"` + PoolFee float64 `json:"poolFee"` + PoolFeeAddress string `json:"poolFeeAddress"` + Donate bool `json:"donate"` + Depth int64 `json:"depth"` + ImmatureDepth int64 `json:"immatureDepth"` + KeepTxFees bool `json:"keepTxFees"` + Interval string `json:"interval"` + Daemon string `json:"daemon"` + Timeout string `json:"timeout"` + Ecip1017FBlock int64 `json:"ecip1017FBlock"` + Ecip1017EraRounds *big.Int `json:"ecip1017EraRounds"` + ByzantiumFBlock *big.Int `json:"byzantiumFBlock"` + ConstantinopleFBlock *big.Int `json:"constantinopleFBlock"` + Network string `json:"network"` } const minDepth = 16 +// params for etchash +var homesteadReward = math.MustParseBig256("5000000000000000000") var disinflationRateQuotient = big.NewInt(4) // Disinflation rate quotient for ECIP1017 var disinflationRateDivisor = big.NewInt(5) // Disinflation rate divisor for ECIP1017 +// params for ethash +var frontierBlockReward = big.NewInt(5e+18) +var byzantiumBlockReward = big.NewInt(3e+18) +var constantinopleBlockReward = big.NewInt(2e+18) + +// params for ubqhash +var ubiqStartReward = big.NewInt(8e+18) + +// misc consts var big32 = big.NewInt(32) var big8 = big.NewInt(8) - -var homesteadReward = math.MustParseBig256("5000000000000000000") +var big2 = big.NewInt(2) type BlockUnlocker struct { config *UnlockerConfig @@ -48,17 +61,29 @@ type BlockUnlocker struct { lastFail error } -func NewBlockUnlocker(cfg *UnlockerConfig, backend *storage.RedisClient, network *string) *BlockUnlocker { - if *network == "classic" { +func NewBlockUnlocker(cfg *UnlockerConfig, backend *storage.RedisClient, network string) *BlockUnlocker { + // determine which monetary policy to use based on network + // configure any reward params if needed. + if network == "classic" { cfg.Ecip1017FBlock = 5000000 cfg.Ecip1017EraRounds = big.NewInt(5000000) - } else if *network == "mordor" { + } else if network == "mordor" { cfg.Ecip1017FBlock = 0 cfg.Ecip1017EraRounds = big.NewInt(2000000) + } else if network == "ethereum" { + cfg.ByzantiumFBlock = big.NewInt(4370000) + cfg.ConstantinopleFBlock = big.NewInt(7280000) + } else if network == "ropsten" { + cfg.ByzantiumFBlock = big.NewInt(1700000) + cfg.ConstantinopleFBlock = big.NewInt(4230000) + } else if network == "ubiq" { + // nothing needs configuring here, simply proceed. } else { log.Fatalln("Invalid network set", network) } + cfg.Network = network + if len(cfg.PoolFeeAddress) != 0 && !util.IsValidHexAddress(cfg.PoolFeeAddress) { log.Fatalln("Invalid poolFeeAddress", cfg.PoolFeeAddress) } @@ -227,13 +252,31 @@ func (u *BlockUnlocker) handleBlock(block *rpc.GetBlockReply, candidate *storage return err } candidate.Height = correctHeight - era := GetBlockEra(big.NewInt(candidate.Height), u.config.Ecip1017EraRounds) - reward := getConstReward(era) - - // Add reward for including uncles - uncleReward := getRewardForUncle(reward) - rewardForUncles := big.NewInt(0).Mul(uncleReward, big.NewInt(int64(len(block.Uncles)))) - reward.Add(reward, rewardForUncles) + var reward *big.Int = big.NewInt(0) + if u.config.Network == "classic" || u.config.Network == "mordor" { + era := GetBlockEra(big.NewInt(candidate.Height), u.config.Ecip1017EraRounds) + reward = getConstReward(era) + // Add reward for including uncles + uncleReward := getRewardForUncle(reward) + rewardForUncles := big.NewInt(0).Mul(uncleReward, big.NewInt(int64(len(block.Uncles)))) + reward.Add(reward, rewardForUncles) + + } else if u.config.Network == "ubiq" { + reward = getConstRewardUbiq(candidate.Height) + // Add reward for including uncles + uncleReward := new(big.Int).Div(reward, big32) + rewardForUncles := big.NewInt(0).Mul(uncleReward, big.NewInt(int64(len(block.Uncles)))) + reward.Add(reward, rewardForUncles) + + } else if u.config.Network == "ethereum" || u.config.Network == "ropsten" { + reward = getConstRewardEthereum(candidate.Height, u.config) + // Add reward for including uncles + uncleReward := new(big.Int).Div(reward, big32) + rewardForUncles := big.NewInt(0).Mul(uncleReward, big.NewInt(int64(len(block.Uncles)))) + reward.Add(reward, rewardForUncles) + } else { + log.Fatalln("Invalid network set", u.config.Network) + } // Add TX fees extraTxReward, err := u.getExtraRewardForTx(block) @@ -257,8 +300,15 @@ func handleUncle(height int64, uncle *rpc.GetBlockReply, candidate *storage.Bloc if err != nil { return err } - era := GetBlockEra(big.NewInt(height), cfg.Ecip1017EraRounds) - reward := getUncleReward(new(big.Int).SetInt64(uncleHeight), new(big.Int).SetInt64(height), era, getConstReward(era)) + var reward *big.Int = big.NewInt(0) + if cfg.Network == "classic" || cfg.Network == "mordor" { + era := GetBlockEra(big.NewInt(height), cfg.Ecip1017EraRounds) + reward = getUncleReward(new(big.Int).SetInt64(uncleHeight), new(big.Int).SetInt64(height), era, getConstReward(era)) + } else if cfg.Network == "ubiq" { + reward = getUncleRewardUbiq(new(big.Int).SetInt64(uncleHeight), new(big.Int).SetInt64(height), getConstRewardUbiq(height)) + } else if cfg.Network == "ethereum" || cfg.Network == "ropsten" { + reward = getUncleRewardEthereum(new(big.Int).SetInt64(uncleHeight), new(big.Int).SetInt64(height), getConstRewardUbiq(height)) + } candidate.Height = height candidate.UncleHeight = uncleHeight candidate.Orphan = false @@ -569,16 +619,19 @@ func GetBlockEra(blockNum, eraLength *big.Int) *big.Int { return new(big.Int).Sub(d, dremainder) } +// etchash func getConstReward(era *big.Int) *big.Int { var blockReward = homesteadReward wr := GetBlockWinnerRewardByEra(era, blockReward) return wr } +//etchash func getRewardForUncle(blockReward *big.Int) *big.Int { return new(big.Int).Div(blockReward, big32) //return new(big.Int).Div(reward, new(big.Int).SetInt64(32)) } +// etchash func getUncleReward(uHeight *big.Int, height *big.Int, era *big.Int, reward *big.Int) *big.Int { // Era 1 (index 0): // An extra reward to the winning miner for including uncles as part of the block, in the form of an extra 1/32 (0.15625ETC) per uncle included, up to a maximum of two (2) uncles. @@ -594,6 +647,93 @@ func getUncleReward(uHeight *big.Int, height *big.Int, era *big.Int, reward *big return getRewardForUncle(reward) } +// ubqhash +func getConstRewardUbiq(height int64) *big.Int { + // Rewards + reward := new(big.Int).Set(ubiqStartReward) + headerNumber := big.NewInt(height) + + if headerNumber.Cmp(big.NewInt(358363)) > 0 { + reward = big.NewInt(7e+18) + // Year 1 + } + if headerNumber.Cmp(big.NewInt(716727)) > 0 { + reward = big.NewInt(6e+18) + // Year 2 + } + if headerNumber.Cmp(big.NewInt(1075090)) > 0 { + reward = big.NewInt(5e+18) + // Year 3 + } + if headerNumber.Cmp(big.NewInt(1433454)) > 0 { + reward = big.NewInt(4e+18) + // Year 4 + } + if headerNumber.Cmp(big.NewInt(1791818)) > 0 { + reward = big.NewInt(3e+18) + // Year 5 + } + if headerNumber.Cmp(big.NewInt(2150181)) > 0 { + reward = big.NewInt(2e+18) + // Year 6 + } + if headerNumber.Cmp(big.NewInt(2508545)) > 0 { + reward = big.NewInt(1e+18) + // Year 7 + } + + return reward +} + +// ubqhash +func getUncleRewardUbiq(uHeight *big.Int, height *big.Int, reward *big.Int) *big.Int { + + r := new(big.Int) + + r.Add(uHeight, big2) + r.Sub(r, height) + r.Mul(r, reward) + r.Div(r, big2) + if r.Cmp(big.NewInt(0)) < 0 { + // blocks older than the previous block are not rewarded + r = big.NewInt(0) + } + + return r +} + +// ethash +func getConstRewardEthereum(height int64, cfg *UnlockerConfig) *big.Int { + // Select the correct block reward based on chain progression + blockReward := frontierBlockReward + headerNumber := big.NewInt(height) + if cfg.ByzantiumFBlock.Cmp(headerNumber) <= 0 { + blockReward = byzantiumBlockReward + } + if cfg.ConstantinopleFBlock.Cmp(headerNumber) <= 0 { + blockReward = constantinopleBlockReward + } + // Accumulate the rewards for the miner and any included uncles + reward := new(big.Int).Set(blockReward) + return reward +} + +// ethash +func getUncleRewardEthereum(uHeight *big.Int, height *big.Int, reward *big.Int) *big.Int { + r := new(big.Int) + r.Add(uHeight, big8) + r.Sub(r, height) + r.Mul(r, reward) + r.Div(r, big8) + if r.Cmp(big.NewInt(0)) < 0 { + r = big.NewInt(0) + } + + return r +} + +// ethash, etchash, ubqhash + func (u *BlockUnlocker) getExtraRewardForTx(block *rpc.GetBlockReply) (*big.Int, error) { amount := new(big.Int) diff --git a/proxy/miner.go b/proxy/miner.go index e48e18a..2df32cd 100644 --- a/proxy/miner.go +++ b/proxy/miner.go @@ -12,6 +12,7 @@ import ( var ecip1099FBlockClassic uint64 = 11700000 // classic mainnet var ecip1099FBlockMordor uint64 = 2520000 // mordor +var uip1FEpoch uint64 = 22 // ubiq mainnet var hasher *etchash.Etchash = nil @@ -21,6 +22,10 @@ func (s *ProxyServer) processShare(login, id, ip string, t *BlockTemplate, param hasher = etchash.New(&ecip1099FBlockClassic, nil) } else if s.config.Network == "mordor" { hasher = etchash.New(&ecip1099FBlockMordor, nil) + } else if s.config.Network == "ubiq" { + hasher = etchash.New(nil, &uip1FEpoch) + } else if s.config.Network == "ethereum" || s.config.Network == "ropsten" { + hasher = etchash.New(nil, nil) } else { // unknown network log.Printf("Unknown network configuration %s", s.config.Network)