Skip to content

Instantly share code, notes, and snippets.

@HAOYUatHZ
Last active June 5, 2023 07:36
Show Gist options
  • Save HAOYUatHZ/d6403fe83d8802eaca252957f6afbc24 to your computer and use it in GitHub Desktop.
Save HAOYUatHZ/d6403fe83d8802eaca252957f6afbc24 to your computer and use it in GitHub Desktop.

Pool

  • 什么是拒绝数?拒绝率?
    • 根据矿池的工作原理,矿池不断给矿机下发新的计算任务,矿机将计算结果提交给矿池。但是由于矿机与矿池的网络连接是有延迟的,从矿池下发新的挖矿高度的任务给矿机,到矿机接收到任务,在这段时间提交的结果已经过时,将不被矿池承认。拒绝率即无效提交与总提交结果之比。
    • 拒绝数是指矿机提交的算力不符合服务器要求,被服务器拒绝的工作量。拒绝率是指拒绝数占总提交数的比例,数值越小,矿机的工作效率就越高。
  • 幸运值
    • 每个区块的幸运值是矿池实际工作量与挖矿难度之比。如果工作量小于难度,说明运气比较好,幸运值就越高。挖矿的运气成分很大,幸运值发生波动也很常见,但挖矿时间越久,总幸运值越接近 100%。
  • 结算方式
    • PPS
      • 收益稳定,只要矿机正常工作就有收益,收益和提交的工作量有关,和矿池幸运值、交易手续费无关
    • PPS+
      • 该结算方式蚂蚁矿池将交易手续费分配给矿工,所以交易手续费高,收益高;交易手续费低,收益低
    • PPLNS
      • 收益与矿池幸运值有关,矿池幸运值高,收益高;矿池幸运值低,收益低
    • SOLO
      • 矿机爆块才有收益,如果矿机爆块可获得该块扣除挖矿手续费的所有收益,如果矿机不爆块则没有收益
@HAOYUatHZ
Copy link
Author

config/genesis.go

block := &types.Block{
	BlockHeader: types.BlockHeader{
		Version:   1,
		Height:    0,
		Nonce:     9253507043297,
		Timestamp: 1524549600,
		Bits:      2161727821137910632,
		BlockCommitment: types.BlockCommitment{
			TransactionsMerkleRoot: merkleRoot,
			TransactionStatusHash:  txStatusHash,
		},
	},
	Transactions: []*types.Tx{tx},
}

@HAOYUatHZ
Copy link
Author

HAOYUatHZ commented May 18, 2018

retarget

func (m *Miner) retarget(s *StratumServer, now int64) {
	options := s.config.TargetConfig
	sinceLast := now - m.lastShareTime
	var value int64 = 0
	decreaser := false
	if float64(sinceLast) > s.varDiff.TMax {
		decreaser = true
		value = sinceLast
	}

	avg := m.shareTimeRing.Avg(value)
	var newDiff float64
	var direction int
	if avg > s.varDiff.TMax && m.difficulty > options.MinDiff {
		newDiff = float64(options.TargetTime) / avg * float64(m.difficulty)
		if newDiff < float64(options.MinDiff) {
			newDiff = float64(options.MinDiff)
		}
		direction = -1
	} else if avg < s.varDiff.TMin && m.difficulty < options.MaxDiff {
		newDiff = float64(options.TargetTime) / avg * float64(m.difficulty)
		if newDiff > float64(options.MaxDiff) {
			newDiff = float64(options.MaxDiff)
		}

		direction = 1
	} else {
		return
	}

	if math.Abs(newDiff-float64(m.difficulty))/float64(m.difficulty)*100 > float64(options.MaxJump) {
		change := options.MaxJump / 100 * m.difficulty * int64(direction)
		newDiff = float64(m.difficulty) + float64(change)
	}

	m.setNewDiff(newDiff)
	m.shareTimeRing.Clear()
	if decreaser {
		m.lastShareTime = now
	}
}

@HAOYUatHZ
Copy link
Author

HAOYUatHZ commented May 18, 2018

