FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
PacketCrypt/src/Difficulty.c at develop · javascriptit/PacketCrypt · GitHub
javascriptit
PacketCrypt
Repository navigation
Code
Pull requests
Actions
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
PacketCrypt
/
src
/
Difficulty.c
Copy path
More file actions
More file actions
Latest commit
History
History
History
304 lines (262 loc) · 8.16 KB
Breadcrumbs
PacketCrypt
/
src
/
Difficulty.c
Copy path
File metadata and controls
304 lines (262 loc) · 8.16 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
/**
* (C) Copyright 2019
* Caleb James DeLisle
*
* SPDX-License-Identifier: (LGPL-2.1-only OR LGPL-3.0-only)
*/
#include
"Difficulty.h"
#include
"Conf.h"
#include
"config.h"
#include
<assert.h>
#include
<stdbool.h>
#ifdef
__APPLE__
// Apple ships with openssl and then complains when you use it
// because they'd rather you use their framework instead
#pragma
GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#include
<openssl/bn.h>
static
void
bnSetCompact
(
BIGNUM
*
bn
,
uint32_t
nCompact
)
{
unsigned
int
nSize
=
nCompact
>>
24
;
bool
fNegative
=
(
nCompact
&
0x00800000
)
!=
0
;
unsigned
int
nWord
=
nCompact
&
0x007fffff
;
if
(
nSize
<=
3
)
{
nWord
>>=
8
*
(
3
-
nSize
);
assert
(
BN_set_word
(
bn
,
nWord
));
}
else
{
assert
(
BN_set_word
(
bn
,
nWord
));
assert
(
BN_lshift
(
bn
,
bn
,
8
*
(
nSize
-
3
)));
}
BN_set_negative
(
bn
,
fNegative
);
}
static
uint32_t
bnGetCompact
(
const
BIGNUM
*
bn
)
{
unsigned
int
nSize
=
BN_num_bytes
(
bn
);
unsigned
int
nCompact
=
0
;
if
(
nSize
<=
3
)
nCompact
=
BN_get_word
(
bn
) <<
8
*
(
3
-
nSize
);
else
{
//CBigNum x;
BIGNUM
*
x
=
BN_new
();
assert
(
x
);
assert
(
BN_rshift
(
x
,
bn
,
8
*
(
nSize
-
3
)));
nCompact
=
BN_get_word
(
x
);
BN_free
(
x
);
}
// The 0x00800000 bit denotes the sign.
// Thus, if it is already set, divide the mantissa by 256 and increase the exponent.
if
(
nCompact
&
0x00800000
)
{
nCompact
>>=
8
;
nSize
++
;
}
nCompact
|=
nSize
<<
24
;
nCompact
|= (
BN_is_negative
(
bn
) ?
0x00800000
:
0
);
return
nCompact
;
}
static
inline
void
bn256
(
BIGNUM
*
out
) {
BN_one
(
out
);
assert
(
BN_lshift
(
out
,
out
,
256
));
}
// work = 2**256 / (target + 1)
static
inline
void
bnWorkForDiff
(
BN_CTX
*
ctx
,
BIGNUM
*
workOut
,
/*const*/
BIGNUM
*
diff
) {
// workOut = 2**256
bn256
(
workOut
);
// diff++
assert
(
BN_add
(
diff
,
diff
,
BN_value_one
()));
// workOut /= diff
assert
(
BN_div
(
workOut
,
NULL
,
workOut
,
diff
,
ctx
));
// diff--
assert
(
BN_sub
(
diff
,
diff
,
BN_value_one
()));
}
// diffOut = (2**256 - work) / work
static
inline
void
bnDiffForWork
(
BN_CTX
*
ctx
,
BIGNUM
*
diffOut
,
const
BIGNUM
*
work
)
{
// diffOut = 2**256
bn256
(
diffOut
);
// if work is zero then target is maximum (minimum difficulty)
if
(
BN_is_zero
(
work
)) {
return
; }
// diffOut -= work
assert
(
BN_sub
(
diffOut
,
diffOut
,
work
));
// diffOut /= work
assert
(
BN_div
(
diffOut
,
NULL
,
diffOut
,
work
,
ctx
));
}
static
void
setuint64
(
BIGNUM
*
out
,
uint64_t
n
)
{
unsigned
char
pch
[
sizeof
(
n
)
+
6
];
unsigned
char
*
p
=
pch
+
4
;
bool
fLeadingZeroes
=
true;
for
(
int
i
=
0
;
i
<
8
;
i
++
)
{
unsigned
char
c
=
(
n
>>
56
)
&
0xff
;
n
<<=
8
;
if
(
fLeadingZeroes
)
{
if
(
c
==
0
)
continue
;
if
(
c
&
0x80
)
*
p
++
=
0
;
fLeadingZeroes
=
false;
}
*
p
++
=
c
;
}
unsigned
int
nSize
=
p
-
(
pch
+
4
);
pch
[
0
]
=
(
nSize
>>
24
)
&
0xff
;
pch
[
1
]
=
(
nSize
>>
16
)
&
0xff
;
pch
[
2
]
=
(
nSize
>>
8
)
&
0xff
;
pch
[
3
]
=
(
nSize
)
&
0xff
;
assert
(
BN_mpi2bn
(
pch
,
p
-
pch
,
out
)
==
out
);
}
static
inline
void
assign
(
BIGNUM
*
out
,
const
BIGNUM
*
val
) {
assert
(
BN_zero
(
out
));
assert
(
BN_add
(
out
,
out
,
val
));
}
static
inline
void
getEffectiveWork
(
BN_CTX
*
ctx
,
BIGNUM
*
workOut
,
const
BIGNUM
*
blockWork
,
const
BIGNUM
*
annWork
,
uint64_t
annCount
)
{
if
(
BN_is_zero
(
annWork
)
||
!
annCount
) {
// This is work *required* so when there is no work and no announcements
// that work is "infinite".
bn256
(
workOut
);
return
;
}
assign
(
workOut
,
blockWork
);
// workOut = workOut**3
assert
(
BN_sqr
(
workOut
,
workOut
,
ctx
));
assert
(
BN_mul
(
workOut
,
workOut
,
blockWork
,
ctx
));
#ifdef
PCP2
// difficulty *= 1024
assert
(
BN_lshift
(
workOut
,
workOut
,
10
));
#endif
// workOut /= annWork
assert
(
BN_div
(
workOut
,
NULL
,
workOut
,
annWork
,
ctx
));
BIGNUM
*
bnAnnCount
=
BN_new
();
assert
(
bnAnnCount
);
setuint64
(
bnAnnCount
,
annCount
);
#ifdef
PCP2
assert
(
BN_sqr
(
bnAnnCount
,
bnAnnCount
,
ctx
));
#endif
// workOut /= annCount
assert
(
BN_div
(
workOut
,
NULL
,
workOut
,
bnAnnCount
,
ctx
));
BN_free
(
bnAnnCount
);
}
uint32_t
Difficulty_getEffectiveTarget
(
uint32_t
blockTar
,
uint32_t
annTar
,
uint64_t
annCount
)
{
BN_CTX
*
ctx
=
BN_CTX_new
();
assert
(
ctx
);
BIGNUM
*
x
=
BN_new
();
assert
(
x
);
BIGNUM
*
bnBlockWork
=
BN_new
();
assert
(
bnBlockWork
);
BIGNUM
*
bnAnnWork
=
BN_new
();
assert
(
bnAnnWork
);
bnSetCompact
(
x
,
blockTar
);
bnWorkForDiff
(
ctx
,
bnBlockWork
,
x
);
bnSetCompact
(
x
,
annTar
);
bnWorkForDiff
(
ctx
,
bnAnnWork
,
x
);
getEffectiveWork
(
ctx
,
x
,
bnBlockWork
,
bnAnnWork
,
annCount
);
bnDiffForWork
(
ctx
,
bnBlockWork
,
x
);
uint32_t
res
=
bnGetCompact
(
bnBlockWork
);
BN_free
(
x
);
BN_free
(
bnBlockWork
);
BN_free
(
bnAnnWork
);
BN_CTX_free
(
ctx
);
return
res
>
0x207fffff
?
0x207fffff
:
res
;
}
uint64_t
Difficulty_getHashRateMultiplier
(
uint32_t
annTar
,
uint64_t
annCount
)
{
BN_CTX
*
ctx
=
BN_CTX_new
();
assert
(
ctx
);
BIGNUM
*
x
=
BN_new
();
assert
(
x
);
BIGNUM
*
bnAnnWork
=
BN_new
();
assert
(
bnAnnWork
);
BIGNUM
*
bnAnnCount
=
BN_new
();
assert
(
bnAnnCount
);
bnSetCompact
(
x
,
annTar
);
bnWorkForDiff
(
ctx
,
bnAnnWork
,
x
);
setuint64
(
bnAnnCount
,
annCount
);
#ifdef
PCP2
assert
(
BN_sqr
(
bnAnnCount
,
bnAnnCount
,
ctx
));
#endif
assert
(
BN_mul
(
x
,
bnAnnWork
,
bnAnnCount
,
ctx
));
#ifdef
PCP2
// Difficulty jumps by 1024
assert
(
BN_rshift
(
x
,
x
,
10
));
#endif
uint64_t
out
=
BN_get_word
(
x
);
BN_free
(
bnAnnCount
);
BN_free
(
bnAnnWork
);
BN_free
(
x
);
BN_CTX_free
(
ctx
);
return
out
;
}
static
inline
uint32_t
degradeAnnouncementTarget2
(
uint32_t
annTar
,
uint32_t
annAgeBlocks
)
{
if
(
annAgeBlocks
<
Conf_PacketCrypt_ANN_WAIT_PERIOD
) {
return
0xffffffff
; }
if
(
annAgeBlocks
==
Conf_PacketCrypt_ANN_WAIT_PERIOD
) {
return
annTar
; }
annAgeBlocks
-=
Conf_PacketCrypt_ANN_WAIT_PERIOD
;
BIGNUM
*
bnAnnTar
=
BN_new
();
assert
(
bnAnnTar
);
bnSetCompact
(
bnAnnTar
,
annTar
);
assert
(
BN_lshift
(
bnAnnTar
,
bnAnnTar
,
annAgeBlocks
));
uint32_t
out
=
0xffffffff
;
if
(
BN_num_bits
(
bnAnnTar
)
<
256
) {
out
=
bnGetCompact
(
bnAnnTar
);
}
BN_free
(
bnAnnTar
);
return
out
>
0x207fffff
?
0xffffffff
:
out
;
}
uint32_t
Difficulty_degradeAnnouncementTarget
(
uint32_t
annTar
,
uint32_t
annAgeBlocks
)
{
#ifdef
PCP2
return
degradeAnnouncementTarget2
(
annTar
,
annAgeBlocks
);
#endif
if
(
annAgeBlocks
<
Conf_PacketCrypt_ANN_WAIT_PERIOD
) {
return
0xffffffff
; }
annAgeBlocks
-=
(
Conf_PacketCrypt_ANN_WAIT_PERIOD
-
1
);
BN_CTX
*
ctx
=
BN_CTX_new
();
assert
(
ctx
);
BIGNUM
*
bnAnnTar
=
BN_new
();
assert
(
bnAnnTar
);
BIGNUM
*
bnAnnWork
=
BN_new
();
assert
(
bnAnnWork
);
BIGNUM
*
bnAnnAgeBlocks
=
BN_new
();
assert
(
bnAnnAgeBlocks
);
setuint64
(
bnAnnAgeBlocks
,
annAgeBlocks
);
bnSetCompact
(
bnAnnTar
,
annTar
);
bnWorkForDiff
(
ctx
,
bnAnnWork
,
bnAnnTar
);
assert
(
BN_div
(
bnAnnWork
,
NULL
,
bnAnnWork
,
bnAnnAgeBlocks
,
ctx
));
bnDiffForWork
(
ctx
,
bnAnnTar
,
bnAnnWork
);
uint32_t
out
=
bnGetCompact
(
bnAnnTar
);
BN_free
(
bnAnnTar
);
BN_free
(
bnAnnWork
);
BN_free
(
bnAnnAgeBlocks
);
BN_CTX_free
(
ctx
);
// if out > 0x207fffff then it rounds to zero, meaning the announcement cannot be mined
return
out
>
0x207fffff
?
0xffffffff
:
out
;
}
// IsAnnMinDiffOk is kind of a sanity check to make sure that the miner doesn't provide
// "silly" results which might trigger wrong behavior from the diff computation
bool
Difficulty_isMinAnnDiffOk
(
uint32_t
target
)
{
if
(
target
==
0
||
target
>
0x20ffffff
) {
return
false;
}
#ifdef
PCP2
if
(
target
>
0x207fffff
) {
return
false; }
#endif
BN_CTX
*
ctx
=
BN_CTX_new
();
assert
(
ctx
);
BIGNUM
*
bnTar
=
BN_new
();
assert
(
bnTar
);
BIGNUM
*
bnWork
=
BN_new
();
assert
(
bnWork
);
BIGNUM
*
bnMax
=
BN_new
();
assert
(
bnMax
);
bnSetCompact
(
bnTar
,
target
);
#ifdef
PCP2
if
(
BN_is_zero
(
bnTar
)
||
BN_is_negative
(
bnTar
)) {
return
false; }
#endif
bnWorkForDiff
(
ctx
,
bnWork
,
bnTar
);
if
(
BN_is_zero
(
bnWork
)) {
return
false; }
bn256
(
bnMax
);
if
(
BN_cmp
(
bnWork
,
bnMax
) >=
0
) {
return
false; }
BN_free
(
bnTar
);
BN_free
(
bnWork
);
BN_free
(
bnMax
);
BN_CTX_free
(
ctx
);
return
true;
}
Back
|
FazBrowse Home
|
New Git URL