Of these three things, only the target actually matters. That is what is used to determine if a hash is valid and that is what is changed every 2016 blocks. The number of leading zeros and the difficulty are just different representations of the target to make it easier for people to understand.

The difficulty is also kind of irrelevant. It is just something for us humans to understand how much work is being done to mine blocks. The difficulty is an alternative representation of the target and is just the highest target value possible divided by the current target value.

D = maxTarget/Target

It is easier for people to understand that a hash must have some number of leading zeros which is specified by the target than it is for people to understand that the hash is a very large number, and the target is a very large number, and that the hash must be less than the target.

The "leading zeros" are a simplification. The difficulty is encoded as a target which is essentially a 256 bit number. Since block hashes are produced by SHA-256, they're also a string of 256 bits. if I know a target has n leading zeroes, that's shorthand for saying that the actual specific target lies somewhere between [ 2^(255-n)-1, 2^(256-n)-1 ]

@HAOYUatHZ
Copy link
Author

HAOYUatHZ commented May 18, 2018

//	-------------------------------------------------
//	|   Exponent     |    Sign    |    Mantissa     |
//	-------------------------------------------------
//	| 8 bits [63-56] | 1 bit [55] | 55 bits [54-00] |
//	-------------------------------------------------
//
// 	N = (-1^sign) * mantissa * 256^(exponent-3)

@HAOYUatHZ
Copy link
Author

HAOYUatHZ commented May 18, 2018

difficulty = difficulty_1_target / current_target

The highest possible target (difficulty 1) is defined as 0x1d00ffff.

difficulty_1_target can be different for various ways to measure difficulty. Traditionally, it represents a hash where the leading 32 bits are zero and the rest are one (this is known as "pool difficulty" or "pdiff").

t pooled mining often uses non-truncated targets

There is no minimum target. The maximum difficulty is roughly: maximum_target / 1 (since 0 would result in infinity), which is a ridiculously huge number (about 2^224).

The actual maximum difficulty is when current_target=0, but we would not be able to calculate the difficulty if that happened. (fortunately it never will, so we're ok.)

The minimum difficulty, when the target is at the maximum allowed value, is 1.

To find a block, the hash must be less than the target. The hash is effectively a random number between 0 and 2**256-1. The offset for difficulty 1 is

0xffff * 2**208

and for difficulty D is

(0xffff * 2**208)/D

The expected number of hashes we need to calculate to find a block with difficulty D is therefore

D * 2**256 / (0xffff * 2**208)

or just

D * 2**48 / 0xffff

The difficulty is set such that the previous 2016 blocks would have been found at the rate of one every 10 minutes, so we were calculating (D * 2**48 / 0xffff) hashes in 600 seconds. That means the hash rate of the network was

D * 2**48 / 0xffff / 600

over the previous 2016 blocks. Can be further simplified to

D * 2**32 / 600

without much loss of accuracy.

At difficulty 1, that is around 7 Mhashes per second.

At the time of writing, the difficulty is 22012.4941572, which means that over the previous set of 2016 blocks found the average network hash rate was

22012.4941572 * 2**32 / 600 = around 157 Ghashes per second.

How soon might I expect to generate a block?
(The eternal question.)

The average time to find a block can be approximated by calculating:

time = difficulty * 2**32 / hashrate

where difficulty is the current difficulty, hashrate is the number of hashes your miner calculates per second, and time is the average in seconds between the blocks you find.

For example, using Python we calculate the average time to generate a block using a 1Ghash/s mining rig when the difficulty is 20000:

$ python -c "print 20000 * 2**32 / 10**9 / 60 / 60.0"
23.85

and find that it takes just under 24 hours on average.

@HAOYUatHZ
Copy link
Author


var Diff1 = StringToBig("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")


func GetTargetHex(diff int64) string {
	padded := make([]byte, 32)

	diffBuff := new(big.Int).Div(Diff1, big.NewInt(diff)).Bytes()
	copy(padded[32-len(diffBuff):], diffBuff)
	buff := padded[0:4]
	targetHex := hex.EncodeToString(reverse(buff))
	return targetHex
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment